Gameplay
Three modes share the same question pipeline and scoring math:
| Mode | Players | Description |
|---|---|---|
| Lobby | 2-16 | Real-time multiplayer race. Host creates a lobby, players join by code, everyone answers the same question simultaneously. |
| Endless | 1 | Solo gauntlet. Play until you get one wrong. Score and streak persist on the global leaderboard. |
| Practice | 1 | One-question-at-a-time draws from the cache. No pressure, no timer, used to grind XP and explore categories. |
Question shape
Every question has the same structure regardless of mode:
type Question = {
id: number;
category: string; // 'science', 'history', ...
difficulty: string; // 'easy' | 'medium' | 'hard' | 'auto'
question: string; // the prompt
choices: [ string, string, string, string ];
answer: number | null; // 0-3, null until reveal
explanation: string; // shown after reveal
};
The answer field is null in the safe-format that gets sent to clients during a round. The server only reveals the index when the round is over (all answered, timer expired, or host clicked Next).
Scoring formula
points = (100 + speedBonus) * streakMultiplier
where:
speedBonus = floor ((timeRemaining / timeLimit) * 100) // 0-100
streakMultiplier = streak >= 6 ? 4
: streak >= 4 ? 3
: streak >= 2 ? 2
: 1
A wrong answer resets the streak to 0 and awards 0 points. Full math and rationale: see Scoring & XP.
XP and levels
Independently from per-round score, players accumulate XP that persists across all modes. Level thresholds:
0 100 250 500 1000 1800 3000 5000 8000 12000 18000
Levels are purely cosmetic — they unlock no gameplay, just a level badge.
Categories
Twenty topical categories plus random:
science history geography sports entertainment music
movies television literature art technology nature
food mythology language politics space animals
gaming random
The set is defined in QuestionGenerator::CATEGORIES on the server and mirrored in StartEndless and GenerateQuestions DTOs.