@vworlds/vecs 1.0.43 → 1.0.44

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.
@@ -43,6 +43,56 @@ subclasses) explicitly in your `networkComponents` array to replicate parent-chi
43
43
 
44
44
  `entity.childOf(parent)` is shorthand for `entity.set(ChildOf, { target: parent })`.
45
45
 
46
+ ## Ensuring a target
47
+
48
+ Use `ensureTarget` when a registered relationship should always have some target and a new,
49
+ independent entity is the correct default:
50
+
51
+ ```ts
52
+ world.component(FriendOf);
53
+
54
+ const friend = entity.ensureTarget(FriendOf);
55
+ entity.ensureTarget(FriendOf) === friend; // true
56
+ entity.target(FriendOf) === friend; // true
57
+ ```
58
+
59
+ The method returns the existing target when present. Otherwise it creates an entity, initializes
60
+ the relationship with that target, and attaches the relationship. During deferred execution,
61
+ repeated calls share one pending relationship and return the same target; `target(FriendOf)` still
62
+ returns `undefined` until flush.
63
+
64
+ The generated target is independent: `ensureTarget` does not add `ChildOf`, and destroying the
65
+ source does not destroy the target. Add ownership explicitly when your model requires it. The
66
+ relationship class must be registered before calling `ensureTarget`.
67
+
68
+ ## Owned targets
69
+
70
+ Mark a relationship component with `OwnedTarget` during world setup when every target assigned
71
+ through that relationship should become a `ChildOf` child of its source:
72
+
73
+ ```ts
74
+ import { OwnedTarget, Relationship } from "@vworlds/vecs";
75
+
76
+ class Inventory extends Relationship {}
77
+
78
+ world.component(Inventory).add(OwnedTarget);
79
+
80
+ const inventory = player.ensureTarget(Inventory);
81
+ inventory.parent === player; // true
82
+
83
+ player.destroy();
84
+ inventory.destroyed === true; // ChildOf cascades deletion
85
+ ```
86
+
87
+ `OwnedTarget` installs `onSet`, `onRetarget`, and `onRemove` hooks on `Inventory`. New targets become
88
+ `ChildOf` children, displaced targets are destroyed on retarget, and the current target is destroyed
89
+ when the relationship is removed (including source destruction). During deferred execution, these
90
+ changes apply while the command queue drains.
91
+
92
+ Configure the trait before creating relationship instances; it does not backfill existing targets.
93
+ Do not share one owned target between several sources: retargeting or removing any owning
94
+ relationship can destroy it. `OwnedTarget` rejects ordinary components and `ChildOf` itself.
95
+
46
96
  ## Retargeting
47
97
 
48
98
  Point a relationship somewhere else with a plain `set`:
@@ -60,6 +110,20 @@ lookups.
60
110
  `getMut` throws for relationship components: in-place target mutation would bypass the reverse
61
111
  index used by `children()` and the cleanup cascades. Always retarget with `set`.
62
112
 
113
+ Register `onRetarget` when behavior needs both targets:
114
+
115
+ ```ts
116
+ world.component(InCell).onRetarget((entity, oldCell, newCell) => {
117
+ // entity.target(InCell) is newCell here.
118
+ // oldCell.children(InCell) no longer contains entity.
119
+ // newCell.children(InCell) already contains entity.
120
+ });
121
+ ```
122
+
123
+ It fires only when an existing relationship moves to a different existing target, after reverse
124
+ indexes update and before `onSet`. Initial assignment, same-target writes, and removal do not fire
125
+ `onRetarget`; use `onSet` and `onRemove` for those lifecycle points.
126
+
63
127
  ## Cleanup when a target dies
64
128
 
65
129
  What happens to sources when their target entity is destroyed is governed by the relationship's
@@ -138,16 +202,19 @@ the box — the world's default pipeline is itself a `cascade: DependsOn` query
138
202
 
139
203
  ## Reference
140
204
 
141
- | API | Description |
142
- | --------------------------------------------------- | --------------------------------------------------------------------------------------- |
143
- | `class R extends Relationship {}` | Declare a relationship component with a `target: Entity` field. |
144
- | `e.set(R, { target })` | Create or retarget the relationship. |
145
- | `e.target(R)` | The target entity through relationship `R`, or `undefined`. |
146
- | `e.children(R)` | `ReadonlySet<Entity>` of sources targeting `e` through `R`. |
147
- | `e.childOf(parent)` | Shorthand for `e.set(ChildOf, { target: parent })`. |
148
- | `e.parent` / `e.parent = p` | Getter/setter for the built-in `ChildOf` target; setting `undefined` removes `ChildOf`. |
149
- | `meta.onDeleteTarget` | `Remove` (default) or `Delete` cascade when a target is destroyed. |
150
- | `world.component(R).add(Traversable)` | Enable depth tracking for `cascade` ordering. |
151
- | `{ target: [R, q] }` / `{ parent: q }` | Reactive DSL operators through the relationship. |
152
- | `{ source: [R, q] }` / `{ children: q }` | Filter-only DSL operators down the reverse index. |
153
- | `{ target: [R, [C...]] }` / `{ down: [R, [C...]] }` | Injection markers; see [Systems](./systems.md#relationship-injection-target-and-down). |
205
+ | API | Description |
206
+ | --------------------------------------------------- | ---------------------------------------------------------------------------------------- |
207
+ | `class R extends Relationship {}` | Declare a relationship component with a `target: Entity` field. |
208
+ | `e.set(R, { target })` | Create or retarget the relationship. |
209
+ | `e.target(R)` | The target entity through relationship `R`, or `undefined`. |
210
+ | `e.children(R)` | `ReadonlySet<Entity>` of sources targeting `e` through `R`. |
211
+ | `e.childOf(parent)` | Shorthand for `e.set(ChildOf, { target: parent })`. |
212
+ | `e.ensureTarget(R)` | Return `R`'s target, creating an independent entity when absent. |
213
+ | `world.component(R).add(OwnedTarget)` | Make targets assigned through `R` into `ChildOf` children of their sources. |
214
+ | `world.component(R).onRetarget(handler)` | React after `R` moves between existing targets; receives source, old target, new target. |
215
+ | `e.parent` / `e.parent = p` | Getter/setter for the built-in `ChildOf` target; setting `undefined` removes `ChildOf`. |
216
+ | `meta.onDeleteTarget` | `Remove` (default) or `Delete` cascade when a target is destroyed. |
217
+ | `world.component(R).add(Traversable)` | Enable depth tracking for `cascade` ordering. |
218
+ | `{ target: [R, q] }` / `{ parent: q }` | Reactive DSL operators through the relationship. |
219
+ | `{ source: [R, q] }` / `{ children: q }` | Filter-only DSL operators down the reverse index. |
220
+ | `{ target: [R, [C...]] }` / `{ down: [R, [C...]] }` | Injection markers; see [Systems](./systems.md#relationship-injection-target-and-down). |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vworlds/vecs",
3
- "version": "1.0.43",
3
+ "version": "1.0.44",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: vecs
3
+ description: "Designs, implements, reviews, and debugs games or applications using @vworlds/vecs. Use whenever a task creates or changes vecs components, entities, systems, queries, relationships, modules, phases, lifecycle, networked components, or ECS architecture."
4
+ ---
5
+
6
+ # vecs Application Development
7
+
8
+ Use the documentation shipped with the consuming project's installed `@vworlds/vecs` package.
9
+ Those docs match the API version the project actually uses and are the source of truth for vecs
10
+ design and behavior.
11
+
12
+ ## Before Working
13
+
14
+ 1. Locate `node_modules/@vworlds/vecs/docs/`. In a workspace or non-npm install, resolve the
15
+ installed `@vworlds/vecs` package and use its adjacent `docs/` directory.
16
+ 2. Read `docs/design-guide.md` sections 1, 2, 8, and 9 before designing or changing ECS behavior.
17
+ 3. Read the task-specific sections of that design guide:
18
+ - Components or replicated state: section 3.
19
+ - Systems or queries: section 4.
20
+ - Ordering or timing: section 5.
21
+ - Feature architecture: section 6.
22
+ - Lifecycle and synchronization patterns: section 7.
23
+ 4. Use `docs/README.md` to select any detailed subsystem guides needed by the task. Read
24
+ `docs/concepts.md` and `docs/execution-model.md` when the design depends on unfamiliar vecs
25
+ behavior.
26
+ 5. Inspect the consuming project's existing vecs modules and conventions before proposing a new
27
+ pattern.
28
+
29
+ Do not rely on memory or a different vecs checkout when installed documentation is available.
30
+ Confirm exact names and signatures against the installed declarations under
31
+ `node_modules/@vworlds/vecs/dist/`.
32
+
33
+ ## Design From ECS Semantics
34
+
35
+ Start from the vecs golden rule: components are data, systems are behavior, and component presence
36
+ and change drive lifecycle.
37
+
38
+ Before implementing, identify:
39
+
40
+ - The state represented by each component and whether absence has meaning.
41
+ - Which component transition creates, updates, or removes related state or resources.
42
+ - Whether the work should react through `enter`, `update`, or `exit` rather than scan every frame.
43
+ - Which phase owns the work and what earlier or later phase it must order against.
44
+ - Whether an owned target, relationship, trait, grouped query, or attached resource expresses the
45
+ lifecycle better than imperative bookkeeping.
46
+ - Whether the feature belongs in a `Module` that owns registration, systems, phases, and policy.
47
+
48
+ Prefer the idioms in the installed design guide over generic ECS patterns. vecs execution details,
49
+ including per-system flushes and reactive inbox routing, are part of the design model.
50
+
51
+ ## Avoid Generic Workarounds
52
+
53
+ Check the design guide before introducing:
54
+
55
+ - Side maps keyed by entity id.
56
+ - Components containing behavior or broad god-components with optional sentinel fields.
57
+ - Per-frame scans for changes that vecs can route reactively.
58
+ - Manual lifecycle bookkeeping that duplicates component presence.
59
+ - System registration order as a substitute for explicit cross-feature phase ordering.
60
+ - Parallel object graphs that duplicate relationships already represented in the ECS.
61
+ - Wrapper abstractions that hide normal vecs entities, components, systems, or modules without a
62
+ concrete need.
63
+
64
+ If the requested design conflicts with a documented vecs invariant, explain the conflict and use
65
+ the documented pattern unless the user explicitly chooses otherwise.
66
+
67
+ ## Implement And Verify
68
+
69
+ 1. Reuse existing components and modules where their semantics match; do not reuse them merely
70
+ because their fields look similar.
71
+ 2. Keep components small data classes and put behavior in systems or narrowly scoped lifecycle
72
+ hooks as directed by the guide.
73
+ 3. Express cross-feature ordering with phases. Treat same-phase registration order as a local
74
+ implementation detail unless the installed docs explicitly make it part of the design.
75
+ 4. Test lifecycle transitions, not only steady-state values: entry, mutation, removal, retargeting,
76
+ destruction, and same-tick visibility where relevant.
77
+ 5. Run the consuming project's typecheck and focused tests. Resolve API uncertainty from the
78
+ installed declarations and docs rather than guessing.
79
+
80
+ For networking, physics, Phaser, client, or server integration, also inspect the README and
81
+ declarations shipped with the corresponding `@vworlds/vecs-*` package.