@vworlds/vecs 1.0.43 → 1.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +2 -2
  2. package/dist/component.d.ts +27 -17
  3. package/dist/component.js +9 -0
  4. package/dist/component.js.map +1 -1
  5. package/dist/component_meta.d.ts +40 -13
  6. package/dist/component_meta.js +22 -6
  7. package/dist/component_meta.js.map +1 -1
  8. package/dist/entity/entity.components.d.ts +57 -4
  9. package/dist/entity/entity.components.js +121 -22
  10. package/dist/entity/entity.components.js.map +1 -1
  11. package/dist/entity/entity.d.ts +4 -2
  12. package/dist/entity/entity.js +4 -2
  13. package/dist/entity/entity.js.map +1 -1
  14. package/dist/entity/entity.lifecycle.js +1 -4
  15. package/dist/entity/entity.lifecycle.js.map +1 -1
  16. package/dist/entity/entity.relationships.js +3 -0
  17. package/dist/entity/entity.relationships.js.map +1 -1
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.js +1 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/modules/relationship_types.d.ts +18 -0
  22. package/dist/modules/relationship_types.js +18 -0
  23. package/dist/modules/relationship_types.js.map +1 -1
  24. package/dist/modules/relationships.d.ts +8 -2
  25. package/dist/modules/relationships.js +41 -3
  26. package/dist/modules/relationships.js.map +1 -1
  27. package/dist/package.json +1 -1
  28. package/docs/README.md +6 -6
  29. package/docs/components.md +77 -13
  30. package/docs/concepts.md +8 -2
  31. package/docs/design-guide.md +135 -1
  32. package/docs/entities.md +62 -6
  33. package/docs/execution-model.md +8 -4
  34. package/docs/glossary.md +11 -2
  35. package/docs/modules.md +7 -7
  36. package/docs/relationships.md +81 -0
  37. package/package.json +1 -1
  38. package/skills/vecs/SKILL.md +81 -0
@@ -20,14 +20,16 @@ export type EntityClass<T extends Entity = Entity> = new (world: World, eid: EID
20
20
  * ## Deferred semantics
21
21
  *
22
22
  * Inside a system body or `forEach` iteration the world is in **deferred
23
- * mode**: `add` / `attach` / `set` / `modified` / `remove` / `destroy` only
24
- * enqueue commands. The data layer (the components map and
23
+ * mode**: `add` / `attach` / `set` / `ensure` / `ensureTarget` / `modified` / `remove` /
24
+ * `destroy` only enqueue commands. The data layer (the components map and
25
25
  * `componentBitmask`) is mutated when the world drains its queue. Concretely,
26
26
  * while deferred:
27
27
  *
28
28
  * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.add(C)` (no instance yet).
29
29
  * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.attach(instance)` if C was absent.
30
30
  * - `entity.get(C)` / `entity.getMut(C)` returns the previous value after `entity.set(C, props)`.
31
+ * - `entity.ensure(C)` returns a mutable component immediately, but `entity.get(C)` does not see it until the queue drains.
32
+ * - `entity.ensureTarget(R)` returns its pending target immediately, but `entity.target(R)` does not see it until the queue drains.
31
33
  * - `entity.get(C)` / `entity.getMut(C)` still returns the component after `entity.remove(C)`.
32
34
  *
33
35
  * Outside deferred mode the same calls execute inline and mutations are
@@ -16,14 +16,16 @@ import { IdentityEntity } from "./entity.identity.js";
16
16
  * ## Deferred semantics
17
17
  *
18
18
  * Inside a system body or `forEach` iteration the world is in **deferred
19
- * mode**: `add` / `attach` / `set` / `modified` / `remove` / `destroy` only
20
- * enqueue commands. The data layer (the components map and
19
+ * mode**: `add` / `attach` / `set` / `ensure` / `ensureTarget` / `modified` / `remove` /
20
+ * `destroy` only enqueue commands. The data layer (the components map and
21
21
  * `componentBitmask`) is mutated when the world drains its queue. Concretely,
22
22
  * while deferred:
23
23
  *
24
24
  * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.add(C)` (no instance yet).
25
25
  * - `entity.get(C)` / `entity.getMut(C)` returns `undefined` after `entity.attach(instance)` if C was absent.
26
26
  * - `entity.get(C)` / `entity.getMut(C)` returns the previous value after `entity.set(C, props)`.
27
+ * - `entity.ensure(C)` returns a mutable component immediately, but `entity.get(C)` does not see it until the queue drains.
28
+ * - `entity.ensureTarget(R)` returns its pending target immediately, but `entity.target(R)` does not see it until the queue drains.
27
29
  * - `entity.get(C)` / `entity.getMut(C)` still returns the component after `entity.remove(C)`.
28
30
  *
29
31
  * Outside deferred mode the same calls execute inline and mutations are
@@ -1 +1 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity/entity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAWtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,OAAO,MAAO,SAAQ,cAAc;IACxC,kFAAkF;IAC3E,OAAO,CAAC,MAAc;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,wFAAwF;IACxF,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,4EAA4E;IAC5E,IAAW,MAAM,CAAC,MAA0B;QAC1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,oDAAoD;IACpD,IAAW,KAAK;QACd,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;IAC1B,CAAC;CACF"}
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity/entity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAWtD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,OAAO,MAAO,SAAQ,cAAc;IACxC,kFAAkF;IAC3E,OAAO,CAAC,MAAc;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,wFAAwF;IACxF,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,4EAA4E;IAC5E,IAAW,MAAM,CAAC,MAA0B;QAC1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,oEAAoE;IACpE,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,oDAAoD;IACpD,IAAW,KAAK;QACd,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;IAC1B,CAAC;CACF"}
@@ -50,10 +50,7 @@ export class Lifecycle extends Components {
50
50
  this.componentBitmask.deleteBit(componentMeta.bitPtr);
51
51
  this.world._notifyComponentRemoved(ceid, entity);
52
52
  componentMeta._decrementUsage();
53
- const removeHandlers = componentMeta._onRemoveHandlers;
54
- if (removeHandlers) {
55
- removeHandlers.forEach((handler) => handler(entity, c));
56
- }
53
+ componentMeta._onRemove?.(entity, c);
57
54
  });
58
55
  this._dirtyComponentBitmask.clear();
59
56
  this._queries.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"entity.lifecycle.js","sourceRoot":"","sources":["../../src/entity/entity.lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity.lifecycle.js","sourceRoot":"","sources":["../../src/entity/entity.lifecycle.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,9 @@ export class Relationships extends Queries {
49
49
  }
50
50
  this._removeIncoming(oldTarget, meta.eid);
51
51
  this._addIncoming(newTarget, meta.eid);
52
+ if (oldTarget && newTarget) {
53
+ meta._onRetarget?.(this, oldTarget, newTarget);
54
+ }
52
55
  }
53
56
  }
54
57
  //# sourceMappingURL=entity.relationships.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity.relationships.js","sourceRoot":"","sources":["../../src/entity/entity.relationships.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,MAAM,OAAO,aAAc,SAAQ,OAAO;IACxC,0EAA0E;IACnE,MAAM,CAAC,GAAiB;QAC7B,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QAC1E,OAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAA8B,EAAE,MAAM,CAAC;IAC5E,CAAC;IAED,qEAAqE;IAC9D,QAAQ,CAAC,GAAiB;QAC/B,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QAC1E,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,cAAc,CAAC;IACrE,CAAC;IAED;;;OAGG;IACI,cAAc,CAAC,MAAW;QAC/B,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;IACN,YAAY,CAAC,MAA0B,EAAE,MAAW;QAC5D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QACD,IAAI,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,QAAQ,EAAU,CAAC;YACjC,CAAC,MAAM,CAAC,SAAS,KAAhB,MAAM,CAAC,SAAS,GAAK,IAAI,gBAAgB,EAAE,EAAC,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAyB,CAAC,CAAC;IACzC,CAAC;IAED,gBAAgB;IACN,eAAe,CAAC,MAA0B,EAAE,MAAW;QAC/D,MAAM,OAAO,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,IAAyB,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvB,MAAO,CAAC,SAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,gBAAgB;IACN,eAAe,CACvB,IAAmB,EACnB,SAA6B,EAC7B,SAA6B;QAE7B,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YACpD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;CACF"}
1
+ {"version":3,"file":"entity.relationships.js","sourceRoot":"","sources":["../../src/entity/entity.relationships.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,MAAM,OAAO,aAAc,SAAQ,OAAO;IACxC,0EAA0E;IACnE,MAAM,CAAC,GAAiB;QAC7B,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QAC1E,OAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAA8B,EAAE,MAAM,CAAC;IAC5E,CAAC;IAED,qEAAqE;IAC9D,QAAQ,CAAC,GAAiB;QAC/B,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC;QAC1E,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,cAAc,CAAC;IACrE,CAAC;IAED;;;OAGG;IACI,cAAc,CAAC,MAAW;QAC/B,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;IACN,YAAY,CAAC,MAA0B,EAAE,MAAW;QAC5D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QACD,IAAI,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,IAAI,QAAQ,EAAU,CAAC;YACjC,CAAC,MAAM,CAAC,SAAS,KAAhB,MAAM,CAAC,SAAS,GAAK,IAAI,gBAAgB,EAAE,EAAC,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,IAAyB,CAAC,CAAC;IACzC,CAAC;IAED,gBAAgB;IACN,eAAe,CAAC,MAA0B,EAAE,MAAW;QAC/D,MAAM,OAAO,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,IAAyB,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvB,MAAO,CAAC,SAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,gBAAgB;IACN,eAAe,CACvB,IAAmB,EACnB,SAA6B,EAC7B,SAA6B;QAE7B,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YACpD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,WAAW,EAAE,CAAC,IAAyB,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -5,8 +5,8 @@ export { Iter } from "./inject.js";
5
5
  export type { DownInject, FanInjectElement, FanInjectTuple, InjectElement, InjectTuple, MaybeResolvedInjectTuple, RequiredResolvedInjectTuple, TargetInject, } from "./inject.js";
6
6
  export { DEFAULT_POOLS, World, type WorldOptions } from "./world/index.js";
7
7
  export { Filter } from "./filter.js";
8
- export { ChildOf, DependsOn, SilenceSource } from "./modules/relationships.js";
9
- export { CleanupPolicy, Component, Implements, Relationship, type ComponentInstance, type ComponentClass, type ComponentMeta, type ComponentRef, } from "./component.js";
8
+ export { ChildOf, DependsOn, OwnedTarget, SilenceSource } from "./modules/relationships.js";
9
+ export { CleanupPolicy, Component, Implements, Relationship, type ComponentInstance, type ComponentClass, type ComponentMeta, type ComponentRef, type HookHandler, type RetargetHandler, } from "./component.js";
10
10
  export { Entity, type EID, type EntityClass, Identity } from "./entity/index.js";
11
11
  export { Module, type ModuleConfig } from "./module.js";
12
12
  export { IdentityModule } from "./modules/identity.js";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ export { Query, GroupedQuery, Group } from "./query/index.js";
3
3
  export { Iter } from "./inject.js";
4
4
  export { DEFAULT_POOLS, World } from "./world/index.js";
5
5
  export { Filter } from "./filter.js";
6
- export { ChildOf, DependsOn, SilenceSource } from "./modules/relationships.js";
6
+ export { ChildOf, DependsOn, OwnedTarget, SilenceSource } from "./modules/relationships.js";
7
7
  export { CleanupPolicy, Component, Implements, Relationship, } from "./component.js";
8
8
  export { Entity, Identity } from "./entity/index.js";
9
9
  export { Module } from "./module.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAWnC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAqB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EACL,aAAa,EACb,SAAS,EACT,UAAU,EACV,YAAY,GAKb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAA8B,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,SAAS,EACT,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,IAAI,EAAoC,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAuC,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAqB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAWnC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAqB,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EACL,aAAa,EACb,SAAS,EACT,UAAU,EACV,YAAY,GAOb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAA8B,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,MAAM,EAAqB,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,SAAS,EACT,WAAW,EACX,SAAS,EACT,WAAW,EACX,SAAS,EACT,UAAU,EACV,KAAK,EACL,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,IAAI,EAAoC,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAuC,MAAM,kBAAkB,CAAC;AAC/E,OAAO,EAAE,4BAA4B,EAAqB,MAAM,mBAAmB,CAAC"}
@@ -17,6 +17,24 @@ export declare class DependsOn extends Relationship {
17
17
  */
18
18
  export declare class SilenceSource extends Relationship {
19
19
  }
20
+ /**
21
+ * Marker component that makes every target of a relationship a `ChildOf` child
22
+ * of the relationship source.
23
+ *
24
+ * Add during world setup, before creating relationship instances:
25
+ *
26
+ * ```ts
27
+ * world.component(Inventory).add(OwnedTarget);
28
+ * player.add(Inventory); // creates an owned target
29
+ * ```
30
+ *
31
+ * Adding the relationship creates a target when none was supplied. Retargeting
32
+ * destroys the displaced target, and removing the relationship destroys its
33
+ * current target. Configure owner lifecycle hooks before attaching this trait;
34
+ * the trait wraps them and runs ownership behavior first.
35
+ */
36
+ export declare class OwnedTarget {
37
+ }
20
38
  /**
21
39
  * Marker component used to tag a relationship component as traversable.
22
40
  *
@@ -16,6 +16,24 @@ export class DependsOn extends Relationship {
16
16
  */
17
17
  export class SilenceSource extends Relationship {
18
18
  }
19
+ /**
20
+ * Marker component that makes every target of a relationship a `ChildOf` child
21
+ * of the relationship source.
22
+ *
23
+ * Add during world setup, before creating relationship instances:
24
+ *
25
+ * ```ts
26
+ * world.component(Inventory).add(OwnedTarget);
27
+ * player.add(Inventory); // creates an owned target
28
+ * ```
29
+ *
30
+ * Adding the relationship creates a target when none was supplied. Retargeting
31
+ * destroys the displaced target, and removing the relationship destroys its
32
+ * current target. Configure owner lifecycle hooks before attaching this trait;
33
+ * the trait wraps them and runs ownership behavior first.
34
+ */
35
+ export class OwnedTarget {
36
+ }
19
37
  /**
20
38
  * Marker component used to tag a relationship component as traversable.
21
39
  *
@@ -1 +1 @@
1
- {"version":3,"file":"relationship_types.js","sourceRoot":"","sources":["../../src/modules/relationship_types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,0CAA0C;AAC1C,MAAM,OAAO,OAAQ,SAAQ,YAAY;CAAG;AAE5C,+CAA+C;AAC/C,MAAM,OAAO,SAAU,SAAQ,YAAY;CAAG;AAE9C;;;;;;;;GAQG;AACH,MAAM,OAAO,aAAc,SAAQ,YAAY;CAAG;AAElD;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,WAAW;IAAxB;QACE,+CAA+C;QAC/C,WAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrC,CAAC;CAAA"}
1
+ {"version":3,"file":"relationship_types.js","sourceRoot":"","sources":["../../src/modules/relationship_types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,0CAA0C;AAC1C,MAAM,OAAO,OAAQ,SAAQ,YAAY;CAAG;AAE5C,+CAA+C;AAC/C,MAAM,OAAO,SAAU,SAAQ,YAAY;CAAG;AAE9C;;;;;;;;GAQG;AACH,MAAM,OAAO,aAAc,SAAQ,YAAY;CAAG;AAElD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,WAAW;CAAG;AAE3B;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,WAAW;IAAxB;QACE,+CAA+C;QAC/C,WAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrC,CAAC;CAAA"}
@@ -1,8 +1,8 @@
1
1
  import { Module } from "../module.js";
2
- export { ChildOf, DependsOn, SilenceSource, Traversable } from "./relationship_types.js";
2
+ export { ChildOf, DependsOn, OwnedTarget, SilenceSource, Traversable, } from "./relationship_types.js";
3
3
  /**
4
4
  * Built-in world module that registers the `ChildOf` relationship and
5
- * maintains depth tracking for traversable relationships.
5
+ * maintains ownership and depth tracking policies for relationship traits.
6
6
  *
7
7
  * Registered automatically by every {@link World}. It sets `ChildOf`'s
8
8
  * `onDeleteTarget` cleanup policy to {@link CleanupPolicy.Delete}, so
@@ -14,6 +14,12 @@ export { ChildOf, DependsOn, SilenceSource, Traversable } from "./relationship_t
14
14
  * every entity's depth is updated when the relationship is added, retargeted,
15
15
  * or removed.
16
16
  *
17
+ * When a relationship component entity has `OwnedTarget` attached, the module
18
+ * wraps its hooks so adding the relationship creates a target when needed,
19
+ * every target becomes a `ChildOf` child of its source, and targets are
20
+ * destroyed when displaced or removed. Configure this trait after the
21
+ * relationship's owner hooks and before creating relationship instances.
22
+ *
17
23
  * Depth is computed by walking `entity.target(relEid)` to the root. When an
18
24
  * entity's depth changes, every descendant is recursively recomputed.
19
25
  */
@@ -1,10 +1,10 @@
1
1
  import { CleanupPolicy } from "../component_meta.js";
2
2
  import { Module } from "../module.js";
3
- import { ChildOf, Traversable } from "./relationship_types.js";
4
- export { ChildOf, DependsOn, SilenceSource, Traversable } from "./relationship_types.js";
3
+ import { ChildOf, OwnedTarget, Traversable } from "./relationship_types.js";
4
+ export { ChildOf, DependsOn, OwnedTarget, SilenceSource, Traversable, } from "./relationship_types.js";
5
5
  /**
6
6
  * Built-in world module that registers the `ChildOf` relationship and
7
- * maintains depth tracking for traversable relationships.
7
+ * maintains ownership and depth tracking policies for relationship traits.
8
8
  *
9
9
  * Registered automatically by every {@link World}. It sets `ChildOf`'s
10
10
  * `onDeleteTarget` cleanup policy to {@link CleanupPolicy.Delete}, so
@@ -16,6 +16,12 @@ export { ChildOf, DependsOn, SilenceSource, Traversable } from "./relationship_t
16
16
  * every entity's depth is updated when the relationship is added, retargeted,
17
17
  * or removed.
18
18
  *
19
+ * When a relationship component entity has `OwnedTarget` attached, the module
20
+ * wraps its hooks so adding the relationship creates a target when needed,
21
+ * every target becomes a `ChildOf` child of its source, and targets are
22
+ * destroyed when displaced or removed. Configure this trait after the
23
+ * relationship's owner hooks and before creating relationship instances.
24
+ *
19
25
  * Depth is computed by walking `entity.target(relEid)` to the root. When an
20
26
  * entity's depth changes, every descendant is recursively recomputed.
21
27
  */
@@ -23,8 +29,40 @@ export class RelationshipsModule extends Module {
23
29
  init() {
24
30
  const world = this.world;
25
31
  const childOf = world.component(ChildOf);
32
+ const ownedTarget = world.component(OwnedTarget);
26
33
  const traversable = world.component(Traversable);
27
34
  childOf.meta.onDeleteTarget = CleanupPolicy.Delete;
35
+ ownedTarget.onAdd((rel) => {
36
+ if (!rel.meta.isRelationship) {
37
+ throw new Error("OwnedTarget can only be added to a Relationship component");
38
+ }
39
+ if (rel === childOf) {
40
+ throw new Error("OwnedTarget cannot be added to ChildOf");
41
+ }
42
+ const onAdd = rel.onAdd();
43
+ const onSet = rel.onSet();
44
+ const onRetarget = rel.onRetarget();
45
+ const onRemove = rel.onRemove();
46
+ rel
47
+ .onAdd((source, component) => {
48
+ const relationship = component;
49
+ relationship.target ?? (relationship.target = world.entity());
50
+ relationship.target.childOf(source);
51
+ onAdd?.(source, component);
52
+ })
53
+ .onSet((source, relationship) => {
54
+ relationship.target.childOf(source);
55
+ onSet?.(source, relationship);
56
+ })
57
+ .onRetarget((source, oldTarget, newTarget) => {
58
+ oldTarget.destroy();
59
+ onRetarget?.(source, oldTarget, newTarget);
60
+ })
61
+ .onRemove((source, relationship) => {
62
+ relationship.target.destroy();
63
+ onRemove?.(source, relationship);
64
+ });
65
+ });
28
66
  traversable.onAdd((rel, traversable) => {
29
67
  const relEid = rel.eid;
30
68
  rel
@@ -1 +1 @@
1
- {"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/modules/relationships.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/modules/relationships.ts"],"names":[],"mappings":"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"}
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vworlds/vecs",
3
- "version": "1.0.43",
3
+ "version": "1.0.45",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
package/docs/README.md CHANGED
@@ -14,13 +14,13 @@ Read in this order the first time through:
14
14
  3. [Execution model](./execution-model.md) — phases, the pipeline, deferred mutation, reactive
15
15
  routing. Read this before designing anything non-trivial.
16
16
  4. Subsystem guides, in any order:
17
- - [Components](./components.md) — registration, hooks, exclusivity, cleanup policies,
17
+ - [Components](./components.md) — registration, hooks, traits, exclusivity, cleanup policies,
18
18
  interfaces, singletons.
19
- - [Entities](./entities.md) — creation, lookup, the component API, lifecycle.
19
+ - [Entities](./entities.md) — creation, lookup, the component API, relationship targets, lifecycle.
20
20
  - [Systems](./systems.md) — membership, reactive callbacks, callback options, `each`/`run`, cadence, injection.
21
21
  - [Queries and filters](./queries-and-filters.md) — the query DSL, live queries, one-shot
22
22
  filters, grouped queries, `Bitset`.
23
- - [Relationships](./relationships.md) — entity-to-entity links, hierarchy, cleanup cascades.
23
+ - [Relationships](./relationships.md) — links, target creation and ownership, hierarchy, cleanup cascades.
24
24
  - [Modules](./modules.md) — packaging features, composition, the built-in modules.
25
25
  5. [Design guide](./design-guide.md) — opinionated patterns and anti-patterns distilled from real
26
26
  designs. Read it once you know the machinery.
@@ -36,11 +36,11 @@ Keep the [Glossary](./glossary.md) at hand for terminology.
36
36
  | [getting-started.md](./getting-started.md) | A runnable tutorial from `npm install` to a ticking world. |
37
37
  | [concepts.md](./concepts.md) | The core vocabulary and how the pieces relate. |
38
38
  | [execution-model.md](./execution-model.md) | `world.progress`, the 8 built-in phases, deferred commands, flush boundaries, event routing. |
39
- | [components.md](./components.md) | `world.component`, hooks, exclusive groups, `CleanupPolicy`, `Implements`, `Singleton`. |
40
- | [entities.md](./entities.md) | `world.entity`, `add`/`set`/`get`/`remove`/`destroy`, deferred read semantics. |
39
+ | [components.md](./components.md) | Component registration, hooks, traits, exclusivity, cleanup, aliases, and singletons. |
40
+ | [entities.md](./entities.md) | Entity creation, component mutation, relationship targets, lifecycle, deferred reads. |
41
41
  | [systems.md](./systems.md) | `world.system`, `with`/`without`, `enter`/`update`/`exit`, callback options, tick sources. |
42
42
  | [queries-and-filters.md](./queries-and-filters.md) | `QueryDSL`, `Query`, `Filter`, `groupBy`, `ignoreSource`. |
43
- | [relationships.md](./relationships.md) | `Relationship`, `ChildOf`/`DependsOn`, `parent`/`children`, `Traversable`, cascades. |
43
+ | [relationships.md](./relationships.md) | Relationships, target creation and ownership, hierarchy, traversal, and cleanup cascades. |
44
44
  | [modules.md](./modules.md) | `Module<Config>`, `world.module`, composition, built-in modules. |
45
45
  | [design-guide.md](./design-guide.md) | Patterns, anti-patterns, and a Phaser render-layer case study. |
46
46
  | [utilities.md](./utilities.md) | Public helper classes: `Events`, `ArrayMap`, `IterableArrayMap`, plus `Bitset` cross-ref. |
@@ -71,7 +71,7 @@ Pass `idPools` to the `World` constructor to change ranges (each entry is an `Id
71
71
  released this frame is not immediately recycled. `world.peekNextEid(poolName)` returns the next id
72
72
  a pool would allocate without reserving it. Id 0 is reserved.
73
73
 
74
- ## Hooks: `onAdd`, `onSet`, `onRemove`
74
+ ## Hooks: `onAdd`, `onSet`, `onRemove`, `onRetarget`
75
75
 
76
76
  The `Component` entity exposes lifecycle hooks fired for every entity carrying the component:
77
77
 
@@ -83,11 +83,15 @@ world
83
83
  .onRemove((entity, sprite) => sprite.destroy(scene, entity));
84
84
  ```
85
85
 
86
- | Hook | Fires when… |
87
- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
88
- | `onAdd` | The component is first attached (`add`, or `set` on an entity that lacked it). |
89
- | `onSet` | `entity.set(C, props)` applies data, `entity.attach(instance)` stores an instance, `entity.modified(C)` is called, or `getMut` marks it dirty. |
90
- | `onRemove` | The component is detached (`entity.remove(C)`), or the owning entity is destroyed. |
86
+ | Hook | Fires when… |
87
+ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
88
+ | `onAdd` | The component is first attached (`add`, or `set` on an entity that lacked it). |
89
+ | `onSet` | `entity.set(C, props)` applies data, `entity.attach(instance)` stores an instance, `entity.modified(C)` is called, or `getMut` / `ensure` marks it dirty. |
90
+ | `onRemove` | The component is detached (`entity.remove(C)`), or the owning entity is destroyed. |
91
+
92
+ Relationship component entities additionally expose `onRetarget`. It fires after an existing
93
+ relationship changes to a different target, once `target` and `children` already reflect the new
94
+ reverse-index state. Initial assignment, same-target `set`, and removal do not fire it.
91
95
 
92
96
  Handlers receive `(entity, componentInstance)` — component instances do not carry entity
93
97
  references, so the entity is passed explicitly. Hooks fire synchronously when the corresponding
@@ -95,6 +99,65 @@ command is applied (see [Execution model](./execution-model.md#reactive-routing)
95
99
  resource management and cross-cutting reactions that aren't worth a system; use systems when the
96
100
  reaction belongs to a phase.
97
101
 
102
+ Each lifecycle event has one handler slot per component. Calling `onAdd(handler)`,
103
+ `onSet(handler)`, `onRemove(handler)`, or `onRetarget(handler)` replaces the current handler and
104
+ returns the component entity for chaining. Call the method without an argument to read the current
105
+ handler, or pass `undefined` to remove it.
106
+
107
+ ## Component traits: policy on component entities
108
+
109
+ Registered components are themselves entities. Attach a configuration component to a component
110
+ entity to change policy for every use of that component type. vecs calls these configuration
111
+ components **component traits**:
112
+
113
+ ```ts
114
+ world.component(Gravity).add(Singleton);
115
+ world.component(Inventory).add(OwnedTarget);
116
+ world.component(ChildOf).add(Traversable);
117
+ world.component(Orange).set(Implements, { interfaces: [Fruit] });
118
+ ```
119
+
120
+ | Trait/declaration | Applies to | Effect |
121
+ | ----------------- | ---------------------------------- | -------------------------------------------------------------------- |
122
+ | `Singleton` | Concrete components | Allows at most one carrier entity |
123
+ | `Implements` | Non-relationship components | Exposes concrete data through abstract aliases |
124
+ | `Traversable` | Relationships | Maintains hierarchy depth for cascade ordering |
125
+ | `OwnedTarget` | Relationships other than `ChildOf` | Owns the active target through `ChildOf` and destructive replacement |
126
+
127
+ Traits declare policy; their built-in modules install the hooks and maintain the metadata that
128
+ enforce it. Configure traits in feature-module setup rather than opportunistically inside systems.
129
+ Do not assume all traits have the same lifecycle:
130
+
131
+ - Add `Singleton` before component instances exist.
132
+ - Configure owner hooks, then add `OwnedTarget`, before relationship instances exist; it wraps the
133
+ current hooks and does not backfill.
134
+ - `Traversable` backfills existing relationship instances.
135
+ - Setting or removing `Implements` recomputes interface aliases.
136
+
137
+ Treat traits as setup policy unless their documentation explicitly supports runtime changes. Before
138
+ writing custom component-type bookkeeping, check whether an existing trait already expresses the
139
+ invariant.
140
+
141
+ Custom traits use the same mechanism. Keep the trait class as data and put its behavior in a module:
142
+
143
+ ```ts
144
+ class Audited {}
145
+
146
+ class AuditModule extends Module {
147
+ public init(): void {
148
+ this.world.component(Audited).onAdd((component) => {
149
+ component.onSet((entity) => console.log("changed", component.meta.Class.name, entity.eid));
150
+ });
151
+ }
152
+ }
153
+
154
+ world.module(AuditModule);
155
+ world.component(Position).add(Audited);
156
+ ```
157
+
158
+ Create a custom trait only when several component types need the same reusable, declarative policy.
159
+ For one component type, register hooks directly in its owning module.
160
+
98
161
  ## Exclusive component groups
99
162
 
100
163
  `world.setExclusiveComponents(A, B, C)` declares a mutually exclusive group: setting one
@@ -183,7 +246,7 @@ Rules (enforced by `ImplementsModule`, `lib/vecs/src/modules/implements.ts`):
183
246
 
184
247
  - **Aliases are read/query only.** `get`, `has`, `with`, `filter`, and injection accept an
185
248
  interface type; mutation must go through the concrete component. `add`, `set`, `remove`,
186
- `modified`, `getMut`, and `attach` on an interface throw at runtime (and `add`/`set` are
249
+ `modified`, `getMut`, `ensure`, and `attach` on an interface throw at runtime (and `add`/`set` are
187
250
  rejected by TypeScript for abstract classes).
188
251
  - **Declarations are transitive.** `Orange` implements `Fruit`, `Fruit` implements `Food`, so an
189
252
  entity with `Orange` matches `with(Food)`. Cyclic declarations throw.
@@ -249,12 +312,13 @@ interface markers for polymorphic dispatch — is in the
249
312
  A `Component<T>` is an `Entity` subclass, so the full [entity API](./entities.md#reference)
250
313
  applies. On top of it:
251
314
 
252
- | Member | Description |
253
- | ------------------- | ---------------------------------------------------------------- |
254
- | `onAdd(handler)` | Register an add hook. Returns the component entity for chaining. |
255
- | `onRemove(handler)` | Register a remove hook. |
256
- | `onSet(handler)` | Register a set/modified hook. |
257
- | `meta` | The `ComponentMeta` bookkeeping record. |
315
+ | Member | Description |
316
+ | ---------------------- | -------------------------------------------------------------------------- |
317
+ | `onAdd(handler?)` | Get, set, or remove the single add hook. Setter returns the component. |
318
+ | `onRemove(handler?)` | Get, set, or remove the single remove hook. |
319
+ | `onRetarget(handler?)` | Get, set, or remove the relationship retarget hook. Rejects non-relations. |
320
+ | `onSet(handler?)` | Get, set, or remove the single set/modified hook. |
321
+ | `meta` | The `ComponentMeta` bookkeeping record. |
258
322
 
259
323
  ### `ComponentMeta` (`lib/vecs/src/component_meta.ts`)
260
324
 
package/docs/concepts.md CHANGED
@@ -20,9 +20,10 @@ every idiom in the [Design guide](./design-guide.md) is a consequence of taking
20
20
  | **System** | A `Query` plus per-tick logic (`update`, `each`, `run`), assigned to one pipeline phase. |
21
21
  | **Query** | A reactive, always-up-to-date set of entities matching a predicate, with `enter`/`exit`/`update` callbacks. |
22
22
  | **Filter** | A non-reactive, one-shot scan: walks all world entities on each `forEach` call. |
23
- | **Hook** | Lightweight `onAdd` / `onRemove` / `onSet` callbacks registered per component class. |
23
+ | **Hook** | Lightweight component callbacks (`onAdd` / `onSet` / `onRemove`, plus relationship `onRetarget`). |
24
24
  | **Phase** | Marker component for entities used as pipeline ordering anchors. |
25
25
  | **Relationship** | A component whose `target` field points at another entity, with reverse lookup and cleanup cascades. |
26
+ | **Component trait** | Policy attached to a component entity, configuring every use of that component type. |
26
27
  | **Module** | A unit of packaging: a class whose `init()` registers components, systems, phases, and policy. |
27
28
  | **Exclusive components** | A group of components where at most one may exist on any entity at a time. |
28
29
  | **Implements** | Declares abstract/interface component aliases for a concrete component, for polymorphic queries. |
@@ -43,6 +44,11 @@ own. All behavior lives in systems (and, for small cross-cutting reactions, in h
43
44
  is what makes composition work: any system can operate on any entity that happens to carry the
44
45
  right components, and adding a capability to an entity is just adding a component.
45
46
 
47
+ Because a registered component is also an entity, it can itself carry components. Built-in
48
+ **component traits** use that meta-ECS layer to declare reusable policy: `Singleton` constrains a
49
+ component, `Implements` declares aliases, and `Traversable` / `OwnedTarget` configure relationships.
50
+ The trait remains data; a module owns the hooks and metadata behavior it activates.
51
+
46
52
  Prefer many small, single-purpose components over one large one. An entity that never rotates
47
53
  simply omits `Rotation`; absence encodes "not applicable". See
48
54
  [Components](./components.md).
@@ -77,7 +83,7 @@ on component combinations. The canonical example is the companion-component patt
77
83
 
78
84
  ## Where each topic lives
79
85
 
80
- - Registering, configuring, and hooking components → [Components](./components.md)
86
+ - Registering, configuring, hooking, and applying traits to components → [Components](./components.md)
81
87
  - Creating, mutating, and destroying entities → [Entities](./entities.md)
82
88
  - System membership, callbacks, and cadence → [Systems](./systems.md)
83
89
  - The query DSL, live queries, filters, grouping → [Queries and filters](./queries-and-filters.md)