Module 36

Trivia

Build a game where what you know — and how fast you know it — wins | The Fastest Brain in the Room

"The best trivia game makes you feel smart when you're right and curious when you're wrong."

Prerequisites

ModuleWhat You Used From It
Module 01 - PongA working game loop and basic input handling. Trivia games extend this with timer management, state synchronization, and data-driven content.

Week 1: History & Design Theory

The Origin

Trivia games trace back to parlor games and pub quizzes, but the video game version found its voice in 1995 with You Don't Know Jack by Jellyvision. Rather than treating trivia as a dry flashcard exercise, YDKJ wrapped questions in irreverent humor, wordplay, and time pressure. A snarky host read questions aloud, players buzzed in with answers, and wrong answers were met with ridicule. The game understood something fundamental: trivia is not about testing knowledge — it is about the social performance of knowing (or guessing, or panicking). The format — question, timer, answer, reaction — has remained essentially unchanged for 30 years because it is one of the most naturally compelling loops in all of gaming. Everyone knows something, and everyone wants to prove it.

How the Genre Evolved

You Don't Know Jack (Jellyvision, 1995) — Proved that trivia games need personality. YDKJ's host-driven format, creative question framing ("DisOrDat" categories, trick questions), and punishing wrong-answer penalties made it feel like a game show rather than a quiz. It established that presentation and pacing matter as much as question quality, and that humor is the secret ingredient that keeps players engaged between questions.

Buzz! (Sony, 2005) — Brought trivia to the living room with dedicated wireless buzzers for the PlayStation. Buzz! demonstrated that physical input devices change the social dynamic — literally racing to press a button creates physical comedy and excitement that button presses on a controller cannot match. It also pioneered round variety within trivia (fastest finger, point builder, final countdown), showing that the same question-answer loop can feel fresh with structural variation.

HQ Trivia (Rus Yusupov & Colin Kroll, 2017) — Took trivia live with a real host, real-time participation from millions of players simultaneously, and real cash prizes. HQ proved that trivia could be a mass spectator event and that the live, synchronous format — everyone answering the same question at the same time — created electric tension. It also revealed the infrastructure challenges: server load during live events, question pacing for millions, and cheat prevention at scale.

What Makes It "Great"

A great trivia game makes every player feel like they have a chance. The question pool must span enough categories that a sports expert, a history buff, and a pop-culture junkie each get their moment to shine. Difficulty must escalate naturally so early questions build confidence and late questions create tension. Speed bonuses reward quick thinking without making the game unwinnable for careful readers. And critically, the moment between answering and seeing the result — that half-second of "am I right?" — must be preserved and dramatized. The best trivia games are not about knowing the most; they are about the emotional arc of each question: confidence, doubt, anticipation, and either triumph or the delicious sting of "I should have known that."

The Essential Mechanic

Answering questions correctly under time pressure — speed and knowledge both matter.


Week 2: Build the MVP

What You're Building

A multiplayer trivia game where 2-4 players answer questions from a structured database, earn points based on correctness and speed, build streaks for consecutive correct answers, and compete across multiple rounds. The game pulls questions from a data file, manages timers, tracks scores with streak multipliers, and displays a final results screen.

Core Concepts

1. Question Database Design

Questions are data, not code. A well-structured question format supports multiple question types, categories, difficulty levels, and optional media. The database must be easy to author, validate, and extend.

// Question data structure
QuestionSchema:
    id: unique string
    text: string
    type: enum [MULTIPLE_CHOICE, TRUE_FALSE, FILL_IN]
    answers: Answer[]
    correctAnswerIndex: integer
    category: string          // "Science", "History", "Pop Culture"
    difficulty: enum [EASY, MEDIUM, HARD]
    timeLimit: seconds
    explanation: optional string

// Example question entry
{
    "id": "sci_042",
    "text": "What planet is known as the Red Planet?",
    "type": "MULTIPLE_CHOICE",
    "answers": [
        {"id": "a", "text": "Venus"},
        {"id": "b", "text": "Mars"},
        {"id": "c", "text": "Jupiter"},
        {"id": "d", "text": "Saturn"}
    ],
    "correctAnswerIndex": 1,
    "category": "Science",
    "difficulty": "EASY",
    "timeLimit": 15,
    "explanation": "Mars appears red due to iron oxide on its surface."
}

Why it matters: The question database is the content engine of the entire game. A clean schema means questions can be authored by non-programmers (in a spreadsheet or form), validated automatically, and swapped without touching game code. Separating content from logic is what makes a trivia game maintainable at scale.

Interactive: Trivia Game

Answer 5 game-dev themed trivia questions! Each has a countdown timer — faster correct answers earn more points. Build a streak for bonus multipliers. Click an answer button or press 1-4 to select.

Press Start to begin!

2. Timer-based Answer Windows

Each question has a countdown timer. The player must answer before time runs out. Faster correct answers earn more points, creating tension between speed and deliberation.

class QuestionTimer:
    maxTime = 15
    elapsed = 0
    isActive = false

    function getSpeedBonus():
        remainingRatio = getRemaining() / maxTime
        return floor(remainingRatio * MAX_SPEED_BONUS)

    function render():
        remaining = getRemaining()
        barWidth = (remaining / maxTime) * FULL_BAR_WIDTH
        barColor = remaining > 5 ? GREEN : remaining > 2 ? YELLOW : RED
        drawBar(barWidth, barColor)
        if remaining < 3:
            pulseText(ceil(remaining))
            playTickSound()

Why it matters: The timer is what transforms trivia from a relaxed quiz into a game. Without it, players can deliberate forever and the pacing collapses. The speed bonus creates a risk/reward decision: answer immediately for maximum points, or wait to think and risk running out of time.

3. Multiple Input Methods

Trivia games must support diverse input devices: keyboard buttons, touchscreen taps, controller presses, or even voice input. An input abstraction layer lets the game accept answers from any source.

// Abstract input interface
interface AnswerInput:
    function getSelectedAnswer() -> answerId or null
    function isConfirmed() -> boolean

// Keyboard implementation
class KeyboardAnswerInput implements AnswerInput:
    ANSWER_KEYS = { "1": "a", "2": "b", "3": "c", "4": "d" }

    function getSelectedAnswer():
        for key, answerId in ANSWER_KEYS:
            if isKeyPressed(key):
                return answerId
        return null

Why it matters: The input method defines the social experience. Keyboard buttons work for local play. Phone-as-controller lets everyone use their own device privately. Abstracting input means you can support all of these without rewriting the question-answer loop.

4. Scoring with Streaks and Multipliers

Points are awarded for correct answers, with bonuses for speed and consecutive correct answers (streaks). Streaks multiply the base score, creating high-risk, high-reward dynamics.

class ScoringSystem:
    BASE_POINTS = 100
    MAX_SPEED_BONUS = 50
    STREAK_MULTIPLIERS = [1, 1, 1.5, 2, 2.5, 3]

    function scoreAnswer(playerId, isCorrect, speedBonus):
        player = playerScores[playerId]
        if isCorrect:
            player.streak += 1
            streakIndex = min(player.streak, STREAK_MULTIPLIERS.length - 1)
            multiplier = STREAK_MULTIPLIERS[streakIndex]
            points = floor((BASE_POINTS + speedBonus) * multiplier)
            player.total += points
        else:
            player.streak = 0

Why it matters: Flat scoring is boring — the leader after question 5 is almost always the leader after question 15. Streaks create drama: a player on a 5-question streak is earning triple points, so one mistake costs them enormously.

5. Question Selection Algorithm

The algorithm chooses which question to show next, balancing difficulty progression, category variety, and avoiding repeats.

class QuestionSelector:
    allQuestions = []
    usedQuestionIds = set()
    recentCategories = []

    function selectNextQuestion(roundNumber, totalRounds):
        available = allQuestions.filter(q => q.id NOT in usedQuestionIds)
        progress = roundNumber / totalRounds
        if progress < 0.3: targetDifficulty = EASY
        else if progress < 0.7: targetDifficulty = MEDIUM
        else: targetDifficulty = HARD

        candidates = available.filter(q => q.difficulty == targetDifficulty)
        // Prefer categories not recently used
        recentCats = set(recentCategories.last(3))
        preferred = candidates.filter(q => q.category NOT in recentCats)
        if preferred.isNotEmpty(): candidates = preferred
        selected = random(candidates)
        return selected

Why it matters: If players see the same question twice, trust in the game evaporates. If three Science questions appear in a row, the history expert feels cheated. The selection algorithm is invisible when it works and game-breaking when it does not.

Interactive: Question Selection Balance

A visualization of the question pool by category and difficulty. The algorithm picks the next question to balance coverage. Click "Pick Next" to see the selection distribution update in real time. Watch how it avoids repeating categories and escalates difficulty.

Questions picked: 0

6. Content Pipeline / Authoring Tools

Creating, validating, and managing thousands of questions requires tooling beyond a text editor. A content pipeline lets non-programmers author questions and catches errors before they reach players.

function validateQuestion(question):
    errors = []
    if question.text.length == 0:
        errors.append("Question text is empty")
    if question.answers.length < 2:
        errors.append("Must have at least 2 answers")
    if question.correctAnswerIndex >= question.answers.length:
        errors.append("Correct answer index out of range")
    if question.answers.hasDuplicateTexts():
        errors.append("Duplicate answer text detected")
    return errors

Why it matters: A trivia game is only as good as its questions. If authoring is painful, you will have too few questions and players will see repeats. The pipeline is an investment in content velocity — the ability to add hundreds of quality questions quickly is what keeps a trivia game alive.

7. Live Multiplayer Synchronization

All players must see the same question at the same time and submit answers within the same window. In local play this is trivial (shared state), but the architecture must support the possibility of networked play.

class TriviaGameState:
    currentQuestion: Question
    phase: enum [SHOWING_QUESTION, ACCEPTING_ANSWERS, SHOWING_RESULT, BETWEEN_QUESTIONS]
    timer: float
    playerAnswers: { playerId: AnswerResult }

class LocalTriviaGame:
    state = TriviaGameState()

    function onPlayerAnswer(playerId, answerId):
        if state.phase != ACCEPTING_ANSWERS: return
        if playerId in state.playerAnswers: return
        state.playerAnswers[playerId] = processAnswer(answerId, state)
        if allPlayersAnswered(): endAnswerWindow()

Why it matters: Synchronization is what makes trivia multiplayer rather than parallel solitaire. Every player must experience the question reveal, the ticking countdown, and the answer reveal at the same moment.


Stretch Goals

  1. Add image and audio questions (album art, sound clips, maps).
  2. Implement phone-as-controller input using WebSockets for private answer submission.
  3. Add a "wager" round where players bet points on their confidence.
  4. Create a question editor UI for authoring new questions in-game.
  5. Add category selection so players vote on the topic for the next round.
  6. Implement an audience mode where spectators can answer for bonus prizes.

MVP Spec

ElementScope
Players2-4 local players, each with assigned input keys
Question database30+ questions in JSON file, covering 4+ categories and 3 difficulty levels
Question typesMultiple choice (4 options) as the primary type
TimerCountdown per question (15s default), visual bar + color change at low time
ScoringBase points + speed bonus + streak multiplier, displayed per-question and cumulatively
Rounds10-15 questions per game, difficulty escalating from easy to hard
SelectionNo repeat questions, category rotation, difficulty scaling by round
ResultsFinal scoreboard with rankings, total points, best streak, and fastest answer
FeedbackCorrect/incorrect indication, streak announcements, explanation of correct answer

Deliverable

A playable trivia game where 2-4 players answer multiple-choice questions under time pressure, earn points modified by speed and streak bonuses, and compete across 10-15 rounds with escalating difficulty. Questions load from an external data file with at least 30 entries. The game should feel like a game show: dramatic countdowns, satisfying correct-answer feedback, and a final results screen that makes the winner feel like a champion.


Analogies by Background

These analogies map game dev concepts to patterns you already know. Find your background below.

For Backend Developers

ConceptAnalogy
Question database designLike designing a REST API schema — well-defined fields, validation rules, and a contract that separates content from business logic
Timer-based answer windowsLike request timeouts with SLAs — the client must respond within a deadline, and late responses are rejected
Multiple input methodsLike supporting multiple authentication methods behind a single auth interface
Scoring with streaksLike rate-limiting with burst allowances — sustained good performance earns a higher throughput multiplier
Question selection algorithmLike a load balancer with weighted routing — distribute requests across categories while respecting constraints
Content pipelineLike a CI/CD pipeline for database migrations — validate, transform, and deploy content with automated checks
Live multiplayer syncLike distributed consensus — all nodes must agree on the current state before processing

For Frontend Developers

ConceptAnalogy
Question database designLike a CMS schema for structured content — each question is a content entry with typed fields and validation
Timer-based answer windowsLike form submission with a session timeout — the UI communicates urgency through visual countdown
Multiple input methodsLike progressive enhancement for accessibility — keyboard, mouse, touch all flow through the same event handler
Scoring with streaksLike gamified UI animations — a "combo" counter that scales visual feedback based on sustained engagement
Question selection algorithmLike a content recommendation feed — showing varied, non-repeating content matching the user's context
Content pipelineLike a design system with Storybook — tooling that lets content creators preview and validate their work
Live multiplayer syncLike collaborative real-time editing (CRDT/OT) — all connected clients see the same state

For Data / ML Engineers

ConceptAnalogy
Question database designLike a labeled dataset — each question is a data point with features and a label, and schema quality determines model quality
Timer-based answer windowsLike inference latency budgets — the model must return a prediction within a time constraint
Multiple input methodsLike multi-modal model inputs — text, image, and audio all feed into the same prediction pipeline
Scoring with streaksLike reward shaping in RL — bonus rewards for consistent performance encourage stable behavior
Question selection algorithmLike active learning sample selection — choosing the next data point that maximizes information gain
Content pipelineLike a data labeling pipeline with quality checks — human annotators create content, validators catch errors
Live multiplayer syncLike parameter server synchronization in distributed training — all workers operate on the same model version

Discussion Questions

  1. Knowledge breadth vs. depth: Should a trivia game reward deep expertise in one category or broad knowledge across many? How does category selection change the competitive dynamics?
  2. The content treadmill: A trivia game with 100 questions is fun once. A trivia game with 10,000 questions is fun for months. How do you build a content pipeline that scales? What role could AI play in question authoring?
  3. Speed vs. knowledge: Speed bonuses reward quick answers, but they also reward impulsive guessing. How do you tune the speed bonus so that a thoughtful player has a chance against a fast player?
  4. Voice as input: If players speak their answers aloud instead of pressing buttons, the game becomes a fundamentally different social experience. How does voice input change game design and the emotional arc of a question?