refactor(simulation): replace ad-hoc system ordering with TickPhase pipeline (#843)
10-phase linear pipeline: PreInput → Input → Movement → Simulation → Economy → Storyteller → Snapshot → PostSnapshot → Knowledge → TickAdvance. Each system assigned to exactly one phase via .in_set(TickPhase::X). Cross-phase .after()/.before() eliminated — only intra-phase ordering remains. Prevents schedule cycles by construction. SimulationPlugin refactored into sub-plugins by domain: - InputPlugin (player actions, interactions, dialogue dispatch) - MovementPlugin (pathfinding, movement validation, spatial indexing) - SocialPlugin (conversations, sound, voice enrichment, follow state) - EconomyPlugin (tâtonnement tick, IPC query serving) - TimePlugin (chunk streaming, news ticker, tick advancement) All other plugins (NPC, Knowledge, Perception, Storyteller, Settings, Bridge) updated to use TickPhase assignments instead of cross-plugin ordering constraints. BridgePlugin trimmed to bridge I/O concerns only. Part A of #843. Parts B (multi-threaded executor) and C (background workers) follow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+55
-60
@@ -31,6 +31,8 @@ pub struct NpcPlugin;
|
||||
|
||||
impl Plugin for NpcPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
use crate::tick_phases::TickPhase;
|
||||
|
||||
app.init_resource::<relationships::RelationshipGraph>()
|
||||
.init_resource::<relationships::TrustEventQueue>()
|
||||
.init_resource::<relationships::PropagationQueue>()
|
||||
@@ -41,73 +43,66 @@ impl Plugin for NpcPlugin {
|
||||
.init_resource::<routine::RoutineDeviationEventQueue>()
|
||||
.init_resource::<disclosure::DisclosureGlobalRateLimit>()
|
||||
.init_resource::<trait_modifiers::TraitModifierConfig>()
|
||||
// PreInput: routine phase transition (before pathfinding in Movement)
|
||||
.add_systems(
|
||||
Update,
|
||||
routine::check_phase_transition.in_set(TickPhase::PreInput),
|
||||
)
|
||||
// Input: dialogue systems (consume player talk/walk-away/confrontation actions)
|
||||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
routine::check_phase_transition
|
||||
.before(crate::simulation::pathfinding::compute_paths),
|
||||
mood::update_mood
|
||||
.after(routine::check_phase_transition)
|
||||
.before(crate::simulation::dialogue::process_talk_interaction),
|
||||
relationships::update_trust
|
||||
.after(crate::simulation::dialogue::process_talk_interaction)
|
||||
.after(crate::simulation::dialogue::process_walk_away)
|
||||
.after(crate::simulation::dialogue::process_confrontation_response)
|
||||
.after(crate::simulation::dialogue::process_dialogue_response)
|
||||
.before(crate::simulation::time::advance_tick),
|
||||
relationships::propagate_social_actions
|
||||
.after(relationships::update_trust)
|
||||
.before(crate::simulation::time::advance_tick),
|
||||
relationships::update_relationship_dynamics
|
||||
.after(relationships::update_trust)
|
||||
.before(crate::simulation::time::advance_tick),
|
||||
routine::enter_activity
|
||||
.after(crate::simulation::movement::validate_movement)
|
||||
.before(crate::perception::observer::compute_observer_snapshot),
|
||||
crate::simulation::dialogue::process_talk_interaction,
|
||||
crate::simulation::dialogue::process_walk_away
|
||||
.after(crate::simulation::dialogue::process_talk_interaction),
|
||||
crate::simulation::dialogue::process_confrontation_response,
|
||||
crate::simulation::dialogue::process_dialogue_response
|
||||
.after(crate::simulation::dialogue::process_talk_interaction),
|
||||
)
|
||||
.in_set(TickPhase::Input),
|
||||
)
|
||||
// Simulation: NPC behavior — vision, awareness, mood, tolerance, routine,
|
||||
// disclosure, background tick. Intra-phase ordering where needed.
|
||||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
vision::compute_npc_vision,
|
||||
vision::emit_npc_vision_events
|
||||
.after(vision::compute_npc_vision),
|
||||
awareness::detect_player_awareness
|
||||
.after(vision::compute_npc_vision),
|
||||
mood::update_mood,
|
||||
tolerance::check_tolerance_threshold
|
||||
.after(mood::update_mood)
|
||||
.before(crate::simulation::time::advance_tick),
|
||||
.after(awareness::detect_player_awareness),
|
||||
routine::enter_activity,
|
||||
routine::detect_routine_deviation
|
||||
.after(routine::enter_activity)
|
||||
.before(crate::perception::observer::compute_observer_snapshot),
|
||||
tell_state::derive_tell_state
|
||||
.after(mood::update_mood)
|
||||
.after(routine::detect_routine_deviation)
|
||||
.before(crate::perception::observer::compute_observer_snapshot),
|
||||
background::background_tick
|
||||
.after(crate::simulation::movement::validate_movement)
|
||||
.before(crate::simulation::time::advance_tick),
|
||||
disclosure::derive_disclosure_candidates
|
||||
.before(crate::perception::observer::compute_observer_snapshot),
|
||||
.after(routine::enter_activity),
|
||||
background::background_tick,
|
||||
disclosure::derive_disclosure_candidates,
|
||||
disclosure::process_unprompted_disclosure
|
||||
.after(disclosure::derive_disclosure_candidates)
|
||||
.before(crate::perception::observer::compute_observer_snapshot),
|
||||
// NPC player-awareness (#244)
|
||||
awareness::detect_player_awareness
|
||||
.after(vision::compute_npc_vision)
|
||||
.before(tolerance::check_tolerance_threshold),
|
||||
// NPC vision system (#115, D-011)
|
||||
vision::compute_npc_vision
|
||||
.after(crate::simulation::movement::validate_movement)
|
||||
.after(crate::simulation::tier::update_tier_markers)
|
||||
.before(crate::perception::observer::compute_observer_snapshot),
|
||||
vision::emit_npc_vision_events
|
||||
.after(vision::compute_npc_vision)
|
||||
.before(crate::knowledge::events::process_knowledge_events),
|
||||
vision::degrade_npc_inferences
|
||||
.after(vision::emit_npc_vision_events)
|
||||
.before(crate::simulation::time::advance_tick),
|
||||
crate::simulation::dialogue::process_talk_interaction
|
||||
.after(crate::simulation::input::process_player_input),
|
||||
crate::simulation::dialogue::process_walk_away
|
||||
.after(crate::simulation::input::process_player_input)
|
||||
.after(crate::simulation::dialogue::process_talk_interaction),
|
||||
crate::simulation::dialogue::process_confrontation_response
|
||||
.after(crate::simulation::input::process_player_input),
|
||||
crate::simulation::dialogue::process_dialogue_response
|
||||
.after(crate::simulation::input::process_player_input)
|
||||
.after(crate::simulation::dialogue::process_talk_interaction),
|
||||
),
|
||||
.after(disclosure::derive_disclosure_candidates),
|
||||
)
|
||||
.in_set(TickPhase::Simulation),
|
||||
)
|
||||
// Storyteller: tell state derivation (reads mood + routine deviation)
|
||||
.add_systems(
|
||||
Update,
|
||||
tell_state::derive_tell_state
|
||||
.in_set(TickPhase::Storyteller),
|
||||
)
|
||||
// Knowledge: relationships (trust, propagation, dynamics), vision degradation
|
||||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
relationships::update_trust,
|
||||
relationships::propagate_social_actions
|
||||
.after(relationships::update_trust),
|
||||
relationships::update_relationship_dynamics
|
||||
.after(relationships::update_trust),
|
||||
vision::degrade_npc_inferences,
|
||||
)
|
||||
.in_set(TickPhase::Knowledge),
|
||||
);
|
||||
|
||||
tracing::debug!("NpcPlugin initialized");
|
||||
|
||||
Reference in New Issue
Block a user