Bevy Plugins
Bevy uses an architecture that lets you organize your game into encapsulated features called plugins.
A plugin is any function that takes an App and modifies it with the plugins behavior. These functions can do anything in your normal App definition, even adding other plugins.
fn plugin(app: &mut App) {
  app.add_system(some_plugin_system);
}
fn main() {
  App::new().add_plugins(plugin);
}
These plugins are useful for bundling up all the setup and runtime behavior of a feature into something we can toggle on and off. Plugins encapsulate the complexity of the feature into something we can "plug-into" our app.
By performing the necessary setup such as adding systems, resources and events to your game, each plugin is responsible for injecting its behavior into your game loop.
The Plugin trait
Usually we prefer to use simple functions, but if your plugin has additional life-cycle requirements you can implement the Plugin trait and define the life-cycle methods you are interested in.
pub struct CameraPlugin;
impl Plugin for CameraPlugin {
  fn cleanup(&self, _app: &App) -> bool {
    info!("Time to clean up")
    true
  }
  fn build(&self, app: &mut App) {
    app.add_systems(Startup, initialize_camera);
  }
}
fn initialize_camera(mut commands: Commands) {
  commands.spawn(Camera2d);
}
Plugin life-cycle
Each Plugin will go through a life-cycle of:
- We add our plugin to the Appwithadd_plugins
- Our plugin has its buildmethod called
- Bevy eventually calls readyon our plugin
- Bevy internally polls to ensure all plugins succeeded
- Finally, Bevy calls cleanupon our plugin.
Plugin ordering and dependencies
Plugins are run in the order they are added to the App.
Ideally a plugin would fully encapsulate its dependencies, but that's not always possible. Plugins that have dependencies do not currently have a good way to ensure those dependencies.
Bevy will also panic (by default) if you try and add the same plugin to your app more than once. You can work around this by checking if is_plugin_added before adding it.
fn plugin(app: &mut App) {
    if !app.is_plugin_added::<physics::PhysicsPlugin>() {
        app.add_plugins(physics::PhysicsPlugin);
    }
    if !app.is_plugin_added::<bevy::input::InputPlugin>() {
        app.add_plugins(bevy::input::InputPlugin);
    }
}
This is a good practice for testing so that the test for your plugin can run without running the entire app.
Plugin configuration
If your plugin becomes complicated enough to demand configuration you can add fields to the struct that implements Plugin.
pub struct CameraPlugin {
  debug: bool,
}
impl Plugin for CameraPlugin {
  fn build(&self, app: &mut App) {
    app.add_systems(Startup, initialize_camera);
    if self.debug {
      // Do something
    }
  }
}
fn main() {
  App::new()
    .add_plugins(CameraPlugin { debug: true })
}
Plugin groups
Having plugins call other plugins is powerful and leads to a hierarchy of plugin dependencies. This can make it hard to configure.
Collections of plugins with a complicated setup can use the  PluginGroup trait which allow us to group related plugins together and then configure them later.
This can be great choice for library authors writing plugins that others can add to their game.
pub struct GamePlugins;
impl PluginGroup for GamePlugins {
  fn build(self) -> PluginGroupBuilder {
    PluginGroupBuilder::start::<Self>()
      .add(CameraPlugin::default())
      .add(PhysicsPlugin::default())
      .add(LogicPlugin)
  }
}
This will let us (or anyone consuming your plugins) configure exactly how the set of plugins runs in the context of our app:
fn main() {
  App::new()
    .add_plugins(DefaultPlugins)
    .add_plugins(
      game::GamePlugins
        .build()
        .disable::<physics::PhysicsPlugin>()
    )
    .run();
}
The default plugins
Bevy includes DefaultPlugins in the bevy::prelude which gives us all of the obvious things our game would need:
| Plugin | Description | 
|---|---|
| DiagnosticsPlugin | Adds core diagnostics | 
| DlssInitPlugin | Initializes DLSS support if available | 
| FrameCountPlugin | Adds frame counting functionality | 
| HierarchyPlugin | Handles ParentandChildrencomponents | 
| InputPlugin | Adds keyboard and mouse input | 
| PanicHandlerPlugin | Adds sensible panic handling | 
| ScheduleRunnerPlugin | Configures an Appto run itsScheduleaccording to a givenRunMode | 
| TaskPoolPlugin | Setup of default task pools for multi-threading | 
| TimePlugin | Adds time functionality | 
| TransformPlugin | Handles Transformcomponents | 
Then depending on the features you enable (all enabled by default) you have more plugins that are added:
| Plugin | Feature | Description | 
|---|---|---|
| AccessibilityPlugin | bevy_window | Adds non-GUI accessibility functionality | 
| AnimationPlugin | bevy_animation | Adds animation support | 
| AntiAliasPlugin | bevy_anti_alias | Adds multi-sample anti-aliasing (MSAA) | 
| AssetPlugin | bevy_asset | Adds asset server and resources to load assets | 
| AudioPlugin | bevy_audio | Adds support for using sound assets | 
| DefaultPickingPlugins | bevy_picking | Adds picking functionality | 
| DevToolsPlugin | bevy_dev_tools | Enables developer tools in an App | 
| CameraPlugin | bevy_camera | Adds 2D and 3D camera components and systems | 
| CiTestingPlugin | bevy_ci_testing | Helps instrument continuous integration | 
| CorePipelinePlugin | bevy_core_pipeline | The core rendering pipeline | 
| GltfPlugin | bevy_gltf | Adds support for loading gltf models | 
| GilrsPlugin | bevy_gilrs | Adds support for gamepad inputs | 
| GizmoPlugin | bevy_gizmos | Provides an immediate mode drawing api for visual debugging | 
| HotPatchPlugin | hotpatching | Enables hot-patching of assets | 
| ImagePlugin | bevy_render | Adds the Imageasset and prepares them to render on your GPU | 
| LightPlugin | bevy_light | Adds light components and systems | 
| LogPlugin | bevy_log | Adds logging to apps | 
| MeshPlugin | bevy_mesh | Adds the Meshasset and prepares them to render on the GPU | 
| PbrPlugin | bevy_pbr | Adds physical based rendering with StandardMaterialetc | 
| PostProcessingPlugin | bevy_post_process | Adds post processing effects | 
| PipelinedRenderingPlugin | bevy_render | Adds pipelined rendering | 
| RenderPlugin | bevy_render | Sets up rendering backend powered by wgpucrate | 
| ScenePlugin | bevy_scene | Loading and saving collections of entities and components to files | 
| SpritePlugin | bevy_sprite | Handling of sprites (images on our entities) | 
| StatesPlugin | bevy_state | Adds state management for Apps | 
| TerminalCtrlCHandlerPlugin | std | Handles Ctrl-C signals in terminal applications | 
| TextPlugin | bevy_text | Supports loading fonts and rendering text | 
| UiPlugin | bevy_ui | Adds support for UI layouts (flex, grid, etc) | 
| UiRenderPlugin | bevy_ui_render | Adds support for sending UI nodes to renderer | 
| WindowPlugin | bevy_window | Provides an interface to create and manage Windowcomponents | 
| WinitPlugin | bevy_winit | Interface to create operating system windows (to actually display our game) |