From de840fb0060005559d5903cc8872227217a76b6f Mon Sep 17 00:00:00 2001 From: root Date: Mon, 27 Apr 2026 03:02:59 +0000 Subject: [PATCH] feat(engine,server): XP toast on win + display_name max-length validation ProgressPlugin now fires XpAwardedEvent on every win. AnimationPlugin shows a "+N XP" toast so players see XP feedback immediately after winning. Server leaderboard opt-in endpoint also now validates that display_name is at most 32 characters. Co-Authored-By: Claude Sonnet 4.6 --- solitaire_engine/src/animation_plugin.rs | 10 +++++++++- solitaire_engine/src/events.rs | 7 +++++++ solitaire_engine/src/lib.rs | 2 +- solitaire_engine/src/progress_plugin.rs | 5 ++++- solitaire_server/src/leaderboard.rs | 14 ++++++++++++-- 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/solitaire_engine/src/animation_plugin.rs b/solitaire_engine/src/animation_plugin.rs index 8de9ccc..bde4220 100644 --- a/solitaire_engine/src/animation_plugin.rs +++ b/solitaire_engine/src/animation_plugin.rs @@ -11,7 +11,7 @@ use crate::auto_complete_plugin::AutoCompleteState; use crate::card_plugin::CardEntity; use crate::challenge_plugin::ChallengeAdvancedEvent; use crate::daily_challenge_plugin::{DailyChallengeCompletedEvent, DailyGoalAnnouncementEvent}; -use crate::events::{InfoToastEvent, NewGameConfirmEvent}; +use crate::events::{InfoToastEvent, NewGameConfirmEvent, XpAwardedEvent}; use crate::events::{AchievementUnlockedEvent, GameWonEvent}; use crate::game_plugin::GameMutation; use crate::layout::LayoutResource; @@ -94,6 +94,7 @@ impl Plugin for AnimationPlugin { .add_event::() .add_event::() .add_event::() + .add_event::() .init_resource::() .add_systems(Startup, init_slide_duration) .add_systems( @@ -113,6 +114,7 @@ impl Plugin for AnimationPlugin { handle_auto_complete_toast, handle_new_game_confirm_toast, handle_info_toast, + handle_xp_awarded_toast, tick_toasts, ) .after(GameMutation), @@ -330,6 +332,12 @@ fn handle_info_toast(mut commands: Commands, mut events: EventReader) { + for ev in events.read() { + spawn_toast(&mut commands, format!("+{} XP", ev.amount), 3.0); + } +} + fn tick_toasts( mut commands: Commands, time: Res