--- name: bevy-ecs description: > Structure a Bevy app around its Entity Component System: build the App with plugins, define Component/Resource types, write systems with Query/Res/Commands, filter and order systems, and use the Time resource for frame-rate-independent motion. Use when building or debugging a Bevy game in Rust — when the user mentions Bevy, ECS, App::new, add_systems, Query, Commands, components/systems, or a Cargo.toml depending on bevy. --- # Bevy ECS Structure a Bevy game in Rust around the Entity Component System: the `App` and plugins, components and resources, systems with queries, scheduling, and frame-rate-independent updates. New examples target **Bevy 0.19**. If the project already pins another release, keep that release and use its matching migration guide. ## When to use - Use when wiring a Bevy `App`, defining `Component`/`Resource` types, writing systems that query entities, ordering/filtering systems, or fixing borrow-conflict panics and frame-dependent movement. - Use when `Cargo.toml` depends on `bevy` and code calls `App::new()`, `add_systems`, `Query`, or `Commands`. **When *not* to use:** this is the ECS core. Deep rendering, custom shaders/ pipelines, UI layout, and audio are separate concerns. For engine-agnostic AI or procedural algorithms, pair with `game-ai` / `procedural-gen`. ## Core workflow 1. **Detect and pin the version.** Read `Cargo.toml` and `Cargo.lock` first. For a new project use `bevy = "0.19"`; never silently migrate an existing project across a Bevy minor release. Treat the matching docs and migration guides as truth. 2. **Build the `App`.** `App::new().add_plugins(DefaultPlugins)` gives windowing, input, rendering, time, etc. Register systems into schedules: `Startup` (once) and `Update` (every frame). 3. **Model data as components, globals as resources.** `#[derive(Component)]` for per-entity data; `#[derive(Resource)]` for one-of-a-kind data (score, settings, the `Time` clock). In 0.19 `Resource` extends `Component`, so do not derive both. 4. **Write systems as plain functions.** Parameters declare data access: `Query<...>` for entities, `Res`/`ResMut` for resources, `Commands` for deferred spawn/despawn. Systems run in parallel when their accesses don't conflict. 5. **Drive motion by `time.delta_secs()`** so speed is frame-rate independent. 6. **Order only what must be ordered** with `.chain()` or explicit constraints; gate systems with `run_if`. Group related setup into `Plugin`s. Build with `cargo run` and read the panics — Bevy reports conflicting queries at startup. ## Patterns ### 1. Cargo.toml + minimal App ```toml # Cargo.toml — pin the version; the API differs across minor releases. [dependencies] bevy = "0.19" ``` ```rust // main.rs use bevy::prelude::*; fn main() { App::new() .add_plugins(DefaultPlugins) // window, input, render, time, ... .add_systems(Startup, setup) // runs once at startup .add_systems(Update, move_players) // runs every frame .run(); } ``` ### 2. Components, resources, and spawning ```rust #[derive(Component)] struct Player; #[derive(Component)] struct Velocity(Vec2); #[derive(Resource)] struct Score(u32); fn setup(mut commands: Commands) { commands.insert_resource(Score(0)); // Camera2d is a component with required components (bundles removed in 0.16); // spawning it pulls in Transform, Camera, etc. automatically. commands.spawn(Camera2d); // Spawn an entity as a tuple of components. commands.spawn(( Player, Velocity(Vec2::new(150.0, 0.0)), Transform::from_xyz(0.0, 0.0, 0.0), )); } ``` ### 3. A system with a query + the Time resource ```rust // Iterate every entity that has BOTH Velocity and Transform; mutate Transform. fn move_players(time: Res