The live game hub. It broadcasts board state to connected displays over Socket.IO, and serves a pug-rendered host UI for running a game pulled from FantasyFeudApiServer's content.
FantasyFeudApiServer --(game content)--> FantasyFeudServer --(Socket.IO)--> FantasyFeudSite
(question data) host UI reads it (this app) board display
- FantasyFeudApiServer holds the static question/answer content.
- FantasyFeudServer (this app) holds the live game state (team names, scores, members, strikes, which answers are revealed) and pushes it to every connected board over a socket. It also serves a host UI for driving that state without hand-crafting requests.
- FantasyFeudSite is the on-air board display — a static page with no server of its own — that connects to this server's socket.
State gets into the game one of two ways: an external tool POSTs a full
board-state blob to /question, or you use the host UI at /, which does
the same POST on your behalf.
npm install
cp .env.example .env # adjust PORT / RESOURCE_SERVER if needed
npm startListens on port 3000 by default. RESOURCE_SERVER (default
http://localhost:3001, must include the scheme) tells it where to find
FantasyFeudApiServer for the host UI's season/game listings.
The host UI (/, /seasons/:id, /games/:id) requires HTTP Basic Auth,
same as Jeopardy's host-facing routes — the browser will prompt for
credentials. Set them via AUTH_USER/AUTH_PASS.
Open http://localhost:3000/ in a browser (enter the AUTH_USER/AUTH_PASS
credentials when prompted):
- Pick a season, then a game.
- Set team names and paste in each team's members (comma separated) — click a member's name to mark them as the active player at the podium.
- Click Start This Question on a question to push it live (all answers hidden, strikes cleared).
- Click Reveal on an answer as it's guessed correctly.
- Use Add Strike for a wrong answer, Award Pot to Team N to give a team the value of everything currently revealed, and the score fields (directly editable, or ±5) to make manual adjustments. Score Reset zeroes one team's score.
- Reset Board clears the current question/strikes/answers but keeps team names, members, and scores. Reset Game clears all of that too — use it to start a fresh game.
The host page reloads showing whatever is currently live (via
GET /current-state), so refreshing or reconnecting mid-game doesn't lose
anything.
| Method | Path | Purpose |
|---|---|---|
| POST | /question |
Push a full board-state JSON blob live (requires IsValid: true) |
| GET | /current-state |
The last state pushed via /question |
| GET | /status |
{ "clients": <connected socket count> } |
| GET | / (auth required) |
Host UI: season list |
| GET | /seasons/:id (auth required) |
Host UI: games in a season |
| GET | /games/:id (auth required) |
Host UI: run a game (:id is <season-id>---<game-id>) |
| Event | Direction | Purpose |
|---|---|---|
board:init |
client → server | Ask for the current state (on connect/reconnect) |
board:update |
server → client | The current board state |