AgentStack
SKILL verified MIT Self-run

Bevy Ecs Components

skill-chrisgliddon-bevy-skills-bevy-ecs-components · by chrisgliddon

Use when defining `#[derive(Component)]`, declaring required components with `#[require(...)]`, writing observers with `On<E>` (NOT `Trigger<E>` — renamed in 0.17), choosing between Table and SparseSet storage, or registering `on_add`/`on_remove` hooks in Bevy 0.18.

No reviews yet
0 installs
13 views
0.0% view→install

Install

$ agentstack add skill-chrisgliddon-bevy-skills-bevy-ecs-components

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Bevy Ecs Components? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Bevy 0.18 — ECS Components

When to use this skill

  • Defining a new Component for game state.
  • Bundling components via #[require(...)] (the modern replacement for "bundles").
  • Reacting to component lifecycle: spawning, despawning, inserting, removing.
  • Observers — reacting to entity-targeted events with On.
  • Choosing storage: Table (default, fast iteration) vs SparseSet (fast add/remove).

Canonical pattern

use bevy::prelude::*;

// 1. Plain components.
#[derive(Component, Default)]
struct Health(f32);

#[derive(Component)]
struct Velocity(Vec3);

// 2. Required components — spawning `Player` auto-spawns the rest.
//    `#[require]` calls each form: `Type` (Default), `Type::ctor(...)`, or
//    `Type = expression`.
#[derive(Component)]
#[require(Health = Health(100.0), Velocity = Velocity(Vec3::ZERO), Transform)]
struct Player;

// 3. Sparse storage for components added/removed every frame (e.g. tags
//    flipped by gameplay). Default Table storage is faster to iterate.
#[derive(Component)]
#[component(storage = "SparseSet")]
struct Stunned;

// 4. An entity-targeted event reacted to by observers.
#[derive(EntityEvent)]
struct Damage {
    entity: Entity, // EntityEvent requires an `entity` field.
    amount: f32,
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, spawn_player)
        .add_systems(Update, deal_damage)
        .add_observer(on_damage)
        .run();
}

fn spawn_player(mut commands: Commands) {
    commands.spawn(Player);
}

fn deal_damage(mut commands: Commands, query: Query>) {
    for entity in &query {
        commands.trigger(Damage { entity, amount: 10.0 });
    }
}

// Observer parameter is `On`, not `Trigger` (renamed in 0.17, PR #19596).
fn on_damage(damage: On, mut query: Query) {
    let event = damage.event();
    if let Ok(mut hp) = query.get_mut(event.entity) {
        hp.0 -= event.amount;
    }
}

Gotchas (0.18)

  • Trigger is gone. Observer params are On in 0.17+. Methods: event(), event_mut(), observer(), original_event_target(), propagate(bool).
  • EntityEvent::set_target requires use bevy::ecs::entity::SetEntityEventTarget; — not in the prelude.
  • Storage choice is irrevocable: it's compiled into the component. SparseSet adds/removes faster but iterates 2–5× slower. Use Table (default) unless profiling proves SparseSet wins.
  • #[require(T)] runs T::default(). If T: !Default, use #[require(T = expression)] or #[require(T = T::new(...))].
  • Required components are non-recursive at the spec layer but the spawning machinery does insert transitive requires. If you change a required-component graph, run a full scene reload to catch missing inserts.
  • Hooks (on_add, on_insert, on_replace, on_remove) are sharp tools — they run inside World mutations, can't take arbitrary SystemParams, and can't despawn the entity they fire on. Use observers when you need flexibility.
  • Bundle derive still exists but most use-cases are better served by #[require(...)] on a "marker" component, which keeps the spawn surface ergonomic.

See also

  • bevy-ecs-queries — reading components back out.
  • bevy-ecs-systems — observers are themselves systems.
  • bevy-migration-0-17-to-0-18 — full TriggerOn and event→message rename map.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.