@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.
- package/README.md +2 -2
- package/dist/component.d.ts +2 -1
- package/dist/component.js.map +1 -1
- package/dist/component_meta.d.ts +10 -0
- package/dist/component_meta.js +13 -0
- package/dist/component_meta.js.map +1 -1
- package/dist/entity/entity.components.d.ts +40 -1
- package/dist/entity/entity.components.js +93 -11
- package/dist/entity/entity.components.js.map +1 -1
- package/dist/entity/entity.d.ts +4 -2
- package/dist/entity/entity.js +4 -2
- package/dist/entity/entity.js.map +1 -1
- package/dist/entity/entity.relationships.js +3 -0
- package/dist/entity/entity.relationships.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/relationship_types.d.ts +15 -0
- package/dist/modules/relationship_types.js +15 -0
- package/dist/modules/relationship_types.js.map +1 -1
- package/dist/modules/relationships.d.ts +7 -2
- package/dist/modules/relationships.js +27 -3
- package/dist/modules/relationships.js.map +1 -1
- package/dist/package.json +1 -1
- package/docs/README.md +6 -6
- package/docs/components.md +71 -13
- package/docs/concepts.md +8 -2
- package/docs/design-guide.md +129 -0
- package/docs/entities.md +55 -3
- package/docs/execution-model.md +8 -4
- package/docs/glossary.md +11 -2
- package/docs/modules.md +7 -7
- package/docs/relationships.md +80 -13
- package/package.json +1 -1
- package/skills/vecs/SKILL.md +81 -0
package/docs/relationships.md
CHANGED
|
@@ -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.
|
|
149
|
-
| `
|
|
150
|
-
| `world.component(R).
|
|
151
|
-
| `
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
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
|
@@ -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.
|