Gameplay Workflow
Phase state machineβ
waiting
β host:start
βΌ
question_open βββββ host:resume
β β²
β host:pause β
βΌ β
question_paused ββββββββββ
β
β host:reveal (or timer alarm)
βΌ
question_revealed
β
β host:next
βΌ
round_leaderboard (only after last question in a round)
β
β host:next
βΌ
question_open (next round) OR
ended (after final round)
Session creationβ
The host fills in SessionForm:
- Title β optional display name for the tasting (shown in session list). If left blank, the first wine's name is used.
- Wines β one or more wines; each wine gets 5 questions (one per category, fixed order:
color,country,grape_variety,vintage_year,wine_name) - Correct answer β always blank; host fills in
- Distractors β 3 per question; pre-filled for most categories (grape_variety is empty)
- Timer β range slider 15β120 s (default 60 s); applies to all questions
Session edition (edit before game starts)β
While the session is in the waiting phase (lobby), the host can click βοΈ Edit Wines to return to the form pre-filled. Submitting the form sends update_session to the backend, which replaces ctx.wines, saves state, and responds with host:session_updated. The host is returned to the lobby. Edition is blocked once the game has started (phase !== 'waiting').
Scoringβ
| Outcome | Points |
|---|---|
| Correct answer | 100 |
| Wrong answer | 0 |
| No answer (timer expires) | 0 |
Points are awarded at host:reveal. There is no speed bonus.
Answer changingβ
Participants can change their selected option at any time until the host clicks Reveal. The backend overwrites the answer on each submit_answer message. answeredCount (shown to host) increments only on a participant's first answer per question.
Timer behaviourβ
- Timer starts when the question is broadcast (not when
host:startfires) - Host can Pause and Resume any time during
question_open - Timer expiry (
alarm()) automatically triggers reveal (same ashost:reveal) game:timer_tickis emitted every second to all connected clients
Round leaderboardβ
After the last question of each wine (5th question), the server emits game:round_leaderboard instead of proceeding to the next question. After the final wine's last question, it emits game:final_leaderboard and transitions to ended.
Session endβ
Host clicks End Session at any time OR the game completes all questions. On end:
- Final rankings are written to KV (
host:{hostId}key,finalRankingsfield of the matching session entry) - All clients receive
session:ended - Phase transitions to
ended