System Ordering
The scheduler already separates two systems that read and write the same component. Sometimes you need more than that: a SpawnSystem might need to run before anything that reacts to newly spawned entities, even if the two never touch the same data. That’s what explicit ordering is for.
RunBefore and RunAfter
Section titled “RunBefore and RunAfter”[RunAfter(typeof(SpawnSystem))]public sealed partial class ReactToSpawnsSystem : QuerySystem{ protected override IQuery DefineQuery(Query query) => query.With<Spawned>();
public void Update(Time time, in Spawned spawned) { /* ... */ }}[RunBefore(typeof(X))]/[RunAfter(typeof(X))] declare that this system must run in a strictly earlier or later stage than X. Stack as many as you need, one attribute per target.
Ordering against a whole phase
Section titled “Ordering against a whole phase”Naming every system in a phase to order against it doesn’t scale. Define a marker instead, and order against that:
public sealed class InputProcessed : MarkerSystem { }
[RunBefore(typeof(InputProcessed))]public sealed partial class PlayerMoveInputSystem : QuerySystem { /* ... */ }
[RunBefore(typeof(InputProcessed))]public sealed partial class PlayerActionInputSystem : QuerySystem { /* ... */ }
[RunAfter(typeof(InputProcessed))]public sealed partial class AIDecisionSystem : QuerySystem { /* ... */ }AIDecisionSystem now runs after every input system, whatever they turn out to be. Add a third input system later and it’s covered automatically, nothing about AIDecisionSystem changes.
Ordering a system added at runtime
Section titled “Ordering a system added at runtime”AddSystem<T>() returns a chainable registration, for systems added outside the attribute-based path:
world.AddSystem<LateJoinerSystem>().After<InputProcessed>();Ordering controls sequence. For controlling how often a system runs at all, see Timestep, Pause & Timescale.