Data-Oriented Design sounds abstract until you ask: what does it look like when you actually build something with it?
The answer is ECS — Entity Component System. And in Rust, it's not a curiosity. It's how the best game engines work.
What's Actually Happening
Traditional OOP gives you objects that hold both data and behavior:
struct Player {
position: Vec3,
velocity: Vec3,
health: i32,
inventory: Vec<Item>,
fn update(&mut self) { /* ... */ }
fn take_damage(&mut self, amount: i32) { /* ... */ }
}
The problem: each Player is a blob of memory scattered across the heap. To update positions, you need to jump between all those objects. Cache misses everywhere.
ECS flips this. You don't modify objects — you operate on raw data:
// Components: pure data, no methods
#[derive(Component)]
struct Position(Vec3);
#[derive(Component)]
struct Velocity(Vec3);
#[derive(Component)]
struct Health(i32);
// Systems: pure behavior, no state
fn movement_system(mut positions: Query<(&Velocity, &mut Position)>) {
for (velocity, mut position) in &mut positions {
position.0 += velocity.0;
}
}
Each component lives in its own contiguous array. Position components with Position components. Velocity with Velocity. When the CPU fetches one, it prefetches the next.
Why Bevy Matters
Bevy isn't the only ECS in Rust, but it's the one that takes DOD seriously:
- Archetypes: Components are grouped by their type signature. All entities with Position+Velocity+Health live together in memory.
- Change detection: Bevy tracks which components changed, so systems only process what moved.
- Parallel scheduling: Systems declare dependencies, and Bevy runs independent ones in parallel.
The result? A 10,000-entity simulation where you're not fighting the borrow checker or cache.
The Real Benefit
Here's what nobody says about ECS: it's not about entities. It's about composition without inheritance.
Want a flying enemy? Add Velocity, Position, Health, FlyAI. No subclassing. Just adding data.
Want to make everything damageable? Add Health to anything. The system doesn't care what owns the health.
This is DOD in practice: organize data so the machine runs fast, then compose behavior by combining components. The systems are simple. The data layout is optimized. Everything else falls out naturally.
When ECS Is Too Much
Honest take: for a Pong clone, ECS is overkill. A single Ball struct is fine.
But when you have:
- 1,000 bullets needing collision checks
- 500 enemies with different AI behaviors
- A spawning system that creates 100 entities per second
— that's when ECS stops being abstract and starts being the only way to keep your frame rate above 30.
The Thread Continues
DOD gave us cache awareness. SIMD gave us parallel data processing. ECS is the pattern that brings both to actual game development.
Bevy is the Rust implementation that's betting hard on this future. Whether you're building a game or just want to understand why Rust excels at performance-critical code, ECS is worth understanding — not because it's trendy, but because it's what happens when you design for the machine you're actually running on.
Next in the thread: building something with Bevy to see ECS in action.