Component collections
In one line: a per-entity variable-length list on a component — the one controlled exception to Typhon's fixed-size, blittable component rule.
Components are fixed-size blittable structs stored column-major, so there's no room for a list of unknown length — a path's waypoints, an inventory, a parent's children. A ComponentCollection<T> field adds exactly that. On the struct it's just 4 bytes (a buffer id); the elements live in a separate pool shared by every ComponentCollection<T> field of that element type T across all archetypes. T must be unmanaged — the same blittability constraint as any component field. Two flavors: owned value data (ComponentCollection<Waypoint>) and entity-reference lists (ComponentCollection<EntityLink<TArch>>, the collection-on-parent side of a 1:N relationship).
A stored component's collection changes through its entity handle's accessor, EntityRefMut.CreateComponentCollectionAccessor — Add, Replace (the whole content), Clear — and never through Set, which keeps the stored collection. Transaction.CreateComponentCollectionAccessor builds the collection of a value not stored yet, or reads one (ElementCount, GetAllElements); iterate read-only through Transaction.GetReadOnlyCollectionEnumerator. There is no per-element remove (read, filter, Replace), and no index over contents. Storage follows the component's mode: SingleVersion owns its buffer in place; Versioned shares by reference count and clones copy-on-write on first mutation, so an older MVCC snapshot keeps seeing what it read. Transient is rejected at startup — its buffer would outlive the data meant to reference it.
Collection content is WAL-logged at commit and recovers the same way as any other component field (per the UoW's DurabilityMode). A recovered buffer gets a fresh buffer id — the elements, not the physical handle, are what recovery preserves.
How it relates
- Component — the field lives on a component; this is what a component can hold beyond fixed-size fields.
- EntityLink — a
ComponentCollection<EntityLink<T>>is the 1:N parent-side list. - Storage mode —
SingleVersionin-place,Versionedcopy-on-write,Transientunsupported. - Cluster storage — the 4-byte field lives in the cluster slot like any other; the element pool sits beside it.
In the API
ComponentCollection<T>— the 4-byte field (T : unmanaged).EntityRefMut.CreateComponentCollectionAccessor(comp, ref copy, ref copy.Field)— change a stored component's collection —Add/Replace/Clear, each stored as it happens, noSetneeded;Transaction.CreateComponentCollectionAccessor(ref field)— build a new value's collection, or read one:Add/ElementCount/GetAllElements;Transaction.GetReadOnlyCollectionEnumerator(ref field)— allocation-freeforeach.
Learn & use
- Feature detail: Component collections
- Narrative: Guide ch.2 — modeling