doc 9 of 10

Stage 07 — Menus, Pause, Results

You will build: the flow that wraps the game: a menu, song selection that discovers charts automatically, a pause that doesn't lie, and a results screen. You'll learn: scene flow · pause architecture (where the audit's process-mode lesson finally pays off) · UI containers. Warm-up — from memory: in the bug hunt you found a process_mode set on a node for no reason. What does that property actually control, and under what condition does it matter?

Why this exists#

A game you must launch from the editor isn't a game yet. Flow is unglamorous and it's where players actually live: pick a song, play, pause when the phone rings, see how you did, go again. Pause is the interesting one in a rhythm game — get_tree().paused freezes the scene tree, but the audio stream keeps its own clock, and your conductor sits between them. Getting this right is the graduation exam for the timing model.

Build it#

A — The flow skeleton#

Three scenes: menu, game (exists), results. Switch with get_tree().change_scene_to_packed(). The menu needs two buttons and no beauty — flow first, paint later. Results receives the run's numbers — decide how they travel between scenes (the farming curriculum's data-first habit applies; a tiny RunResults object beats six globals).

B — Song select#

Don't hardcode the song list. Scan for charts at startup — built-ins from res://, your stage-05 recordings from user:// — and build the list from what exists. Adding a song to the game must require zero code changes; that's the data-driven promise kept.

C — Pause, honestly#

Esc pauses. Requirements: gameplay freezes, the pause menu works while frozen (process modes — now the audited flag becomes a tool you wield on purpose), the music stops (stream_paused, not stop() — one keeps the position, and you now know which clock cares), and resuming doesn't cause a judgment massacre. Test the ugly case: pause mid-note, wait ten seconds, resume. What should happen to that note? Decide, implement, defend.

D — Results#

Accuracy, grade, combo, per-judgment counts. One button: again; one: menu. Done.

git add . && git commit -m "stage 07: menu, song select, honest pause, results"

Checkpoint — definition of done#

  • Menu → song → play → results → again, without touching the editor
  • A chart recorded in stage 05 appears in song select automatically
  • Pause mid-song, wait, resume: music continues from position, notes stay in sync, no spurious misses — and you can explain which nodes keep processing while paused and why
  • Quit-to-menu mid-song leaks nothing: play three songs back to back and watch the Remote scene tree for orphans
  • Results numbers match what the gameplay screen showed

Stretch (no instructions)#

A three-beat count-in on unpause, so resuming mid-song is playable instead of a sudden wall of notes. The conductor knows everything you need.

If you get stuck#

  • Notes jump on resume → something kept counting while gameplay froze. Which clock does your conductor trust, and did it pause? Print song time across the pause boundary.
  • Pause menu buttons dead while paused → the process-mode chain: the menu, its layer, and its parents. Draw the tree, mark each node's mode, find the frozen ancestor.
  • Music restarts from zero on resume → you used stop()/play() — the position lives in the stream player; the property you want was named in section C.