Run one persistent cutscene for the whole main menu, not just start-game

Previously the main menu UI opened directly with no cutscene, and only
pressing "Start Game" spun up a brand new cutscene
(main_menu_start_game.jsonc) for the save-device check/load-slots flow.
Now a single cutscene (main_menu.jsonc) starts the moment the main menu
scene becomes active, sitting idle (new CUTSCENE_ITEM_TYPE_IDLE item -
no existing item type blocked forever with no side effect) while the
menu is shown, so it can own menu-wide state going forward.

Pressing "Start Game" now jumps the already-running cutscene to a
NEW_GAME marker via cutsceneGoTo instead of starting a second cutscene -
this already-existing mechanism needed no engine changes. Both retry
options (no device / load error) also now jump straight back to
NEW_GAME instead of RESTARTing the whole cutscene, since RESTART would
otherwise strand the player on the idle block. sceneMainMenuStartGame
also handles the case where the cutscene already ran to completion once
(e.g. backing out of the save picker and pressing Start Game again) by
restarting it landing straight on NEW_GAME, avoiding a crash from
jumping a marker with no cutscene running.

Built and verified on Linux (boots/idles without crashing, cutscene
tests pass), PSP, GameCube and Wii (Docker).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-09-04 18:18:49 -05:00
co-authored by Claude Sonnet 5
parent 3c3dc35e1d
commit 707856fcf2
13 changed files with 144 additions and 50 deletions
@@ -1,12 +1,26 @@
{
"items": [
// Runs immediately as soon as the main menu scene becomes active
// (see sceneMainMenuInit) - owns menu-wide ambience, then idles while
// the menu itself is shown and interacted with natively.
// {
// "type": "AUDIO_PLAY",
// "file": "audio/boa.mp3",
// "channel": "BGM_0",
// "volume": 1.0,
// "pan": 0.0,
// "looping": true
// },
{
"type": "AUDIO_PLAY",
"file": "audio/boa.mp3",
"channel": "BGM_0",
"volume": 1.0,
"pan": 0.0,
"looping": true
"type": "IDLE"
},
// New Game pressed (sceneMainMenuStartGame jumps here via
// cutsceneGoTo) - check for a save device before loading slots.
{
"type": "MARKER",
"name": "NEW_GAME"
},
{
"type": "MODAL",
@@ -24,6 +38,8 @@
},
// No save device found - offer to retry or continue without saving.
// Retry jumps straight back to NEW_GAME rather than restarting the
// whole cutscene, so the BGM above isn't retriggered.
{
"type": "MARKER",
"name": "NO_DEVICE"
@@ -38,7 +54,7 @@
"options": [
{
"text": "main_menu.no_device.retry",
"marker": "RETRY"
"marker": "NEW_GAME"
},
{
"text": "main_menu.no_device.continue",
@@ -47,18 +63,6 @@
]
},
// Retry
{
"type": "MARKER",
"name": "RETRY"
},
{
"type": "MODAL_CLOSE"
},
{
"type": "RESTART"
},
// Save device found - attempt to load all save slots.
{
"type": "MARKER",
@@ -87,7 +91,7 @@
"options": [
{
"text": "main_menu.save_load_error.retry",
"marker": "RETRY"
"marker": "NEW_GAME"
}
]
},