bevy-ecs-expert
Original:🇺🇸 English
Translated
Master Bevy's Entity Component System (ECS) in Rust, covering Systems, Queries, Resources, and parallel scheduling.
3installs
Added on
NPX Install
npx skill4agent add sickn33/antigravity-awesome-skills bevy-ecs-expertTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Bevy ECS Expert
Overview
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.
When to Use This Skill
- Use when developing games with the Bevy engine in Rust.
- Use when designing game systems that need to run in parallel.
- Use when optimizing game performance by minimizing cache misses.
- Use when refactoring object-oriented logic into data-oriented ECS patterns.
Step-by-Step Guide
1. Defining Components
Use simple structs for data. Derive and .
ComponentReflectrust
#[derive(Component, Reflect, Default)]
#[reflect(Component)]
struct Velocity {
x: f32,
y: f32,
}
#[derive(Component)]
struct Player;2. Writing Systems
Systems are regular Rust functions that query components.
rust
fn 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();
}
}3. Managing Resources
Use for global data (score, game state).
Resourcerust
#[derive(Resource)]
struct GameState {
score: u32,
}
fn score_system(mut game_state: ResMut<GameState>) {
game_state.score += 10;
}4. Scheduling Systems
Add systems to the builder, defining execution order if needed.
Apprust
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.init_resource::<GameState>()
.add_systems(Update, (movement_system, score_system).chain())
.run();
}Examples
Example 1: Spawning Entities with Require Component
rust
use 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")),
));
}Example 2: Query Filters
Use and to filter entities efficiently.
WithWithoutrust
fn enemy_behavior(
query: Query<&Transform, (With<Enemy>, Without<Dead>)>,
) {
for transform in &query {
// Only active enemies processed here
}
}Best Practices
- ✅ Do: Use filters (
Query,With,Without) to reduce iteration count.Changed - ✅ Do: Prefer over
Reswhen read-only access is sufficient to allow parallel execution.ResMut - ✅ Do: Use to spawn complex entities atomically.
Bundle - ❌ Don't: Store heavy logic inside Components; keep them as pure data.
- ❌ Don't: Use or interior mutability inside components; let the ECS handle borrowing.
RefCell
Troubleshooting
Problem: System panic with "Conflict" error.
Solution: You are likely trying to access the same component mutably in two systems running in parallel. Use to order them or split the logic.
.chain()