docs(lacrosse-scoreboard): document all 170 settings, with real renders - #428
Merged
Conversation
The README documented a fraction of the plugin's 170 settings and had no images. It now covers every schema leaf -- verified by a token audit -- and shows the three men's display modes, both leagues side by side, the show_records toggle, and the card at four panel sizes. The two league blocks are identical in every setting except one: ncaa_mens defaults to enabled and ncaa_womens does not. Documenting one <league> table rather than two identical sets keeps 104 of the 170 leaves readable instead of duplicated. Two things the old README did not say: - display_options.show_records and show_ranking default to true per league, while defaults.show_records and defaults.show_ranking default to false, and the per-league copy wins. Because the UI writes schema defaults on save, changing the defaults copy appears to do nothing. Both the settings reference and troubleshooting now say so. - The favorites key here is teams.favorite_teams_only, not show_favorite_teams_only as in the single-league scoreboards, and it defaults to off rather than on. other_games_min_quality is live in this plugin -- NCAA lacrosse has a national poll to rank against -- unlike in nrl, where it is inert. other_games_divisions stays inert; it is a college football taxonomy. Renders come from docs/assets/lacrosse-scoreboard/shots.json. Lacrosse keeps one manager per league and mode as a plain attribute rather than in a dict, and only builds them when that league's enabled flag is set, so the fixture turns both leagues on. Real ESPN crests, not placeholders. check_plugin.py passes with no FAIL. Carries the docs-tooling changes from #423, which this render depends on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Up to standards ✅🟢 Issues
|
The rewrite dropped the breaking-change notice from 1.1.0, when the display modes gained a lax_ prefix to stop colliding with the NCAA hockey modes. Anyone still holding an old pin in display_durations or rotation_order needs it, and the CHANGELOG mapping is the only other place it is written down. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The merge from main left the 1.24.2 entry holding both sides bodies -- two notes keys, two changelog keys, and a missing comma between them -- so manifest.json was not valid JSON and the version gate could not read it. Both sides had added a 1.24.2: main from the font fix in #409, this branch from the README rewrite. Rebuilt from main manifest, which is intact, with the docs change moved to a new 1.24.3 entry above it. That keeps main 1.24.2 exactly as merged and follows the shape the other docs PRs used on main -- the new entry carries the previous entry notes and changelog plus its own changes array. plugins.json regenerated: latest_version 1.24.3. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ChuckBuilds
added a commit
that referenced
this pull request
Sep 4, 2026
Seventeen manifests conflicted. The docs pass has been landing on main one plugin at a time, and this branch bumped the same manifests for the 1-bit text fix, so most collided on the version number. Resolved from main's history in every case, with this branch's entry added above it. Matching by version number alone would have been wrong: on seven plugins -- baseball, elections, leaderboard, masters, mqtt, ufc and youtube-stats -- both sides had numbered a DIFFERENT release the same, so main's docs entry and this branch's text fix shared a number. Dropping either would have lost a release note for a change that shipped, so both are kept and ours takes the next free number. Four numbers were skipped because other open PRs already claim them: basketball 1.29.3 and soccer 2.24.3 (#412), football 3.5.0 (#424) and lacrosse 1.24.3 (#428). Those four can now merge in any order relative to this one instead of colliding again on whichever lands second. Every manifest re-checked: valid JSON, version matches versions[0], no duplicates, descending order. plugins.json regenerated and in sync with all 43 manifests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ChuckBuilds
added a commit
that referenced
this pull request
Sep 4, 2026
scripts/test_scroll_card_renders.py has been red on main since #409, which made the safety check fail on every open PR regardless of what that PR touched -- #428 fails it while changing only one plugin's README and manifest. The signal was useless: a real render regression would have looked identical to this noise. #409 deliberately changed which font several text elements draw in, so the goldens committed on 2026-08-02 describe the old, wrong rendering. Measured: at the parent of #409 the guard reports 3 problems, on main it reports 42. These 39 are that difference. Checked rather than assumed. Every regenerated card was compared against its predecessor pixel by pixel, and the four sampled visually: the text content is identical and only the glyph shapes change, which is what a font swap should look like. --update also rewrote 24 cards whose pixels had not changed at all, presumably encoder metadata; those are reverted so the diff is only the 39 that actually differ. Baseball's three upcoming cards are deliberately NOT refreshed. They are the 3 that were already failing before #409, and they fail for an unrelated reason: game_renderer.py formats the date with %-m/%-d and %-I:%M%p, which are glibc extensions. Off glibc they raise, the except falls back to a raw ISO string, and the card loses its start time and shows 2026-09-19 instead of Sep 19. The committed goldens are correct; regenerating them anywhere but glibc would bake the broken output in. Filed separately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ChuckBuilds
added a commit
that referenced
this pull request
Sep 4, 2026
Second pass: #412, #424 and #428 merged since the last one, so the same manifests collided again. Four manifests resolved from main's history with this branch's entry above it. Football needed care -- main reached 3.5.0 from #424 while this branch sat at 3.4.3, so taking the next free number would have sorted our entry into the middle of the list rather than the top. Ours now takes the next number above whatever main has reached, which is 3.5.1. The module-collisions workflow conflicted because both sides added a guard: this branch's 1-bit text check and main's scroll-reachability check. They are independent, so both the path filters and both steps are kept. All 43 manifests re-validated -- valid JSON, version matches versions[0], no duplicates, descending order -- and plugins.json is in sync with every one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ChuckBuilds
added a commit
that referenced
this pull request
Sep 5, 2026
scripts/test_scroll_card_renders.py has been red on main since #409, which made the safety check fail on every open PR regardless of what that PR touched -- #428 fails it while changing only one plugin's README and manifest. The signal was useless: a real render regression would have looked identical to this noise. #409 deliberately changed which font several text elements draw in, so the goldens committed on 2026-08-02 describe the old, wrong rendering. Measured: at the parent of #409 the guard reports 3 problems, on main it reports 42. These 39 are that difference. Checked rather than assumed. Every regenerated card was compared against its predecessor pixel by pixel, and the four sampled visually: the text content is identical and only the glyph shapes change, which is what a font swap should look like. --update also rewrote 24 cards whose pixels had not changed at all, presumably encoder metadata; those are reverted so the diff is only the 39 that actually differ. Baseball's three upcoming cards are deliberately NOT refreshed. They are the 3 that were already failing before #409, and they fail for an unrelated reason: game_renderer.py formats the date with %-m/%-d and %-I:%M%p, which are glibc extensions. Off glibc they raise, the except falls back to a raw ISO string, and the card loses its start time and shows 2026-09-19 instead of Sep 19. The committed goldens are correct; regenerating them anywhere but glibc would bake the broken output in. Filed separately. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
ChuckBuilds
added a commit
that referenced
this pull request
Sep 7, 2026
…olver (#462) * test(scroll-cards): refresh the goldens #409 made stale scripts/test_scroll_card_renders.py has been red on main since #409, which made the safety check fail on every open PR regardless of what that PR touched -- #428 fails it while changing only one plugin's README and manifest. The signal was useless: a real render regression would have looked identical to this noise. #409 deliberately changed which font several text elements draw in, so the goldens committed on 2026-08-02 describe the old, wrong rendering. Measured: at the parent of #409 the guard reports 3 problems, on main it reports 42. These 39 are that difference. Checked rather than assumed. Every regenerated card was compared against its predecessor pixel by pixel, and the four sampled visually: the text content is identical and only the glyph shapes change, which is what a font swap should look like. --update also rewrote 24 cards whose pixels had not changed at all, presumably encoder metadata; those are reverted so the diff is only the 39 that actually differ. Baseball's three upcoming cards are deliberately NOT refreshed. They are the 3 that were already failing before #409, and they fail for an unrelated reason: game_renderer.py formats the date with %-m/%-d and %-I:%M%p, which are glibc extensions. Off glibc they raise, the except falls back to a raw ISO string, and the card loses its start time and shows 2026-09-19 instead of Sep 19. The committed goldens are correct; regenerating them anywhere but glibc would bake the broken output in. Filed separately. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * refactor(scroll): route every scrolling plugin through the shared resolver Eleven plugins each hand-rolled scroll configuration and disagreed with one another about what identical config meant. odds-ticker ranked the deprecated scroll_pixels_per_second ABOVE the documented scroll_speed/scroll_delay pair, and because that key carries a schema default the documented settings were dead for every user (#408). ledmatrix-leaderboard read the same key only as a fallback, so the same config produced different speeds in the two plugins. stock-news derived px/frame through its own arithmetic. Nobody was wrong locally; they were just eleven answers to one question. All of them now call src.common.scroll_config.configure(), which resolves every supported config shape in one place, snaps the speed to one the panel can render in whole pixels, and reports the frame hold needed to keep slow speeds crisp. Identical config now means an identical speed everywhere. Each plugin keeps its original logic as a fallback behind try: from src.common import scroll_config as _scroll_config except ImportError: _scroll_config = None because plugins update independently of the core and must keep working against one that predates the helper. Where the legacy block sits inline in __init__ the shared call runs after it and wins, rather than re-indenting logic other config shapes still depend on; those plugins log a line saying so, because two scroll speeds in the journal with no indication which took effect is exactly the confusion this change exists to remove. Plugins pass settings.frame_hold to set_scrolling_state(True, ...) when they begin scrolling. The hold cannot be applied once at construction: plugins share one display manager, and it is reset whenever any other plugin finishes its scroll. Verified on hardware (Pi 4, 2x128x64, 100Hz). Four enabled plugins resolve through the helper with no tracebacks, and ledmatrix-stocks at 50 px/s measures 50.0 fps, median 20.00ms -- exactly two refreshes per frame, with the panel still refreshing at 100Hz so flicker is unchanged. Requires core support: ChuckBuilds/LEDMatrix#523. Without it every plugin takes the fallback path and behaves exactly as before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(odds-ticker): make the documented scroll settings reachable (#408) Two defects meant display_options.scroll_speed / scroll_delay -- the format the plugin documents and recommends -- could never take effect. The priority-1 branch read scroll_pixels_per_second into self rather than clearing it the way the display_config branch does. config_schema.json gives that deprecated key a default of 50.0 and schema defaults are merged into plugin config, so it was never None and use_frame_based() below was never True. Separately, use_frame_based() only ever inspected display_config, so even with that fixed the recommended shape still could not select frame-based mode. Both halves were needed. The visible symptom was the plugin logging its scroll configuration twice on startup, ~0.36s apart, the second line quietly overriding the first: Using display_options.scroll_speed=1.0 px/frame ... (frame-based mode) Using scroll_pixels_per_second: 50.0 px/s (time-based mode) with the second one being what actually ran. On a 100Hz panel that meant 0.5px per frame, so every second frame rendered identically, dirty tracking skipped the panel swap, and the ticker juddered. Editing scroll_speed had no effect, and deleting scroll_pixels_per_second only restored the schema default. Also takes the live-game check off the render path. display() called _get_current_update_interval() every frame, and its slow path reads the scoreboard cache from disk and parses JSON per enabled league -- producing a single ~15ms frame every few minutes, measurable as a stall mid-scroll. The interval is now memoised for 15s; the scoreboard re-check underneath is rate limited to 300s regardless, so live detection is unaffected. The neighbouring debug line used an f-string, so it called _has_live_games() on every skipped update even with debug logging off; it now uses %s args. Verified on hardware: odds-ticker selects frame-based mode with no time-based line following it, and resolves to 100.0 px/s at 1px per refresh. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix: make the frame-hold call safe for the test doubles, and update to main Three display-manager doubles still declared set_scrolling_state with a single argument, so the frame_hold this PR passes raised TypeError mid-render. display() swallows that in its own except Exception, leaving only "no frame reached the display" -- odds-ticker's cache-invalidation test failed for a reason that had nothing to do with cache invalidation. CI caught one of the three; the other two never reach the scrolling branch. scripts/test_scroll_state_doubles.py checks the invariant instead, and catches all three (including the *args one, which looks tolerant but cannot take a keyword). odds-ticker's double also needed _scroll_frame_hold itself: it borrows only the methods under test, and display() now calls that one. Fixes a continuation line in odds-ticker/manager.py that was indented back to column 12 inside the call -- legal, but not what anyone meant. Merges main. This branch was two commits behind, which made its diff look like it deleted versions[] entries main had gained. Six plugins then needed version bumps they did not need before, because main had bumped past them. ledmatrix-leaderboard and nfl-draft sit one patch above #466's numbers rather than duplicating them -- two PRs must never publish the same version, and a user could not tell which build they have. That pins the merge order these two already needed. Verified against a core with #523 and #534 merged: safety harness clean on all 11 changed plugins, 23 unit tests pass, version and collision gates pass. The one failing repo guard, test_odds_centre_collision.py, fails identically on main and is untouched here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9 --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: t <t@l>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The lacrosse README documented a fraction of the plugin's 170 settings and had no images. It now covers every schema leaf — verified with a token audit against
config_schema.json— and shows the three men's display modes, both leagues side by side, theshow_recordstoggle, and the live card at four panel sizes.Structure
The
ncaa_mensandncaa_womensconfig blocks are identical in every setting except one:ncaa_mensdefaults toenabled: trueandncaa_womenstofalse. Documenting a single<league>table rather than two byte-identical sets keeps 104 of the 170 leaves readable instead of duplicated, which is the point of the exercise.What the old README did not say
display_options.show_recordsandshow_rankingdefault totrueper league, whiledefaults.show_recordsanddefaults.show_rankingdefault tofalse— and the per-league copy wins (manager.py:795,resolve_value). Because the web UI writes schema defaults on save, a saved config already carries the per-leaguetrue, so changing thedefaultscopy appears to do nothing. Documented in the settings reference and again under troubleshooting, where a user would actually look.teams.favorite_teams_only, notshow_favorite_teams_onlyas in the single-league scoreboards, and it defaults to off here rather than on. Easy to carry the wrong key over from another scoreboard's config.other_games_min_qualityis live in this plugin. NCAA lacrosse has a national poll to rank against, so itsrankeddefault really does restrict non-favorite games — unlike in nrl, where the same setting is inert.other_games_divisionsstays inert; it is a college football taxonomy.mode_durationsandcustomization.favorite_result_colorsare read by the core (src/common/sports_card.py), not by this plugin. The README says where, so the next person does not delete them as dead.Renders
From
docs/assets/lacrosse-scoreboard/shots.json. Lacrosse differs from nrl: it keeps one manager per league and mode as a plain attribute (ncaa_mens_live,ncaa_womens_recent, …) rather than in a_managersdict, and only constructs them when that league'senabledflag is set — so the fixture turns both leagues on. These are real ESPN crests (Yale, Dartmouth, Quinnipiac, Harvard), not the grey placeholders nrl had.One fixture correction worth noting: the switch-mode recent card reads
game.get("period_text", "Final"), a.getdefault rather than a falsy check, so an empty-stringperiod_textdraws nothing. Real data never hits that —lacrosse.py:174sets"Final"for any post-state game — so the fixture now carries what the extractor actually produces rather than an unreachable state.Checks
check_plugin.py: zero FAIL (16 checks; the harness exercises the men's recent and upcoming modes)additionalPropertiesconfig_schema.jsonplugins.jsonregenerated byupdate_registry.pyDoes not touch the shared
sports.pylineage.Dependency
Carries the docs-tooling commits from #423 so this branch renders standalone; identical in both branches and they collapse on merge.
🤖 Generated with Claude Code