- 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>
7.4 KiB
7.4 KiB
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) ornumber(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) andjudge_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
liveand 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.
- Scoring grid: rows = teams, columns = criteria, using the same block/number inputs.
- 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:
Nnext game,Pprev game,Hcycle visibility,Tstart/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:
Tstart/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:
participantsper team). - Multiple admins / co-hosts (stretch).
- Per-game timers and buzzers for contestants (stretch). The event countdown timer is in 4.5.