feat(engine): in-engine replay playback core

Promotes the replay feature from disk-only to a real in-engine
playback path. A new ReplayPlaybackState resource models a three-
state machine (Inactive / Playing / Completed); start_replay_playback
resets the live game to the recorded deal via
GameState::new_with_mode(seed, draw_mode, mode) and a tick system
fires the canonical MoveRequestEvent / DrawRequestEvent for each
recorded move at REPLAY_MOVE_INTERVAL_SECS (0.45s).

The reset path bypasses NewGameRequestEvent because the existing
event always sources draw_mode from Settings — a Draw-1 replay
would silently coerce to Draw-3 (or vice versa) on a player whose
preference doesn't match the recording. Inserting GameStateResource
directly applies the recording's exact draw_mode and sidesteps the
abandon-current-game confirmation modal that would otherwise block
playback.

Recording suppression during playback is non-invasive: a sibling
system snapshots RecordingReplay's length on entry to playback and
truncates the buffer back to that mark every frame while is_playing
or is_completed. game_plugin's recording append paths are
untouched.

Completion lingers for REPLAY_COMPLETION_LINGER_SECS (5s) so the
overlay can show "Replay complete" before the auto-clear flips
state to Inactive.

Six new tests cover the state transitions, tick cadence, canonical
event firing, completion, stop-clears-state, and the
recording-suppression contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-05 20:34:16 +00:00
parent 95fcdad5d2
commit 8e90574437
2 changed files with 692 additions and 0 deletions
+10
View File
@@ -24,6 +24,8 @@ pub mod onboarding_plugin;
pub mod pause_plugin;
pub mod profile_plugin;
pub mod radial_menu;
pub mod replay_overlay;
pub mod replay_playback;
pub mod settings_plugin;
pub mod progress_plugin;
pub mod resources;
@@ -112,6 +114,14 @@ pub use radial_menu::{
legal_destinations_for_card, radial_anchor_for_index, radial_hovered_index, RadialIcon,
RadialMenuPlugin, RightClickRadialState, Z_RADIAL_MENU,
};
pub use replay_overlay::{
ReplayOverlayBannerText, ReplayOverlayPlugin, ReplayOverlayProgressText, ReplayOverlayRoot,
ReplayStopButton, Z_REPLAY_OVERLAY,
};
pub use replay_playback::{
start_replay_playback, stop_replay_playback, ReplayPlaybackPlugin, ReplayPlaybackState,
REPLAY_COMPLETION_LINGER_SECS, REPLAY_MOVE_INTERVAL_SECS,
};
pub use settings_plugin::{
PendingWindowGeometry, SettingsChangedEvent, SettingsPlugin, SettingsResource, SettingsScreen,
SFX_STEP, WINDOW_GEOMETRY_DEBOUNCE_SECS,