Learning Goals 3 min
By the end of this lesson you will be able to:
- Create a global level variable, set it to 1 on green flag, and increment it with change [level v] by (1) on a level-end event.
- Broadcast level-up when the level changes, and write a when I receive (level-up v) handler on the Stage that switches to the matching backdrop.
- Gate sprite behaviour on the current level using if <(level) = (2)> then, so each level can have its own enemies, coins, or layout while sharing one set of scripts.
Warm-Up — predict the never-changing world 7 min
You spent last lesson planning a three-level game on paper. Today we start building. The very first question: how does the game know which level the player is on?
Imagine a project with three backdrops (forest, cave, sky) and this Stage script:
when flag clicked
switch backdrop to (forest v)
when I receive (level-up v)
next backdrop
Looks reasonable. But the project has no level variable at all. The enemies all spawn the same way, the coins all spawn the same way, and the only difference between levels is the backdrop. Predict: what does the player experience?
Reveal the answer
Three levels that look different and play identically. The forest, cave and sky have the same enemy patrols and the same coin layout. The player notices instantly — "oh, this is just one level with three skins." Without a level variable that other scripts can read, the level number is invisible to the rest of the game. Backdrop changes alone don't change behaviour.
The fix is today's lesson. A real level variable, set on flag, changed on level-up, and read by every spawner script. Once you have it, the whole world reshapes around it. One number, complete control.
New Concept — level as a remote control 15 min
The level variable does one job: it tells every other sprite "what level we're on right now". One number. Three possible values. Read by everyone.
Step 1 — Create it (for all sprites)
In the Variables palette, click Make a Variable. Name it level. Make sure For all sprites is selected — this is critical. For this sprite only would hide the variable from everyone else, which is the opposite of what we want. The whole point is that every sprite can read it.
Step 2 — Set it to 1 on green flag
On the Stage (or any sprite that owns the "game start" logic), drop this:
when flag clicked
set [level v] to (1)
Step 3 — Increment on level-up
When the player reaches the end of a level (touches the Goal sprite, hits the right edge, whatever your design says), two things happen in one motion: the variable goes up, and a broadcast fires so everyone knows.
when I receive (goal-reached v)
change [level v] by (1)
broadcast (level-up v)
Step 4 — The Stage swaps backdrop on level-up
On the Stage, listen for the broadcast and switch backdrops based on the new value:
when I receive (level-up v)
if <(level) = (2)> then
switch backdrop to (cave v)
end
if <(level) = (3)> then
switch backdrop to (sky v)
end
if <(level) = (4)> then
broadcast (you-win v)
end
Step 5 — Every spawner gates on the level
This is the magic. Any sprite that wants to behave differently per level reads the variable in an if-then. Example: an enemy spawner that creates one enemy on level 1, two on level 2, three on level 3:
when I receive (start-level v)
delete this clone
if <(level) = (1)> then
create clone of (myself v)
end
if <(level) = (2)> then
create clone of (myself v)
create clone of (myself v)
end
if <(level) = (3)> then
create clone of (myself v)
create clone of (myself v)
create clone of (myself v)
end
The big picture
You now have a remote control. Change level from 1 to 2 anywhere in your project. Three things happen automatically:
- The backdrop switches (because the Stage's when I receive (level-up v) reads the variable).
- The enemies respawn in their level-2 pattern (because the spawner gated on level).
- Any other sprite that gated on level (coins, goal position, music) updates too.
One number changed. Whole world rebuilt. That is the level variable.
Worked Example — wiring the level variable into Kampung Quest 15 min
We'll set up the bare bones of the multi-level platformer's level system. Start from a clean project. Eight steps.
Step 1 — Add three backdrops
On the Stage, open the Backdrops tab. Add or paint three backdrops named forest, cave, sky. (For testing, plain coloured rectangles are fine — you can polish art later.)
Step 2 — Create the level variable
Variables palette → Make a Variable → name level → For all sprites. Tick the watcher on so you can see the current level on the Stage during testing.
Step 3 — Stage: set level on flag
On the Stage:
when flag clicked
set [level v] to (1)
switch backdrop to (forest v)
broadcast (start-level v)
Step 4 — Stage: handle level-up
Still on the Stage, add the level-up listener:
when I receive (level-up v)
if <(level) = (2)> then
switch backdrop to (cave v)
end
if <(level) = (3)> then
switch backdrop to (sky v)
end
broadcast (start-level v)
Step 5 — A test goal sprite
Add a temporary Goal sprite — for testing, any small sprite will do. Drop this script on it:
when flag clicked
forever
if <key [n v] pressed?> then
change [level v] by (1)
broadcast (level-up v)
wait (0.5) seconds
end
end
Step 6 — Test the backdrop swap
Hit the flag. You should see the forest backdrop. Press N. Backdrop swaps to cave. Press again. Sky. Press again. Stays on sky (because level = 4 has no if handler yet) — but the variable watcher shows 4, which proves the increment is working.
Step 7 — Add a level-gated enemy spawner
Add an Enemy sprite (paint a square, doesn't matter). On it:
when flag clicked
hide
when I receive (start-level v)
if <(level) = (1)> then
go to x: (-100) y: (0)
create clone of (myself v)
end
if <(level) = (2)> then
go to x: (0) y: (50)
create clone of (myself v)
end
if <(level) = (3)> then
go to x: (100) y: (-50)
create clone of (myself v)
end
Step 8 — Watch the world reshape
Hit the flag. Enemy clone appears on the left (level 1). Press N. Backdrop swaps to cave AND the enemy reappears at a new position (level 2). Press again. Sky + new enemy position. The same enemy sprite, the same spawner script behaves three different ways. That's the level variable at work.
What you just built: the spine of every multi-level Scratch game. One variable, two broadcasts, three backdrops. Every sprite you add from now on (player, coins, music, goal) can plug into this system by reading (level) in its own scripts. The level variable is the steering wheel; everything else is a wheel that follows it.
Try It Yourself — three level-variable drills 15 min
Goal: Add a second level-gated sprite — a Coin. On level 1, the coin sits at x: 100, y: 0. On level 2, at x: -100, y: 50. On level 3, at x: 0, y: -100. Use the same when I receive (start-level v) + gated if blocks as the enemy spawner.
when I receive (start-level v)
if <(level) = (1)> then
go to x: (100) y: (0)
end
if <(level) = (2)> then
go to x: (-100) y: (50)
end
if <(level) = (3)> then
go to x: (0) y: (-100)
end
show
Think: Notice how similar this is to the enemy spawner. Same shape, different sprite, different numbers. The pattern "on start-level, gate on (level), set my per-level state" repeats for every sprite in a multi-level game.
Goal: Add a "press R to restart from level 1" feature. Anywhere in the project, listen for the R key, set level back to 1, switch the backdrop to forest, and broadcast start-level so every spawner rebuilds.
when [r v] key pressed
set [level v] to (1)
switch backdrop to (forest v)
broadcast (start-level v)
Think: Why didn't you have to touch the Enemy or Coin sprite to make restart work? Because they listen for start-level, not for the R key. Loose coupling through broadcasts means new features can be added without modifying existing sprites.
Goal: Use (level) inside an arithmetic expression instead of an if-tree. Make the enemy patrol speed scale with the level: level 1 = 2 steps, level 2 = 4 steps, level 3 = 6 steps. Achieve this with a single block instead of three branched ones.
when I receive (start-level v)
forever
move ((level) * (2)) steps
if on edge, bounce
end
Think: Branching with if trees is one way to react to the level. Arithmetic on the variable is another, and it scales: this script works for level 17 with no edits. Whenever per-level data follows a pattern (doubled, halved, plus-one-per-level), prefer arithmetic over branches.
Mini-Challenge — "Iqbal's frozen sky" 5 min
Backdrop swaps, enemies don't
Iqbal built the level system. Press N and the backdrop walks forest → cave → sky as expected. But the enemies stay frozen on the level-1 layout the whole game. He shows you his Goal sprite stack:
when key [n v] pressed
broadcast (level-up v)
change [level v] by (1)
The Stage swaps backdrops correctly. The enemies don't move. Why?
Reveal one valid solution
The broadcast (level-up v) fires before change [level v] by (1) runs. When the Stage's when I receive (level-up v) handler reads (level), it still sees the old value. The backdrop swap works because Iqbal's Stage handler probably uses next backdrop (which doesn't depend on the variable) — but the enemy spawner, which gates on if <(level) = (2)> then, reads level = 1 and re-spawns the same level-1 pattern.
The fix is to swap the order — change the variable first, then broadcast:
when key [n v] pressed
change [level v] by (1)
broadcast (level-up v)
The deeper lesson: a broadcast in Scratch fires and continues — but receivers may read your variables at any moment. Always update the variable first, broadcast second, so receivers see the new world. State change before signal — it's a rule that holds in every event-driven system, not just Scratch.
Recap 3 min
You met the most important variable in any multi-level Scratch game: level. Set it to 1 on green flag, change it by 1 on the level-end event, broadcast level-up right after, and the Stage swaps the backdrop in its when I receive (level-up v) handler. Every other sprite can read (level) in its own scripts to behave differently per level — different spawn positions, different patrol speeds, different costumes. One variable is the remote control for the whole game. The rule that ties it together: change the state first, broadcast second, so listeners always see the new world.
- Level variable
- A single number (typically 1, 2, 3, …) that represents which level the player is currently on. Made "For all sprites" so every sprite can read it.
- Level-up broadcast
- The signal sent immediately after the level variable changes. Sprites that need to react to the new level listen with when I receive (level-up v).
- Level gate
- An if <(level) = (n)> then wrapper that runs blocks only on a specific level. The fundamental tool for per-level behaviour.
- Start-level broadcast
- A separate signal that says "rebuild this level from scratch". Fires on green flag (for level 1) and again after every level-up. Spawners listen and do their per-level setup.
- State-before-signal
- The rule that changes to a variable must happen before the broadcast that announces the change — otherwise receivers read the old value. Universal in event-driven code.
Homework 2 min
Wire the level system into your design doc. Open a fresh Scratch project and build the skeleton of the platformer you planned in SCR-L04-17.
- Add the three backdrops from your plan, named to match your theme.
- Create the level variable (For all sprites) and the watcher.
- On the Stage, write the flag handler (set level to 1, switch to backdrop 1, broadcast start-level) and the level-up handler (swap backdrops by level, broadcast start-level).
- Add a temporary N-to-advance cheat sprite as in Step 5 of the worked example.
- Add one test sprite (an enemy or a coin) that uses an if-gated when I receive (start-level v) to position itself differently on each level.
- Save as
HW-L4-18-Level-Skeleton.sb3.
Bring back next class:
- The
.sb3file. - Your answer to: "You changed one variable from 1 to 2. List every visible change in the game that resulted. How many things were rewired without you writing a single new script?"
Heads up for next class: SCR-L04-19 deepens the backdrop side of this lesson — Per-Level Backdrops. We'll add the full art, paint proper level scenery, and use when backdrop switches to for backdrop-specific scripts (level music, ambient effects, lighting tint).