Code status: illustrative pseudocode. Adapt the listing to your program and check it on your target machine. This page links no assembly or execution record for the listing itself.
Overview
Players die with the fire button held — that’s how everyone dies. Without protection, the game-over screen reads that held button on its first frame, snaps to the title, the title reads the same held button, and a new game starts before the death tone finishes. Three screens in three frames; the player never reads their own ending.
The fix is a dwell: entering any screen that waits for a button loads a frame counter, and the screen refuses to believe the button until the counter runs out. A second of stillness on game over; half a second on the title. The pause isn’t dead time — it’s the punctuation that makes win and loss land.
This is the timer-based sibling of edge detection. Edge detection ignores a held button entirely (act on the press, not the level); the dwell slows everything down regardless of edges, which also gives the moment room to breathe. Finished games often want both: the dwell for the beat, the edge for the button.
Pseudocode
; entering an ending screen — wherever the state changes
enter_game_over:
state = GAME_OVER
ui_lock = 50 ; one second at 50 updates per second
enter_title:
state = TITLE
ui_lock = 25 ; half a second at the same 50 Hz clock
; in the screen's per-frame handler
game_over_update:
draw the screen
if ui_lock > 0:
ui_lock -= 1
return ; the button is not yet believed
if fire pressed:
enter_titleImplementation Notes
The lock loads where the state changes, not where the screen draws. A screen that repaints every frame would reload the lock every frame and never expire. Flock’s endtick dwells via WINWAIT/ENDWAIT loaded at the win/loss moment; Starfield’s ui_lock loads in the out-of-lives branch and in enter_title.
One variable serves every screen — the title and the game-over screen never run at the same time, so a single ui_lock byte with different load values per screen is enough.
Differentiate the two endings. Flock dwells longer on a win (180 frames, then straight to the next level) than on a loss (300 frames, then the long walk back to the title) — the dwell length is part of how each ending feels.
Verification note: the dwell is invisible in screenshots. Starfield’s was verified frame-exact by scripted runs — GAME OVER must survive a held button at +30 and +55 frames, flip to the title at +75, and start a new game at +105. If you can’t see a behaviour in a still, script it.
Trade-offs
| Aspect | Cost |
|---|---|
| CPU | One decrement and branch per frame on ending screens |
| Memory | One byte |
| Complexity | One byte and a branch — the discipline is loading it at every state change |
When to use: every screen that waits for a button, in every game.
When to avoid: mid-game prompts where responsiveness matters more than ceremony — there, use edge detection alone.
Benefits
- Endings land — the player reads the screen because the game makes them
- No accidental skip-through — a held button can’t chain across screens
- Tunable feel — the dwell lengths are two bytes of game-design intent
Choose the clock before choosing these counts. A held button can leave as soon as this minimum dwell ends; require a new press after the lock if that is the intended interaction. This timer delays screen transitions, not input sampling or the rest of the game loop.