Repository navigation
fix(football): a two-point conversion is not a safety (3.28.1) - #665
Conversation
The try after a touchdown usually lands after the touchdown's takeover has closed, so it arrived as a lone +2 and was named from its size alone: SAFETY. An ambiguous +2 is now named from ESPN's scoring plays (game summary, fetched only for a +2, 3 s timeout) when they are up to date, and otherwise from the score sequence: the touchdown side's next +2 is its conversion, the other side's a defensive return, anything else a safety. A late extra point gets its own takeover (EXTRA PT!). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 32 |
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.
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 32 minutes. View limit details
Walkthrough
Merge Risk:
|
…l returns Review follow-ups for #665: - A failed try changes no score, so the owed try survived until the next score; a same-side safety a drive later read as 2PT GOOD!. The try is untimed, so it now ends once the period changes or the clock has run (5 s slack). Unreadable clocks keep the one-score-change limit. - A score correction (any decrease) clears the owed try. - A touchdown and the other side's +2 in one poll: the +2 is the defensive return on that try, and no try is left owed. - A non-object scoringType no longer raises out of classification; it falls back to the score sequence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Football's metadata conflicted with #665 (3.28.1); code merged cleanly. Resolution: football 3.28.2 stays the newest version, with the 3.28.1 entry kept beneath it in manifest.json versions[] and CHANGELOG.md, and plugins.json regenerated with update_registry.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(scoreboards): switching screens never flashes the panel black display_manager.clear() writes black straight to the matrix. All nine scoreboards called it before drawing a card whenever force_clear was set -- a mode change, a block boundary, or a >5 s gap between display() calls (a slow update() holding the plugin lock) -- and rendering the card took long enough for the black to show. With one favourite team the same card came back, so the board read as flashing. Empty modes also blanked the panel as the controller tried them on its way past; the recent screen did so on every frame while its list was empty. Every draw path already builds a full frame and assigns it, so the clears are simply removed: the panel keeps the previous frame until the new one is pushed, and the core's dirty-frame check skips an unchanged card. Empty modes return False and leave the panel to the controller, which blanks it once when the whole rotation is empty. Same fix as calendar's #328. Guarded by scripts/test_scoreboards_never_blank_the_panel.py (no display_manager.clear() in any of the nine) and football's test_switching_never_flashes_black.py (real display() paths). afl 1.44.1, baseball 1.66.1, basketball 1.52.1, football 3.28.2 (3.28.1 is #665), hockey 1.54.1, lacrosse 1.45.1, nrl 1.43.1, soccer 2.50.1, ufc 1.27.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore(registry): sync the nine scoreboards Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(scoreboards): require core 3.9.0 for the empty-rotation blank Review follow-ups for #666: - The panel is now blanked only by the controller when every mode is empty, and that blank first shipped in core 3.9.0 (#799). On 3.8.7 the last card would stay up, so all nine scoreboards' newest version entry and compatible_versions now require 3.9.0. - test_switching_never_flashes_black: a forced redraw must show the card, not only avoid black; bind the draw stub with types.MethodType (Codacy misread the descriptor call). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Problem
User report: the football plugin celebrates a two-point conversion as a SAFETY.
The celebration phrase was inferred purely from the size of the score increment (
+2 → SAFETY). The follow-up after a touchdown was only suppressed while the TD takeover was on screen (8 s), but in a real game the try lands after a review or TV break — long after that — so it arrived as a lone +2.Fix
Each score is now classified into a kind (
td,fg,safety,pat,two_pt,def_two_pt). Only +2 is ambiguous:scoringPlays(game summary endpoint) — the play whose running score matches the new score. Safeties and defensive returns are typed (safety,defensive-two-point-conversion); a conversion is folded into its touchdown entry's text, e.g.(Cam Ward Run for Two-Point Conversion). Fetched only for a +2, plainrequests.getwith a 3 s timeout (the session's retry adapter backs off for tens of seconds).A try landing after the TD takeover closed now gets its own:
KC 2PT GOOD!(goal line),KC EXTRA PT!(goalposts),DAL DEF 2PT!. One landing during the TD takeover stays part of it, as before.Tests
test_score_celebration.py(conversion / PAT / defensive return after the window, pending-try lifetime, suppressed TD still tracked, +8 in one poll, real ESPN play texts from Oct 2026, lagging summary fallback, fetch only for +2, URL + failure handling).run_plugin_tests.py football-scoreboard: 66 passed, 1 skipped, 0 failed.scripts/test_celebration_renders.py: 135 frames match goldens. Version-bump / manifest checks pass.Not exercised against a live game (none on when built).
🤖 Generated with Claude Code
Summary by CodeRabbit