Learning Goals 3 min
By the end of this Build lesson you will have:
- A complete ten-question Malaysia trivia game with parallel question/answer lists (L04-37), no-repeat shuffling (L04-38), high-score persistence (L04-39), and pass-and-play two-player mode (L04-40) all wired together.
- Two playable modes: 1-player (chase your own high score) or 2-player (alternating turns with the 3-minus swap), chosen at the title screen.
- A polished game flow: title sprite asks for mode and player names, the quiz runs ten questions with sound feedback for right/wrong, and the end-screen shows final scores plus the all-time high score saved across sessions.
Warm-Up — what you already own 7 min
Cluster G was four lessons. You spent each one building one slice of a quiz game. Before you open Scratch today, list every piece you already have working:
- L04-37 — Parallel lists: two lists, questions and answers, where
item N of questionsanditem N of answersare always a matching pair. The ask () and wait + (answer) = (item N of answers) answer-checking pattern. - L04-38 — No-repeat shuffle: the asked list that records which question numbers have already been used in this game. Pick a random number 1–10, check if it's in asked, if so pick again. Guarantees each question shows up exactly once per game.
- L04-39 — High-score persistence: the high-score variable, the green-flag check that compares final score against high-score, and the cloud-variable (or list-based) save pattern that survives reloading the project.
- L04-40 — Pass-and-play multiplayer: current-player, score-p1, score-p2, the 3-minus swap, the join-inside-join prompts, and the three-way winner check at the end.
Predict puzzle. Look at this fragment from inside today's main quiz loop. What does it actually do — and which previous lesson does each block come from?
set [q-index v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (q-index) ?>>
set [q-index v] to (pick random (1) to (length of [questions v]))
end
add (q-index) to [asked v]
ask (item (q-index) of [questions v]) and wait
Reveal the answer
This fragment picks a question number that hasn't been asked yet (L04-38 no-repeat shuffle), records it in the asked list, then pulls the question text from the questions list (L04-37 parallel lists) and asks the player. Five blocks span two cluster G lessons. Today's lesson is mostly about where to put these familiar fragments — the gluing, not the gluework.
New Concept — the assembly map 15 min
A Build lesson doesn't introduce one block — it introduces a structure. Today's structure is the broadcast chain that flows through one game session:
The event chain
- Flag click → Title sprite shows, all variables reset, all lists rebuilt, high-score loaded from storage.
- Title click → Title asks "1 player or 2?" → sets mode, then broadcasts game-start.
- game-start → Title hides, quiz sprite shows, asked list is cleared, scores are zeroed, current-player set to 1.
- Main quiz loop (inside the quiz sprite) → 10 times: pick a no-repeat question, prompt the current player, check the answer, score the right player, swap players (only if 2-player mode), play right/wrong sound.
- Quiz finished → Quiz sprite broadcasts game-end.
- game-end → End-screen sprite shows. In 1-player mode it announces score and updates high-score; in 2-player mode it announces the winner.
Three sprites — Title, Quiz, EndScreen. Two lists — questions, answers (plus the helper list, asked). Six or seven variables. One game.
The mode switch
One variable, mode, holds the player count: 1 or 2. The title sprite asks the player which they want and stores the answer. The whole game then reads this variable to decide whether to swap players after each turn:
ask [How many players? Type 1 or 2.] and wait
set [mode v] to (answer)
Inside the main quiz loop, the swap is wrapped in an if:
if <(mode) = (2)> then
set [current-player v] to ((3) - (current-player))
end
The scoring branch
Same conditional structure. In 1-player mode, every correct answer just changes score-p1. In 2-player mode, the score lands in whichever player's slot is current:
if <(answer) = (item (q-index) of [answers v])> then
start sound (chord v)
if <(current-player) = (1)> then
change [score-p1 v] by (1)
else
change [score-p2 v] by (1)
end
else
start sound (boing v)
end
Where each previous lesson plugs in
- L04-37 parallel lists → the data layer. questions and answers hold the trivia.
item (q-index) of (questions)in the ask block,item (q-index) of (answers)in the equality check. - L04-38 no-repeat shuffle → the question picker. The asked list grows by one each turn. The repeat-until loop guarantees uniqueness.
- L04-39 high-score → the end screen. After the final question, compare score-p1 against high-score and update if higher. Only relevant in 1-player mode (the standard convention).
- L04-40 pass-and-play → the per-turn alternation. The 3-minus swap, only when mode = 2.
Common assembly mistakes
Worked Build — assembling the full quiz in twelve steps 35 min
Open Scratch. You can start from your most complete L04-40 project (it already has the multiplayer skeleton) or from a fresh project. Either way, the steps below build the game piece by piece.
Step 1 — Set up the three sprites
Three sprites: Title, Quiz, and EndScreen. Paint or import a costume for each — Title can have the game name in big letters, Quiz can be a Scratch cat or a question-mark mascot, EndScreen can be a trophy or scoreboard. All three hide on flag-click except the Title.
Step 2 — Make the variables and lists
Variables: mode, current-player, score-p1, score-p2, q-index, turn-count, high-score. Lists: questions, answers, asked. Tick the Stage boxes for score-p1, score-p2, and high-score so they show during play.
Step 3 — Fill the question/answer lists
Right-click the questions list on the Stage and pick "import" or add items by hand. Write 10 Malaysia-themed questions. Use a mix of capitals, food, and festivals — for example:
What is the capital of Malaysia?→Kuala LumpurWhere do Malaysia's federal government offices move to?→PutrajayaWhich dish is Malaysia's unofficial national breakfast?→Nasi LemakWhat is the flatbread eaten with curry called?→Roti CanaiWhat festival celebrates the end of Ramadan?→Hari RayaWhich festival do Hindus celebrate with oil lamps?→DeepavaliWhat is the currency symbol of Malaysia?→RMWhat sport is Datuk Lee Chong Wei famous for?→BadmintonWhat are the tallest twin towers in KL called?→PetronasWhich state is known as the Land of Hornbills?→Sarawak
Make sure questions and answers are in the same order — item 1 of questions must match item 1 of answers.
Step 4 — Title sprite asks the mode
On the Title sprite: when ⚑ clicked → show → ask How many players? Type 1 or 2. → set [mode v] to (answer) → hide → broadcast (game-start v). Test by clicking the flag and typing 1. The title should hide.
Step 5 — Quiz sprite handles game-start
On the Quiz sprite: when I receive (game-start v). Inside: show, then clear everything: delete (all) of [asked v], set [score-p1 v] to (0), set [score-p2 v] to (0), set [current-player v] to (1), set [turn-count v] to (0). The quiz is now ready to ask its first question.
Step 6 — Add the main quiz loop
Still in the game-start handler, after the resets: repeat (10). Inside, increment change [turn-count v] by (1). The body of this repeat is the heart of the game (next four steps).
Step 7 — Pick a non-repeating question
Inside the repeat: set [q-index v] to (pick random (1) to (length of [questions v])), then repeat until <not <[asked v] contains (q-index) ?>>, with another pick-random inside. After the loop, add (q-index) to [asked v]. This is L04-38 verbatim.
Step 8 — Ask the current player the question
Still inside the repeat-10, after the no-repeat picker: ask (join (join (join [Player ] (current-player)) [: ]) (item (q-index) of [questions v])) and wait. Three nested joins build the prompt Player 1: What is the capital of Malaysia?.
Step 9 — Check the answer and score
Still inside the repeat-10, after the ask: if <(answer) = (item (q-index) of [answers v])> then start sound (chord v), then a nested if <(current-player) = (1)> then change [score-p1 v] by (1) else change [score-p2 v] by (1). The outer else: start sound (boing v).
Step 10 — Swap players (if 2-player mode)
Still inside the repeat-10, after the answer check: if <(mode) = (2)> then set [current-player v] to ((3) - (current-player)). End of the repeat body. Test now: click the flag, type 2, answer two questions, and confirm the prompt alternates between Player 1 and Player 2.
Step 11 — Finish and broadcast game-end
After the repeat (10) in the game-start handler: hide (the quiz sprite gets out of the way), then broadcast (game-end v).
Step 12 — EndScreen handles game-end
On the EndScreen sprite: when I receive (game-end v) → show. Then branch on mode. 1-player: compare score-p1 against high-score, update if higher, say "Score: X. High score: Y." 2-player: compare score-p1 and score-p2, announce winner or tie. Test the full chain end-to-end twice — once in 1-player mode, once in 2-player.
The full assembled stack — Quiz sprite main loop
when I receive (game-start v)
show
delete (all) of [asked v]
set [score-p1 v] to (0)
set [score-p2 v] to (0)
set [current-player v] to (1)
set [turn-count v] to (0)
repeat (10)
change [turn-count v] by (1)
set [q-index v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (q-index) ?>>
set [q-index v] to (pick random (1) to (length of [questions v]))
end
add (q-index) to [asked v]
ask (join (join (join [Player ] (current-player)) [: ]) (item (q-index) of [questions v])) and wait
if <(answer) = (item (q-index) of [answers v])> then
start sound (chord v)
if <(current-player) = (1)> then
change [score-p1 v] by (1)
else
change [score-p2 v] by (1)
end
else
start sound (boing v)
end
if <(mode) = (2)> then
set [current-player v] to ((3) - (current-player))
end
end
hide
broadcast (game-end v)
EndScreen — mode-aware game-end
when I receive (game-end v)
show
if <(mode) = (1)> then
if <(score-p1) > (high-score)> then
set [high-score v] to (score-p1)
say (join [New high score! ] (score-p1)) for (4) seconds
else
say (join (join [You scored ] (score-p1)) [. Try to beat the high score!]) for (4) seconds
end
else
if <(score-p1) > (score-p2)> then
say [Player 1 wins!] for (4) seconds
else
if <(score-p2) > (score-p1)> then
say [Player 2 wins!] for (4) seconds
else
say [Tie!] for (4) seconds
end
end
end
Title — the mode picker
when flag clicked
show
ask [How many players? Type 1 or 2.] and wait
set [mode v] to (answer)
hide
broadcast (game-start v)
What you just built: a complete shareable trivia game. Title → mode pick → ten unique Malaysia questions about capitals, food, and festivals → score tracking → end screen with high score or winner announcement. Every piece was a previous lesson; today's lesson was the structure that lets them cooperate. Upload this to scratch.mit.edu and ask your family to play. They'll have fun and you'll have built a real game.
Try It Yourself — three assembly drills 15 min
Goal: Add a player name prompt at the start. Instead of saying "Player 1", the game says "Aishah" or "Daniel". Add two more variables, name-p1 and name-p2, ask for them on the Title sprite right after the mode picker, and swap the join in the quiz prompt to use the name.
ask [Player 1, what is your name?] and wait
set [name-p1 v] to (answer)
if <(mode) = (2)> then
ask [Player 2, what is your name?] and wait
set [name-p2 v] to (answer)
end
join [Player ] (current-player) with an if-else: if current-player = 1, use name-p1; else use name-p2.Think: Names cost six blocks but make the game feel personal. The same trivia, called "Aishah vs Daniel: Malaysia Trivia Battle", is ten times more fun than "Player 1 vs Player 2". This is the cheapest polish in the entire course.
Goal: Add a category system. The Title asks "Pick a category: 1=Capitals, 2=Food, 3=Festivals" and your game uses one of three list pairs depending on the answer. Keep three pairs of lists: questions-capitals/answers-capitals, questions-food/answers-food, questions-festivals/answers-festivals. On game-start, copy the chosen pair into the main questions and answers lists.
when I receive (load-category v)
delete (all) of [questions v]
delete (all) of [answers v]
set [i v] to (1)
if <(category) = (1)> then
repeat (length of [questions-capitals v])
add (item (i) of [questions-capitals v]) to [questions v]
add (item (i) of [answers-capitals v]) to [answers v]
change [i v] by (1)
end
end
Think: Categories triple the play-count. The same player will replay your game three times to try each one — that's the difference between "played once" and "favourited".
Goal: Add a 30-second per-question timer. If the player doesn't answer within 30 seconds, they lose the turn (no point, swap player). You'll need to think about how Scratch's ask () and wait blocks the script — the cleanest trick is to not use ask-and-wait for the timed turn, and instead show a text-on-stage prompt while a parallel script watches the timer.
when I receive (start-turn-timer v)
reset timer
wait until <<(timer) > (30)> or <(turn-done) = (1)>>
if <(turn-done) = (0)> then
set [time-up v] to (1)
broadcast (force-next-turn v)
end
Think: Adding a timer to a turn-based game changes the feel completely — it goes from leisurely to tense. The hardest part isn't the timer itself, it's coordinating the two parallel scripts (the question-asker and the timer-watcher). This is your first taste of concurrent game logic.
Mini-Challenge — the quiz that won't end 5 min
"Daniel's hanging quiz"
Daniel built the trivia game and it works perfectly for the first few questions — but somewhere around question 8 or 9, the game just freezes. The question prompt never appears. The cat sits there, doing nothing. Here's his no-repeat picker:
set [q-index v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (q-index) ?>>
set [q-index v] to (pick random (1) to (length of [questions v]))
end
add (q-index) to [asked v]
Daniel says his questions list has exactly 8 items and his answers list has 8 items. He's running a 10-question repeat. What goes wrong?
Reveal one valid solution
Daniel only wrote 8 questions, but his main loop is repeat (10). By question 9, the asked list contains all 8 question numbers. The repeat-until-no-repeat loop tries to pick a number 1–8 that isn't in the list — but every number 1–8 is in the list. The condition can never become true, so the repeat-until loop runs forever. The game appears frozen because the script is busy rejecting numbers in a tight loop.
Two valid fixes:
- Make the loop count match the list length. Change the outer repeat from
repeat (10)to repeat (length of [questions v]). The game asks every question once, whatever that count is. This is the most robust pattern. - Add more questions. Pad the list to 10 items. Faster but brittle — anyone editing the questions later has to remember the count must match.
repeat (length of [questions v])
change [turn-count v] by (1)
set [q-index v] to (pick random (1) to (length of [questions v]))
repeat until <not <[asked v] contains (q-index) ?>>
set [q-index v] to (pick random (1) to (length of [questions v]))
end
add (q-index) to [asked v]
end
The rule: never hard-code a count that's also stored as a list length. Use length of and the two stay in sync forever, no matter who edits the list later.
Recap 3 min
You shipped a real trivia game. The Title sprite asks for the player count and stores it in mode. The Quiz sprite runs the main loop: it picks a question without repeats (L04-38), asks the current player using parallel lists (L04-37), scores the correct player's variable, and swaps players if mode = 2 (L04-40). The EndScreen sprite reads the mode and announces either a new high score (1-player, L04-39) or the winner of a head-to-head match. Three sprites, three broadcasts, ten variables and lists. Every concept from cluster G is here. You have a finished game. Upload it and watch your family play.
- Build lesson
- A lesson that assembles previous lessons rather than introducing new blocks. The challenge is structure and timing, not new syntax. Cluster G's Build is SCR-L04-41.
- Mode-aware code
- Scripts wrapped in
if (mode) = (N)so the same project behaves differently depending on a single setting. Today's game runs as either 1-player or 2-player because two key blocks (the swap line and the end-screen branch) check mode. - Data layer
- The lists (questions, answers) that hold the content, separate from the scripts that handle the logic. Changing the questions never requires changing the code.
- Event chain
- The sequence of broadcasts that runs the whole game: game-start → main loop → game-end. Each broadcast hands control to a different sprite.
- End-to-end test
- Playing the entire game from flag-click to end-screen without stopping, to confirm every wire works. The only test that catches integration bugs. Run it at least twice — once per mode.
Homework 2 min
The Quiz Cup. Take your finished game and run a tournament with your family or friends.
- Save your project as
HW-L4-41-Malaysia-Trivia.sb3. - Upload it to scratch.mit.edu and set it to Shared. Write a one-paragraph project description with the controls (just type the answer + Enter). If you are under 13, share the
.sb3file directly with your teacher instead of publishing publicly. - Run three head-to-head matches with three different pairs of opponents. Track who won each match in your notebook.
- For each match, write down the most surprising wrong answer someone gave. (These are the questions that need to be re-worded for clarity — the answer was right, but the wording was confusing.)
- Beat your own high score in 1-player mode at least once.
Bring back next class:
- The shareable Scratch URL (or the
.sb3file if under 13). - The list of three matches and their winners.
- Your three surprising-wrong-answer notes, plus your rewrite of each confusing question.
Heads up for next class: SCR-L04-42 — Pre-Share Checklist opens cluster H (Ship, Share, Recap). It's the first non-coding lesson in a while — a meta-skill for publishing projects. You'll learn the 7-point checklist that professional Scratch creators run through before clicking the Share button, so your project page doesn't have embarrassing public bugs. Bring your trivia URL — we'll run today's project through the checklist as the worked example.