Open-Source Wikis

/

Bevy

/

Primitives

/

Schedule

bevyengine/bevy

Schedule

A Schedule is a directed graph of systems plus configuration: ordering constraints, run conditions, and system sets. Each tick, the runner picks a schedule and asks the executor to run it.

Built-in schedules

Defined in crates/bevy_app/src/main_schedule.rs:

  • First — frame counters, time updates.
  • PreUpdate — input events.
  • StateTransition — apply queued state changes.
  • RunFixedMainLoop — run the fixed-timestep loop zero or more times.
  • Update — main game systems.
  • SpawnScene — apply scene spawns.
  • PostUpdate — transform propagation, visibility, animation.
  • Last — diagnostic logs, deferred despawns.

Plus startup variants: PreStartup, Startup, PostStartup (each runs exactly once on the first tick).

The renderer adds its own schedules: ExtractSchedule, Render. They run in the render SubApp.

Adding to a schedule

app.add_systems(Update, my_system);
app.add_systems(PostUpdate, propagate_my_thing.in_set(MySet));
app.add_systems(FixedUpdate, physics);

Ordering

app.add_systems(Update, (a, b, c).chain());
app.add_systems(Update, b.after(a).before(c));

.chain() runs the systems sequentially. before/after adds an edge between specific systems or sets.

System sets

A SystemSet is a label for grouping systems:

#[derive(SystemSet, Hash, Eq, PartialEq, Clone, Debug)]
struct PhysicsSet;

app.configure_sets(Update, PhysicsSet.before(MySet::Logic));
app.add_systems(Update, integrate.in_set(PhysicsSet));

Sets are how plugins publish a stable scheduling API. Other plugins compose against the set, not against the function pointer (which is private).

Run conditions

app.add_systems(Update, gameplay.run_if(in_state(AppState::InGame)));
app.add_systems(Update, periodic.run_if(on_timer(Duration::from_secs(1))));

Conditions can be combined with .and(...) and .or(...).

Sub-schedules

Some plugins define their own schedules and run them from a parent schedule:

app.init_schedule(MyChildSchedule);
app.add_systems(Update, run_child_schedule);

fn run_child_schedule(world: &mut World) {
    world.run_schedule(MyChildSchedule);
}

bevy_state uses this for OnEnter / OnExit / OnTransition. bevy_app uses it for the fixed-timestep loop.

Executors

The default executor is multi-threaded — it dispatches systems on ComputeTaskPool whenever access patterns don't conflict. Single-threaded fallback is also available (crates/bevy_ecs/src/schedule/executor/single_threaded.rs) for Wasm without atomics or for deterministic testing.

See also

  • System — what schedules contain.
  • Architecture — schedule order in the App lifecycle.
  • bevy_ecscrates/bevy_ecs/src/schedule/.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Schedule – Bevy wiki | Factory