Open-Source Wikis

/

Bevy

/

Primitives

/

System

bevyengine/bevy

System

A system is a function that reads and writes a World. Anything implementing IntoSystem can be added to an App. Systems are how every Bevy crate ships behavior; the rest of the engine is just plumbing to schedule and dispatch them.

A system is a function

fn move_things(time: Res<Time>, mut q: Query<(&mut Transform, &Velocity)>) {
    for (mut t, v) in &mut q {
        t.translation += v.0 * time.delta_secs();
    }
}

The function's parameters are typed. Each parameter implements SystemParam; together they declare what the system reads and writes.

Adding a system

app.add_systems(Update, move_things);
app.add_systems(Update, (move_things, check_health).chain());
app.add_systems(Update, my_system.run_if(in_state(GameState::Playing)));

Systems can be chained (run sequentially), grouped into SystemSets, gated by run conditions, and ordered with before / after constraints.

Common parameters

Parameter What it does
Res<T> / ResMut<T> Read / mutate a resource.
Query<Q, F> Iterate entities matching component signature.
Commands Deferred world mutation (spawn/despawn/insert/remove).
EventReader<E> / EventWriter<E> Read / write events.
Local<T> Per-system state.
&World / &mut World Exclusive world access (system runs alone).
NonSendMut<T> Non-Send resource (main thread only).

The full list lives in crates/bevy_ecs/src/system/system_param.rs.

Parallelism

The schedule executor runs systems in parallel when their access patterns don't conflict. Two Query<&mut Health> systems cannot run simultaneously (write/write conflict on Health). One Query<&Health> and one Query<&mut Velocity> can.

This is the central reason for Bevy's archetypal ECS: the conflict graph is computable from parameter types alone. See bevy_ecs for the executor implementation.

Exclusive systems

A system that takes &mut World is exclusive — the executor runs it alone, no other systems concurrent. Use sparingly; prefer Commands for deferred mutations.

fn rare_world_surgery(world: &mut World) {
    // do some structural change that can't be expressed with Commands
}

Run conditions

app.add_systems(Update, gameplay.run_if(in_state(AppState::InGame).and(every_frame)));

A run condition is a system that returns bool. The bevy_ecs::schedule::common_conditions module has the built-in ones: in_state, state_changed, resource_exists, resource_changed, on_event, on_timer, every_frame.

One-shot systems

Need to run a system once on demand instead of every frame? Register it and run it from Commands:

let id = world.register_system(my_system);
commands.run_system(id);

See also

  • Schedule — graph of systems.
  • Query — the most-used system parameter.
  • Observer — reactive systems run by events.
  • bevy_ecs — implementation.

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

System – Bevy wiki | Factory