Files
game-scoreboard/docs/PRD.md
T
joshuaandClaude Opus 5.5 bf5b6194f6 Add scoreboard countdown timer and sound effects
- Timer: one per event, set from the control room (duration, presets,
  start/pause/resume/reset, show/hide, T shortcut). Rules are pure
  functions in src/lib/timer.ts; the server's clock sets the end time and
  each screen counts down locally, corrected for its own clock.
  Needs supabase/migrations/0002_timer.sql.
- Sound effects on the scoreboard, synthesised with Web Audio (no files):
  drum-roll + crash per revealed team, fanfare for first place, a chime
  on game change, ticks for the last 10 seconds and a buzzer at zero.
  Triggers are pure functions comparing consecutive payloads.
- 'Turn sound on' button on the scoreboard, since browsers block audio
  until a click; the choice is remembered across reloads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 22:14:10 +02:00

7.4 KiB
Raw Blame History

PRD — Game Night Live

1. Goal

Run a youth game night (e.g. "Worship Game Night") from one admin tab while a projector tab shows a live scoreboard, and judges score from their phones via links. Versatile enough for any game format.

2. Roles

Role Access How they get in
Admin Everything Logs in (magic link). Email must be in ADMIN_EMAILS.
Scoreboard viewer Read-only scoreboard for ONE event Public link /s/{scoreboardToken}
Judge Score ONE game Personal link /j/{judgeToken} OR open game link /jo/{openToken} (enters name first)

3. Core concepts

  • Event — one game night. Has teams, games, one scoreboard link, visibility state.
  • Team — name + colour. Belongs to an event.
  • Game — one activity. Ordered. Has a scoring mode:
    • judged — judges submit scores via links; admin can see progress & override.
    • direct — admin enters scores directly.
  • Criterion ("block") — one thing being scored in a game. A game has 1..N criteria.
    • e.g. Karaoke: Pitch, Energy, Lyrics accuracy, Stage presence, Crowd reaction (each 1–5).
    • e.g. Guess the Lyric: one criterion "Correct answers" (number input, 0–20).
    • Input type: blocks (tap a number in a row of buttons) or number (free numeric input / +/- stepper).
    • Has min, max, step, weight, and a description (shown to whoever scores it).
  • Points mode per game (how a game's result becomes leaderboard points):
    • raw — game points = criteria total × multiplier.
    • placement — teams ranked by criteria total, then awarded placement points (default 10/7/5/3).
  • Adjustment — bonus or penalty points with a reason, optionally tied to a game.
  • Notes — admin_notes (only admin sees) and judge_notes (judges see) per game.

4. Features

4.1 Admin — Setup (/admin/events/[id])

  • Create/edit/delete events; duplicate an event (copies teams, games, criteria — not scores).
  • Teams: add, rename, recolour, reorder, delete.
  • Games builder: add, reorder (drag or up/down), duplicate, delete.
    • Title, description, scoring mode, points mode, multiplier, placement points.
    • Criteria list: add/remove/reorder; label, description, input type, min/max/step, weight.
    • Quick presets: "Karaoke (5 × 1–5)", "Single score (0–10)", "Points (number)", "Win/Lose (0–1)".
    • Admin notes + judge notes (multiline).
  • Judges (judged games only):
    • Nominate judges by name → each gets a personal link (copy button + QR code).
    • Toggle the open link on/off; anyone opening it types their name and becomes a judge.
    • Revoke a judge (link stops working, their scores excluded).
  • Share panel: scoreboard link + QR, all judge links per game.

4.2 Admin — Control room (/admin/events/[id]/live)

This is the screen used during the night. Must be fast and hard to mess up.

  • Game switcher: Prev / Next buttons + list of all games with status (upcoming / live / done). Setting a game as current marks it live and shows it on the scoreboard.
  • Current game panel:
    • Scoring grid: rows = teams, columns = criteria, using the same block/number inputs.
      • Direct mode: admin types/taps here. Autosaves.
      • Judged mode: shows per-team average per criterion, a judge-progress matrix (✓ per judge per team), and per-judge breakdown on expand. Admin can override a cell (override wins over judge average; clearly marked; can be cleared).
    • Spotlight: pick "now performing" team — judges see it highlighted.
    • Lock judging toggle (judges become read-only).
    • Mark game done.
    • Admin notes visible.
  • Bonus/penalty: per team quick buttons (+1, +5, +10, −5) and custom amount + reason. Recent adjustments list with undo.
  • Scoreboard visibility: Visible / Frozen / Hidden (see 4.3). Big obvious toggle.
  • "Open scoreboard" button (new tab) + "Reveal mode" button (see 4.3).
  • Keyboard shortcuts: N next game, P prev game, H cycle visibility, T start/pause timer, ? help.

4.3 Scoreboard (/s/[token])

  • Projector-first, 16:9, readable from the back of a hall.
  • Shows: event name, current game title, team standings (rank, name, colour, total points). v1 shows totals only; per-game points columns are a later option.
  • Updates live (< 1s) when admin changes anything. Rank changes animate.
  • Visible — live totals.
  • Frozen — shows totals as they were the moment it was frozen, with a subtle "scores frozen" note. Server stores the snapshot; live scores are not sent. The current game title still updates live.
  • Hidden — no scores sent at all. Shows team names (no order implied — alphabetical) and the current game, with a "scores are hidden" state.
  • Reveal mode (admin-triggered): scoreboard reveals final standings last place → first, one team per admin click ("Reveal next") — tied teams too, each showing the shared rank — then sets visibility to Visible.
  • Auto-reconnects; also polls every 10s as a fallback. Shows a small offline dot if disconnected.
  • Fullscreen button; hides cursor after inactivity.

4.4 Judge (/j/[token])

  • Mobile-first. Shows game title, judge notes, and their own name.
  • One card per team (spotlighted team pinned on top + highlighted).
  • Each card: one block row per criterion (e.g. 1 2 3 4 5 big tap targets) with the criterion label + description; number criteria get a stepper.
  • Autosaves on every tap; shows saved ✓ / saving / error per card.
  • Judges see only their own scores — never other judges' or totals.
  • If judging locked or game done: read-only with a message. If revoked: "This link is no longer active."
  • Open link (/jo/[token]): enter name → creates judge → redirects to personal link and stores it in localStorage so a refresh keeps them in.

4.5 Timer

One countdown timer per event, run from the control room; not tied to a game.

  • Set a time (minutes + seconds, or presets 30s / 1 min / 2 min / 5 min). Setting a time resets the timer.
  • Start, pause, resume, reset. Show or hide it on the scoreboard; starting it also shows it.
  • The scoreboard shows it large above the standings. It is not a score, so it shows whether scores are visible, frozen or hidden.
  • The last 10 seconds are highlighted; at zero it shows "Time's up" until reset.
  • The server's clock decides when it ends, so every screen agrees even if a device clock is wrong.
  • Keyboard shortcut in the control room: T start/pause.

4.6 Sound effects (scoreboard only)

Played by the scoreboard page, so they come out of the projector PC's speakers.

  • Reveal: a drum-roll, then a crash as each team appears; a fanfare for first place.
  • Game transition: a chime when the current game changes.
  • Timer: a tick for each of the last 10 seconds (sharper for the last 3) and a buzzer at zero.
  • Browsers only allow sound after a click on the page, so the scoreboard has a "Turn sound on" button. The choice is remembered, but after a reload one click anywhere is needed again.
  • Sounds are synthesised in the browser (no audio files). With reduced motion the drum-roll is skipped.

5. Non-functional

  • Live latency target < 1s on normal Wi-Fi.
  • Works with ~10 teams, ~20 games, ~10 judges per game without lag.
  • No data loss on refresh; all state server-side.
  • Accessible: visible focus, sufficient contrast, tap targets ≥ 44px.

6. Out of scope (v1)

  • Individual contestants within teams (stretch: participants per team).
  • Multiple admins / co-hosts (stretch).
  • Per-game timers and buzzers for contestants (stretch). The event countdown timer is in 4.5.