fix(simulation): address PR #50 review — determinism, overflow, invariants
- Sort eligible NPCs by StableId for deterministic conversation pairing (D-010) - Replace single_mut() with per-observer iteration (D-010 principle 3, D-027) - Widen current_stress * 100 to i32 in mood derivation to prevent i16 overflow - Promote line_interval to named constant LINE_INTERVAL_TICKS - Add 4 Sprint 14 component invariants (MoodState, InteractionMemory, ActivityState+PathRequest exclusion, double-tagged tier detection) - Attach MoodState to content spawn pipeline and gauntlet fixup - VecDeque for InteractionMemory.notable_events (O(1) pop_front) - Rename who_knows() to who_knows_full_scan() to communicate O(N) cost - Add O(N^2) growth limit comment on conversation pair scan - Document Suspicious/Focused as externally-set moods on enum variants Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -495,6 +495,48 @@ pub fn setup_gauntlet(app: &mut App) {
|
||||
}
|
||||
|
||||
app.insert_resource(snapshots);
|
||||
|
||||
// --- Sprint 14 component fixup ---
|
||||
// Attach MoodState and InteractionMemory to all Npc entities that are
|
||||
// missing them. Gauntlet room builders don't include these yet — this
|
||||
// ensures invariant S14-1/S14-2 pass and the mood/trust systems have
|
||||
// valid component targets.
|
||||
{
|
||||
use crate::npc::interaction::InteractionMemory;
|
||||
use crate::npc::mood::MoodState;
|
||||
use crate::npc::Npc;
|
||||
|
||||
let missing_mood: Vec<bevy_ecs::prelude::Entity> = {
|
||||
let mut q = app
|
||||
.world_mut()
|
||||
.query_filtered::<bevy_ecs::prelude::Entity, (
|
||||
bevy_ecs::prelude::With<Npc>,
|
||||
bevy_ecs::prelude::Without<MoodState>,
|
||||
)>();
|
||||
q.iter(app.world()).collect()
|
||||
};
|
||||
for entity in missing_mood {
|
||||
app.world_mut()
|
||||
.entity_mut(entity)
|
||||
.insert(MoodState::default());
|
||||
}
|
||||
|
||||
let missing_mem: Vec<bevy_ecs::prelude::Entity> = {
|
||||
let mut q = app
|
||||
.world_mut()
|
||||
.query_filtered::<bevy_ecs::prelude::Entity, (
|
||||
bevy_ecs::prelude::With<Npc>,
|
||||
bevy_ecs::prelude::Without<InteractionMemory>,
|
||||
)>();
|
||||
q.iter(app.world()).collect()
|
||||
};
|
||||
for entity in missing_mem {
|
||||
app.world_mut()
|
||||
.entity_mut(entity)
|
||||
.insert(InteractionMemory::default());
|
||||
}
|
||||
}
|
||||
|
||||
app.insert_resource(registry);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user