DOTS//CORE local · not synced

m01 · Entities Core · drill · 45 min

Design the archetype for a system you haven't been given

Why this is a drill and not a lab

The density lab handed you archetypes and asked you to measure them. That proves the chunk arithmetic behaves as claimed. It does not test the thing this module is actually for, which is making the layout decision in the first place, when nobody has told you what the components are.

That decision is where DOTS performance is won or lost, and it happens before a single line of system code exists. So here you get requirements, not components — and the requirements deliberately conflict, because real ones do.

The requirements

You are laying out entities for a crowd simulation. All of the following must be representable:

  1. Position and velocity, read and written every frame by the movement system. This is the hot loop.
  2. A faction — one of four values. Entities of different factions never interact and are always processed separately.
  3. Health, read every frame by nothing, written occasionally on damage, and read by a death-check system that runs every frame.
  4. A stunned flag, which turns on and off several times per second during combat. Stunned entities skip movement.
  5. A display name, a string, needed only when a player inspects an entity — perhaps once a minute, for one entity.
  6. Pathfinding data: a 2 KB navigation grid, identical for every entity of the same faction.
  7. A current target, an entity reference, updated by AI roughly once per second and read by combat.

Ten thousand entities. The movement system must run at maximum possible chunk density.

The conflicts, named

Read those requirements again and notice they do not all want the same thing.

  • (5) and (6) are large and cold. Module 1 says cold data in a hot archetype taxes every chunk. But both are genuinely per-entity properties by the authoring model’s logic.
  • (2) partitions entities into groups. That smells like one mechanism. But (4) also sounds like a flag, and it wants a completely different one, because it changes constantly and (2) never does.
  • (3) is read every frame by the death check but not by movement. Same entity, two loops, different appetites.
  • (7) is small but changes at a rate between (2) and (4).

Each requirement maps to a different mechanism, and the mapping is determined by access frequency and cardinality, not by what the property “is” conceptually. That sentence is the drill.

| Constraint | The shortcut it closes | |---|---| | Hot loop stated first, in writing | Designing data and back-filling a justification | | Every component justified by a reader | Components that exist because the concept exists | | No deleting requirements | Winning on density by refusing to solve the problem | | >64 bytes needs explicit costing | Sneaking a payload in without pricing it | | ≥1 non-plain mechanism, justified on cost | Making everything an IComponentData and calling it done |

How to work it

Milestones, not steps.

  1. Write the hot loop sentence. One line. Everything follows.
  2. Classify all seven requirements by read frequency and cardinality before choosing any mechanism. A table is the right form.
  3. Assign a mechanism to each, and write the rejection reason for the other three. That rejection reasoning is most of the deliverable.
  4. Compute bytes per entity by hand for the hot archetype, and predict chunk capacity from the 16 KB budget.
  5. Verify with a probe. Reuse the density lab’s SystemBase one-shot host — create your archetype, log ChunkCapacity, compare to your prediction.
  6. Check the cold path still works. A layout that makes the hot loop perfect and inspection impossible has moved the problem, not solved it.

When you are done

Answer without checking your work:

  • What is your hot archetype’s bytes-per-entity, and what chunk capacity did that predict? How close was the measurement, and what does the gap tell you about the header?
  • For requirement (2), which mechanism did you choose and what specifically would have gone wrong with each of the other three?
  • For requirement (4), why is the answer different from (2), given both are “a property with few values”?
  • Which requirement did you find hardest to place, and what does that difficulty tell you about the requirement itself?
  • If a designer now says stunned entities need a stun duration rather than a flag, what changes, and does your mechanism choice survive it?

That last one is the real test. A layout that is optimal for exactly the requirements as stated and collapses on the first change is a layout you got lucky with.

If you conclude that two of the requirements genuinely belong on separate entities, that is a strong outcome — provided you priced the correlation cost rather than assuming it away.

m01.l08