m01 · Entities Core · reading · 9 min
Archetypes — identity is a set of types
An entity is not an object
An Entity is a number — an index and a version, 8 bytes, and nothing
else. It holds no data, no methods, no vtable. Everything you’d think of
as “the entity’s state” lives elsewhere, in its components, and the
entity value is only a handle the runtime uses to find them. This is
the first thing to unlearn from object-oriented practice: the entity is
not where the entity is. It’s a key.
What, then, decides where a given entity’s data physically sits? Its
archetype — the exact set of component types it currently has. Two
entities with {LocalTransform, Health} share an archetype. Add
Velocity to one and it no longer does: it now has a different set, so
it belongs to a different archetype, and — this is the load-bearing
part — it is stored in a different place. Identity in ECS is set
membership, and set membership is an address.
Why the set is the layout
Recall the
If entities were grouped by just one component, a loop reading two
components would have no guarantee the second one sat contiguously
alongside the first. By grouping on the entire set, the runtime can
promise that for any combination of components an archetype has,
each of those component arrays is dense and parallel. A system asking
for {LocalTransform, Velocity} gets two tight arrays that advance in
lockstep — one cache-friendly stream per component.
That full line is the entire payoff. The archetype is not an organizational nicety the API happens to expose; it is the reason the access pattern from the previous module is achievable at all. You could have derived that some such grouping must exist. Unity calls it the archetype.
Structural change: the move you keep paying for
Here is the cost the design hands you in exchange. If identity is set
membership, and set membership dictates physical location, then
changing an entity’s set of components physically relocates its
data. Adding Velocity doesn’t append a field — there is no object to
append to. It means: find the archetype for the new, larger set (create
it if this is the first entity to ever have that exact set), allocate
room there, copy every existing component’s bytes for this entity
from the old location to the new, and free the old slot. Removing a
component is the same move in reverse.
This is a
The trade you’re being offered
Sit with the shape of this trade, because it dictates most of what follows. The layout that makes iteration nearly free makes mutation of shape expensive. So the entire craft of DOTS bends toward: decide an entity’s component set as rarely as possible, and when behaviour must vary, find a way to express it without changing the set. That single pressure is the seed of enableable components, of tag-vs-data decisions, of shared components, and of the command-buffer pattern — all of which are downstream of the fact that identity is a set and a set is an address.
What this buys you
You now have the vocabulary the rest of the module measures against: an entity is a handle, an archetype is a component set that doubles as a storage location, and a structural change is the physical move between archetypes. The next lesson opens up the archetype’s storage and shows the fixed-size block it’s actually made of — and why that block is 16 KB rather than any other number.