From b7c3a4996f3449701fb9fee2196e9a4cfe613952 Mon Sep 17 00:00:00 2001 From: funman300 Date: Wed, 6 May 2026 15:44:31 +0000 Subject: [PATCH] fix(engine): Restore-prompt resolution suppresses Home auto-show MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolving the Welcome-back / Restore prompt (either Continue or New game) cleared `PendingRestoredGame` and despawned the modal, but the launch-time Home auto-show then fired the next frame and stacked itself over the player's chosen path — clicking "New game" would deal a fresh game AND immediately pop the mode picker on top. `LaunchHomeShown` becomes pub so `handle_restore_prompt` can flip it to `true` after either resolution; `M` still re-opens the picker on demand. Headless tests already pre-set the flag to true via `HomePlugin::headless()`, so they're unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) --- solitaire_engine/src/game_plugin.rs | 17 ++++++++++++++++- solitaire_engine/src/home_plugin.rs | 6 +++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/solitaire_engine/src/game_plugin.rs b/solitaire_engine/src/game_plugin.rs index 290d16b..514472d 100644 --- a/solitaire_engine/src/game_plugin.rs +++ b/solitaire_engine/src/game_plugin.rs @@ -586,6 +586,7 @@ fn handle_restore_prompt( mut game: ResMut, mut changed: MessageWriter, mut new_game: MessageWriter, + mut launch_home_shown: Option>, ) { if screens.is_empty() { return; @@ -605,7 +606,7 @@ fn handle_restore_prompt( .any(|i| *i == Interaction::Pressed); let click_new = new_game_buttons.iter().any(|i| *i == Interaction::Pressed); - if key_continue || click_continue { + let resolved = if key_continue || click_continue { if let Some(restored) = pending.0.take() { game.0 = restored; changed.write(StateChangedEvent); @@ -613,6 +614,7 @@ fn handle_restore_prompt( for entity in &screens { commands.entity(entity).despawn(); } + true } else if key_new || click_new { pending.0 = None; for entity in &screens { @@ -623,6 +625,19 @@ fn handle_restore_prompt( mode: None, confirmed: true, }); + true + } else { + false + }; + + // The player has just made an explicit launch-time choice (continue + // saved game, or start a fresh deal). Suppress the launch-time Home + // auto-show so it doesn't pop on top of the resolution they picked. + // `M` still re-opens the picker on demand. + if resolved + && let Some(ref mut shown) = launch_home_shown + { + shown.0 = true; } } diff --git a/solitaire_engine/src/home_plugin.rs b/solitaire_engine/src/home_plugin.rs index ddae6be..68af2e3 100644 --- a/solitaire_engine/src/home_plugin.rs +++ b/solitaire_engine/src/home_plugin.rs @@ -120,8 +120,12 @@ struct HomeModeCard(HomeMode); /// the first time it spawns the modal, so the auto-show is one-shot per /// process — subsequent dismissals (Cancel / mode pick) don't trigger /// a respawn, but the player can still re-open the picker with `M`. +/// +/// Other plugins (e.g. `game_plugin`'s restore-prompt handler) can flip +/// the flag manually to suppress the launch auto-show when the player +/// has already made a launch-time choice through a different surface. #[derive(Resource, Debug, Default)] -struct LaunchHomeShown(bool); +pub struct LaunchHomeShown(pub bool); // --------------------------------------------------------------------------- // Plugin