Repository navigation
v0.7.0
The first tagged release. It covers everything since the project began on 2026-08-22, so this entry describes what is in it rather than what changed.
The four surfaces
- Scoreboard — a broadcast bug on a transparent 1920×1080 canvas: score, clock, timeouts, hold/break, a turnover count, and a statistic strip that says something true about the game or nothing at all. Point a browser source at one URL. It can follow a field rather than a game, so a fixed source keeps working when the schedule moves.
- Studio — a full-frame stage hosting several cards at once, and the page that decides what is on it: card placement per slot, arming before showing, automatic half-time, full-time and post-goal cards, and an export of the whole configuration.
?auto=1runs a stage with no operator at all. - Commentator — a second screen, never on air, so it can hold numbers a graphic must refuse: rosters, line sharing between desks, prepared notes, pronunciation and pronouns as declared fields, timeouts left, and a per-point view of who is on the field.
- Match control — the score and the clock from a phone at the pitch, applied on screen first and sent afterwards, plus possession, timeouts, an injury stoppage and the opening ratio behind a More panel.
Two deployment modes
Hosted on Live! by BULA, and standalone with nothing underneath — no database, no Composer, no build step. The same renderer and the same payload shape serve both, with one provider seam between them, and a fact one mode cannot know is omitted rather than sent as zero.
Standalone brings its own event authoring in a browser, squads through the commentary desk, an administrator login, and a recorded capture so every page renders with no host at all. ultimate-broadcast.org is one, on ordinary shared hosting.
Keeping score with no signal
A whole game, or a weekend of them, on a phone with no network. /k/<game> installs to the home screen, the queue and the last server answer both survive being closed, and /k/ lists every game the device is carrying with what each still owes. A goal is written as the point it completes, never as +1, which is what makes a retry, a replay after a reload or a delivery a day late safe. What cannot be delivered exports as a file. docs/OFFLINE.md.
Post-production
?at=<seconds>&goals=<n> draws one deterministic frame, through the same renderer a live broadcast uses rather than a second one, for adding a scoreboard to footage recorded without a switcher. docs/POSTPRODUCTION.md.
Running an installation
deploy.sh for a standalone site, install/ for the host rules and the first configuration, version.json so a site can be asked what it is running, a brand with a per-surface tab icon, and visitor counting that reads the web server's access log and adds nothing to the software. Relicensed to AGPL-3.0-only with a section 7 permission scoped to combination with Live! and UltiOrganizer.
Known limits, carried into this release
lines.phphas no lock around its read-modify-write, so two commentators saving different teams in the same moment can still lose one.AGENTS.mdrecords it as a gap rather than a decision.- Diagnostics are painted onto the broadcast canvas, which is useful during setup and unacceptable on air, and the page cannot tell the two apart.
docs/STUDIO.md§11 has the three options. - Conflicts between two people scoring one game are detected and reported, never merged.
docs/MATCHCONTROL.md§0b is case by case. - A score kept in match control has no route back. Hosted, the integration is the point: brackets, standings, rosters, histories and the score all come from UltiOrganizer, and a game its own Scorekeeper records is on the tournament record already. What cannot go back is a score this project kept itself — the API is six endpoints and all GET — so match control's log sits beside the record rather than in it.
docs/UPSTREAM.mdis the ask.