Skip to main content

Stage 4: Win or Lose

Course progressStage 4 of 10
~90 min
Your workspace

Keep your Scratch project tab open all week. Open in a new tab so you don’t leave the course.

Build

two broadcast handlers — one for winning, one for losing

Learn

how one sprite shouts a message and another listens

Ship

a game that can be both won and lost

Teacher demo

Show the room — the win and lose paths are mirror patterns. Build both side by side so the kids SEE the parallel:

  1. Click the Player sprite, Code tab.
  2. Drag in two when I receive event blocks. Set one to playerEaten (lose), the other to playerWon (win).
  3. Build the lose chain: set playerAlive to 0, set rotation style all around, point in direction -90, stop other scripts in sprite, start sound Bubbles, repeat 100 change pixelate effect by 1, broadcast gameover, hide.
  4. Build the win chain right next to it: set playerAlive to 0, switch costume to Party Hat-a, stop other scripts in sprite, stop all sounds, start sound Eggs, wait 5 seconds, repeat 100 change ghost effect by 1, broadcast gameover, hide.
  5. Test by typing broadcast playerEaten in the broadcast dropdown manually, then playerWon. Watch both endings play.

Then say "Look at both chains. They're almost the same — the difference is the FEEL."

The big idea

Until today, the fish could swim — but it couldn't win or lose. Today we add the two endings.

The whole concept comes down to a Scratch superpower called broadcasting.

one sprite another sprite
shouts a message listens for it
│ │
▼ ▼
broadcast (playerWon) when I receive (playerWon)
do all this stuff →

The Player Fish doesn't check itself to see if it's won. That would be slow and weird. Instead, the size-check script from Stage 3 shouts the message playerWon when playerSize > 100. A separate listener script — the one we build today — catches the message and runs the celebration code.

We build two listeners today:

  • When I receive playerEaten — the lose path. Set the player to dead, rotate the fish, play a sad sound, dissolve into pixels.
  • When I receive playerWon — the win path. Set the player to dead too (game's over either way), switch to the party-hat costume, play a celebration sound, fade out gently.

Both endings do the same overall job (end the round and start the cleanup). The details are what tell the story: pixelate + bubbles + a rotated fish feels like getting eaten. Party hat + eggs + ghost fade feels like winning. Same shape of code, opposite feel.

New words
when I receive
an event block that runs when its message is broadcast
broadcast
send a message to every sprite listening
stop other scripts in sprite
kill the other forever loops on this same sprite
effect
a visual change — pixelate makes the sprite blocky, ghost makes it see-through
all around
a rotation style that lets the sprite rotate freely instead of only flipping left and right
Before you start

Stage 3 should be done — your Player sprite has playerAlive and playerSize variables, and your size loop broadcasts playerWon when playerSize > 100.

Build it

Step 1 — Build the LOSE listener

We start with the loss path. (The lose broadcast playerEaten will be sent by the enemy fish in Stage 8 — we're building the listener now so it's ready.)

In the Player's code area, drag in a fresh when I receive (message1) block from Events (yellow). Click its dropdown, choose New message, type playerEaten, click OK.

Snap these blocks below it, in order:

Lose listener

when I receive [playerEaten v]
set [playerAlive v] to (0)
set rotation style [all around v]
point in direction (-90)
stop [other scripts in sprite v]
start sound [Bubbles v]
repeat (100)
change [pixelate v] effect by (1)
end
broadcast [gameover v]
hide

A few notes on each block:

  • set playerAlive to 0 — tells the rest of the game "the player is dead now."
  • set rotation style (all around) — lets the fish rotate freely. The default left-right would only flip it horizontally.
  • point in direction (-90) — rotates the fish for the losing animation, matching the book's block stack.
  • stop other scripts in sprite — this kills the Stage 2 keyboard loop and the Stage 3 size loop. They can't keep running while the game is ending.
  • start sound (Bubbles) — sad watery sound.
  • repeat 100 + change pixelate effect by 1 — the fish slowly pixelates into a blocky mess over 100 frames.
  • broadcast (gameover) — sends the game-is-truly-over message to the stats screen (Stage 10).
  • hide — the fish disappears completely.

Note: type gameover lowercase, no space. We'll use the exact same message in the win path.

Step 2 — Build the WIN listener

Now drag a second when I receive block, set its message to playerWon (the broadcast you already made in Stage 3 should be in the dropdown).

Snap the win chain below it:

Win listener

when I receive [playerWon v]
set [playerAlive v] to (0)
switch costume to [Party Hat-a v]
stop [other scripts in sprite v]
stop all sounds
start sound [Eggs v]
wait (5) seconds
repeat (100)
change [ghost v] effect by (1)
end
broadcast [gameover v]
hide

Notes:

  • set playerAlive to 0 — game's over, win or lose. Same line as the lose path.
  • switch costume to (Party Hat-a) — the fish puts on a party hat. The visual reward for winning.
  • stop other scripts in sprite — same reason as lose.
  • stop all sounds — the music (Stage 9) is probably playing. We silence it for the celebration moment.
  • start sound (Eggs) — a bright celebration sound. (Yes, Scratch's "Eggs" sound — it's a wobbly happy noise that fits.)
  • wait 5 seconds — give the player time to enjoy the win before the fish fades.
  • repeat 100 + change ghost effect by 1 — the fish slowly fades out over 100 frames. Ghost is Scratch's transparency effect.
  • broadcast (gameover) — same end signal as the lose path.
  • hide — the fish disappears.

Step 3 — Test both endings

We can't fully test the lose path yet (Stage 8 will trigger it). But we can fake both manually.

Click the green flag. The fish appears tiny on the stage.

Test the WIN path:

  • On the stage, find the playerSize variable. Show it if it's hidden (right-click → show variable). Click on the number and type 101. The size loop fires, broadcasts playerWon, and your win chain runs. The fish should put on a party hat, the Eggs sound plays, and after 5 seconds the fish fades out.

Test the LOSE path:

  • Click the green flag to reset.
  • Open the broadcast dropdown trick: drag a fresh broadcast (playerEaten) block into a blank spot. Click it. The lose chain fires — sad sound, rotated fish, pixelate fade.
  • Delete the test broadcast block when you're done.

Save your project.

Understand it

The most important pattern in this stage is the mirror. Read both listeners side by side. Almost every line has a counterpart in the other chain:

Lose chainWin chain
set playerAlive to 0set playerAlive to 0
set rotation style (all around)switch costume to (Party Hat-a)
point in direction (-90)(no equivalent — fish stays upright)
stop other scripts in spritestop other scripts in sprite
(no equivalent)stop all sounds
start sound (Bubbles)start sound (Eggs)
repeat 100 change pixelatewait 5 seconds, then repeat 100 change ghost
broadcast (gameover)broadcast (gameover)
hidehide

Pros call this parallel structure. When two pieces of code do similar jobs, you write them so the shape matches. Future-you (or another developer) can read both side by side and instantly spot the differences. The differences are where the story lives.

The reason both endings set playerAlive to 0 is that the rest of the game (especially Stage 9's timer and Stage 10's stats screen) checks playerAlive to decide if the round is still going. Setting it to 0 stops the timer, freezes the score, and signals everything else to wind down. Win or lose, the game is over.

The reason we stop other scripts in sprite is critical. Without that block, the Stage 2 keyboard loop would keep running — the player could still move their pixelated dying fish. The Stage 3 size loop would keep running — playerSize could change after the death sequence started. Stop other scripts in sprite kills both, leaving only the win/lose chain running. Clean shutdown.

The different visual effects (pixelate vs ghost) tell the player two different stories. Pixelate makes the fish look like it's breaking apart — your fish lost its battle. Ghost makes the fish fade out gently — your fish is celebrating in peace. Same Scratch effect category, opposite emotional read.

The gameover broadcast at the end of both tells the rest of the game "we're truly done now, show the stats screen." Stage 10 listens for this message. By using the same lowercase string in both chains, we make sure the stats screen runs either way.

Try this

Learning beat

Try this

Three short experiments. Predict before you run, then test your guess.

Predict first

Comment out (remove) the stop other scripts in sprite block in the LOSE chain. Trigger the lose path. Predict what happens. Try it. What broke? Put the block back when you're done.

Compare

Swap the effects: use ghost in the LOSE chain and pixelate in the WIN chain. Trigger both. Which version feels right? Why do effects match an emotion better when you pick them carefully?

Connect

Stage 5 starts building the enemy fish. The enemy is the one who will eventually broadcast playerEaten when it bumps into the player. Look at your listener for playerEaten. What does the enemy NEED TO KNOW before it can send that broadcast?

Test your stage

  • You have a when I receive (playerEaten) script with the full lose chain.
  • You have a when I receive (playerWon) script with the full win chain.
  • Setting playerSize to 101 on the stage triggers the WIN path (party hat, eggs, fade out).
  • Manually broadcasting playerEaten triggers the LOSE path (rotated fish, bubbles, pixelate).
  • Both chains end with broadcast (gameover) and hide.
  • Your project is saved.
  • Design check. Compare your two chains side by side in the code area. Are they parallel? Is the difference visible in 3 seconds of looking?

If it breaks

  • The win chain runs but the fish stays as Fish-a. The switch costume to (Party Hat-a) block is missing or set to the wrong costume. Drop down and pick Party Hat-a explicitly.
  • The lose chain runs but the fish doesn't rotate. Two suspects. First, did you add set rotation style (all around)? Without it, the fish stays in left-right mode. Second, did you set point in direction to -90 as shown in the book stack?
  • The Bubbles sound never plays. Two possibilities. First, did you add the sound to the Player sprite in Stage 1? Second, is the sound named exactly Bubbles in the Sounds tab? Sound names are case-sensitive.
  • The fish pixelates but never comes back. That's the point — the fish is supposed to stay broken until the next round. Click the green flag again. The setup section resets everything: switch costume to Fish-a, set rotation back to left-right, clear effects (you may need to add clear graphic effects to the start of the script — Stage 9 adds it explicitly).
  • The gameover broadcast doesn't seem to do anything. That's correct for today. Stage 10 will receive it. Right now nothing is listening yet.
  • Both chains broadcast gameover but only one fires. Make sure you spelled the receiving message in each one — playerEaten for lose, playerWon for win. If both when I receive blocks say the same message, only one ending exists.
Coach notes

This stage introduces broadcast/receive, which is the most powerful (and most confusing) Scratch pattern for kids 7–9. Move slowly. The book has both endings on separate pages; we put them on one page for pedagogy reasons (mirror pattern visible).

The single most common failure: building only ONE of the two listeners. Walk the room after Step 2 and confirm every laptop has BOTH when I receive (playerEaten) and when I receive (playerWon) scripts.

The second most common: typo in the broadcast names. playerEaten (one word, lowercase 'e', not "playereaten" or "Player Eaten"). playerWon (one word, lowercase 'w' not "PlayerWon"). gameover (one word, lowercase). Walk the room and read names out loud.

The "stop other scripts in sprite" block is critical and easy to miss. If a camper's fish keeps moving after death, that's the issue.

For the manual testing in Step 3 — kids will think "I can't test without Stage 8 done." Show them the trick: manually edit playerSize to 101 on the stage to trigger win. Manually broadcast playerEaten from a dragged-in block to trigger lose. This is real engineering — testing one piece without the others.

If a camper finishes early, push them into the medium stretch (tuning the celebration). The hard stretch (say blocks for context) is great prep for the stats screen — only push if they're way ahead.