@vworlds/vecs 1.0.9 → 1.0.11

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 (46) hide show
  1. package/.husky/pre-commit +1 -0
  2. package/README.md +218 -229
  3. package/dist/command.d.ts +1 -0
  4. package/dist/command.js +2 -0
  5. package/dist/command.js.map +1 -0
  6. package/dist/component.d.ts +51 -59
  7. package/dist/component.js +31 -25
  8. package/dist/component.js.map +1 -1
  9. package/dist/dsl.d.ts +34 -26
  10. package/dist/dsl.js +46 -20
  11. package/dist/dsl.js.map +1 -1
  12. package/dist/entity.d.ts +110 -127
  13. package/dist/entity.js +323 -164
  14. package/dist/entity.js.map +1 -1
  15. package/dist/filter.d.ts +31 -23
  16. package/dist/filter.js +41 -32
  17. package/dist/filter.js.map +1 -1
  18. package/dist/index.d.ts +1 -1
  19. package/dist/package.json +3 -1
  20. package/dist/phase.d.ts +5 -28
  21. package/dist/phase.js +11 -10
  22. package/dist/phase.js.map +1 -1
  23. package/dist/query.d.ts +128 -94
  24. package/dist/query.js +254 -145
  25. package/dist/query.js.map +1 -1
  26. package/dist/system.d.ts +64 -128
  27. package/dist/system.js +156 -149
  28. package/dist/system.js.map +1 -1
  29. package/dist/util/array_map.d.ts +4 -55
  30. package/dist/util/array_map.js +35 -37
  31. package/dist/util/array_map.js.map +1 -1
  32. package/dist/util/bitset.d.ts +40 -50
  33. package/dist/util/bitset.js +76 -62
  34. package/dist/util/bitset.js.map +1 -1
  35. package/dist/util/events.d.ts +14 -18
  36. package/dist/util/events.js +24 -3
  37. package/dist/util/events.js.map +1 -1
  38. package/dist/util/ordered_set.d.ts +1 -17
  39. package/dist/util/ordered_set.js +74 -25
  40. package/dist/util/ordered_set.js.map +1 -1
  41. package/dist/world.d.ts +222 -201
  42. package/dist/world.js +394 -323
  43. package/dist/world.js.map +1 -1
  44. package/eslint-rules/internal-underscore.js +60 -0
  45. package/eslint.config.js +5 -0
  46. package/package.json +3 -1
package/dist/entity.d.ts CHANGED
@@ -1,209 +1,192 @@
1
1
  import { Component } from "./component.js";
2
2
  import type { World } from "./world.js";
3
- import { type Query } from "./query.js";
3
+ import { ReadonlyArrayMap } from "./util/array_map.js";
4
4
  import { Events } from "./util/events.js";
5
5
  import { Bitset } from "./util/bitset.js";
6
6
  type EntityEvents = Events<{
7
7
  destroy(): void;
8
8
  }>;
9
9
  /**
10
- * A game object a unique identifier with an arbitrary set of
11
- * {@link Component | components} attached to it.
10
+ * A game object: a unique numeric id with an arbitrary set of
11
+ * {@link Component | components} attached.
12
12
  *
13
- * You never construct an `Entity` directly. Use {@link World.entity} to create
14
- * one, or {@link World.getOrCreateEntity} when the id is assigned by an
15
- * external authority (e.g. the server):
13
+ * Never instantiate `Entity` directly. Use {@link World.entity} for an
14
+ * auto-assigned id, or {@link World.getOrCreateEntity} when the id comes from
15
+ * an external authority such as a game server:
16
16
  *
17
17
  * ```ts
18
18
  * const e = world.entity();
19
19
  * e.set(Position, { x: 100 });
20
20
  * ```
21
21
  *
22
- * Entities support a parent–child hierarchy. When a parent is destroyed its
23
- * children are destroyed recursively. The `children` set is created lazily.
22
+ * Entities support a parent–child hierarchy. `parent` and `children` form a
23
+ * bidirectional link maintained by {@link setParent}; the children set is
24
+ * created lazily. Destroying a parent recursively destroys its children.
25
+ *
26
+ * ## Deferred semantics
27
+ *
28
+ * Inside a system body or `forEach` iteration the world is in **deferred
29
+ * mode**: `add` / `set` / `modified` / `remove` / `destroy` / `setParent` only
30
+ * enqueue commands. The data layer (the components map and `componentBitmask`)
31
+ * is mutated when the world drains its queue. Concretely, while deferred:
32
+ *
33
+ * - `entity.get(C)` returns `undefined` after `entity.add(C)` (no instance yet).
34
+ * - `entity.get(C)` returns the previous value after `entity.set(C, props)`.
35
+ * - `entity.get(C)` still returns the component after `entity.remove(C)`.
36
+ *
37
+ * Outside deferred mode the same calls execute inline and mutations are
38
+ * visible immediately.
24
39
  */
25
40
  export declare class Entity {
26
- /** The {@link World} that owns this entity. */
41
+ /** World that owns this entity. */
27
42
  readonly world: World;
28
- /** Unique numeric entity id assigned at creation time. */
43
+ /** Unique numeric entity id assigned at creation. */
29
44
  readonly eid: number;
30
- private components;
31
- private deletedComponents;
32
45
  /**
33
- * Bitmask representing the set of component types currently attached to this
34
- * entity. Used by the world to efficiently match entities against query
35
- * predicates.
46
+ * Bitmask of component type ids currently attached to this entity. Used by
47
+ * the world for fast archetype matching against query predicates.
36
48
  */
37
49
  readonly componentBitmask: Bitset;
38
- private readonly queries;
39
- private readonly newQueries;
40
50
  /**
41
- * A free-form property bag that modules can use to associate arbitrary data
42
- * with an entity without registering a component.
51
+ * Free-form property bag. Modules can use it to associate arbitrary data with
52
+ * an entity without registering a dedicated component.
43
53
  */
44
54
  properties: Map<string, any>;
45
- _events: EntityEvents;
46
- /** Parent entity in the scene hierarchy, or `undefined` if root. */
47
- parent: Entity | undefined;
48
- /** @internal */
49
- _children: Set<Entity> | undefined;
50
- _archetypeChanged: boolean;
51
- private destroyed;
52
55
  constructor(
53
- /** The {@link World} that owns this entity. */
56
+ /** World that owns this entity. */
54
57
  world: World,
55
- /** Unique numeric entity id assigned at creation time. */
58
+ /** Unique numeric entity id assigned at creation. */
56
59
  eid: number);
57
60
  /**
58
- * The set of direct child entities in the scene hierarchy.
59
- *
60
- * The set is created lazily on first access. Mutate it only through
61
- * {@link Entity.destroy} or by setting {@link Entity.parent} on a child —
62
- * both will keep the parent–child links consistent.
61
+ * Re-evaluate every world query for this entity, firing `_enter` / `_exit`
62
+ * routing whenever membership flipped.
63
63
  */
64
- get children(): Set<Entity>;
65
- private getComponentInstance;
64
+ private _updateQueries;
66
65
  /**
67
- * Queue an `onSet` / `update` notification for the given component and
68
- * return the entity for chaining.
66
+ * Construct a fresh component of `type`, apply `props`, store it on this
67
+ * entity, fire the `onAdd` hook, and route query updates.
69
68
  *
70
- * Equivalent to `component.modified()`, but usable inside an entity method
71
- * chain (e.g. after `add` or `set`).
69
+ * If the component type belongs to an exclusivity group, any conflicting
70
+ * component already on this entity is removed first.
71
+ */
72
+ private _new;
73
+ /** Parent entity in the scene hierarchy, or `undefined` for a root entity. */
74
+ get parent(): Entity | undefined;
75
+ /**
76
+ * Read-only view of direct child entities. The backing set is created lazily
77
+ * on the first child link; before that this getter returns a shared empty set.
78
+ */
79
+ get children(): ReadonlySet<Entity>;
80
+ /**
81
+ * Typed event emitter for entity-level lifecycle events. Currently only the
82
+ * `"destroy"` event is emitted, just before the entity is fully torn down.
72
83
  *
73
- * @param c - The component instance whose data changed.
74
- * @returns This entity, for chaining.
84
+ * The emitter is created lazily on first access.
75
85
  */
76
- modified<C extends typeof Component>(c: InstanceType<C>): Entity;
86
+ get events(): EntityEvents;
87
+ /** `true` when no components are currently attached to this entity. */
88
+ get empty(): boolean;
77
89
  /**
78
- * Add a component of type `Class` to this entity and return the instance.
90
+ * Read-only view of all components currently attached to this entity, keyed
91
+ * by numeric component type id.
92
+ *
93
+ * The mutating methods (`set`, `delete`, `clear`) are not exposed. Use
94
+ * `entity.add`, `entity.set`, and `entity.remove` to change the component
95
+ * set.
79
96
  *
80
- * If the component is already present the existing instance is returned and
81
- * no callback is fired. Pass `markAsModified = false` to suppress the
82
- * initial `onSet` / `update` notification (useful when bulk-loading
83
- * network snapshots before systems are running).
97
+ * ```ts
98
+ * entity.components.forEach((c) => console.log(c.constructor.name));
99
+ * ```
100
+ */
101
+ get components(): ReadonlyArrayMap<Component>;
102
+ /**
103
+ * Reparent this entity. In deferred mode the change is queued; outside
104
+ * deferred mode it executes inline.
84
105
  *
85
- * @param Class - The component class to instantiate.
86
- * @param markAsModified - Whether to immediately queue an `update`
87
- * notification. Defaults to `true`.
88
- * @returns The new (or existing) component instance, typed as
89
- * `InstanceType<Class>`.
106
+ * @param newParent - New parent, or `undefined` to make this a root entity.
90
107
  */
91
- _add<C extends typeof Component>(Class: C, markAsModified?: boolean): InstanceType<C>;
108
+ setParent(newParent: Entity | undefined): void;
92
109
  /**
93
- * Add a component by its numeric type id.
110
+ * Mark `c` as having changed, queueing the corresponding `onSet` / `update`
111
+ * notifications.
94
112
  *
95
- * @param type - Numeric component type id (as returned by
96
- * {@link World.getComponentType}).
97
- * @param markAsModified - Whether to queue an update notification.
113
+ * Equivalent to `c.modified()` but returns the entity for chaining. Repeated
114
+ * calls before the world routes the modified command are coalesced via the
115
+ * component's dirty flag.
116
+ *
117
+ * @param c - Component instance whose data changed.
118
+ * @returns This entity, for chaining.
98
119
  */
99
- _add(type: number, markAsModified?: boolean): Component;
120
+ modified<C extends typeof Component>(c: InstanceType<C>): Entity;
100
121
  /**
101
- * Add a component of type `Class` to this entity and return the entity.
122
+ * Attach a component to this entity if it is not already present.
102
123
  *
103
- * If the component is already present the existing instance is returned and
104
- * no callback is fired. Pass `markAsModified = false` to suppress the
105
- * initial `onSet` / `update` notification (useful when bulk-loading
106
- * network snapshots before systems are running).
124
+ * Idempotent. Does not fire `onSet` use {@link set} when you want to apply
125
+ * data and notify watchers.
107
126
  *
108
- * @param Class - The component class to instantiate.
109
- * @param markAsModified - Whether to immediately queue an `update`
110
- * notification. Defaults to `true`.
127
+ * @param Class - Component class to instantiate.
111
128
  * @returns This entity, for chaining.
112
129
  */
113
- add<C extends typeof Component>(Class: C, markAsModified?: boolean): Entity;
130
+ add<C extends typeof Component>(Class: C): Entity;
114
131
  /**
115
- * Add a component by its numeric type id.
132
+ * Attach a component by numeric type id.
116
133
  *
117
- * @param type - Numeric component type id (as returned by
118
- * {@link World.getComponentType}).
119
- * @param markAsModified - Whether to queue an update notification.
134
+ * @param type - Numeric component type id.
135
+ * @returns This entity, for chaining.
120
136
  */
121
- add(type: number, markAsModified?: boolean): Entity;
137
+ add(type: number): Entity;
122
138
  /**
123
- * Add a component of type `Class` (if not already present), assign the
124
- * provided properties onto the instance, and return the entity for chaining.
139
+ * Attach a component (creating it if necessary), copy `props` onto the
140
+ * instance, and fire the `onSet` hook plus any `update` callbacks for the
141
+ * component type.
125
142
  *
126
- * @param Class - The component class to instantiate.
143
+ * In deferred mode `props` are not applied until the queued `Set` command is
144
+ * routed.
145
+ *
146
+ * @param Class - Component class to instantiate.
127
147
  * @param props - Properties to assign onto the component instance.
128
148
  * @returns This entity, for chaining.
129
149
  */
130
150
  set<C extends typeof Component>(Class: C, props: Partial<InstanceType<C>>): Entity;
131
151
  /**
132
- * Add a component by its numeric type id, assign the provided properties,
133
- * and return the entity for chaining.
152
+ * Attach a component by numeric type id and copy `props` onto it.
134
153
  *
135
154
  * @param type - Numeric component type id.
136
155
  * @param props - Properties to assign onto the component instance.
156
+ * @returns This entity, for chaining.
137
157
  */
138
158
  set(type: number, props: Partial<Component>): Entity;
139
159
  /**
140
- * Remove the component of the given class from this entity.
160
+ * Detach a component from this entity.
141
161
  *
142
- * The `onRemove` hook and any `exit` callbacks on matching systems are
143
- * called when archetype changes are flushed at the end of the next system
144
- * run. Does nothing if the component is not present.
162
+ * In deferred mode the removal is queued; `get(C)` continues to return the
163
+ * component until the queue drains. When applied, queries fire `exit`
164
+ * callbacks first and the `onRemove` hook fires last.
145
165
  *
146
- * @param Class - The component class to remove.
166
+ * @param Class - Component class to detach.
147
167
  */
148
168
  remove<C extends typeof Component>(Class: C): void;
149
169
  /**
150
- * Remove a component by its numeric type id.
170
+ * Detach a component by numeric type id.
151
171
  *
152
172
  * @param type - Numeric component type id.
153
173
  */
154
174
  remove(type: number): void;
155
- /** @internal Called by queries to deliver update notifications. */
156
- _notifyModified(component: Component): void;
157
175
  /**
158
- * Retrieve the component of type `Class`, or `undefined` if not present.
176
+ * Look up a component on this entity.
159
177
  *
160
178
  * @param typeOrClass - Component class or numeric type id.
161
- * @param get_deleted - If `true`, also search components that were removed
162
- * in the current frame but not yet garbage-collected. Useful inside
163
- * `exit` callbacks to read final component values.
164
- * @returns The component instance or `undefined`.
179
+ * @returns The component instance, or `undefined` when it is not attached.
165
180
  */
166
- get<C extends typeof Component>(typeOrClass: number | C, get_deleted?: boolean): InstanceType<C> | undefined;
181
+ get<C extends typeof Component>(typeOrClass: number | C): InstanceType<C> | undefined;
167
182
  /**
168
- * Typed event emitter for entity-level lifecycle events.
183
+ * Destroy this entity and recursively destroy its children.
169
184
  *
170
- * Currently emits one event:
171
- * - `"destroy"` fired just before the entity is fully torn down.
172
- *
173
- * The emitter is created lazily on first access.
174
- */
175
- get events(): EntityEvents;
176
- /** @internal */
177
- _hasQuery(q: Query): boolean;
178
- /** @internal Removes a query from this entity's tracking sets without firing any callbacks. */
179
- _purgeQuery(q: Query): void;
180
- /** @internal */
181
- _addQuery(q: Query): void;
182
- /** @internal */
183
- _removeQuery(q: Query): void;
184
- /** @internal */
185
- _updateQueries(): void;
186
- /** `true` when the entity has no components attached. */
187
- get empty(): boolean;
188
- /** @internal */
189
- _destroy(): void;
190
- /**
191
- * Destroy this entity and recursively destroy all of its children.
192
- *
193
- * All components are removed (triggering `onRemove` hooks and `exit`
194
- * callbacks), the entity is unregistered from the world, and the `"destroy"`
195
- * event is emitted. The entity must not be used after calling this method.
185
+ * Each component fires its `onRemove` hook, the `"destroy"` event is emitted
186
+ * just before teardown, and the entity is unregistered from the world.
187
+ * After destruction the entity must not be used.
196
188
  */
197
189
  destroy(): void;
198
- /** @internal */
199
- clearDeletedComponents(): void;
200
- /**
201
- * Iterate over every component currently attached to this entity.
202
- *
203
- * @param callback - Called with each component instance. Iteration order is
204
- * not guaranteed.
205
- */
206
- forEachComponent(callback: (c: Component) => void): void;
207
190
  /** Returns `"EntityN"` where N is the entity id. */
208
191
  toString(): string;
209
192
  }