Relevant official examples: ecs_guide.


Entities

Entities are just a simple integer ID, that identifies a particular set of component values.

To create ("spawn") new entities, use Commands.

Components

Components are the data associated with entities.

To create a new component type, simply define a Rust struct or enum, and derive the Component trait.

#[derive(Component)]
struct Health {
    hp: f32,
    extra: f32,
}

Types must be unique -- an entity can only have one component per Rust type.

Use wrapper (newtype) structs to make unique components out of simpler types:

#[derive(Component)]
struct PlayerXp(u32);

#[derive(Component)]
struct PlayerName(String);

You can use empty structs to help you identify specific entities. These are known as "marker components". Useful with query filters.

/// Add this to all menu ui entities to help identify them
#[derive(Component)]
struct MainMenuUI;

/// Marker for hostile game units
#[derive(Component)]
struct Enemy;

/// This will be used to identify the main player entity
#[derive(Component)]
struct Player;

Components can be accessed from systems, using queries.

You can add/remove components on existing entities, using Commands.

Component Bundles

Bundles are like "templates", to make it easy to create entities with a common set of components.

#[derive(Bundle)]
struct PlayerBundle {
    xp: PlayerXp,
    name: PlayerName,
    health: Health,
    _p: Player,

    // We can nest/include another bundle.
    // Add the components for a standard Bevy Sprite:
    #[bundle]
    sprite: SpriteSheetBundle,
}

Bevy also considers arbitrary tuples of components as bundles:

(ComponentA, ComponentB, ComponentC)

Note that you cannot query for a whole bundle. Bundles are just a convenience when creating the entities. Query for the individual component types that your system needs to access.