C++ Design Boundaries: From Big OOPs to ECS¶
Before choosing ECS, decide which operations need which data and who owns it. This chapter turns a question about encapsulation into a small, testable design exercise rather than a rule that inheritance must always be replaced.
What Big OOPs Contributes¶
Casey Muratori's talk questions compile-time hierarchies that copy a domain's classification and place encapsulation around those objects. It contrasts that choice with organising access around systems. Importantly, the speaker does not claim that ECS is universally a good design.
Our source is the supplied edited transcript of The Big OOPs, especially “Encapsulation boundaries” and “Credit where due.” Treat historical statements there as the speaker's account, not independently verified facts. This course uses the question, not the talk's historical narrative, as its technical foundation.
Our interpretation: choose a boundary by examining the work the program must perform. That is a design proposal to evaluate, not a quotation or a performance result.
C++ Design Boundaries: Three Different Questions¶
Keep these questions separate:
| Question | Example in our simulation |
|---|---|
| Domain meaning | Is this body a projectile or decoration? |
| Data ownership | Which world owns its position and remaining lifetime? |
| Processing access | Which pass may read velocity or update position? |
A projectile can be both moving and visible, but a decoration can be stationary and visible. A moving invisible body is also valid. Domain labels do not automatically tell us how these properties should be stored or processed.
Here are two possible access paths, not two performance measurements:
Either approach still needs an ownership policy. Broad data access does not mean every function should be allowed to mutate every value.
Write the Requirements Before the Classes¶
We will use one small headless 2D simulation:
- A body has a position.
- Movement, visibility, and lifetime are independent properties.
- A step moves live moving bodies, then expires bodies whose lifetime runs out.
- Rendering returns positions of visible surviving bodies.
- Invalid time steps are rejected without modifying the world.
This deliberately leaves out a graphics engine, collision solver, networking, and multithreading. Each would introduce additional requirements; none is needed to compare the initial designs.
The first release uses an ordered snapshot as its observation boundary. It does not expose pointers into the world's storage. Stable Entity IDs and cross-body references are future work.
Define What You Will Compare¶
For each candidate, ask:
- Where do I edit the code to add an independent capability?
- Which object or container owns the data?
- Which invalid states are representable?
- What references become invalid during deletion or reallocation?
- Can the same behavioural tests run against the implementation?
- What must I measure before making a performance claim?
The first three chapters establish behaviour and modification points. They do not rank designs by speed.
Where OOP and Design Patterns Still Fit¶
A virtual interface may be appropriate for interchangeable implementations of a service. That does not require making every simulated body's domain label a subclass. Likewise, a plain struct can be wrapped in a class that protects its invariants without creating a deep hierarchy.
Review Strategy for interchangeable algorithms and State for behaviour driven by state. Those are options to evaluate, not mandatory steps on the way to ECS.
ECS is also not the only alternative to inheritance: values, flags, composition, and explicit functions are useful intermediate choices. We will implement those choices before introducing separate component stores.
Exercise: Draw Access, Not Just Types¶
For movement, lifetime, and rendering, write down the data each operation reads and writes. Then add “a body that moves but is not visible.”
If your diagram requires a new subclass, explain why. If it only requires a different data configuration, explain where that configuration is validated. Neither answer is automatically wrong; your justification matters.
Next: Build the plain simulation. Return to the course overview.