feat(simulation): sprint anomaly double-take monologue (#428, D-055)

When sprinting past a Contradicted entity, queue a delayed retroactive
monologue that fires after ~1.5s: "Wait — something wasn't right back
there." SprintAnomalyQueue component with first-in-wins semantics.
Detection in observer pipeline, processing in monologue system.
Wire MovementProfile, Stance, and SprintAnomalyQueue into player spawn.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 16:00:20 +01:00
co-authored by Claude Opus 4.6
parent 1d76100f5d
commit df81b24cd1
4 changed files with 459 additions and 6 deletions
+8 -2
View File
@@ -15,9 +15,10 @@ use settled_reach_server::npc::{
};
use settled_reach_server::perception::vision_cone::Facing;
use settled_reach_server::simulation::interaction::{Interactable, NearbyInteractionBuffer};
use settled_reach_server::simulation::monologue::{MonologueBuffer, MonologueState};
use settled_reach_server::simulation::monologue::{MonologueBuffer, MonologueState, SprintAnomalyQueue};
use settled_reach_server::simulation::movement::{PlayerCharacter, TilePosition, WalkabilityMap};
use settled_reach_server::simulation::path_follow::MovementSpeed;
use settled_reach_server::simulation::stance::{MovementProfile, PlayerMoveCooldown};
use settled_reach_server::simulation::time::DayPhase;
use settled_reach_server::simulation::SimulationPlugin;
@@ -63,7 +64,8 @@ fn main() {
let mut registry = EntityRegistry::new(0);
// Player at (16,16)
// Player at (16,16) — smuggler archetype (#418, D-053)
let profile = MovementProfile::smuggler();
let player = app
.world_mut()
.spawn((
@@ -74,6 +76,10 @@ fn main() {
NearbyInteractionBuffer::default(),
MonologueState::default(),
MonologueBuffer::default(),
SprintAnomalyQueue::default(),
profile,
profile.initial_stance(),
PlayerMoveCooldown::default(),
))
.id();
registry.register(player);