Need help getting started? Try the player guide. These notes include older work; the game overview explains what’s ready now.
Finite lives and game over
Latest user correction (2026-10-19): restore retries until all lives are lost, then the original Game Over sequence before Main. This supersedes the earlier request to return to Main on every death. After the original death animation and black fade, the Windows frontend now honors SSA_RUN_RETRY, consumes one life and rebuilds the level from its entry snapshot. The last life runs original Game Over text/music and returns directly to Main after the terminal fade. Retries now skip NETRICSA and the map, entering the normal black-to-level reveal directly. Initial starts and level advancement retain their pre-level screens. No restart confirmation or death name-entry prompt is added. Pause Quit and campaign ending retain their existing high-score flows.
A reproducible stuck-death case was added: lethal combat damage with frame pause bit1 retained skips entity updates, so06154 never advances its death timer or requests terminal mode4. The frontend now clears that bit for a dead player until mode4. Actual pause/NETRICSA screens still own their separate event-loop branches; the terminal fade still deliberately freezes the completed death frame. This is a demonstrated cause of the reported symptom, not a claim that the user's exact prior session state was captured.
New Game, passwords and selected-level starts receive5/3/2 lives on Easy/Normal/ Hard, including the current life. Both the recovered native helpers and Windows frontend now retry with level-entry equipment/score. Remaining lives carry through ordinary level advancement and the Egypt-to-Rome chapter transition. Starting a new run resets the allowance. Existing progress, settings and score-file formats are unchanged.
The previous frontend restored the difficulty allowance on every reload and paused indefinitely at death. It also allowed Enter to restart without consuming a life. Death now has an automatic retry/final-menu handoff; Enter retains its explicit startup/transition-diagnostic behavior only. R reloads alternate Colts; it never restarts the level.
The shared game runtime and gameplay adapter now both receive the initial life count. Previously, setting only the gameplay projection after runtime creation let the first entity update overwrite Easy/Hard with Normal's value3.
Original HUD life-digit correction (2026-10-19): the native HUD projection now copies game.life_game.continue_flag into hud.game_value before each controller. The retained type16 controller selects its digit with animation6B+game_value; the projection previously left that field zero. It now shows the same live count as Classic:5/3/2 at difficulty starts, reduced counts after retries, and0 after the last life is consumed. Original controller/artwork/animation behavior stays intact. Native death/retry checks inspect the HUD digit before each death and on the first death frame, including the final1->0 transition.
Original boundaries
06154 still owns the full death sequence, camera collapse, notices and audio.
With more than one life it submits localized B5 (YOU ARE TOAST) and sound17,
then requests input mode4 after301 ticks at the native60Hz simulation clock.
The last life is consumed immediately: the timer starts at500, requests music
command10 and localized B4 (GAME OVER) after91 ticks, then requests mode4 after
another301 ticks. The ordinary death voice is omitted on this final-life path,
as in the ROM. Music10 no longer starts on every ordinary retry boundary.
The frontend freezes that completed death frame, releases gameplay input, and
runs the original black-fade rate, 15614(0,64,31): visual volume0..0xF00 in
64-unit steps. 08E74(7) is a music/effects fade interval, not sound7. The audio
worker stays independent of the display. The terminal black frame must reach
presentation before returning to Main. No restart key is required.
ssa_run_exit recovers the terminal mode4/mode5 state projection after that
fade. It clears the notice timer, decrements a nonzero life count and requests
initialization mode0, or requests menu mode7/name entry when the count is zero.
The original mode5 Main-menu destination is retained in this helper too. Final
game flags are2. Unsupported modes fail without changes. Completion/advance
continues through the existing tally and record pipeline; this helper does not
replace it or pretend to implement network sessions.
On a retry, the completed black death frame remains active until the normal outer-loop reload constructs the new level. Catch-up ticks cannot consume a second life or briefly show an unfaded dead scene. Reload preserves the reduced life count after applying difficulty/settings and starts the normal level reveal without NETRICSA, map or chapter story. The shared reveal helper restarts gameplay audio, prepares the ready weapon/HUD, and starts a fresh60tick fade clock after black is presented. Movement runs during the reveal. It restores the entry snapshot rather than the inventory/score at the instant of death.
The final Windows permanent-death name-entry route remains replaced by the requested direct Main return after Game Over. Pause Quit and the ending retain the rank/name editor. Existing score-file merge, failure and Clear Data behavior remains intact.
Validation
decomp.ps1 test-run-exit-rom:2,048 comparisons against the actual original exit fragment, all256 life-byte values, both terminal modes,1..4 player-count projections, randomized flags/timers and9 invalid-input checks. UBSan enabled.decomp.ps1 test-run-exit:26,453 ASan/UBSan/leak checks over9,879 native frames: 30 complete deaths,21 retries and9 permanent deaths in all3 difficulties and languages. It verifies exact death timing,21 death voices,9 game-over music changes, life counts and restored entry inventory/score.scripts/test-run-exit.ps1 -SkipBuild: GCC/MSVC core agreement plus24 lethal combat deaths (12 retries and12 final Main returns), both HUD styles/renderers, all three languages/difficulties, ordinary/final-life timing and24 black presentations. Half the cases inject the stale pause bit; this failed before the guard. Four additional tests run the real Windows wall clock, event loop, rendering, muted live audio worker, automatic retry and final menu return. Each supplies two lethal hits with stale pause bits, verifying2->1->0 lives. The ordinary pre-level NETRICSA/map screens appear only on initial startup; retries must bypass them and enter a new level reveal, with no restart confirmation. Windows are briefly shown without activation for the presentation paths. No user save is touched.- Existing native/Windows pause, completion, score-entry and persistence suites pass. Localized GAME OVER and partial-fade captures were visually inspected.
Current counts/source hashes are in run-exit-rom-validation.json,
run-exit-validation.json and windows-run-exit-validation.json. Full campaign
playthroughs remain manual. ARM execution is test-only; runtime uses native C.
Latest focused retry-reveal validation (2026-10-19): MSVC26453 native core
checks pass. Windows4697889 checks cover24 deaths,12 direct retries,12 final
Main returns and four real wall-clock retry/Game-Over loops in both HUD styles
and renderers. They verify no extra NETRICSA/map starts, fresh fade clocks,
presented black, ready weapons and movement during fade. Initial briefings/maps
still run. Existing Classic560 and intermission6205 Windows checks also pass.
Static125libraries/frontend rebuilt. See retry-reveal-validation.json. No broad
sanitizer or campaign replay was performed for this Windows-only routing change.
This pass adds no exact byte match and does not modify the ROM. Full original
feature parity, multiplayer and disk storage of campaign-session totals remain
unfinished.