Tainted\\Coders

Plugin organization

Bevy version: 0.19Last updated:

We should structure our game to roughly follow the rule of 1 plugin per file.

The downside of this right now is that dependencies between plugins do not have a very good way to manage their ordering.

Prefer simple functional plugins

Write your plugins in a way that has the least friction, that usually means preferring the simpler interface of a function instead of impl Plugin unless you need the lifecycle hooking functionality:

use bevy::prelude::*;

pub fn plugin(app: &mut App) {
    app.add_systems(Update, (move_player, move_enemies));
}

Keep main.rs simple

To further keep logic out of main and inside your lib (which can make testing easier) you can have a top most plugin that sets everything up.

This lets you keep your main.rs file clean:

// src/main.rs
use bevy::prelude::*;

use starter::AppPlugin;

fn main() {
  App::new().add_plugins(AppPlugin).run();
}

Now when you go to test your game, you are not recreating logic inside main you can simply load your AppPlugin inside a new App.

Keep plugins isolated

Catlin Cambell who is building Exofactory with Bevy recommends the following:

  1. Start with one crate and do everything there. No need for preemptive optimization.
  2. Be 100%, fully, completely, no-joking-around strict about plugin isolation. No plugin should import anything from any other plugin ever.
  3. All plugin imports should be from either that plugin, or non-plugin, independent structs that are independent of other plugins.

Having good plugin isolation can help speed up build times as you break up the logic of your game into smaller crates.