Learning Goals 3 min
By the end of this lesson you will be able to:
- Track a per-game score and a session-wide high-score, and update high-score only when <(score) > (high-score)>.
- Explain what persistence means in Scratch — what variables remember between flag-clicks, between page reloads, and across different players — and why a plain variable survives only one of those.
- Choose between three persistence options for a project: in-session variable (default, easy), ask ( ) and wait into Project Notes (manual, shareable), and cloud variables (true persistence, but with rules).
Warm-Up — predict the forgetful quiz 7 min
You now have a randomised 10-question Malaysia trivia. Imagine playing three rounds in a row, getting 7/10, 9/10, 6/10. The cat says "Game over!" each time and resets. Predict what your game knows the next time you click the flag.
when flag clicked
set [score v] to (0)
If the player scored 9/10 a minute ago and you want the title screen to say "Best so far: 9", what does the game need to remember between flag-clicks?
Reveal the answer
Right now, nothing is remembered. score is set to 0 on every flag click, so it forgets the previous game. The 9/10 result is displayed for those two seconds at the end of the game — and then it's gone.
You need a second variable, high-score, that you never reset on green flag. It only changes when the current score beats it. That variable survives multiple games inside the same browser tab — but here's the catch, it still vanishes when the page reloads. We'll see why, and what to do about it.
New Concept — three layers of persistence 15 min
"Persistence" means: how long does the number live? Scratch gives you three options, getting more persistent each time.
Layer 1 — local variable (lives one script-run)
Your existing score is reset on every when ⚑ clicked. It exists only inside one game. As soon as the flag is clicked again, gone. Useful for round-specific tracking; useless for "best ever".
Layer 2 — session variable (lives one page visit)
If you make a second variable high-score and never set it to 0 on flag, it keeps its value from one flag-click to the next. The player can play 20 games in a row and the high score climbs.
when flag clicked
set [score v] to (0)
To update it, you compare at the end of each game:
if <(score) > (high-score)> then
set [high-score v] to (score)
end
But — session means "this browser tab visit". Close the tab. Reload the page. Send the project to your friend. The high score is gone. The Scratch player loads the project fresh, with every variable back to its initial value.
Layer 3 — truly persistent (cloud variables)
Scratch has cloud variables — variables whose values are stored on Scratch's servers. Their names start with a cloud icon (☁ high-score). When any player changes one, every other player sees the new value the next time they load the project. That's how the global leaderboards on famous Scratch games work.
The catch: cloud variables only work on the official Scratch website, only for users aged 13+ (Scratch policy, not a technical limit), and they can only hold numbers, not strings. They're powerful but they come with rules. We'll meet them properly in a later lesson — for now, just know they exist.
Layer 2.5 — the Project Notes trick
A practical middle option for class projects: at game-over, the cat says "Tell the next player your high score is X. They should type it on the title screen." On the title screen, ask [Last player's best? Type a number, or 0 to skip:] and wait, then set [high-score v] to (answer). Manual, but it works on day one.
Worked Example — adding the best-ever banner 12 min
Open your shuffled Malaysia quiz from L04-38. We'll add a score counter and a session-persistent best-score banner.
high-score watcher visible in the top-right corner throughout play. The score watcher can sit next to it or be hidden — your choice. The cat (✏️ badge) manages both variables.Step 1 — Make the two variables
Variables → Make a Variable → score, For all sprites. Again → high-score, For all sprites. Both watchers appear on the Stage. Drag high-score to a corner where it can stay visible.
Step 2 — Reset score, NOT high-score, on flag
Find your when ⚑ clicked hat. Right after the list wipes, drop set [score v] to (0). Critically, do not add any block touching high-score.
Step 3 — Increment score on correct answer
Find your existing if/else inside the round loop. In the then branch (after say [Correct!]), drop change [score v] by (1). Every correct reply adds one.
Step 4 — Show a title-screen "Best ever"
At the very top of the script (before the round loop, even before the list loading if you like), drop say ( ) for (2) seconds with a join: join [Best so far: ] (high-score). First-time players will see "Best so far: 0", repeat players will see their record.
Step 5 — End-of-game promotion
After the outer round loop finishes (all 10 questions asked), drop the comparison:
if <(score) > (high-score)> then
set [high-score v] to (score)
say [New record!] for (2) seconds
else
say (join [Final score: ] (score)) for (2) seconds
end
Step 6 — Test the session behaviour
Click the flag. Answer some questions. Get a score, see it promote to high-score if it beats 0. Click flag again. Title screen now says "Best so far: 7" (or whatever you got). Score resets to 0; high-score stays.
Step 7 — Test the page-reload behaviour
Now reload the browser tab (Ctrl+R or Cmd+R). Click the flag. Title screen says "Best so far: 0" again. That's session-only persistence — proof that even high-score didn't survive the reload.
Step 8 — Show the manual-recovery option
To handle the reload, add this once at the very start (before the "Best so far" line):
ask [Last player's best score? Type a number or 0:] and wait
set [high-score v] to (answer)
The full assembled end-of-quiz stack (game-over half only)
say (join [Best so far: ] (high-score)) for (2) seconds
ask [Last player's best score? Type a number or 0:] and wait
set [high-score v] to (answer)
set [score v] to (0)
broadcast (run-quiz v)
when I receive (game-over v)
if <(score) > (high-score)> then
set [high-score v] to (score)
say [New record!] for (2) seconds
else
say (join [Final score: ] (score)) for (2) seconds
end
What you just built: a complete high-score system at three levels of persistence. Session-only by default, manual recovery via Project Notes for between sessions, and you know cloud variables exist for true cross-player persistence.
Try It Yourself — three persistence drills 15 min
Goal: Add a "lowest-ever" variable (the player's worst score, for laughs). Same idea as high-score but flipped — promote only when <(score) < (low-score)>.
when flag clicked
set [score v] to (0)
if <(low-score) = (0)> then
set [low-score v] to (999)
end
Think: The seeding trick (start it impossibly high) is a common pattern for "minimum" tracking. High-score didn't need this because 0 was a safe floor.
Goal: Add a games-played counter. It starts at 0, never resets on flag, and increments by 1 every time a game finishes. Show "Games played this session: N" on the title screen.
say (join [Games played this session: ] (games-played)) for (2) seconds
when I receive (game-over v)
change [games-played v] by (1)
Think: Same trick as high-score — variables that aren't reset on flag survive the session. Every persistent value is just "a variable I deliberately don't touch in my flag setup".
Goal: Save the high scorer's name alongside the high score. On a new record, ask [Champion! What's your name?] and wait, then set [high-name v] to (answer). Show "Best: 9 by Aishah" on the title screen.
if <(score) > (high-score)> then
set [high-score v] to (score)
ask [Champion! What's your name?] and wait
set [high-name v] to (answer)
end
say (join [Best: ] (join (high-score) (join [ by ] (high-name)))) for (3) seconds
Think: Two parallel session-variables now — high-score and high-name. They get promoted together inside the same if-block so they can never go out of sync. Note this couldn't use cloud variables — names are strings, not numbers.
Mini-Challenge — the score that never beats itself 5 min
"Priya's stubborn high score"
Priya finishes her quiz with score = 8. The cat says "Final score: 8" but never says "New record!", even though the watcher shows high-score = 0. She tries again with score = 10. Still no "New record!". The high-score watcher stays at 0 forever.
Here's her game-over code:
when I receive (game-over v)
set [high-score v] to (0)
if <(score) > (high-score)> then
set [high-score v] to (score)
say [New record!] for (2) seconds
else
say (join [Final score: ] (score)) for (2) seconds
end
Read line-by-line. What's the value of high-score when the if-comparison runs?
Reveal one valid solution
Priya's set [high-score v] to (0) at the top of the game-over handler resets the high score every time a game ends. By the time the if-comparison runs, high-score is 0 — so score = 8 compares against 0, promotes correctly, and the watcher shows 8. Then another game-over fires; the reset wipes it back to 0; and so on. Priya never sees the promoted value because the wipe always precedes the display.
The fix is to delete the reset line entirely. high-score must never be set to 0 anywhere except inside the if-then promotion (and even there, only by setting it to score, not to 0):
when I receive (game-over v)
if <(score) > (high-score)> then
set [high-score v] to (score)
say [New record!] for (2) seconds
else
say (join [Final score: ] (score)) for (2) seconds
end
One block removed. The rule for any persistent variable in Scratch: find every set [ v] to ( ) block that touches it, and make sure each one is genuinely intentional. A stray reset is the difference between "session-persistent" and "always zero".
Recap 3 min
You learned how Scratch remembers things — and how it doesn't. A local score resets every game, exactly what you want. A session-wide high-score survives multiple flag-clicks but vanishes on page reload, because the Scratch player loads each project fresh. For true cross-player persistence, Scratch offers cloud variables (numbers only, age 13+, scratch.mit.edu only). For a class project today, the practical middle path is the Project Notes / pass-it-on trick: ask the next player to type the previous best at the title screen. The golden rule for any persistent variable: never reset it accidentally.
- Persistence
- How long a value lasts. Local = one script-run. Session = one page visit. Cloud / saved = forever, across players. Choosing the right level is a design decision, not just a code one.
- Session
- One uninterrupted visit to the Scratch player tab. Many flag-clicks, no reload. Variables that aren't touched on green flag survive the whole session.
- High-score variable
- A session-wide tracker promoted only when <(score) > (high-score)>. The single most common "persistence pattern" in beginner game design.
- Cloud variable
- A Scratch variable stored on Scratch's servers. Name prefixed with ☁. Numbers only. Available only on the Scratch website to verified Scratchers aged 13+. The pattern behind every shared leaderboard you've seen on Scratch.
- Project Notes
- The text box below the Stage on every shared Scratch project, where the creator can write instructions. Doesn't change as the project runs, but useful for "tell the next player...". The basis of today's pass-it-on persistence trick.
Homework 2 min
Add a session high-score to your shuffled quiz. Build on top of last lesson's HW-L4-38-Shuffled-Quiz.sb3.
- Open
HW-L4-38-Shuffled-Quiz.sb3. - Make two new variables:
scoreandhigh-score, both For all sprites. Show the high-score watcher on the Stage; hide the score watcher (or show it — your call). - On when ⚑ clicked, add set [score v] to (0). Do not reset high-score.
- Inside the round loop's correct-branch, add change [score v] by (1).
- After the round loop, add the promotion: if <(score) > (high-score)> then ... set [high-score v] to (score) ... say [New record!] for (2) seconds, with an else that says "Final: " joined with the score.
- At the top of the script, add a title-screen banner: say (join [Best so far: ] (high-score)) for (2) seconds.
- Test: play three rounds. Confirm the banner climbs as you beat your record, and stays the same if you don't.
Save as HW-L4-39-High-Score-Quiz.sb3.
Bring back next class:
- The
.sb3file. - Your answer to: "After reaching a high score of 9, you close the browser tab and reopen the project. The banner says 'Best so far: 0'. Explain in your own words why — and describe two different ways you could fix it so the 9 comes back."
Heads up for next class: SCR-L04-40 takes the quiz multi-player. Two players take turns on the same keyboard, each gets their own score variable, and a turn variable swaps between them. The same persistence ideas apply, just doubled.