Table of Contents

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).

The API is append-and-bulk-read: mutate through Transaction.CreateComponentCollectionAccessor (Add, ElementCount, GetAllElements); iterate read-only through Transaction.GetReadOnlyCollectionEnumerator. There is no per-element remove/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.

⚠️ Durability is checkpoint-bounded, not commit-bounded. Collection content reaches disk at the next checkpoint, not via WAL redo — a crash between a collection write and that checkpoint recovers the buffer id but not the new elements. This is a known, separately-tracked gap; don't treat collection writes as commit-durable.

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 modeSingleVersion in-place, Versioned copy-on-write, Transient unsupported.
  • Cluster storage — the 4-byte field lives in the cluster slot like any other; the element pool sits beside it.

In the API

Learn & use