Local Resources

Relevant official examples: ecs_guide.


Local resources allow you to have per-system data.

Local<T> is a system parameter similar to ResMut<T>, which gives you full mutable access to an instance of some data type, that is independent from entities and components.

Res<T>/ResMut<T> refer to a single global instance of the type, shared between all systems. On the other hand, every Local<T> parameter is a separate instance, exclusively for that system.

#[derive(Default)]
struct MyState;

fn my_system1(mut local: Local<MyState>) {
    // you can do anything you want with the local here
}

fn my_system2(mut local: Local<MyState>) {
    // the local in this system is a different instance
}

The type must implement Default or FromWorld. It is automatically initialized.

A system can have multiple Locals of the same type.

Specify an initial value

Local<T> is always automatically initialized using the default value for the type.

If you need specific data, you can use a closure instead. Rust closures that take system parameters are valid Bevy systems, just like standalone functions. Using a closure allows you to "move data into the function".

This example shows how to initialize some data to configure a system, without using Local<T>:

#[derive(Default)]
struct MyConfig {
    magic: usize,
}

fn my_system(
    mut cmd: Commands,
    my_res: Res<MyStuff>,
    // note this isn't a valid system parameter
    config: &MyConfig,
) {
    // TODO: do stuff
}

fn main() {
    let config = MyConfig {
        magic: 420,
    };

    App::new()
        // create a "move closure", so we can use the `config`
        // variable that we created above
        .add_system(move |cmd: Commands, res: Res<MyStuff>| {
            // call our function from inside the closure
            my_system(cmd, res, &config);
        })
        .run();
}