Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@
"last_updated": "2026-10-02",
"verified": true,
"screenshot": "",
"latest_version": "1.55.0",
"latest_version": "1.56.0",
"ledmatrix_min_version": "3.8.0",
"commit": "b99d6eccbcf083ac6f6c46eebdf22964a8b9eece"
"commit": "43c19f76c144c1b8cecd3d811706a1de371c7ea7"
},
{
"id": "basketball-scoreboard",
Expand Down
16 changes: 16 additions & 0 deletions plugins/baseball-scoreboard/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## [1.56.0] - 2026-10-02

### Added
- Game activity pop-ups: a one-line banner along the bottom of the live scorebug
for the plays between runs -- `Harper SINGLE! Top 8th`,
`Acuna Jr. STEALS 3RD Bot 1st`, `McFarlane IN RELIEF Bot 7th` -- holding for
a few seconds and fading back to the scorebug. Runs are left to the
celebration and the scorer card.
- Per-league `display_options.show_game_activity` (off by default; MLB and NCAA
Baseball, which have play-by-play), `game_activity_detail`
(`hits_and_steals`, `highlights`, `everything`), `game_activity_dwell_seconds`
and `game_activity_fade_seconds`.
- One extra ESPN request per live update for the game on screen, shared with the
celebration's when a run has just scored. A first look at a game only records
where the feed is, so joining mid-inning replays nothing.

## [1.55.0] - 2026-10-02

### Added
Expand Down
33 changes: 33 additions & 0 deletions plugins/baseball-scoreboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ inning, bases, outs and count are what the panel showed at that moment.*
- [Per-league: update intervals](#per-league-update-intervals)
- [Per-league: what appears on the card](#per-league-what-appears-on-the-card)
- [Run and home-run celebrations](#run-and-home-run-celebrations)
- [Game activity pop-ups](#game-activity-pop-ups)
- [The extra baseball screens](#the-extra-baseball-screens)
- [The matchup card: separator, date and time](#the-matchup-card-separator-date-and-time)
- [Favourite team result colours](#favourite-team-result-colours)
Expand Down Expand Up @@ -505,6 +506,37 @@ play-by-play, so it exists for MLB and NCAA Baseball only.
| `scorer_card_dwell_seconds` | `6` | **Advanced.** Seconds on screen (3-20) |
| `scorer_card_favorites_only` | `false` | **Advanced.** Only for a favourite team's runs |

### Game activity pop-ups

Between runs a scoreless inning can look frozen. With pop-ups on, a one-line
banner appears along the bottom of the live scorebug for the plays that happen
-- `Harper SINGLE! Top 8th`, `Acuna Jr. STEALS 3RD Bot 1st`,
`McFarlane IN RELIEF Bot 7th` -- holds for a few seconds, then fades back to
the scorebug. It is the same idea as the hockey scoreboard's game-activity
banner. Runs are left to the celebration and the scorer card.

The banner picks the fullest wording that fits: a smaller font is tried before
any word is given up, then the surname alone, the short label (`1B`, `SB`,
`K`), the short inning (`T8`), and last of all the inning itself. Accents are
folded (`Acuna`), because the small face has no accented letters.

It is **off by default**, only draws on panels 32 pixels tall or more, and
reads ESPN's play-by-play, so it exists for MLB and NCAA Baseball only. It
costs one extra ESPN request per live update for the game on screen, shared
with the celebration when a run has just scored.

| Setting | Default | What it does |
|---|---|---|
| `display_options.show_game_activity` | `false` | **Advanced.** Show the pop-ups (MLB and NCAA Baseball) |
| `game_activity_detail` | `highlights` | **Advanced.** `hits_and_steals`: singles, doubles, triples, stolen bases. `highlights`: those plus strikeouts, walks, double plays, errors and pitching changes. `everything`: also outs and sacrifices |
| `game_activity_dwell_seconds` | `6` | **Advanced.** How long each pop-up stays, fade included (2-20) |
| `game_activity_fade_seconds` | `3` | **Advanced.** How much of that is spent fading out; `0` removes it at once (0-10) |

A pop-up can trail the play by up to one live update interval; the inning on it
says when it happened. A burst of plays keeps the newest three. The first look
at a game only records where the feed is, so joining a game mid-inning does not
replay its history.

### The extra baseball screens

Baseball has more to say than most sports mid-at-bat, so the plugin can
Expand Down Expand Up @@ -973,6 +1005,7 @@ baseball-scoreboard/
├── manager.py # BaseballScoreboardPlugin: league and mode routing
├── baseball_celebration.py # Run / home-run / win celebrations
├── baseball_scorer_card.py # The card naming who drove a run in
├── baseball_activity.py # Play-by-play pop-up banners
├── mlb_managers.py # MLB fetching and cache keys
├── milb_managers.py # MiLB fetching
├── ncaa_baseball_managers.py # NCAA fetching
Expand Down
9 changes: 8 additions & 1 deletion plugins/baseball-scoreboard/baseball.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from PIL import Image, ImageDraw, ImageFont

from baseball_activity import BaseballActivityMixin
from baseball_celebration import BaseballCelebrationMixin
from baseball_scorer_card import BaseballScorerCardMixin
from data_sources import ESPNDataSource
Expand Down Expand Up @@ -1143,7 +1144,8 @@ def _draw_scorebug_layout(self, game: Dict, force_clear: bool = False) -> None:
self.fonts["time"] = original


class BaseballLive(BaseballScorerCardMixin, BaseballCelebrationMixin, Baseball, SportsLive):
class BaseballLive(BaseballActivityMixin, BaseballScorerCardMixin, BaseballCelebrationMixin,
Baseball, SportsLive):
"""Base class for live baseball games."""

def __init__(
Expand Down Expand Up @@ -1181,6 +1183,7 @@ def __init__(
self._headshot_mgr = None # lazily created in the render path
self._init_celebration()
self._init_scorer_card()
self._init_game_activity()

def _at_bat_card_style(self) -> str:
"""'card' (the default) draws the pitcher/batter screen as a full
Expand All @@ -1205,6 +1208,8 @@ def update(self):
self._check_scorer_cards()
if self.test_mode:
return
if self.show_game_activity and self.espn_summary_sport_league:
self._poll_game_activity()
pbp_wanted = self.show_pitcher_batter or self.show_last_play or self.show_player_card
if not pbp_wanted:
return
Expand Down Expand Up @@ -2790,6 +2795,8 @@ def text_width(text, font):
# Composite the text overlay onto the main image
main_img = Image.alpha_composite(main_img, overlay)
main_img = main_img.convert("RGB") # Convert for display
# The play-by-play banner along the bottom row, when one is due.
main_img = self._with_activity_popup(main_img, game)

# Display the final image
self.display_manager.image.paste(main_img, (0, 0))
Expand Down
Loading
Loading