Choose Records, Composition, or ECS for C++ Projects¶
Finishing this course does not mean adopting ECS. Choose the least costly representation satisfying actual ownership, processing, and change requirements.
Revisit the Evidence¶
We added acceleration before refactoring, preserved behaviour, compared capability combinations, separated identity from location, defined visibility, reproduced a bug, and tested recovery.
None establishes a performance winner. Measure later if an actual workload has speed or memory requirements.
Decision Guide¶
| Situation | Starting point | Cost to check |
|---|---|---|
| Small fixed capabilities and local updates | Records/functions | Flags remain understandable |
| Optional owned behaviours stay together | Composition | Nested relationships stay clear |
| Small family of substitutable algorithms | Inheritance | Base contract and construction |
| Operations naturally process capability subsets | ECS | Cross-store invariants and entity traces |
| ECS requirements exceed teaching code | Evaluate a library | Semantics, dependencies, migration |
Selection alone suggests IDs, not ECS. Deferred edits suggest timing boundaries, not generations. Runtime capability replacement is not demonstrated here.
Three Concrete Decisions¶
Small particle exercise: fixed flags, direct updates, no external references. Keep records if the loop stays readable.
Selected simulation body: selection must survive unrelated deletion. Add owner-scoped IDs to records and stop if stores solve nothing else.
Capability-oriented tooling: many operations need subsets and clearly identified writers. Separate stores may help; budget for lifecycle consistency and trace tooling.
These are design judgements, not measured rankings.
Teaching Implementation vs Library¶
Our code exposes policies; it is not a production engine. It lacks generic queries, mature tooling, parallel scheduling, and integration facilities.
EnTT's entity/component documentation describes registry facilities. Flecs' systems documentation describes its systems and execution model. Treat these as evaluation starting points, not drop-in replacements.
Before migration, verify:
- Handle lifetime and cross-world ownership.
- Visibility of creation and deletion.
- Iteration and observation order.
- Component reference invalidation.
- Tracing one entity's writers.
- Failure behaviour callers rely on.
Use the chosen version's documentation for API details. This course neither installs nor benchmarks those libraries.
Extensions Only When Required¶
For reusable slots, study generations. For a concrete storage concern, study component storage.
Neither is a prerequisite to the decision, nor proof that records were inadequate.
Final Exercise¶
Write a decision record: requirements, chosen representation, rejected alternatives, invariants, debugging path, and conditions for revisiting it.
A defensible “keep the direct loop” is as valid as a defensible ECS adoption.