Professional dual-screen trivia hosting with a broadcast view, host dashboard, helper controls, custom media, and scriptable setup flags.
Trivia Broadcast Engine runs a live-hosted trivia game on your local network. The audience sees a full-screen broadcast board, while the host controls clue selection, reveals, scores, wagers, audio, and game flow from a dashboard.
| View | URL | Purpose |
|---|---|---|
| Broadcast | /broadcast |
Audience-facing display for a TV, projector, or capture card |
| Dashboard | /dashboard |
Main host controls for the whole game |
| Scoring Helper | /helper-scoring |
Secondary scoring controls |
| Board Helper | /helper-board |
Secondary board controls |
| Editor | /editor |
In-browser content and settings editor |
| Stats | /stats |
Post-game charts and printable reports |
- Dual-screen hosting — broadcast view for the audience, dashboard for the host, plus helper screens for scoring and board control
- Fully scriptable setup — configure everything from CLI flags: board size, values, players, labels, audio, video, and CSV/Sheets imports
- Google Sheets & CSV import — paste a published Sheets URL or local CSV path; supports simple column format and grid format
- Custom audio & video — per-clue timer, intro video/music, background music, bonus clue sound, applause, and more — all config-gated so unconfigured assets are silent no-ops
- Timer with pause/resume — starts on DONE READING; pauses on INCORRECT for other players to buzz; keyboard shortcuts for BUZZ/UNBUZZ
- Bonus clue (Daily Double) — full-screen cover flip, auto-transition to wager screen, configurable per-round count and positions
- Championship / Final — wager-only reveal (no answer input needed); step-by-step name → wager reveal; multiple questions support
- Fuzzy answer comparison — server-side answer matching tolerates extra spaces, casing, and parenthetical variations
- Answer shown indicator — visual badge on broadcast and dashboard mirror when the answer has been revealed
- Category cover reveal — full-screen image cover that flips to show each category name; includes progress indicator (current / next category)
- Player selector modal — CORRECT/INCORRECT buttons open a popup with player name buttons; auto-adjusts score and pauses timer
- Blocking toasts — prevent returning to board without showing the answer first
- Child-host mode — shorter timer, friendlier labels, walkthrough shown on first load
- Practice mode —
/practicepage to cycle through all clues from Rounds 1, 2, and Final with back/next navigation and answer toggle - Post-game stats — detailed per-player and per-game charts: correct/incorrect streaks, category breakdown, value distribution, and printable reports
- In-browser editor — edit categories, clues, answers, and settings directly from the browser at
/editor - Stress-tested — dedicated verification script for timer/audio desync plus full stress suite covering duplicates, scoring, wagers, reset, and edge cases
Requires Node.js 18+.
git clone https://github.com/L-Logix/Trivia-Board.git
cd Trivia-Board
npm install
npm run setup
npm startThe server opens on port 3333. Use http://localhost:3333 on the host machine, or the LAN address printed in the terminal for another device.
- Open
/broadcaston the audience screen and click once to unlock browser audio. - Open
/dashboardon the host laptop. - Start the intro, reveal categories, populate the board, and select clues.
- Use the dashboard to mark correct/incorrect answers and control the timer.
- Bonus clues use wagers.
- Final/championship only asks the host for wagers. The host does not enter contestant answers.
trivia setupThe wizard configures board size, values, bonus clues, timer duration, CSV or Google Sheets content, players, labels, and media files.
If the global trivia command fails with node.exe is not recognized, Node is not on your PATH. Install Node.js 18+, reopen PowerShell, then reinstall or relink the package with npm install -g . from this folder.
Refresh your saved sheets without walking through the wizard:
trivia setup --update-contentLoad specific sheets and use modern values:
trivia setup --modern --round1 round1.csv --round2 round2.csv --championship final.csvUpdate only players, labels, and intro video music:
trivia setup --players "Alice,Bob,Charlie" --bonus-label "DAILY DOUBLE" --video-music intro-theme.mp3Update exact bonus clue positions. Positions are 1-based as column:row.
trivia setup --bonus-positions-r1 3:5 --bonus-positions-r2 2:3,1:4Set any config value directly:
trivia setup --set "labels.bonusClue=DAILY DOUBLE" --set timerSeconds=8| Flag | Meaning |
|---|---|
--content, --update-content |
Refresh from saved sources or sources passed in this command |
--round1 PATH_OR_URL, --r1 PATH_OR_URL |
Round 1 CSV file or published Google Sheets CSV URL |
--round2 PATH_OR_URL, --r2 PATH_OR_URL |
Round 2 CSV file or published Google Sheets CSV URL |
--round2-same-as-round1 |
Build Round 2 from the Round 1 source using double values |
--championship PATH_OR_URL, --final PATH_OR_URL |
Final/championship CSV file or URL |
--players "A,B,C" |
Replace player names |
--no-save-sources |
Do not remember the passed sheet/file sources |
| Flag | Meaning |
|---|---|
--modern |
Use 200,400,600,800,1000 and 400,800,1200,1600,2000 |
--traditional |
Use 100,200,300,400,500 and 200,400,600,800,1000 |
--values LIST |
Round 1 values, for example 200,400,600,800,1000 |
--double-values LIST |
Round 2 values |
| Flag | Meaning |
|---|---|
--columns N |
Board column count |
--rows N |
Board row count |
--timer N, --timer-seconds N |
Clue timer duration in seconds |
| `--double-round [true | false]` |
--single-round, --no-double-round |
Disable Round 2 |
--bonus-r1 N, --bonus-clues-r1 N |
Number of Round 1 bonus clues |
--bonus-r2 N, --bonus-clues-r2 N |
Number of Round 2 bonus clues |
--bonus-positions-r1 LIST |
Round 1 bonus positions, for example 3:5,6:5 |
--bonus-positions-r2 LIST |
Round 2 bonus positions, for example 2:3,1:4 |
--bonus-method TEXT |
Bonus clue assignment method label stored in config |
| `--child-host [true | false], --kid-mode [true |
--no-child-host, --no-kid-mode |
Disable child-host mode |
| `--jeopardy-style [true | false]` |
--no-jeopardy-style |
Disable Jeopardy-style labels |
| Flag | Meaning |
|---|---|
--bonus-label TEXT |
Label for bonus clues |
--championship-label TEXT, --final-label TEXT |
Header label for Final/championship |
--championship-section TEXT, --final-section TEXT |
Section label for Final/championship |
--round2-suffix TEXT |
Round 2 suffix label |
Asset flags copy your file into the correct public/ folder and update config.json.
| Flag | Destination |
|---|---|
--logo PATH |
public/img/logo.* |
--category-cover PATH, --price-cover PATH |
public/img/cat-cover.* |
--intro-video PATH |
public/video/intro.mp4 |
--intro-audio PATH, --intro-music PATH, --video-music PATH |
public/audio/intro-audio.mp3 |
--bonus-image PATH, --bonus-clue-image PATH |
public/img/bonus-clue.* |
--promo-image PATH |
public/img/promo.* |
--host-intro PATH |
public/audio/host-intro.mp3 |
--times-up PATH |
public/audio/times-up.mp3 |
--bonus-sound PATH, --bonus-clue-sound PATH |
public/audio/daily-double.mp3 |
--think-music PATH, --final-think PATH |
public/audio/final-think.mp3 |
--applause PATH |
public/audio/applause.mp3 |
--board-fill PATH |
public/audio/board-fill.mp3 |
--correct-sound PATH |
public/audio/correct.mp3 |
--incorrect-sound PATH |
public/audio/incorrect.mp3 |
--outro PATH |
public/audio/outro.mp3 |
--background-music PATH, --bg-music PATH |
public/audio/background.mp3 |
Generic asset controls:
| Flag | Meaning |
|---|---|
--asset key=PATH |
Update any asset by key |
--enable-asset KEY |
Mark an existing asset enabled |
--disable-asset KEY, --no-asset KEY |
Mark an asset disabled |
Asset keys are logo, categoryCover, introVideo, introAudio, bonusClueImage, promoImage, hostIntro, timesUp, bonusClue, championshipThink, applause, boardFill, correct, incorrect, outro, and backgroundMusic.
| Flag | Meaning |
|---|---|
--set path=value |
Set any config.json field, including nested paths |
Use quotes when the value contains spaces:
trivia setup --set "labels.championshipHdr=FINAL JEOPARDY"JSON arrays and objects are accepted:
trivia setup --set "baseValues=[200,400,600,800,1000]"Simple CSV format:
| Category | Clue | Answer | Value |
|---|---|---|---|
| History | This president was born in 1732 | Who is George Washington? | 200 |
| Science | H2O is the chemical formula for this | What is water? | 400 |
Rules:
- Row 1 should be
Category,Clue,Answer,Value. Valueis optional but recommended.- Clues are grouped by category and sorted into rows by value when values are present.
- Published Google Sheets CSV URLs work anywhere a CSV path works.
Final/championship CSV uses:
Category,Clue,Answer
Famous Homes,This estate stored National Gallery art during World War II,What is the Biltmore?Run the focused audio/done-reading verifier:
npm run verify:done-readingRun the full stress suite:
npm run stressThe stress suite covers duplicate done-reading events, timer stability, answer scoring, bonus wagers, Final wager-only behavior, reset behavior, invalid inputs, broadcast audio playback, and setup flags.
bin/
trivia.js
src/
cli/
setup.js
start.js
server/
game-state.js
socket-handlers.js
public/
broadcast.html
dashboard.html
editor.html
stats.html
helper-board.html
helper-scoring.html
js/
css/
audio/
img/
video/
scripts/
stress-test.js
verify-done-reading-audio.js
npm install
npm run setup
npm start
npm run stressSee CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SECURITY.md for project process and reporting.