Why Is It Designed This Way?
Why ECS instead of a tree of game objects?
Components group data by capability rather than inheritance. A movement system
can ask for every (Velocity, &mut Transform) without knowing which concrete
game-object classes exist. This makes behavior composable and exposes the exact
data access the scheduler needs.
Why infer parallelism from parameters?
Requiring users to spawn every task would make world safety their problem.
Bevy converts Res<T>, ResMut<T>, Query<&T>, and Query<&mut T> into access
metadata. Two systems may overlap only when those sets are compatible.
Why defer structural changes?
Spawning an entity or adding a component can move archetype storage and
invalidate iteration assumptions. Commands records mutations while systems
run against a stable world, then applies them at a synchronization point.
Why retain explicit ordering?
Non-conflicting does not mean semantically independent. Schedules, sets,
before, after, and chained configurations let applications state causal
requirements that data access alone cannot infer.
Why a separate render world?
Simulation data is broad and mutable; rendering needs a prepared snapshot of a smaller set of values. Extraction creates a boundary where simulation can advance independently of later render preparation and GPU submission. Bevy can also pipeline these sub-applications.
Why several task pools?
Frame-critical compute, long-running async compute, and I/O have different latency and saturation characteristics. Separate pools prevent background loading from consuming the same scheduling budget as systems that must finish this frame.