fix(engine): pin modals via GlobalZIndex and surface forfeit-no-op toast
CI / Test & Lint (push) Failing after 28s
CI / Release Build (push) Has been skipped

Two fixes the smoke test surfaced:

1. The forfeit-confirm modal at `Z_PAUSE_DIALOG` (225) was invisible
   behind the pause card at `Z_PAUSE` (220). In Bevy 0.18, root-level
   UI nodes don't reliably sort across stacking contexts via plain
   `ZIndex` alone, so `spawn_modal` now adds `GlobalZIndex(z_panel)`
   alongside the existing `ZIndex(z_panel)`. Every overlay built on
   `ui_modal` (pause, forfeit-confirm, confirm-new-game, help, home,
   leaderboard, profile, achievements, stats, game-over) inherits the
   fix.

2. `handle_forfeit_request` no longer silently drops the request when
   `move_count == 0` — pressing G or clicking the pause modal's
   Forfeit button on a freshly-dealt game now opens the confirm modal,
   and the only short-circuit is "game is already won", which now
   fires an `InfoToastEvent` ("No game to forfeit") so the player
   gets feedback. The `move_count > 0` half of the gate was the
   reason a fresh-deal G press appeared to do nothing.

The G-key gate in `handle_keyboard_forfeit` is simplified to just
"not paused"; the rest of the forfeit-eligibility check moves into
`handle_forfeit_request` so it can surface the toast.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
funman300
2026-04-30 02:35:52 +00:00
parent 6723416a55
commit cb93bd9265
3 changed files with 55 additions and 40 deletions
+7
View File
@@ -144,6 +144,13 @@ where
..default()
},
BackgroundColor(SCRIM),
// GlobalZIndex pins this root modal at `z_panel` regardless
// of any sibling stacking-context quirks in Bevy 0.18 — the
// ordinary `ZIndex` is preserved as a fallback for nested
// contexts. Without GlobalZIndex, a confirmation modal at
// `Z_PAUSE_DIALOG` (225) was rendering *behind* the pause
// modal at `Z_PAUSE` (220) in some scenes.
GlobalZIndex(z_panel),
ZIndex(z_panel),
))
.with_children(|root| {