Files
settled-reach/server/src/simulation/social_plugin.rs
T
jpmschweitzerandClaude Opus 4.6 47d4918cc8 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>
2026-04-10 23:51:06 +02:00

48 lines
2.3 KiB
Rust

//! Social simulation plugin — NPC conversations, knowledge transfer, disclosure.
//!
//! All systems run in [`TickPhase::Simulation`]. Intra-phase ordering:
//! - conversations → knowledge_transfer (transfer reads conversation results)
//! - conversations → sound collection (sound reads conversation events)
use bevy_app::prelude::*;
use bevy_ecs::schedule::IntoScheduleConfigs;
use crate::tick_phases::TickPhase;
pub struct SocialPlugin;
impl Plugin for SocialPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<super::sound::SoundEventQueue>()
.init_resource::<super::follow::FollowEndEventQueue>()
.init_resource::<super::monologue::PostConversationQueue>()
.init_resource::<super::poi_discovery::PoiDiscoveryEventQueue>()
.add_systems(
Update,
(
super::conversation::run_npc_conversations,
super::npc_knowledge_transfer::transfer_npc_knowledge
.after(super::conversation::run_npc_conversations),
super::sound::collect_sound_events
.after(super::conversation::run_npc_conversations),
// Voice enrichment (D-138) — rewrite NPC text with voiced variants.
// No-op when VoiceCacheResource is absent.
crate::voice::integration::voice_enrich_dialogue_response,
crate::voice::integration::voice_enrich_conversation_events
.after(super::conversation::run_npc_conversations),
// POI discovery reads visibility geometry (also Simulation phase)
super::poi_discovery::discover_pois,
// Follow state reads visibility geometry + movement
super::follow::update_follow_state,
// Contraband scan reads movement + NPC awareness
super::contraband::check_contraband_scan,
// Pressure reads NPC awareness + relationship graph
super::pressure::update_character_pressure,
// Triangle escalation (#250) — runs on game-minute boundaries
super::triangle::tick_triangle_escalation,
)
.in_set(TickPhase::Simulation),
);
}
}