//! Server tick cycle — named system set phases (#843). //! //! Replaces ad-hoc `.after()`/`.before()` constraints with a linear pipeline. //! Each system belongs to exactly one phase. Phases execute sequentially. //! Within a phase, systems with no intra-phase ordering run in parallel //! (when the multi-threaded executor is enabled). //! //! ```text //! PreInput → Input → Movement → Simulation → Economy //! → Storyteller → Snapshot → PostSnapshot → Knowledge → TickAdvance //! ``` //! //! ## Rules //! //! 1. Every system in the Update schedule MUST have `.in_set(TickPhase::X)`. //! 2. Cross-phase `.after()`/`.before()` is FORBIDDEN — if you need it, //! the system is in the wrong phase. //! 3. Intra-phase `.after()`/`.before()` is allowed for systems within //! the same phase that have a real data dependency. use bevy_app::prelude::*; use bevy_ecs::prelude::*; use bevy_ecs::schedule::IntoScheduleConfigs; /// The 10 phases of the server tick cycle. /// /// Ordered linearly: each phase completes before the next begins. /// Configure once in the App with `configure_sets(Update, ...)`. #[derive(SystemSet, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum TickPhase { /// Setup before player input: chunk streaming, bridge input, NPC routine transitions. PreInput, /// Process player actions: input dispatch, door/terminal/examine interactions, dialogue. Input, /// Position resolution: pathfinding, path following, movement validation, spatial indexing. Movement, /// Game logic: NPC behavior, vision, conversations, monologue, sound, visibility geometry. Simulation, /// Economics: tick the economy simulation, serve economy state queries. Economy, /// Storyteller: contamination, activation, tell escalation, tell state derivation. Storyteller, /// Assemble tick output: observer snapshot, ticker, settings, debug commands, save/load. Snapshot, /// React to snapshot: observation events, send to client, anomaly detection. PostSnapshot, /// Update persistent state: knowledge events, cognitive delay, relationships. Knowledge, /// Increment the clock. Must be last. TickAdvance, } impl TickPhase { /// Configure the linear phase ordering on the app. /// /// Call once during plugin setup: /// ```ignore /// TickPhase::configure(&mut app); /// ``` pub fn configure(app: &mut bevy_app::App) { use TickPhase::*; app.configure_sets( Update, ( PreInput, Input, Movement, Simulation, Economy, Storyteller, Snapshot, PostSnapshot, Knowledge, TickAdvance, ) .chain(), ); } }