feat(engine): add StatsPlugin with persistent stats and toggleable overlay

StatsPlugin loads stats on startup, persists them on every GameWonEvent
and abandoned NewGameRequestEvent (>=1 move, not won), and provides a
full-window overlay toggled with `S` showing games played/won, win rate,
streak, best score, fastest win, and average win time.

The storage path is configurable via StatsPlugin::storage_path: the
default ctor uses dirs::data_dir(); StatsPlugin::headless() disables
I/O entirely so tests don't read or overwrite the user's real
stats.json. record_abandoned runs before GameMutation so it reads
move_count before handle_new_game clobbers it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-04-24 12:43:49 -07:00
parent 5ced4c01ce
commit 2ce11f8f4d
3 changed files with 331 additions and 1 deletions
+4 -1
View File
@@ -1,5 +1,7 @@
use bevy::prelude::*;
use solitaire_engine::{AnimationPlugin, CardPlugin, GamePlugin, InputPlugin, TablePlugin};
use solitaire_engine::{
AnimationPlugin, CardPlugin, GamePlugin, InputPlugin, StatsPlugin, TablePlugin,
};
fn main() {
App::new()
@@ -18,5 +20,6 @@ fn main() {
.add_plugins(CardPlugin)
.add_plugins(InputPlugin)
.add_plugins(AnimationPlugin)
.add_plugins(StatsPlugin::default())
.run();
}