1. Architecture overview
SpreeSports is a cloud-hosted multi-tenant SaaS. Every game runs on its own isolated StateManager instance in memory. Operators control their game from a browser-based controller; the same game state renders to a browser-source URL that vMix or OBS picks up as an overlay.
End-to-end data flow:
Stadium scoreboard
└─ serial cable → USB-to-serial adapter
└─ ScoreBox device (Tailscale VPN)
└─ wss:// to spreesports.clickingspree.com
└─ tenant-isolated StateManager (your game instance)
├─ /api/game/state → controller (browser)
├─ /ws → controller, output(s)
└─ /output → vMix/OBS browser source
Tenant isolation is enforced at three layers: (1) per-instance StateManager objects in memory; (2) AsyncLocalStorage + Proxy in the request middleware so legacy route handlers always touch the right tenant; (3) account-bound JWT checks reject any cross-account access at HTTP 403.
2. Getting started — your first game
Steps for your first broadcast:
- Create your account at /admin/ — or follow the email invitation an admin sent you.
- Buy a license — Per Game ($1,000) or Weekly ($3,000). Stripe checkout. License is active immediately.
- Set up your teams — go to the Game tab in the controller. Either type the team identities by hand or use the Importer to pull them from ScoreStream + MaxPreps.
- Start the instance — from the dashboard, click Start New Game and pick the saved game setup. The controller URL and the vMix browser-source URL are both displayed.
- Wire up vMix / OBS — see section 3 below.
- Optional: bind a ScoreBox — if you want live scoreboard data, see section 4.
3. Connecting vMix / OBS to the output
The output renderer is a regular web page. Whatever switcher you use, drop in the URL as a browser source.
vMix
- Add Input → Web Browser
- URL:
https://spreesports.clickingspree.com/output/?token=<your-output-token> - Resolution:
1920×1080 - Tick Transparent background
- Add the input as an overlay channel above your game feed
OBS Studio
- Add Source → Browser
- URL: same as above
- Width
1920, Height1080, FPS30(or 60) - Add custom CSS:
body { background: transparent !important; } - Drag above your camera scene
4. ScoreBox setup
ScoreBox is the optional plug-and-play hardware that reads the stadium scoreboard's serial output and pushes the data to your game instance live. Setup is covered fully on /hardware — TL;DR:
- Register the unit in the admin panel under Devices with its serial number
- Pick the scoreboard type (Daktronics Football, Electro-Mech LX, etc.)
- Plug it into the scoreboard controller's console port + the network + power
- Bind it to a game instance when you start the game
5. Scoreboard data — how it reaches the cloud
SpreeSports is cloud-hosted. There's nothing for you to install locally, which also means there's no local process listening for ScoreBridge OSC/TCP packets from your press-box PC. Direct ScoreBridge-over-LAN is only possible in self-hosted deployments of earlier builds.
For cloud-hosted broadcasts, the live-scoreboard path is one of these three:
a) ScoreBox device (recommended)
Our $299 plug-and-play box reads the scoreboard controller's serial output directly, normalizes the protocol (Daktronics, Electro-Mech, Fair-Play, etc.), and pushes it to your game instance over a pre-authenticated Tailscale VPN — outbound only, no firewall changes required. See /hardware for the full walkthrough. This is the only solution that works with zero IT involvement on the school network.
b) Manual operator entry
If you don't have a ScoreBox, the controller has full manual controls for clock, score, period, down & distance, possession, timeouts, and penalty flags. Your producer drives the graphics directly from the controller — same as they'd drive any other CG. Obviously more work than a live feed, but free and works for any board.
c) ScoreBridge forwarder (on the roadmap)
For crews who already run ScoreBridge on a press-box PC, we're adding a small helper utility that runs alongside ScoreBridge, joins our Tailscale tailnet, and forwards its OSC / TCP / HTTP output to your cloud instance. Outbound VPN only, same pattern as ScoreBox. If you need this sooner, email web@clickingspree.com and we'll prioritize.
6. Importing teams, rosters & stats
The Game Import panel pulls team and game data from ScoreStream, then optionally pulls rosters and per-player stats from MaxPreps:
- Search ScoreStream by team name (e.g., "Palmetto")
- Pick the team from the results
- Choose a season and pick the game from the schedule
- Click Import — team identities (logo, colors), score, and starting state populate
- For rosters/stats, click the MaxPreps button on the imported team to pull the latest roster and per-game stats
7. Ticker & sponsor management
The bottom-line ticker is its own panel in the controller. It tracks the teams you've enabled across NFL, NCAA football, NBA, NCAA basketball, NHL, MLB, MLS, and NWSL. Game schedules and team metadata come from ScoreStream; live game state (clock, score, baserunners, etc.) is enriched from ESPN's public sports APIs.
- Teams — pick which teams from each sport appear in the rotation. Disable teams you don't want.
- Sponsors — drop sponsor cards into the rotation with two text lines and an optional logo. Set order; cards rotate at the configured frequency.
- Settings — crawl speed, sponsor frequency, sport-label colors, gather window for the score-fetch job, auto-gather-on-startup toggle.
- Transitions — configure the animation between game tiles and sponsor tiles.
- Live controls — pause, skip-to-next, hide ticker overlay (e.g., during a fullscreen replay graphic), all from the dashboard.
8. Running multiple games at once
Each active license allows one concurrent game instance. Per Game and Weekly licenses both work the same way here — the difference is just the license window (24 hours vs 7 days), not how many games you can run in parallel.
To broadcast multiple games at the same time, buy multiple licenses. Examples:
- Single Friday-night game → 1 × Per Game ($1,000)
- Tournament weekend, one production covering different games on different nights → 1 × Weekly ($3,000)
- Conference network covering 4 games on the same Friday night → 4 × Per Game ($4,000) or 4 × Weekly ($12,000) depending on how many weeks you'll do this
- Network broadcaster running 16 concurrent games → email web@clickingspree.com for a multi-license bundle quote
Each concurrent instance runs on its own StateManager, with completely isolated state — different teams, different scores, different rosters, different operators. Each gets its own controller URL, its own browser-source URL, and binds to its own ScoreBox device (if you have multiple units).
Cross-tenant access is hard-rejected at the API layer — operator A cannot read or write operator B's instance, even if they have the URL.
POST /api/platform/instances/start rejects with HTTP 403 ("All licenses in use") if you already have as many active instances as you have active subscriptions. End an existing game from the dashboard or buy another license to start the next one.
9. Saving & loading game setups
From the controller, Save Setup stores the current state — teams, rosters, lineups, sponsor configurations, graphics presets — under a name. Setups are scoped to your account; only you (and admins) see yours.
To reuse, click Load Setup and pick the name. Auto-save runs every 30 seconds against the current instance, so a browser crash mid-game doesn't lose your place.
10. Admin panel — accounts & licenses
The admin panel at /admin/ is for platform admins (accounts with is_admin=true). It can:
- List, search, edit, and delete user accounts
- Invite new users by email — they receive a one-time link to set their password
- Grant comp licenses (Per Game or Weekly) without going through Stripe
- View every active game instance across all tenants and force-end any of them
- See every ScoreBox device across all tenants — online/offline, last heartbeat
- Pause / resume the public demo simulator (for authoring the demo state)
11. Troubleshooting
Output is blank in vMix/OBS
- Confirm the URL ends in
/output/?token=…— note the trailing slash. - Check the browser-source resolution is 1920×1080.
- Open the URL in a regular browser; if you see a page but no graphics, the controller hasn't broadcast any state yet — switch to the controller and toggle a graphic on.
ScoreBox shows offline
- Status LED state — solid amber means booting, blinking green means joining VPN, solid green means online.
- Confirm internet on the press-box network — the box only needs outbound HTTPS.
- Admin panel → Devices → see last seen timestamp. If it's recent (under 90s), the box is online.
Ticker shows mock games / no real scores
- Settings → ScoreStream API Key must be set on your account.
- Settings → Auto-gather on startup should be enabled if you want games loaded automatically.
- The first gather can take 10–30 seconds; subsequent polls are fast.
Score from the scoreboard isn't updating the scorebar
- Confirm the ScoreBox in the Devices tab is bound to the active game instance — the device-to-instance binding is set when you start the game.
- Confirm the device shows online in the admin Devices tab, with a recent last seen timestamp (under 90 seconds).
- Check the scoreboard controller is actually emitting on its console port — many boards have a settings menu to enable serial output. The status LED on the ScoreBox blinks per byte received from the scoreboard.
- If you don't have a ScoreBox, the cloud build has no other automatic feed — the operator drives the scorebar from the controller manually.
Lost my admin password
- There's no self-service reset yet (on the roadmap). Email web@clickingspree.com or, if you're self-hosting, run an SQL update against the
accountstable with a fresh bcrypt hash (cost factor 12).