Skip to content

fix(scoreboards): render the font each element's schema advertises - #409

Open
ChuckBuilds wants to merge 1 commit into
mainfrom
fix/font-default-matches-schema
Open

fix(scoreboards): render the font each element's schema advertises#409
ChuckBuilds wants to merge 1 commit into
mainfrom
fix/font-default-matches-schema

Conversation

@ChuckBuilds

Copy link
Copy Markdown
Owner

Nine elements advertised one font in the settings page and drew another.

afl, basketball, football, lacrosse, nrl, soccer, hockey
    status_text   schema says 4x6-font.ttf   renders PressStart2P-Regular.ttf
hockey
    detail_text   schema says 4x6-font.ttf   renders PressStart2P-Regular.ttf
    odds_text     schema says 4x6-font.ttf   renders PressStart2P-Regular.ttf

The call sites never passed default_font, so _load_custom_font used its own fallback face instead of the schema's. Picking the font the picker already showed as active therefore changed the display — which reads as a broken picker. It's also why hockey's odds looked unlike every other sport.

Pre-existing, not from the consolidation — the missing argument is identical before and after it.

Schema-driven, not a blanket change

Baseball's schema genuinely declares PressStart2P for status_text, so baseball is untouched. Each plugin now renders what its own schema declares.

Football needed a second edit: its status default also lives in the style-resolver table _LOADER_DEFAULTS, so patching the call site alone left it mismatched.

Hockey's game_renderer._load_custom_font gains the default_font parameter its seven siblings already have. My first attempt passed the keyword without checking, which raised TypeError into a bare except and silently sent every hockey font to the emergency fallback — the same swallow-and-continue shape as the bug being fixed here. The corrected pass reads each file's actual signature first.

Measured impact

42 of 176 safety-harness renders, tightly scoped:

panel sizes affected 64×32, 64×64, 96×48, 128×32, 128×64, 128×96
not affected 256×32, 256×128 — wide panels draw that header with the time font (if display_width > 128)
modes upcoming only
plugins 7 (baseball correctly unchanged)

It also fixes a knock-on defect the code comments about: "Next Game" is 72px in PressStart2P@8 and had to shed to "Next" on a 64px panel; at 4x6-font@7 it is 41px and fits whole.

The one test that changed

football/test_fonts_render_crisply.py distinguishes "the config path ran" from "the emergency fallback ran" — a real hazard, since _load_fonts wraps everything in try/except and drops to crisp hardcoded defaults, hiding a broken call.

It used the status face as the discriminator, which stops discriminating once both paths agree on 4x6-font. The discriminator was replaced, not the check weakened: it now keys on the odds slot, which only the config path builds. Verified it still fails when a bad keyword is injected into that path.

Fleet: 245 passed, 1 pre-existing unrelated failure resolved by this branch's test update.

Nine elements advertised one font in the settings page and drew another. The
status text on seven plugins, plus hockey's detail and odds text, declared
4x6-font.ttf in config_schema.json while rendering PressStart2P-Regular.ttf.

The call sites never passed default_font, so _load_custom_font fell back to its
own default face instead of the schema's. Picking the font the picker already
showed as active therefore changed the display, which reads as a broken picker.
It is also why hockey's odds looked unlike every other sport.

Pre-existing, not from the consolidation: the missing argument is identical
before and after it.

The fix is schema-driven per plugin, not a blanket change. Baseball's schema
genuinely declares PressStart2P for status, so baseball is untouched. Football
needed a second edit -- its status default also lives in the style-resolver
table _LOADER_DEFAULTS, so patching the call site alone left it mismatched.

Hockey's game_renderer._load_custom_font gains the default_font parameter its
seven siblings already have. A first attempt at this passed the keyword without
checking, which raised TypeError into a bare except and silently sent *every*
hockey font to the emergency fallback -- the same swallow-and-continue shape as
the bug this branch is fixing.

Measured impact: 42 of 176 safety-harness renders, all on panels 128px wide and
narrower, all upcoming screens. Wider panels draw that header with the time
font (`if display_width > 128`) and are byte-identical.

It also fixes a knock-on defect the code comments about: "Next Game" is 72px in
PressStart2P@8 and had to shed to "Next" on a 64px panel; at 4x6-font@7 it is
41px and fits whole.

football/test_fonts_render_crisply.py needed its discriminator changed, not
weakened. It tells "the config path ran" from "the emergency fallback ran", and
used the status face to do it -- which stops discriminating once both paths
agree on 4x6-font. It now keys on the odds slot, which only the config path
builds. Verified it still fails when a bad keyword is injected into that path,
which is the bug it exists to catch.
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: fb448982-cc55-4e15-a8cb-d64d9e0e821c


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity

Metric Results
Complexity 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

ChuckBuilds pushed a commit that referenced this pull request Sep 4, 2026
Addresses three CodeRabbit findings on #417, all of them real.

The first is the one that mattered: ledmatrix-flights had six anti-aliased
draws this PR had already claimed to fix. None of its ten Draw sites calls
.text() itself -- every renderer hands the Draw to _draw_centered()/_draw(),
which do. The first version of this gate matched `<var>.text(` file-wide and
caught them; tightening it to same-scope AST matching to cut false positives
threw the real findings away and reported the file clean. The runtime probe
missed them too, because the harness never renders those flight paths.

So the gate now resolves, to a fixpoint, which functions draw text on a
parameter, and treats a Draw handed to one of those as text-rendering. That
sits between the file-wide regex (130 findings, mostly noise) and same-scope
matching (missed real ones): an overlay Draw passed to a compositing helper is
still ignored, while _draw_centered(draw, ...) counts.

Two smaller gate defects, also reported and also real:

  * any `.fontmode` assignment satisfied the check, so `fontmode = "L"` -- the
    anti-aliasing default -- would have passed. Now only the constant "1".
  * ast.walk() descended into nested scopes and ignored statement order, so a
    fontmode set *before* its Draw() counted. Now scoped and ordered.

Each is mutation-tested: removing a hand-off fontmode, setting it to "L", or
moving it above its Draw() each make the gate fail.

That found 40 further sites in 13 plugins, including overlay and celebration
paths in all eight scoreboards that the harness never renders.

Versions are picked above every number claimed by #409 and #412; football takes
3.4.3 so #424 keeps 3.5.0. Merge order: #409, #412, this, then #424.

Verified: 246 passed / 2 skipped / 0 failed, 72-card scroll guard passes, all
repo gates pass, and the runtime probe still reports 0 anti-aliased text draws
across 31 plugins at every panel size.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants