Broadcast graphics that follow the person keeping the book
Add one browser source in OBS or vMix and the scorebug is live. It reads the same events the scorekeeper is already tapping in at the table, so nobody retypes the score into a graphics package a second time. A director's Master Control page stages the next graphic, takes it to air, and holds the score still while you play a replay. Overlays are part of the paid Streaming & Overlays module, and every match carries its own streaming toggle that has to be on before anything renders.
The graphics operator is retyping a score that already exists
Most small broadcasts run the scorebug by hand. Someone sits behind OBS with a text file or a Stream Deck and retypes the number every time it changes — so the graphic trails the play, a free throw goes missing, and at the break the wrong team is shown leading. Meanwhile the person at the table has already recorded every point, foul and period change correctly, in the right shape for the sport. The score exists. It just never reaches the stream. Tournament days make it worse: four courts, one operator, back-to-back games, and the overlay on court three still showing the final score of the game before.
Four steps, no configuration
Turn streaming on for the match
Streaming is off per match by default — the overlay URL renders nothing at all until an operator flips that specific match's toggle. The toggle appears once the league holds the Streaming & Overlays module.
Paste the browser source into OBS
Master Control copies the browser-source URL to your clipboard. Add it to OBS or vMix as a browser source: one consolidated URL for everything, a separate URL per graphic if you want them on their own layers, or a vertical 1080x1920 variant for a phone stream. The background is transparent.
The scorekeeper just scores
Every sport's console publishes its scoreline to the overlay channel, and the scorebug renders in the shape that sport uses — sets, innings, frames, legs, ends or a running clock. State travels over a WebSocket relay, so the tablet at the table, the director's laptop and the OBS machine can be three different computers.
Direct it from Master Control
Stage the lower third on Preview, take it to program, drop in halftime stats, lock scoring while a replay rolls, and clear the output with one panic button. Master Control is open to super admins, platform support and league admins; a scorekeeper opening it is redirected.
What you can put on air
Everything below is built and running today. Unbadged items are included on every plan; a badge means the capability needs a module added to your plan, a higher plan tier, or a piece of setup finished first.
11 of these are included on every plan. One group needs the Streaming & Overlays module.
OBS / vMix broadcast overlays (browser sources)
Streaming & Overlays modulePoint OBS or vMix at a per-match browser-source URL and BallOBall renders transparent broadcast graphics that follow the live game — one consolidated URL, or a dedicated URL per graphic.
Nothing renders until an operator flips that specific match's streaming toggle (OverlayBase returns null when streamingEnabled is false). In the SPA the toggle card is hidden entirely from anyone below league admin, and admins see a short 'not available' note in place of the toggle unless the LIVE_STREAM_OVERLAY feature module is enabled for the league — it is part of the paid 'Streaming & Overlays' product.
Overlay graphics library (scorebug, lower third, VS, lineups, halftime stats, team comparison, shot chart, bracket, final score, game over, player of the game, slideshow, highlights, sponsor bug, banner, commercial-break countdown)
A set of broadcast graphics ships with the platform — scorebug, lower third, VS card, starting lineups, halftime and team-comparison stats, shot chart, tournament bracket, final score, game-over, player of the game, slideshow, highlights, sponsor bug and a commercial-break countdown.
Only the graphic the director has put on air is visible at any moment; all of them are subject to the same per-match streaming toggle.
Master Control director panel (preview → program, take, scene presets, panic clear, score lock, copy-to-clipboard OBS URLs)
A director's Master Control page lets an operator stage a graphic on Preview, put it on air, apply scene presets, lock scoring during replays, and copy the browser-source URLs straight into OBS or vMix.
Role-gated: only SUPER_ADMIN, PLATFORM_SUPPORT and LEAGUE_ADMIN can open it (scorekeepers and fans are redirected). It is a public route with the check inside the page.
Cross-machine WebSocket overlay relay
Overlay state travels over a WebSocket relay (API Gateway WebSocket + Lambda + DynamoDB), so Master Control running in one browser drives an OBS browser source running in a different process or on a different machine.
If the socket cannot open, the client silently falls back to browser localStorage, which only reaches sources in the same browser profile. Write messages are protected by a single shared per-deployment token handed to authorised operators — it is static, not per-match, so any authorised operator's token writes to any match, and a deployment that leaves it empty runs with the write guard off.
Sport-correct scorebugs; every sport's scorekeeper console publishes to the overlay channel
The scorekeeper consoles push the live scoreline straight to the overlay channel, and the scorebug renders in the shape the sport actually uses — sets, innings, frames, legs, ends, or a running clock.
Scorebug rendering is grouped into sport families (set-based, innings, frame/leg, clock-based, tennis, cricket, soccer, football, archery), not a bespoke design per sport.
Full-screen scoreboard for a gym TV / second monitor
A full-screen scoreboard page opens in one click from the scorekeeper console, drags onto a second display over HDMI, and lets the operator show, hide, resize and reposition every element, with one-click Standard / Minimal / Detailed presets.
Layout choices are saved per match in that browser's localStorage, not on the server, so they do not follow the operator to another device. For a non-public league the page needs either a signed-in operator or the match's streaming toggle on, because the underlying match read answers 404 to an anonymous caller otherwise; the board then paints an access notice instead of a black screen, and keeps polling so flipping either switch brings it up without touching OBS.
Vertical 9:16 overlay for phone / vertical streams
A vertical (1080x1920) overlay variant renders the same live scoreline for vertical streaming setups, and the public watch page switches to it with an aspect parameter.
Same per-match streaming toggle and public-read gate as the landscape overlays.
Court-addressed overlay + per-court master control (multi-game / tournament day)
Streaming & Overlays moduleA court can be configured once as a single OBS browser-source URL: the server decides what should be on air for that court (pinned, live, final-score hold, up next or idle) and the overlay switches itself between back-to-back games, while a per-court control board shows on-air and on-deck and lets the director pin, hold, skip or resume automatic switching.
Requires the MULTI_COURT_STREAM feature module enabled for the league (part of the paid 'Streaming & Overlays' product) and an operator role for the control board. Anonymous overlay reads additionally require the league to be public and ACTIVE or COMPLETED and the court to be both active and stream-enabled; anything short of that answers 404 rather than 403, so court existence is never leaked.
Social share card generator (1080x1080 and 1080x1920 PNG)
After a game an operator can open a share-card page and download a square or vertical PNG of the final score to post on social media.
Rendered in the operator's own browser with canvas — it is a manual download, not an automated post or an auto-generated link-preview image. Link previews for a shared match URL fall back to the single site-wide static banner (frontend/index.html:56), because the crawler meta layer only builds a bespoke card for league, team, player and organisation paths and returns none for a match URL.
Near-real-time live event feed behind overlays and fan pages
Overlays and fan surfaces subscribe to a server-held long-poll event feed so the score updates shortly after the scorekeeper records a play, with a periodic poll as the fallback when the feed is unhealthy.
It is ndjson long-polling, not Server-Sent Events or WebSockets — API Gateway HTTP API buffers responses, so true SSE is not available. The feed is shut off once a match reaches a terminal status. No measured latency figure exists in the code.
Overlay relay write protection
Only callers authorised to score a match can obtain the token the relay requires on state-changing messages, so a stranger who guesses a match id cannot push fake scoreboard state to a live broadcast.
The token is a single static per-deployment secret shared across all matches, not a per-match credential — any authorised operator's token writes to any match. If it is deployed empty the guard is off. Read-only subscribers stay open by design, because broadcast output is public: an OBS browser source or fan page subscribes anonymously and sends no token at all.
Multi-camera tally indicator
Master Control's preview pane can show which camera the director has marked as live, as a coordination cue for a human-switched multi-camera setup.
Visual cue only, and it renders only in preview mode — never on the program output. There is no NDI, SRT or vMix tally hardware integration; the source says that is the operator's responsibility.
Public watch page (video + live overlays composited)
A shareable public watch URL plays the league's video stream with the live broadcast graphics composited on top, with no app chrome around it.
BallOBall does not supply the video on this page — the operator passes a stream URL or configures one, and it must pass a host allow-list (YouTube, Twitch, Vimeo, Facebook, or a direct HLS/MP4 URL). Where the tenant sells a fan tier the backend can withhold the embed URL and mark the stream paywalled, in which case the page shows a Go Premium card in place of the player; an explicit ?stream= override on the URL bypasses that gate by construction.
Managed live streaming hosted on AWS IVS (RTMPS ingest + HLS playback)
Streaming & Overlays moduleAn operator can start a platform-hosted stream for a match: the backend provisions an AWS IVS channel and returns an RTMPS ingest endpoint and stream key for their encoder, and fans watch the HLS playback in an in-app player on the match page.
Gated twice. (1) The tenant must hold the paid MANAGED_STREAMING entitlement or start returns 403. (2) A deployment-level switch STREAMING_ENABLED must be 'true' or start returns 503 STREAMING_UNAVAILABLE and makes zero AWS calls; the prod deploy script does pass -c streamingEnabled=true, so a manual deploy that omits the flag silently turns managed streaming back off.
Before you ask
What do we need on the streaming machine?
OBS, vMix, or anything else that can load a web page as a source, plus the camera and encoder you already stream with. The overlay is a URL with a transparent background — you drop it on a layer above your video. There is no plugin to install and no capture card involved.
Does BallOBall record the game or push it to YouTube for us?
There is a hosted option for the video itself. With the Streaming & Overlays module — plus a per-deployment streaming flag that ships switched off — BallOBall provisions a live channel on AWS IVS and hands your encoder an RTMPS ingest address and a stream key. Fans then watch inside the app on the public watch page, with the overlay composited on top. Four things it does not do, and they are worth knowing before you plan a broadcast. There is no recording, so the feed is gone once your encoder stops. There is no DVR or archive to scrub back through. There is no transcode-for-download, so there is no file to hand a coach afterwards. And there is no restream out to YouTube, Facebook or Twitch. If the game needs to land on YouTube, your encoder sends it there — BallOBall renders the graphics, and nothing on the platform touches a camera or a switcher.
Can the OBS machine be a different computer from the scorer's tablet?
Yes, that is the point of the relay. Overlay state travels over a WebSocket relay, so Master Control in one browser drives a browser source in another process or on another machine. One caveat worth knowing before a venue firewall surprises you: if that socket cannot open, the client falls back to browser storage, which only reaches sources running in the same browser profile on the same machine.
We do not stream at all. Is any of this useful?
Yes. The full-screen scoreboard opens in one click from the scorekeeper console and drags onto a second display over HDMI — a gym TV, a projector, a monitor behind the table. Show, hide, resize and move any element, or take the Standard, Minimal or Detailed preset. Layout choices are saved in that browser on that device, so they do not follow the operator to another laptop.
Can a stranger push a fake score to our broadcast?
Writing to the relay requires a token that only callers authorised to score the match can obtain, so guessing a match id is not enough to put a wrong number on air. Read-only subscribers stay open on purpose, because a broadcast machine should not have to sign in. Be clear about the shape of it: the token is a single shared per-deployment secret, not a per-match credential, so any authorised operator's token can write to any match.
We run four courts on a tournament day. Is that one overlay per court?
A court can be configured once as a single browser source, and the server decides what belongs on air for it — the live game, a final-score hold, up next, or idle — switching itself between back-to-back games. A per-court control board shows on-air and on-deck and lets a director pin, hold, skip, or hand control back to automatic. That is part of the Streaming & Overlays module and needs the multi-court feature enabled for the league.