Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Master Bevy's Entity Component System (ECS) in Rust, covering Systems, Queries, Resources, and parallel scheduling.
.claude/skills/bevy-ecs-expert/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-16 | ✗→✓ | ▲ Improved | — | — |
| case-11 | ✓→✓ | = Same ✓ | — | — |
| case-06 | ✗→✗ | = Same ✗ | — | — |
| case-21 | ✗→✗ | = Same ✗ | — | — |
| case-01 | ✗→✗ | = Same ✗ | — | — |
A guide to building high-performance game logic using Bevy's data-oriented ECS architecture. Learn how to structure systems, optimize queries, manage resources, and leverage parallel execution.
Use simple structs for data. Derive Component and Reflect.
rust#[derive(Component, Reflect, Default)] #[reflect(Component)] struct Velocity { x: f32, y: f32, } #[derive(Component)] struct Player;
Systems are regular Rust functions that query components.
rustfn movement_system( time: Res<Time>, mut query: Query<(&mut Transform, &Velocity), With<Player>>, ) { for (mut transform, velocity) in &mut query { transform.translation.x += velocity.x * time.delta_seconds(); transform.translation.y += velocity.y * time.delta_seconds(); } }
Use Resource for global data (score, game state).
rust#[derive(Resource)] struct GameState { score: u32, } fn score_system(mut game_state: ResMut<GameState>) { game_state.score += 10; }
Add systems to the App builder, defining execution order if needed.
rustfn main() { App::new() .add_plugins(DefaultPlugins) .init_resource::<GameState>() .add_systems(Update, (movement_system, score_system).chain()) .run(); }
rustuse bevy::prelude::*; #[derive(Component, Reflect, Default)] #[require(Velocity, Sprite)] struct Player; #[derive(Component, Default)] struct Velocity { x: f32, y: f32, } fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { commands.spawn(( Player, Velocity { x: 10.0, y: 0.0 }, Sprite::from_image(asset_server.load("player.png")), )); }
Use With and Without to filter entities efficiently.
rustfn enemy_behavior( query: Query<&Transform, (With<Enemy>, Without<Dead>)>, ) { for transform in &query { // Only active enemies processed here } }
Query filters (With, Without, Changed) to reduce iteration count.Res over ResMut when read-only access is sufficient to allow parallel execution.Bundle to spawn complex entities atomically.RefCell or interior mutability inside components; let the ECS handle borrowing.Problem: System panic with "Conflict" error. Solution: You are likely trying to access the same component mutably in two systems running in parallel. Use .chain() to order them or split the logic.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.