@vworlds/vecs 1.0.10 → 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.
- package/README.md +218 -229
- package/dist/command.d.ts +1 -46
- package/dist/component.d.ts +51 -59
- package/dist/component.js +31 -25
- package/dist/component.js.map +1 -1
- package/dist/dsl.d.ts +34 -26
- package/dist/dsl.js +46 -20
- package/dist/dsl.js.map +1 -1
- package/dist/entity.d.ts +96 -106
- package/dist/entity.js +261 -190
- package/dist/entity.js.map +1 -1
- package/dist/filter.d.ts +31 -23
- package/dist/filter.js +24 -17
- package/dist/filter.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/package.json +3 -1
- package/dist/phase.d.ts +5 -28
- package/dist/phase.js +11 -10
- package/dist/phase.js.map +1 -1
- package/dist/query.d.ts +107 -144
- package/dist/query.js +200 -169
- package/dist/query.js.map +1 -1
- package/dist/system.d.ts +59 -87
- package/dist/system.js +114 -114
- package/dist/system.js.map +1 -1
- package/dist/util/array_map.d.ts +4 -55
- package/dist/util/array_map.js +35 -37
- package/dist/util/array_map.js.map +1 -1
- package/dist/util/bitset.d.ts +40 -50
- package/dist/util/bitset.js +76 -62
- package/dist/util/bitset.js.map +1 -1
- package/dist/util/events.d.ts +14 -18
- package/dist/util/events.js +24 -3
- package/dist/util/events.js.map +1 -1
- package/dist/util/ordered_set.d.ts +1 -17
- package/dist/util/ordered_set.js +74 -25
- package/dist/util/ordered_set.js.map +1 -1
- package/dist/world.d.ts +212 -224
- package/dist/world.js +368 -330
- package/dist/world.js.map +1 -1
- package/eslint-rules/internal-underscore.js +60 -0
- package/eslint.config.js +5 -0
- package/package.json +3 -1
package/dist/world.d.ts
CHANGED
|
@@ -4,21 +4,21 @@ import { Query } from "./query.js";
|
|
|
4
4
|
import { System } from "./system.js";
|
|
5
5
|
import { Filter } from "./filter.js";
|
|
6
6
|
import { type QueryDSL, type ExtractRequired } from "./dsl.js";
|
|
7
|
-
import { IPhase
|
|
8
|
-
import { type Command } from "./command.js";
|
|
7
|
+
import { IPhase } from "./phase.js";
|
|
9
8
|
/**
|
|
10
|
-
* The central ECS container.
|
|
9
|
+
* The central ECS container. One world per game session.
|
|
11
10
|
*
|
|
12
|
-
* A `World` owns
|
|
13
|
-
* pipeline.
|
|
11
|
+
* A `World` owns every entity, every registered component class, every
|
|
12
|
+
* registered query / system, and the update pipeline. The typical lifecycle:
|
|
14
13
|
*
|
|
15
|
-
* 1. **Register components** —
|
|
16
|
-
* {@link registerComponentType}) for every component class.
|
|
17
|
-
* 2. **
|
|
18
|
-
*
|
|
14
|
+
* 1. **Register components** — {@link registerComponent} (and optionally
|
|
15
|
+
* {@link registerComponentType}) for every component class you plan to use.
|
|
16
|
+
* 2. **Build the pipeline** — {@link addPhase} for every named phase, then
|
|
17
|
+
* {@link system} / {@link query} for each processor.
|
|
19
18
|
* 3. **Start** — call {@link start} to freeze component registration and
|
|
20
19
|
* distribute systems into their phases.
|
|
21
|
-
* 4. **Run loop** — call {@link runPhase}
|
|
20
|
+
* 4. **Run loop** — call {@link runPhase} per phase or {@link progress} for
|
|
21
|
+
* every phase, once per frame.
|
|
22
22
|
*
|
|
23
23
|
* ```ts
|
|
24
24
|
* const world = new World();
|
|
@@ -28,204 +28,234 @@ import { type Command } from "./command.js";
|
|
|
28
28
|
*
|
|
29
29
|
* world.system("Move")
|
|
30
30
|
* .requires(Position, Velocity)
|
|
31
|
-
* .
|
|
31
|
+
* .each([Position, Velocity], (e, [pos, vel]) => {
|
|
32
|
+
* pos.x += vel.vx;
|
|
33
|
+
* });
|
|
32
34
|
*
|
|
33
35
|
* world.start();
|
|
34
36
|
*
|
|
35
37
|
* // game loop:
|
|
36
|
-
* world.
|
|
38
|
+
* world.progress(now, delta);
|
|
37
39
|
* ```
|
|
40
|
+
*
|
|
41
|
+
* ## Deferred mode
|
|
42
|
+
*
|
|
43
|
+
* The world can be in **deferred mode**, in which case entity mutations
|
|
44
|
+
* (`add` / `set` / `remove` / `destroy` / `setParent` / `modified`) are
|
|
45
|
+
* queued instead of applied inline. Systems run inside an automatically
|
|
46
|
+
* deferred scope; user code can wrap arbitrary blocks with
|
|
47
|
+
* {@link beginDefer} / {@link endDefer} or {@link defer}. {@link flush}
|
|
48
|
+
* drains the queue at top level.
|
|
38
49
|
*/
|
|
39
50
|
export declare class World {
|
|
40
|
-
private _entities;
|
|
41
|
-
private componentNameTypeMap;
|
|
42
|
-
private _queries;
|
|
43
|
-
private Class2Meta;
|
|
44
|
-
private Type2Meta;
|
|
45
|
-
private localComponentCounter;
|
|
46
|
-
private componentRegistrationDisabled;
|
|
47
|
-
/** @internal Single ordered command queue used in deferred mode. */
|
|
48
|
-
private commandQueue;
|
|
49
|
-
/** @internal Nested `beginDefer` / `endDefer` count. */
|
|
50
|
-
private deferredDepth;
|
|
51
|
-
/** @internal True while `processCommandQueue` is iterating, to avoid re-entrant drains. */
|
|
52
|
-
private draining;
|
|
53
|
-
/** `true` when the world is in deferred mode — mutations are queued rather than applied immediately. */
|
|
54
|
-
get deferred(): boolean;
|
|
55
|
-
/** @internal */
|
|
56
|
-
_pipeline: Map<string, Phase>;
|
|
57
|
-
private eidCounter;
|
|
58
51
|
constructor();
|
|
59
|
-
/**
|
|
52
|
+
/** Read-only view of the live entities, keyed by entity id. */
|
|
60
53
|
get entities(): Omit<Map<number, Entity>, "set" | "delete" | "clear">;
|
|
61
|
-
/**
|
|
54
|
+
/** Read-only view of every registered query (includes systems). */
|
|
62
55
|
get queries(): ReadonlyArray<Query>;
|
|
63
56
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
57
|
+
* `true` while the world is in deferred mode — entity mutations are queued
|
|
58
|
+
* rather than applied inline. Equivalent to "the queue depth is non-zero or
|
|
59
|
+
* the world is currently draining".
|
|
60
|
+
*/
|
|
61
|
+
get deferred(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Enter deferred mode. Mutations made until the matching {@link endDefer}
|
|
64
|
+
* are queued instead of executing inline.
|
|
67
65
|
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
*
|
|
66
|
+
* Nested `beginDefer` / `endDefer` pairs are allowed; only the outermost
|
|
67
|
+
* `endDefer` triggers a queue drain.
|
|
68
|
+
*/
|
|
69
|
+
beginDefer(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Leave deferred mode. When the depth returns to zero the world drains the
|
|
72
|
+
* command queue (firing hooks and routing enter / exit / update events).
|
|
73
|
+
*/
|
|
74
|
+
endDefer(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Run `fn` inside a deferred scope. Equivalent to
|
|
77
|
+
* `beginDefer(); try { fn(); } finally { endDefer(); }`.
|
|
74
78
|
*
|
|
75
|
-
* @param
|
|
76
|
-
* @param onCreateCallback - Optional callback invoked only when a **new**
|
|
77
|
-
* entity is created, before it is returned. Use this to initialise
|
|
78
|
-
* bookkeeping (e.g. tracking it in a local set).
|
|
79
|
-
* @returns The existing or newly created entity.
|
|
79
|
+
* @param fn - Callback executed in deferred mode.
|
|
80
80
|
*/
|
|
81
|
-
|
|
81
|
+
defer(fn: () => void): void;
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
83
|
+
* Drain any commands queued at the top level (depth 0).
|
|
84
84
|
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
85
|
+
* Call between phases or after batch-loading network snapshots to surface
|
|
86
|
+
* accumulated mutations (firing hooks and routing enter / exit / update)
|
|
87
|
+
* before the next read or system run.
|
|
87
88
|
*/
|
|
88
|
-
|
|
89
|
+
flush(): void;
|
|
89
90
|
/**
|
|
90
|
-
*
|
|
91
|
+
* Pre-register a `componentName → typeId` mapping without binding a class.
|
|
91
92
|
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
93
|
+
* Useful when network messages refer to components by type id and the
|
|
94
|
+
* corresponding class may be registered later. Call this **before**
|
|
95
|
+
* {@link registerComponent} so the class picks up the server-assigned id
|
|
96
|
+
* rather than a locally generated one.
|
|
97
|
+
*
|
|
98
|
+
* @param componentName - String name used in network payloads.
|
|
99
|
+
* @param type - Numeric type id assigned by the server.
|
|
94
100
|
*/
|
|
95
|
-
|
|
101
|
+
registerComponentType(componentName: string, type: number): void;
|
|
96
102
|
/**
|
|
97
|
-
*
|
|
103
|
+
* Register a component class with the world.
|
|
98
104
|
*
|
|
99
|
-
* Must be called
|
|
100
|
-
* {@link
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
105
|
+
* Must be called before any entity uses the component. Registration is
|
|
106
|
+
* disabled once {@link start} (or {@link disableComponentRegistration}) is
|
|
107
|
+
* called.
|
|
108
|
+
*
|
|
109
|
+
* **Overloads:**
|
|
110
|
+
* - `registerComponent(Class)` — type id auto-assigned from the
|
|
111
|
+
* {@link registerComponentType} map, falling back to a local counter
|
|
112
|
+
* (≥ 256) if the name is not yet mapped.
|
|
113
|
+
* - `registerComponent(Class, type)` — explicit numeric type id.
|
|
114
|
+
* - `registerComponent(Class, componentName)` — auto-assigned id, custom
|
|
115
|
+
* display name (useful when the class name differs from the network name).
|
|
116
|
+
* - `registerComponent(Class, type, componentName)` — explicit id + name.
|
|
104
117
|
*
|
|
105
|
-
* @param
|
|
106
|
-
* @throws
|
|
118
|
+
* @param ComponentClass - Component class to register.
|
|
119
|
+
* @throws When the class has already been registered or registration is
|
|
120
|
+
* disabled.
|
|
107
121
|
*/
|
|
108
|
-
|
|
122
|
+
registerComponent(ComponentClass: typeof Component): void;
|
|
123
|
+
registerComponent(ComponentClass: typeof Component, type: number): void;
|
|
124
|
+
registerComponent(ComponentClass: typeof Component, componentName?: string): void;
|
|
125
|
+
registerComponent(ComponentClass: typeof Component, type: number, componentName: string): void;
|
|
109
126
|
/**
|
|
110
|
-
*
|
|
127
|
+
* Look up the {@link ComponentMeta} for a registered component.
|
|
111
128
|
*
|
|
112
|
-
* @param typeOrClass -
|
|
113
|
-
* @returns The corresponding
|
|
114
|
-
* @throws
|
|
129
|
+
* @param typeOrClass - Component class or numeric type id.
|
|
130
|
+
* @returns The corresponding meta record.
|
|
131
|
+
* @throws When no component with that class or type id has been registered.
|
|
115
132
|
*/
|
|
116
133
|
getComponentMeta(typeOrClass: ComponentClassOrType): ComponentMeta;
|
|
117
134
|
/**
|
|
118
135
|
* Resolve a component class or type id to its numeric type id.
|
|
119
136
|
*
|
|
120
|
-
* @param typeOrClass -
|
|
137
|
+
* @param typeOrClass - Component class or numeric type id.
|
|
121
138
|
* @returns The numeric type id.
|
|
122
139
|
*/
|
|
123
140
|
getComponentType(typeOrClass: ComponentClassOrType): number;
|
|
124
141
|
/**
|
|
125
|
-
*
|
|
126
|
-
* are queued instead of executing inline.
|
|
142
|
+
* Return the {@link Hook} for a component class.
|
|
127
143
|
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
144
|
+
* Hooks let you react to component lifecycle events (add / remove / set)
|
|
145
|
+
* without building a full {@link System}. The same hook is returned on every
|
|
146
|
+
* call — handlers stack on the underlying meta record.
|
|
130
147
|
*
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
*
|
|
135
|
-
*
|
|
148
|
+
* ```ts
|
|
149
|
+
* world.hook(Sprite)
|
|
150
|
+
* .onAdd(c => c.initialize(scene))
|
|
151
|
+
* .onRemove(c => c.destroy());
|
|
152
|
+
* ```
|
|
136
153
|
*
|
|
154
|
+
* @param C - Component class.
|
|
155
|
+
* @returns The hook bound to that component type.
|
|
137
156
|
*/
|
|
138
|
-
|
|
157
|
+
hook<T extends typeof Component>(C: T): Hook<InstanceType<T>>;
|
|
139
158
|
/**
|
|
159
|
+
* Declare a group of mutually exclusive components.
|
|
160
|
+
*
|
|
161
|
+
* Adding any component in the group to an entity that already has another
|
|
162
|
+
* member of the group automatically removes the previous member. Members
|
|
163
|
+
* not in the group are unaffected.
|
|
140
164
|
*
|
|
141
|
-
*
|
|
165
|
+
* ```ts
|
|
166
|
+
* world.setExclusiveComponents(Walking, Running, Idle);
|
|
167
|
+
* entity.add(Walking);
|
|
168
|
+
* entity.add(Running); // Walking is removed automatically
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* Each call defines one independent group. A component may belong to at
|
|
172
|
+
* most one group at a time; calling {@link setExclusiveComponents} with the
|
|
173
|
+
* same class again overwrites its group. Safe to call before or after
|
|
174
|
+
* {@link start}.
|
|
175
|
+
*
|
|
176
|
+
* @param components - Two or more component classes that cannot coexist.
|
|
177
|
+
* @throws When any class has not been registered.
|
|
142
178
|
*/
|
|
143
|
-
|
|
179
|
+
setExclusiveComponents(...components: (typeof Component)[]): void;
|
|
144
180
|
/**
|
|
145
|
-
*
|
|
181
|
+
* Set the starting value of the auto-incrementing entity id counter.
|
|
146
182
|
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
183
|
+
* Must be called **before** {@link start} (or
|
|
184
|
+
* {@link disableComponentRegistration}). Useful when the world runs
|
|
185
|
+
* alongside a server that owns a different id range — locally created
|
|
186
|
+
* client entities can start at a high offset to avoid collisions with
|
|
187
|
+
* server-assigned ids.
|
|
188
|
+
*
|
|
189
|
+
* @param min - First id assigned by {@link entity}.
|
|
190
|
+
* @throws When called after registration has been disabled.
|
|
150
191
|
*/
|
|
151
|
-
|
|
152
|
-
/** @internal Append a command to the queue. */
|
|
153
|
-
_enqueue(cmd: Command): void;
|
|
192
|
+
setEntityIdRange(min: number): void;
|
|
154
193
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
194
|
+
* Return the entity with id `eid`, creating it if it does not yet exist.
|
|
195
|
+
*
|
|
196
|
+
* Used by networking code to materialise server-assigned entities:
|
|
197
|
+
*
|
|
198
|
+
* ```ts
|
|
199
|
+
* const e = world.getOrCreateEntity(snapshot.eid, (e) => {
|
|
200
|
+
* networkEntities.add(e);
|
|
201
|
+
* });
|
|
202
|
+
* e.add(snapshot.type);
|
|
203
|
+
* ```
|
|
204
|
+
*
|
|
205
|
+
* @param eid - Entity id to look up or create.
|
|
206
|
+
* @param onCreateCallback - Optional callback invoked only when a new
|
|
207
|
+
* entity is created, before it is returned. Use it to initialise
|
|
208
|
+
* bookkeeping (e.g. tracking it in a local set).
|
|
209
|
+
* @returns The existing or newly created entity.
|
|
158
210
|
*/
|
|
159
|
-
|
|
211
|
+
getOrCreateEntity(eid: number, onCreateCallback?: (e: Entity) => void): Entity;
|
|
160
212
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
213
|
+
* Create a new entity with an auto-assigned id.
|
|
214
|
+
*
|
|
215
|
+
* The id counter starts at `0` (or at the value set by
|
|
216
|
+
* {@link setEntityIdRange}) and increments by one for each call. In
|
|
217
|
+
* deferred mode the new entity is queued onto the command queue and is not
|
|
218
|
+
* visible in {@link entities} until the queue drains.
|
|
163
219
|
*/
|
|
164
|
-
|
|
165
|
-
/** @internal Remove an entity from the world's entity map. Called by Entity._destroy. */
|
|
166
|
-
_unregisterEntity(entity: Entity): void;
|
|
220
|
+
entity(): Entity;
|
|
167
221
|
/**
|
|
168
|
-
*
|
|
222
|
+
* Look up an existing entity by id.
|
|
169
223
|
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* **Overloads:**
|
|
174
|
-
* - `registerComponent(Class)` — type id auto-assigned from the name map, or
|
|
175
|
-
* from a local counter (≥ 256) if the name is not yet mapped.
|
|
176
|
-
* - `registerComponent(Class, type)` — explicit numeric type id.
|
|
177
|
-
* - `registerComponent(Class, componentName)` — auto-assigned id, custom
|
|
178
|
-
* display name (useful when the class name differs from the network name).
|
|
179
|
-
* - `registerComponent(Class, type, componentName)` — explicit id + name.
|
|
180
|
-
*
|
|
181
|
-
* @param ComponentClass - The component class to register.
|
|
182
|
-
* @throws If the class has already been registered, or if registration is
|
|
183
|
-
* disabled.
|
|
224
|
+
* @param id - Numeric entity id.
|
|
225
|
+
* @returns The entity, or `undefined` when no entity with that id exists.
|
|
184
226
|
*/
|
|
185
|
-
|
|
186
|
-
registerComponent(ComponentClass: typeof Component, type: number): void;
|
|
187
|
-
registerComponent(ComponentClass: typeof Component, componentName?: string): void;
|
|
188
|
-
registerComponent(ComponentClass: typeof Component, type: number, componentName: string): void;
|
|
227
|
+
entity(id: number): Entity | undefined;
|
|
189
228
|
/**
|
|
190
|
-
*
|
|
191
|
-
* class.
|
|
192
|
-
*
|
|
193
|
-
* Useful when network messages refer to components by type id and the
|
|
194
|
-
* corresponding class may be registered later. Call this before
|
|
195
|
-
* {@link registerComponent} to ensure the class picks up the server-assigned
|
|
196
|
-
* id rather than a locally generated one.
|
|
229
|
+
* Destroy every entity currently tracked by the world.
|
|
197
230
|
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
231
|
+
* Triggers all `onRemove` hooks and `exit` callbacks. Useful when
|
|
232
|
+
* transitioning between game sessions or resetting to a clean state.
|
|
200
233
|
*/
|
|
201
|
-
|
|
202
|
-
/** @internal Called by the {@link Query} constructor to register itself. */
|
|
203
|
-
_addQuery(q: Query): void;
|
|
204
|
-
/** @internal Called by {@link Query.destroy} to unregister a query and remove it from all entities. */
|
|
205
|
-
_removeQuery(q: Query): void;
|
|
234
|
+
clearAllEntities(): void;
|
|
206
235
|
/**
|
|
207
|
-
* Create a new {@link System},
|
|
236
|
+
* Create, register, and return a new {@link System}, ready for fluent
|
|
237
|
+
* configuration.
|
|
208
238
|
*
|
|
209
239
|
* ```ts
|
|
210
240
|
* world.system("Render")
|
|
211
241
|
* .phase("update")
|
|
212
242
|
* .requires(Position, Sprite)
|
|
213
243
|
* .enter([Sprite], (e, [sprite]) => sprite.initialize(scene))
|
|
214
|
-
* .
|
|
244
|
+
* .each([Position, Sprite], (e, [pos, sprite]) => sprite.draw(pos.x, pos.y));
|
|
215
245
|
* ```
|
|
216
246
|
*
|
|
217
|
-
* @param name -
|
|
218
|
-
* @returns The new
|
|
247
|
+
* @param name - Unique display name for the system.
|
|
248
|
+
* @returns The new system.
|
|
219
249
|
*/
|
|
220
|
-
system(name: string): System
|
|
250
|
+
system(name: string): System;
|
|
221
251
|
/**
|
|
222
|
-
* Create a standalone {@link Query},
|
|
252
|
+
* Create, register, and return a standalone {@link Query}, ready for fluent
|
|
223
253
|
* configuration.
|
|
224
254
|
*
|
|
225
255
|
* Unlike a {@link System}, a standalone query has no phase and no per-tick
|
|
226
|
-
* callbacks — it is a reactive
|
|
227
|
-
*
|
|
228
|
-
*
|
|
256
|
+
* callbacks — it is a reactive entity set that can be read at any time. It
|
|
257
|
+
* can also be created **after** {@link start}; existing matched entities
|
|
258
|
+
* are backfilled immediately.
|
|
229
259
|
*
|
|
230
260
|
* ```ts
|
|
231
261
|
* const enemies = world.query("Enemies")
|
|
@@ -236,81 +266,44 @@ export declare class World {
|
|
|
236
266
|
* // enemies.entities is kept up-to-date automatically
|
|
237
267
|
* ```
|
|
238
268
|
*
|
|
239
|
-
* @param name -
|
|
240
|
-
* @returns The new
|
|
269
|
+
* @param name - Unique display name for the query.
|
|
270
|
+
* @returns The new query.
|
|
241
271
|
*/
|
|
242
|
-
query(name: string): Query
|
|
272
|
+
query(name: string): Query;
|
|
243
273
|
/**
|
|
244
274
|
* Create a non-reactive {@link Filter} that matches entities satisfying `q`.
|
|
245
275
|
*
|
|
246
276
|
* Unlike {@link query}, the returned filter holds no tracked entity set and
|
|
247
|
-
* registers nothing
|
|
248
|
-
* all current world entities and invokes the callback
|
|
277
|
+
* registers nothing on the world. Each call to {@link Filter.forEach} walks
|
|
278
|
+
* all current world entities and invokes the callback on the matches.
|
|
249
279
|
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
* and `AND` of those forms). For
|
|
253
|
-
* (`OR`, `NOT`, `PARENT`, custom `EntityTestFunc`)
|
|
280
|
+
* The component classes guaranteed present on every matched entity are
|
|
281
|
+
* inferred from the DSL where possible (plain arrays, `HAS`, `HAS_ONLY`,
|
|
282
|
+
* and `AND` of those forms). For shapes the inferer cannot see through
|
|
283
|
+
* (`OR`, `NOT`, `PARENT`, custom `EntityTestFunc`) supply a `_guaranteed`
|
|
254
284
|
* tuple as a type-level override:
|
|
255
285
|
*
|
|
256
286
|
* ```ts
|
|
257
|
-
* // Auto-deduced
|
|
287
|
+
* // Auto-deduced: pos and vel are non-nullable.
|
|
258
288
|
* world.filter([Position, Velocity])
|
|
259
289
|
* .forEach([Position, Velocity], (e, [pos, vel]) => { ... });
|
|
260
290
|
*
|
|
261
|
-
* // Manual override for an opaque query
|
|
291
|
+
* // Manual override for an opaque query.
|
|
262
292
|
* world.filter(myTestFunc, [Position])
|
|
263
293
|
* .forEach([Position], (e, [pos]) => pos.x);
|
|
264
294
|
* ```
|
|
265
295
|
*
|
|
266
|
-
* @param q -
|
|
296
|
+
* @param q - Query expression.
|
|
267
297
|
* @param _guaranteed - Optional type hint declaring which components are
|
|
268
298
|
* guaranteed present (not validated at runtime).
|
|
269
299
|
*/
|
|
270
300
|
filter<Q extends QueryDSL>(q: Q): Filter<ExtractRequired<Q>>;
|
|
271
301
|
filter<T extends (typeof Component)[]>(q: QueryDSL, _guaranteed: readonly [...T]): Filter<T>;
|
|
272
302
|
/**
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* Called automatically by {@link start}. Can be called early if you want to
|
|
276
|
-
* lock component registration before systems are fully configured.
|
|
277
|
-
*/
|
|
278
|
-
disableComponentRegistration(): void;
|
|
279
|
-
/**
|
|
280
|
-
* Freeze component registration and prepare the world for running.
|
|
281
|
-
*
|
|
282
|
-
* Distributes all systems registered so far into their pipeline phases
|
|
283
|
-
* (defaulting to `"update"`) and logs the phase → system order to the
|
|
284
|
-
* console. Systems and queries can still be created after this call —
|
|
285
|
-
* standalone queries will immediately backfill existing matched entities.
|
|
286
|
-
*
|
|
287
|
-
* Call this once before the first {@link runPhase} call.
|
|
288
|
-
*/
|
|
289
|
-
start(): void;
|
|
290
|
-
private reindexSystems;
|
|
291
|
-
/**
|
|
292
|
-
* Return the {@link Hook} for a component class.
|
|
303
|
+
* Add a named phase to the update pipeline.
|
|
293
304
|
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
* component's {@link ComponentMeta} and the same object is returned on every
|
|
297
|
-
* call.
|
|
298
|
-
*
|
|
299
|
-
* ```ts
|
|
300
|
-
* world.hook(Sprite)
|
|
301
|
-
* .onAdd(c => c.initialize(scene))
|
|
302
|
-
* .onRemove(c => c.destroy());
|
|
303
|
-
* ```
|
|
304
|
-
*
|
|
305
|
-
* @param C - The component class.
|
|
306
|
-
* @returns The `Hook` for that component type.
|
|
307
|
-
*/
|
|
308
|
-
hook<T extends typeof Component>(C: T): Hook<InstanceType<T>>;
|
|
309
|
-
/**
|
|
310
|
-
* Add a named phase to the update pipeline and return it.
|
|
311
|
-
*
|
|
312
|
-
* Phases are executed in insertion order when you call {@link runPhase} for
|
|
313
|
-
* each one. Systems are assigned to a phase via {@link System.phase}.
|
|
305
|
+
* Phases are executed in insertion order when {@link runPhase} or
|
|
306
|
+
* {@link progress} is called. Systems join a phase via {@link System.phase}.
|
|
314
307
|
*
|
|
315
308
|
* ```ts
|
|
316
309
|
* const preUpdate = world.addPhase("preupdate");
|
|
@@ -319,52 +312,47 @@ export declare class World {
|
|
|
319
312
|
* ```
|
|
320
313
|
*
|
|
321
314
|
* @param name - Unique phase name. Systems can reference it by this string.
|
|
322
|
-
* @returns The new
|
|
315
|
+
* @returns The new phase.
|
|
323
316
|
*/
|
|
324
317
|
addPhase(name: string): IPhase;
|
|
325
318
|
/**
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
* Pending top-level mutations are drained at the start of the phase so the
|
|
329
|
-
* first system observes a consistent world. Each system's body runs in a
|
|
330
|
-
* deferred scope; mutations made by callbacks are appended to the world
|
|
331
|
-
* queue and processed by the world after the system returns, before the
|
|
332
|
-
* next system runs.
|
|
319
|
+
* Prevent any further calls to {@link registerComponent}.
|
|
333
320
|
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
* @param delta - Milliseconds elapsed since the previous tick.
|
|
321
|
+
* Called automatically by {@link start}. Call directly if you want to lock
|
|
322
|
+
* registration before the rest of the systems are wired up.
|
|
337
323
|
*/
|
|
338
|
-
|
|
324
|
+
disableComponentRegistration(): void;
|
|
339
325
|
/**
|
|
340
|
-
*
|
|
341
|
-
* registered via {@link addPhase}). Equivalent to calling
|
|
342
|
-
* {@link runPhase} for each phase manually.
|
|
326
|
+
* Freeze component registration and prepare the world for running.
|
|
343
327
|
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
328
|
+
* Distributes every system registered so far into its phase (defaulting to
|
|
329
|
+
* `"update"`) and logs the phase → system order to the console. Systems
|
|
330
|
+
* and queries can still be created after this call — standalone queries
|
|
331
|
+
* backfill existing matched entities immediately.
|
|
332
|
+
*
|
|
333
|
+
* Call once before the first {@link runPhase} / {@link progress}.
|
|
346
334
|
*/
|
|
347
|
-
|
|
335
|
+
start(): void;
|
|
348
336
|
/**
|
|
349
|
-
*
|
|
337
|
+
* Execute every system in `phase` for one tick.
|
|
350
338
|
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
339
|
+
* Pending top-level mutations are drained before the first system runs so
|
|
340
|
+
* each system observes a consistent world. Each system body executes in a
|
|
341
|
+
* deferred scope; mutations made by callbacks land in the world queue and
|
|
342
|
+
* are processed before the next system runs.
|
|
353
343
|
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
* ```
|
|
358
|
-
*
|
|
359
|
-
* @param components - Two or more component classes that cannot coexist.
|
|
360
|
-
* @throws If any class has not been registered.
|
|
344
|
+
* @param phase - Phase reference returned from {@link addPhase}.
|
|
345
|
+
* @param now - Absolute timestamp in milliseconds (e.g. `Date.now()`).
|
|
346
|
+
* @param delta - Milliseconds elapsed since the previous tick.
|
|
361
347
|
*/
|
|
362
|
-
|
|
348
|
+
runPhase(phase: IPhase, now: number, delta: number): void;
|
|
363
349
|
/**
|
|
364
|
-
*
|
|
350
|
+
* Run every phase in the pipeline in registration order.
|
|
365
351
|
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
352
|
+
* Equivalent to calling {@link runPhase} for each phase manually.
|
|
353
|
+
*
|
|
354
|
+
* @param now - Absolute timestamp in milliseconds (e.g. `Date.now()`).
|
|
355
|
+
* @param delta - Milliseconds elapsed since the previous tick.
|
|
368
356
|
*/
|
|
369
|
-
|
|
357
|
+
progress(now: number, delta: number): void;
|
|
370
358
|
}
|