@zylem/game-lib 0.6.4 → 0.8.0

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 (156) hide show
  1. package/README.md +18 -2
  2. package/dist/actions.d.ts +321 -11
  3. package/dist/actions.js +1 -936
  4. package/dist/api/game-lib.api.json +54074 -0
  5. package/dist/api/game-lib.api.md +4544 -0
  6. package/dist/api/game-lib.d.ts +8258 -0
  7. package/dist/api/game-lib.typedoc.json +345421 -0
  8. package/dist/audio.d.ts +13 -0
  9. package/dist/audio.js +1 -0
  10. package/dist/base-node-life-cycle-D2NuN1VB.d.ts +151 -0
  11. package/dist/behavior.d.ts +2 -0
  12. package/dist/behavior.js +1 -0
  13. package/dist/blueprints-TbGY-h53.d.ts +162 -0
  14. package/dist/chunk-4QLJUQSJ.js +1 -0
  15. package/dist/chunk-7FR5JSQ2.js +1 -0
  16. package/dist/chunk-7GYFZKK7.js +1 -0
  17. package/dist/chunk-7WRQ2UAN.js +1 -0
  18. package/dist/chunk-BH53MBAZ.js +1 -0
  19. package/dist/chunk-BIGH6D34.js +0 -0
  20. package/dist/chunk-CM5YRNBJ.js +19 -0
  21. package/dist/chunk-COM6HJ2L.js +1 -0
  22. package/dist/chunk-D2PATZCC.js +1 -0
  23. package/dist/chunk-DFLI7ICU.js +0 -0
  24. package/dist/chunk-E3UBSUPX.js +1 -0
  25. package/dist/chunk-FKIKN7RP.js +24 -0
  26. package/dist/chunk-G4HONLWC.js +1 -0
  27. package/dist/chunk-IKWE2W6L.js +1 -0
  28. package/dist/chunk-IPWUDOV5.js +1 -0
  29. package/dist/chunk-JEHFHUH4.js +0 -0
  30. package/dist/chunk-JNKPTL77.js +1 -0
  31. package/dist/chunk-JQKS42G4.js +1 -0
  32. package/dist/chunk-M3XNO56P.js +1 -0
  33. package/dist/chunk-MSC2BEO5.js +1 -0
  34. package/dist/chunk-ORIDWL3T.js +0 -0
  35. package/dist/chunk-QB3NL7VQ.js +1 -0
  36. package/dist/chunk-QXVH6POE.js +1 -0
  37. package/dist/chunk-RXDTAWI2.js +29 -0
  38. package/dist/chunk-TAUWDQZF.js +9 -0
  39. package/dist/chunk-VS2D4B3W.js +1 -0
  40. package/dist/chunk-WQ3WMMZD.js +1 -0
  41. package/dist/chunk-XK63E4SX.js +1 -0
  42. package/dist/chunk-XNDS4YFR.js +1 -0
  43. package/dist/chunk-XNHVRFAK.js +1 -0
  44. package/dist/chunk-XRP4JJXL.js +1 -0
  45. package/dist/chunk-YHEWKN7N.js +1 -0
  46. package/dist/chunk-ZRT3ZQVH.js +1 -0
  47. package/dist/collision-builder-jF-toPIl.d.ts +38 -0
  48. package/dist/core.d.ts +223 -16
  49. package/dist/core.js +1 -12424
  50. package/dist/debug-state-BPT6jEog.d.ts +17 -0
  51. package/dist/debug.d.ts +76 -0
  52. package/dist/debug.js +1 -0
  53. package/dist/default-controls-0-vCnli7.d.ts +111 -0
  54. package/dist/{entity-vj-HTjzU.d.ts → entity-BdSI8CL3.d.ts} +119 -626
  55. package/dist/{entity-Bq_eNEDI.d.ts → entity-DZbFQ1Wg.d.ts} +4 -4
  56. package/dist/entity-type-map-Bd69SpAS.d.ts +928 -0
  57. package/dist/entity.d.ts +268 -0
  58. package/dist/entity.js +1 -0
  59. package/dist/events.d.ts +181 -0
  60. package/dist/events.js +1 -0
  61. package/dist/game-C1FHVqXl.d.ts +1886 -0
  62. package/dist/game-default-QHROHW2O.js +1 -0
  63. package/dist/game-interfaces-mchNYSZE.d.ts +90 -0
  64. package/dist/globals.d.ts +115 -0
  65. package/dist/globals.js +1 -0
  66. package/dist/graphics.d.ts +53 -0
  67. package/dist/graphics.js +1 -0
  68. package/dist/input-ui.d.ts +35 -0
  69. package/dist/input-ui.js +1 -0
  70. package/dist/input.d.ts +73 -0
  71. package/dist/input.js +1 -0
  72. package/dist/material-9vJ6SZaI.d.ts +126 -0
  73. package/dist/public.d.ts +38 -0
  74. package/dist/public.js +1 -0
  75. package/dist/runtime.d.ts +59 -0
  76. package/dist/runtime.js +1 -0
  77. package/dist/schema/entity.schema.json +244 -0
  78. package/dist/schema/game-config.schema.json +625 -0
  79. package/dist/schema/input-config.schema.json +499 -0
  80. package/dist/schema/stage-config.schema.json +93 -0
  81. package/dist/schema/stage.schema.json +271 -0
  82. package/dist/schema.d.ts +538 -0
  83. package/dist/schema.js +1 -0
  84. package/dist/stage-transition-CmGpV4tc.d.ts +46 -0
  85. package/dist/vector-CiSHbivc.d.ts +133 -0
  86. package/dist/web-components.d.ts +70 -0
  87. package/dist/web-components.js +1 -0
  88. package/dist/zylem-camera-C3bn6BTI.d.ts +575 -0
  89. package/package.json +70 -73
  90. package/dist/actions.js.map +0 -1
  91. package/dist/behavior/jumper-2d.d.ts +0 -114
  92. package/dist/behavior/jumper-2d.js +0 -711
  93. package/dist/behavior/jumper-2d.js.map +0 -1
  94. package/dist/behavior/platformer-3d.d.ts +0 -296
  95. package/dist/behavior/platformer-3d.js +0 -761
  96. package/dist/behavior/platformer-3d.js.map +0 -1
  97. package/dist/behavior/ricochet-2d.d.ts +0 -275
  98. package/dist/behavior/ricochet-2d.js +0 -425
  99. package/dist/behavior/ricochet-2d.js.map +0 -1
  100. package/dist/behavior/ricochet-3d.d.ts +0 -117
  101. package/dist/behavior/ricochet-3d.js +0 -443
  102. package/dist/behavior/ricochet-3d.js.map +0 -1
  103. package/dist/behavior/screen-visibility.d.ts +0 -79
  104. package/dist/behavior/screen-visibility.js +0 -358
  105. package/dist/behavior/screen-visibility.js.map +0 -1
  106. package/dist/behavior/screen-wrap.d.ts +0 -87
  107. package/dist/behavior/screen-wrap.js +0 -246
  108. package/dist/behavior/screen-wrap.js.map +0 -1
  109. package/dist/behavior/shooter-2d.d.ts +0 -79
  110. package/dist/behavior/shooter-2d.js +0 -180
  111. package/dist/behavior/shooter-2d.js.map +0 -1
  112. package/dist/behavior/thruster.d.ts +0 -11
  113. package/dist/behavior/thruster.js +0 -292
  114. package/dist/behavior/thruster.js.map +0 -1
  115. package/dist/behavior/top-down-movement.d.ts +0 -56
  116. package/dist/behavior/top-down-movement.js +0 -125
  117. package/dist/behavior/top-down-movement.js.map +0 -1
  118. package/dist/behavior/world-boundary-2d.d.ts +0 -142
  119. package/dist/behavior/world-boundary-2d.js +0 -235
  120. package/dist/behavior/world-boundary-2d.js.map +0 -1
  121. package/dist/behavior/world-boundary-3d.d.ts +0 -76
  122. package/dist/behavior/world-boundary-3d.js +0 -274
  123. package/dist/behavior/world-boundary-3d.js.map +0 -1
  124. package/dist/behavior-descriptor-BXnVR8Ki.d.ts +0 -159
  125. package/dist/blueprints-DmbK2dki.d.ts +0 -26
  126. package/dist/camera-4XO5gbQH.d.ts +0 -905
  127. package/dist/camera.d.ts +0 -6
  128. package/dist/camera.js +0 -1993
  129. package/dist/camera.js.map +0 -1
  130. package/dist/composition-BASvMKrW.d.ts +0 -218
  131. package/dist/core-CARRaS55.d.ts +0 -541
  132. package/dist/core.js.map +0 -1
  133. package/dist/entities-ChFirVL9.d.ts +0 -410
  134. package/dist/entities.d.ts +0 -9
  135. package/dist/entities.js +0 -4986
  136. package/dist/entities.js.map +0 -1
  137. package/dist/entity-types-DAu8sGJH.d.ts +0 -26
  138. package/dist/global-change-2JvMaz44.d.ts +0 -25
  139. package/dist/main.d.ts +0 -1353
  140. package/dist/main.js +0 -19525
  141. package/dist/main.js.map +0 -1
  142. package/dist/physics-pose-DCc4oE44.d.ts +0 -25
  143. package/dist/physics-protocol-BDD3P5W2.d.ts +0 -200
  144. package/dist/physics-worker.d.ts +0 -21
  145. package/dist/physics-worker.js +0 -306
  146. package/dist/physics-worker.js.map +0 -1
  147. package/dist/physics.d.ts +0 -205
  148. package/dist/physics.js +0 -577
  149. package/dist/physics.js.map +0 -1
  150. package/dist/stage-types-C19IhuzA.d.ts +0 -731
  151. package/dist/stage.d.ts +0 -52
  152. package/dist/stage.js +0 -8479
  153. package/dist/stage.js.map +0 -1
  154. package/dist/sync-state-machine-CZyspBpj.d.ts +0 -16
  155. package/dist/thruster-23lzoPZd.d.ts +0 -180
  156. package/dist/world-DfgxoNMt.d.ts +0 -105
@@ -1,147 +1,10 @@
1
- import { Vector3, Vector2, Color, Material, BufferGeometry, Mesh, Group, ShaderMaterial } from 'three';
2
- import { Vector3 as Vector3$1, RigidBodyDesc, ColliderDesc, RigidBody, Vector, Collider } from '@dimforge/rapier3d-compat';
3
- import { IComponent } from 'bitecs';
4
- import * as mitt from 'mitt';
5
- import { c as BehaviorDescriptor, d as BehaviorHandle, e as BehaviorRef } from './behavior-descriptor-BXnVR8Ki.js';
6
-
7
- /** Input
8
- *
9
- * Maximum number of local players is 8.
10
- * All input can be mapped to a gamepad or keyboard but shares the common
11
- * interface represented as a gamepad.
12
- */
13
- type InputPlayerNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
14
- type InputPlayer = `p${InputPlayerNumber}`;
15
- interface ButtonState {
16
- pressed: boolean;
17
- released: boolean;
18
- held: number;
19
- }
20
- interface AnalogState {
21
- value: number;
22
- held: number;
23
- }
24
- interface InputGamepad {
25
- playerNumber: InputPlayerNumber;
26
- buttons: {
27
- A: ButtonState;
28
- B: ButtonState;
29
- X: ButtonState;
30
- Y: ButtonState;
31
- Start: ButtonState;
32
- Select: ButtonState;
33
- L: ButtonState;
34
- R: ButtonState;
35
- };
36
- directions: {
37
- Up: ButtonState;
38
- Down: ButtonState;
39
- Left: ButtonState;
40
- Right: ButtonState;
41
- };
42
- shoulders: {
43
- LTrigger: ButtonState;
44
- RTrigger: ButtonState;
45
- };
46
- axes: {
47
- Horizontal: AnalogState;
48
- Vertical: AnalogState;
49
- SecondaryHorizontal: AnalogState;
50
- SecondaryVertical: AnalogState;
51
- };
52
- /** Screen-space cursor position (normalized 0..1). Only populated by MouseProvider. */
53
- pointer?: {
54
- x: number;
55
- y: number;
56
- };
57
- }
58
- type Inputs = Record<InputPlayer, InputGamepad>;
59
- interface InputProvider {
60
- getInput(delta: number): Partial<InputGamepad>;
61
- isConnected(): boolean;
62
- getName(): string;
63
- dispose?(): void;
64
- }
65
-
66
- type LoadingEvent = {
67
- type: 'start' | 'progress' | 'complete';
68
- message?: string;
69
- progress?: number;
70
- total?: number;
71
- current?: number;
72
- };
73
- interface IGame<TGlobals extends Record<string, unknown> = any> {
74
- start: () => Promise<this>;
75
- nextStage: () => void;
76
- previousStage: () => void;
77
- reset: () => Promise<void>;
78
- pause: () => Promise<void>;
79
- resume: () => Promise<void>;
80
- onLoading: (callback: (event: LoadingEvent) => void) => void;
81
- loadStageFromId: (stageId: string) => Promise<void>;
82
- end: () => Promise<void>;
83
- goToStage: () => void;
84
- }
85
- interface IStage {
86
- onUpdate: (callback: UpdateFunction<IStage>) => void;
87
- onSetup: (callback: SetupFunction<IStage>) => void;
88
- onDestroy: (callback: DestroyFunction<IStage>) => void;
89
- }
90
- interface ICamera {
91
- move: (position: Vector3) => void;
92
- rotate: (pitch: number, yaw: number, roll: number) => void;
93
- }
94
-
95
- type GlobalRecord = Record<string, unknown>;
96
- /** Setup */
97
- interface SetupContext<T, TGlobals extends GlobalRecord = any> {
98
- me: T;
99
- globals: TGlobals;
100
- inputs?: Inputs;
101
- camera?: ICamera;
102
- stage?: IStage;
103
- game?: IGame<TGlobals>;
104
- }
105
- interface SetupFunction<T, TGlobals extends GlobalRecord = any> {
106
- (context: SetupContext<T, TGlobals>): void;
107
- }
108
- /** Loaded */
109
- interface LoadedContext<T, TGlobals extends GlobalRecord = any> {
110
- me: T;
111
- globals: TGlobals;
112
- }
113
- interface LoadedFunction<T, TGlobals extends GlobalRecord = any> {
114
- (context: LoadedContext<T, TGlobals>): void;
115
- }
116
- /** Update */
117
- type UpdateContext<T, TGlobals extends GlobalRecord = any> = {
118
- me: T;
119
- delta: number;
120
- inputs: Inputs;
121
- globals: TGlobals;
122
- camera: ICamera;
123
- stage?: IStage;
124
- game?: IGame<TGlobals>;
125
- };
126
- interface UpdateFunction<T, TGlobals extends GlobalRecord = any> {
127
- (context: UpdateContext<T, TGlobals>): void;
128
- }
129
- /** Destroy */
130
- interface DestroyContext<T, TGlobals extends GlobalRecord = any> {
131
- me: T;
132
- globals: TGlobals;
133
- }
134
- interface DestroyFunction<T, TGlobals extends GlobalRecord = any> {
135
- (context: DestroyContext<T, TGlobals>): void;
136
- }
137
- /** Cleanup */
138
- interface CleanupContext<T, TGlobals extends GlobalRecord = any> {
139
- me: T;
140
- globals: TGlobals;
141
- }
142
- interface CleanupFunction<T, TGlobals extends GlobalRecord = any> {
143
- (context: CleanupContext<T, TGlobals>): void;
144
- }
1
+ import { BufferGeometry, Material, Mesh, Group, Vector3, Color, ShaderMaterial } from 'three';
2
+ import { SimulationColliderDefinition, TransformState, SimulationBodyDefinition, MoveableEntity, BehaviorRuntime, Vector, BehaviorDescriptor, BehaviorHandle, BehaviorRef } from '@zylem/behaviors/core';
3
+ import { c as Vec3, e as Vec3Input, b as Vec2Input, l as SimulationBody } from './vector-CiSHbivc.js';
4
+ import { M as MaterialBuilder, e as MaterialOptions } from './material-9vJ6SZaI.js';
5
+ import { C as CollisionBuilder, a as CollisionOptions } from './collision-builder-jF-toPIl.js';
6
+ import { a as SetupContext, U as UpdateContext, D as DestroyContext, h as SetupFunction, i as LoadedFunction, g as UpdateFunction, j as DestroyFunction, C as CleanupFunction, k as LoadedContext, l as CleanupContext } from './base-node-life-cycle-D2NuN1VB.js';
7
+ import { EventEmitterDelegate, EntityEvents } from './events.js';
145
8
 
146
9
  interface NodeInterface {
147
10
  uuid: string;
@@ -170,7 +33,6 @@ declare abstract class BaseNode<Options = any, T = any> implements NodeInterface
170
33
  protected parent: NodeInterface | null;
171
34
  protected children: NodeInterface[];
172
35
  options: Options;
173
- eid: number;
174
36
  uuid: string;
175
37
  name: string;
176
38
  markedForRemoval: boolean;
@@ -237,484 +99,49 @@ declare abstract class BaseNode<Options = any, T = any> implements NodeInterface
237
99
  private recordLifecycleRegistration;
238
100
  }
239
101
 
240
- type Vec3 = Vector3 | Vector3$1;
241
-
242
- declare function shortHash(objString: string): string;
243
-
244
- /**
245
- * GLSL shader object (traditional approach for WebGL)
246
- */
247
- type ZylemShaderObject = {
248
- fragment: string;
249
- vertex: string;
250
- };
251
- /**
252
- * TSL shader type (for WebGPU)
253
- * colorNode should be a TSL node that returns the fragment color
254
- */
255
- type ZylemTSLShader = {
256
- colorNode: any;
257
- transparent?: boolean;
258
- };
259
- /**
260
- * Combined shader type supporting both GLSL and TSL
261
- */
262
- type ZylemShader = ZylemShaderObject | ZylemTSLShader;
263
- /**
264
- * Check if a shader is a TSL shader
265
- */
266
- declare function isTSLShader(shader: ZylemShader): shader is ZylemTSLShader;
267
- /**
268
- * Check if a shader is a GLSL shader
269
- */
270
- declare function isGLSLShader(shader: ZylemShader): shader is ZylemShaderObject;
271
- interface MaterialOptions {
272
- path?: string;
273
- normalMap?: string;
274
- repeat?: Vector2;
275
- shader?: ZylemShader;
276
- color?: Color;
277
- /** Opacity from 0 (fully transparent) to 1 (fully opaque). */
278
- opacity?: number;
279
- /**
280
- * When true, prefer TSL/NodeMaterial (for WebGPU)
281
- * When false, prefer GLSL/ShaderMaterial (for WebGL)
282
- */
283
- useTSL?: boolean;
284
- }
285
- type BatchGeometryMap = Map<symbol, number>;
286
- interface BatchMaterialMapObject {
287
- geometryMap: BatchGeometryMap;
288
- material: Material;
289
- }
290
- type BatchKey = ReturnType<typeof shortHash>;
291
- type TexturePath = string | null;
292
- declare class MaterialBuilder {
293
- static batchMaterialMap: Map<BatchKey, BatchMaterialMapObject>;
294
- /**
295
- * Clear the static batch material cache.
296
- * Should be called during game disposal to prevent stale material references
297
- * from persisting across demo/stage switches.
298
- */
299
- static clearBatchCache(): void;
300
- materials: Material[];
301
- /** Whether to use TSL/NodeMaterial (for WebGPU compatibility) */
302
- private useTSL;
303
- constructor(useTSL?: boolean);
304
- batchMaterial(options: Partial<MaterialOptions>, entityType: symbol): void;
305
- build(options: Partial<MaterialOptions>, entityType: symbol): void;
306
- withColor(color: Color, useTSL?: boolean, opacity?: number): this;
307
- withShader(shader: ZylemShaderObject, opacity?: number): this;
308
- withTSLShader(shader: ZylemTSLShader, opacity?: number): this;
309
- private applyOpacity;
310
- /**
311
- * Set texture - loads in background (deferred).
312
- * Material is created immediately with null map, texture applies when loaded.
313
- */
314
- setTexture(texturePath?: TexturePath, repeat?: Vector2, useTSL?: boolean, opacity?: number): void;
315
- /**
316
- * Set normal map for the current material
317
- */
318
- setNormalMap(normalMapPath: string, repeat?: Vector2): void;
319
- setColor(color: Color, useTSL?: boolean, opacity?: number): void;
320
- /**
321
- * Set GLSL shader (WebGL only)
322
- */
323
- setShader(customShader: ZylemShaderObject, opacity?: number): void;
324
- /**
325
- * Set TSL shader (WebGPU compatible)
326
- */
327
- setTSLShader(tslShader: ZylemTSLShader, opacity?: number): void;
328
- }
329
-
330
- /**
331
- * Options for configuring entity collision behavior.
332
- */
333
- interface CollisionOptions {
334
- static?: boolean;
335
- sensor?: boolean;
336
- size?: Vector3$1;
337
- position?: Vector3$1;
338
- collisionType?: string;
339
- collisionFilter?: string[];
340
- }
341
- declare class CollisionBuilder {
342
- static: boolean;
343
- sensor: boolean;
344
- gravity: Vec3;
345
- build(options: Partial<CollisionOptions>): [RigidBodyDesc, ColliderDesc];
346
- withCollision(collisionOptions: Partial<CollisionOptions>): this;
347
- collider(options: CollisionOptions): ColliderDesc;
348
- bodyDesc({ isDynamicBody }: {
349
- isDynamicBody?: boolean | undefined;
350
- }): RigidBodyDesc;
351
- }
352
-
353
102
  /**
354
103
  * TODO: allow for multiple materials requires geometry groups
355
104
  * TODO: allow for instanced uniforms
356
105
  * TODO: allow for geometry groups
357
- * TODO: allow for batched meshes
358
- * import { InstancedUniformsMesh } from 'three-instanced-uniforms-mesh';
359
- * may not need geometry groups for shaders though
360
- * setGeometry<T extends BufferGeometry>(geometry: T) {
361
- * MeshBuilder.bachedMesh = new BatchedMesh(10, 5000, 10000, material);
362
- * }
363
106
  */
364
- type MeshBuilderOptions = Partial<Pick<GameEntityOptions, 'batched' | 'material'>>;
107
+ type MeshBuilderOptions = Partial<Pick<GameEntityOptions, 'material'>>;
365
108
  declare class MeshBuilder {
366
- _build(meshOptions: MeshBuilderOptions, geometry: BufferGeometry, materials: Material[]): Mesh;
109
+ _build(_meshOptions: MeshBuilderOptions, geometry: BufferGeometry, materials: Material[]): Mesh;
367
110
  _postBuild(): void;
368
111
  }
369
112
 
370
113
  declare abstract class EntityCollisionBuilder extends CollisionBuilder {
371
- abstract collider(options: GameEntityOptions): ColliderDesc;
114
+ abstract collider(options: GameEntityOptions): SimulationColliderDefinition;
372
115
  }
373
116
  declare abstract class EntityMeshBuilder extends MeshBuilder {
374
117
  build(options: GameEntityOptions): BufferGeometry;
375
118
  postBuild(): void;
376
119
  }
377
-
378
- interface Behavior {
379
- component: IComponent;
380
- values: any;
381
- }
382
-
383
- /**
384
- * Reusable delegate for event emission and subscription.
385
- * Use via composition in Game, Stage, and Entity classes.
386
- *
387
- * @example
388
- * class Game {
389
- * private eventDelegate = new EventEmitterDelegate<GameEvents>();
390
- *
391
- * dispatch<K extends keyof GameEvents>(event: K, payload: GameEvents[K]) {
392
- * this.eventDelegate.dispatch(event, payload);
393
- * }
394
- * }
395
- */
396
- declare class EventEmitterDelegate<TEvents extends Record<string, unknown>> {
397
- private emitter;
398
- private unsubscribes;
399
- constructor();
400
- /**
401
- * Dispatch an event to all listeners.
402
- */
403
- dispatch<K extends keyof TEvents>(event: K, payload: TEvents[K]): void;
404
- /**
405
- * Subscribe to an event. Returns an unsubscribe function.
406
- */
407
- listen<K extends keyof TEvents>(event: K, handler: (payload: TEvents[K]) => void): () => void;
408
- /**
409
- * Subscribe to all events.
410
- */
411
- listenAll(handler: (type: keyof TEvents, payload: TEvents[keyof TEvents]) => void): () => void;
412
- /**
413
- * Clean up all subscriptions.
414
- */
415
- dispose(): void;
120
+ declare abstract class EntityBuilder<T extends GameEntity<U> & P, U extends GameEntityOptions, P = any> {
121
+ protected meshBuilder: EntityMeshBuilder | null;
122
+ protected collisionBuilder: EntityCollisionBuilder | null;
123
+ protected materialBuilder: MaterialBuilder | null;
124
+ protected options: Partial<U>;
125
+ protected entity: T;
126
+ constructor(options: Partial<U>, entity: T, meshBuilder: EntityMeshBuilder | null, collisionBuilder: EntityCollisionBuilder | null);
127
+ withPosition(setupPosition: Vec3): this;
128
+ withMaterial(options: Partial<MaterialOptions>, entityType: symbol): this;
129
+ applyMaterialToGroup(group: Group, materials: Material[]): void;
130
+ build(): T;
131
+ protected abstract createEntity(options: Partial<U>): T;
416
132
  }
417
133
 
418
- /**
419
- * Payload for game loading events with stage context.
420
- */
421
- interface GameLoadingPayload extends LoadingEvent {
422
- stageName?: string;
423
- stageIndex?: number;
424
- }
425
- /** Payload for stage configuration sent to editor. */
426
- interface StageConfigPayload {
427
- id: string;
428
- backgroundColor: string;
429
- backgroundImage: string | null;
430
- gravity: {
431
- x: number;
432
- y: number;
433
- z: number;
434
- };
435
- inputs: Record<string, string[]>;
436
- variables: Record<string, unknown>;
437
- }
438
- /** Payload for entity configuration sent to editor. */
439
- interface EntityConfigPayload {
440
- uuid: string;
441
- name: string;
442
- type: string;
443
- position: {
444
- x: number;
445
- y: number;
446
- z: number;
447
- };
448
- rotation: {
449
- x: number;
450
- y: number;
451
- z: number;
452
- };
453
- scale: {
454
- x: number;
455
- y: number;
456
- z: number;
457
- };
458
- }
459
- /** Payload for state dispatch events from game to editor. */
460
- interface StateDispatchPayload {
461
- scope: 'game' | 'stage' | 'entity';
462
- path: string;
463
- value: unknown;
464
- previousValue?: unknown;
465
- config?: {
466
- id: string;
467
- aspectRatio: number;
468
- fullscreen: boolean;
469
- bodyBackground: string | undefined;
470
- internalResolution: {
471
- width: number;
472
- height: number;
473
- } | undefined;
474
- debug: boolean;
475
- } | null;
476
- stageConfig?: StageConfigPayload | null;
477
- entities?: EntityConfigPayload[] | null;
478
- }
479
- type GameEvents = {
480
- 'loading:start': GameLoadingPayload;
481
- 'loading:progress': GameLoadingPayload;
482
- 'loading:complete': GameLoadingPayload;
483
- 'paused': {
484
- paused: boolean;
485
- };
486
- 'debug': {
487
- enabled: boolean;
488
- };
489
- 'state:dispatch': StateDispatchPayload;
490
- };
491
- type StageEvents = {
492
- 'stage:loaded': {
493
- stageId: string;
494
- };
495
- 'stage:unloaded': {
496
- stageId: string;
497
- };
498
- 'stage:variable:changed': {
499
- key: string;
500
- value: unknown;
501
- };
502
- };
503
- type EntityEvents = {
504
- 'entity:spawned': {
505
- entityId: string;
506
- name: string;
507
- };
508
- 'entity:destroyed': {
509
- entityId: string;
510
- };
511
- 'entity:collision': {
512
- entityId: string;
513
- otherId: string;
514
- };
515
- 'entity:model:loading': {
516
- entityId: string;
517
- files: string[];
518
- };
519
- 'entity:model:loaded': {
520
- entityId: string;
521
- success: boolean;
522
- meshCount?: number;
523
- };
524
- 'entity:animation:loaded': {
525
- entityId: string;
526
- animationCount: number;
527
- };
528
- };
529
- type ZylemEvents = GameEvents & StageEvents & EntityEvents;
530
- /**
531
- * Global event bus for cross-package communication.
532
- *
533
- * Usage:
534
- * ```ts
535
- * import { zylemEventBus } from '@zylem/game-lib';
536
- *
537
- * // Subscribe
538
- * const unsub = zylemEventBus.on('loading:progress', (e) => console.log(e));
539
- *
540
- * // Emit
541
- * zylemEventBus.emit('loading:progress', { type: 'progress', progress: 0.5 });
542
- *
543
- * // Cleanup
544
- * unsub();
545
- * ```
546
- */
547
- declare const zylemEventBus: mitt.Emitter<ZylemEvents>;
548
-
549
- type VelocityIntentMode = 'replace' | 'add';
550
- interface VelocityIntent {
551
- x?: number;
552
- y?: number;
553
- z?: number;
554
- mode: VelocityIntentMode;
555
- priority?: number;
556
- }
557
- /**
558
- * Transform state managed by Valtio for batched physics updates.
559
- *
560
- * This store accumulates transformation intents during the frame,
561
- * then applies them all at once after onUpdate() callbacks complete.
562
- *
563
- * Design decisions:
564
- * - Position: Accumulated deltas (additive)
565
- * - Rotation: Last value wins (replacement)
566
- * - Velocity: Accumulated deltas (additive)
567
- * - Angular velocity: Accumulated deltas (additive)
568
- */
569
- interface TransformState {
570
- /** Position deltas to be applied (accumulated) */
571
- position: {
572
- x: number;
573
- y: number;
574
- z: number;
575
- };
576
- /** Rotation quaternion (last value wins) */
577
- rotation: {
134
+ /** Structural slice of the physics body used by rotation helpers. */
135
+ interface RotatableBodyLike {
136
+ rotation(): {
578
137
  x: number;
579
138
  y: number;
580
139
  z: number;
581
140
  w: number;
582
141
  };
583
- /** Linear velocity (accumulated) */
584
- velocity: {
585
- x: number;
586
- y: number;
587
- z: number;
588
- };
589
- /** Angular velocity (accumulated) */
590
- angularVelocity: {
591
- x: number;
592
- y: number;
593
- z: number;
594
- };
595
- /** Per-source velocity intents composed once per frame */
596
- velocityChannels: Record<string, VelocityIntent>;
597
- /** Dirty flags to track what needs to be applied */
598
- dirty: {
599
- position: boolean;
600
- rotation: boolean;
601
- /** @deprecated Use per-axis velocityX/Y/Z flags for new code */
602
- velocity: boolean;
603
- velocityX: boolean;
604
- velocityY: boolean;
605
- velocityZ: boolean;
606
- velocityChannels: boolean;
607
- angularVelocity: boolean;
608
- };
609
- }
610
- /**
611
- * Create a new transform store with optional initial values.
612
- * The store is a Valtio proxy, making it reactive for debugging/visualization.
613
- *
614
- * @param initial Optional initial state values
615
- * @returns Reactive transform state
616
- */
617
- declare function createTransformStore(initial?: Partial<TransformState>): TransformState;
618
- /**
619
- * Reset a transform store to its initial clean state.
620
- * Called after applying changes to prepare for the next frame.
621
- *
622
- * @param store The transform store to reset
623
- */
624
- declare function resetTransformStore(store: TransformState): void;
625
-
626
- interface EntityWithBody {
627
- body: RigidBody | null;
628
- transformStore?: TransformState;
629
- }
630
- /**
631
- * Move an entity along the X axis, preserving other velocities.
632
- */
633
- declare function moveX(entity: EntityWithBody, delta: number): void;
634
- /**
635
- * Move an entity along the Y axis, preserving other velocities.
636
- */
637
- declare function moveY(entity: EntityWithBody, delta: number): void;
638
- /**
639
- * Move an entity along the Z axis, preserving other velocities.
640
- */
641
- declare function moveZ(entity: EntityWithBody, delta: number): void;
642
- /**
643
- * Move an entity along the X and Y axis, preserving Z velocity.
644
- */
645
- declare function moveXY(entity: EntityWithBody, deltaX: number, deltaY: number): void;
646
- /**
647
- * Move an entity along the X and Z axis, preserving Y velocity.
648
- */
649
- declare function moveXZ(entity: EntityWithBody, deltaX: number, deltaZ: number): void;
650
- /**
651
- * Move entity based on a vector, adding to existing velocities.
652
- */
653
- declare function move(entity: EntityWithBody, vector: Vector3): void;
654
- /**
655
- * Reset entity velocity
656
- */
657
- declare function resetVelocity(entity: EntityWithBody): void;
658
- /**
659
- * Move entity forward in 2D space, preserving Z velocity
660
- */
661
- declare function moveForwardXY(entity: EntityWithBody, delta: number, rotation2DAngle: number): void;
662
- /**
663
- * Get entity position
664
- */
665
- declare function getPosition(entity: EntityWithBody): Vector | null;
666
- /**
667
- * Get entity velocity
668
- */
669
- declare function getVelocity(entity: EntityWithBody): Vector | null;
670
- /**
671
- * Set entity position
672
- */
673
- declare function setPosition(entity: EntityWithBody, x: number, y: number, z: number): void;
674
- /**
675
- * Set entity X position
676
- */
677
- declare function setPositionX(entity: EntityWithBody, x: number): void;
678
- /**
679
- * Set entity Y position
680
- */
681
- declare function setPositionY(entity: EntityWithBody, y: number): void;
682
- /**
683
- * Set entity Z position
684
- */
685
- declare function setPositionZ(entity: EntityWithBody, z: number): void;
686
- /**
687
- * Wrap entity around 2D bounds
688
- */
689
- declare function wrapAroundXY(entity: EntityWithBody, boundsX: number, boundsY: number): void;
690
- /**
691
- * Wrap entity around 3D bounds
692
- */
693
- declare function wrapAround3D(entity: EntityWithBody, boundsX: number, boundsY: number, boundsZ: number): void;
694
- /**
695
- * Enhanced moveable entity with bound methods
696
- */
697
- interface MoveableEntity extends EntityWithBody {
698
- moveX(delta: number): void;
699
- moveY(delta: number): void;
700
- moveZ(delta: number): void;
701
- moveXY(deltaX: number, deltaY: number): void;
702
- moveXZ(deltaX: number, deltaZ: number): void;
703
- move(vector: Vector3): void;
704
- resetVelocity(): void;
705
- moveForwardXY(delta: number, rotation2DAngle: number): void;
706
- getPosition(): Vector | null;
707
- getVelocity(): Vector | null;
708
- setPosition(x: number, y: number, z: number): void;
709
- setPositionX(x: number): void;
710
- setPositionY(y: number): void;
711
- setPositionZ(z: number): void;
712
- wrapAroundXY(boundsX: number, boundsY: number): void;
713
- wrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void;
714
142
  }
715
-
716
143
  interface RotatableEntity {
717
- body: RigidBody | null;
144
+ body: RotatableBodyLike | null;
718
145
  group: any;
719
146
  transformStore?: TransformState;
720
147
  }
@@ -800,14 +227,14 @@ interface RotatableEntityAPI extends RotatableEntity {
800
227
  }
801
228
 
802
229
  /**
803
- * A built collision component containing a rigid body description and collider description.
804
- * Returned by collision factory functions (boxCollision, sphereCollision, etc.)
805
- * and consumed by GameEntity.add().
230
+ * A built collision component containing plain body and collider definitions
231
+ * for the behaviors `Simulation`. Returned by collision factory functions
232
+ * (boxCollision, sphereCollision, etc.) and consumed by GameEntity.add().
806
233
  */
807
234
  interface CollisionComponent {
808
235
  __kind: 'collision';
809
- bodyDesc: RigidBodyDesc;
810
- colliderDesc: ColliderDesc;
236
+ bodyDesc: SimulationBodyDefinition;
237
+ colliderDesc: SimulationColliderDefinition;
811
238
  cloneComponent: () => CollisionComponent;
812
239
  }
813
240
  interface BaseCollisionOptions {
@@ -815,8 +242,12 @@ interface BaseCollisionOptions {
815
242
  static?: boolean;
816
243
  /** Whether this collider is a sensor */
817
244
  sensor?: boolean;
245
+ /** Allow the body to sleep when at rest (recommended for bulk dynamic scenes) */
246
+ canSleep?: boolean;
247
+ /** Continuous collision detection (expensive at scale; disable for small boxes) */
248
+ ccdEnabled?: boolean;
818
249
  /** Position offset relative to the entity origin */
819
- offset?: Vec3;
250
+ offset?: Vec3Input;
820
251
  /** Collision type string for group filtering */
821
252
  collisionType?: string;
822
253
  /** Allowed collision types for filtering */
@@ -824,7 +255,7 @@ interface BaseCollisionOptions {
824
255
  }
825
256
  interface BoxCollisionOptions extends BaseCollisionOptions {
826
257
  /** Box dimensions (default: 1x1x1) */
827
- size?: Vec3;
258
+ size?: Vec3Input;
828
259
  }
829
260
  /**
830
261
  * Create a box (cuboid) collision component.
@@ -882,10 +313,7 @@ interface PillCollisionOptions extends BaseCollisionOptions {
882
313
  declare function pillCollision(opts?: PillCollisionOptions): CollisionComponent;
883
314
  interface PlaneCollisionOptions extends BaseCollisionOptions {
884
315
  /** Tile dimensions (default: 10x10) */
885
- tile?: {
886
- x: number;
887
- y: number;
888
- };
316
+ tile?: Vec2Input;
889
317
  /** Number of subdivisions per axis (default: 10) */
890
318
  subdivisions?: number;
891
319
  /** Pre-computed height data for the heightfield */
@@ -898,7 +326,7 @@ interface PlaneCollisionOptions extends BaseCollisionOptions {
898
326
  declare function planeCollision(opts?: PlaneCollisionOptions): CollisionComponent;
899
327
  interface ZoneCollisionOptions extends BaseCollisionOptions {
900
328
  /** Zone dimensions (default: 1x1x1) */
901
- size?: Vec3;
329
+ size?: Vec3Input;
902
330
  }
903
331
  /**
904
332
  * Create a zone (sensor cuboid) collision component.
@@ -958,12 +386,25 @@ type IBuilder<BuilderOptions = any> = {
958
386
  build: (options: BuilderOptions) => BuilderOptions;
959
387
  postBuild: (options: BuilderOptions) => BuilderOptions;
960
388
  };
389
+ type GameEntitySimulationMode = 'ts' | 'runtime';
390
+ /** Scene-direct, WebGPU bundle (static), or instanced pack. Default `none`. */
391
+ type RenderCategory = 'none' | 'environment' | 'pack';
392
+ type RuntimeEntityBodyMode = 'dynamic' | 'static' | 'none';
393
+ type RuntimeEntityColorMode = 'base' | 'heatTint';
394
+ interface RuntimeEntityOptions {
395
+ simulation?: GameEntitySimulationMode;
396
+ packKeyOverride?: string;
397
+ body?: RuntimeEntityBodyMode;
398
+ colorMode?: RuntimeEntityColorMode;
399
+ }
961
400
  type GameEntityOptions = {
962
401
  name?: string;
963
402
  color?: Color;
964
- size?: Vec3;
965
- position?: Vec3;
966
- batched?: boolean;
403
+ size?: Vec3Input;
404
+ position?: Vec3Input;
405
+ /** Render path: `environment` (bundle), `pack` (instanced), or `none` (default). */
406
+ category?: RenderCategory;
407
+ runtime?: RuntimeEntityOptions;
967
408
  collision?: Partial<CollisionOptions>;
968
409
  material?: Partial<MaterialOptions>;
969
410
  custom?: {
@@ -987,32 +428,54 @@ interface EntityDebugInfo {
987
428
  buildInfo: () => Record<string, string>;
988
429
  }
989
430
  declare class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implements GameEntityLifeCycle, EntityDebugInfo, MoveableEntity, RotatableEntityAPI {
990
- behaviors: Behavior[];
991
431
  group: Group | undefined;
992
432
  mesh: Mesh | undefined;
993
433
  materials: Material[] | undefined;
994
- bodyDesc: RigidBodyDesc | null;
995
- body: RigidBody | null;
434
+ bodyDesc: SimulationBodyDefinition | null;
435
+ body: SimulationBody | null;
996
436
  physicsAttached: boolean;
997
- colliderDesc: ColliderDesc | undefined;
998
- collider: Collider | undefined;
437
+ /**
438
+ * The physics world that currently owns this entity's body/colliders.
439
+ * Tagged on registration and checked on teardown so a stale world never
440
+ * frees handles another world now owns (which would poison the wasm
441
+ * simulation). Untyped to avoid a circular import.
442
+ */
443
+ physicsWorldRef: unknown;
444
+ colliderDesc: SimulationColliderDefinition | undefined;
999
445
  custom: Record<string, any>;
1000
446
  /** All collider descriptions for this entity (including primary) */
1001
- colliderDescs: ColliderDesc[];
1002
- /** All colliders attached to this entity's rigid body */
1003
- colliders: Collider[];
447
+ colliderDescs: SimulationColliderDefinition[];
1004
448
  /** Additional meshes for compound visual entities (added via add()) */
1005
449
  compoundMeshes: Mesh[];
1006
450
  debugInfo: Record<string, any>;
1007
451
  debugMaterial: ShaderMaterial | undefined;
1008
452
  collisionDelegate: CollisionDelegate<this, O>;
1009
453
  collisionType?: string;
1010
- /** Batch key for instanced rendering (null if not instanced) */
1011
- batchKey: string | null;
1012
- /** Index within the instanced mesh batch */
454
+ /** Pack key for instanced rendering (null if not instanced) */
455
+ packKey: string | null;
456
+ /** Bundle key for WebGPU bundle rendering (null if not bundled) */
457
+ bundleKey: string | null;
458
+ /** Index within the instanced mesh pack */
1013
459
  instanceId: number;
1014
460
  /** Whether this entity uses instanced rendering */
1015
461
  isInstanced: boolean;
462
+ /** Whether this entity is drawn via a WebGPU render bundle */
463
+ isBundled: boolean;
464
+ /**
465
+ * Raw wasm slot index for this entity in the stage's `Simulation`; -1 when
466
+ * not attached. Behavior systems address the runtime's slot-indexed buffers by
467
+ * this slot.
468
+ */
469
+ runtimeHandle: number;
470
+ /** True once the entity has been spawned into the wasm simulation. */
471
+ runtimeAttached: boolean;
472
+ /**
473
+ * The stage simulation's low-level runtime adapter. Set by
474
+ * `ZylemWorld.addEntity()` so {@link GameEntity.getPose} /
475
+ * {@link GameEntity.setPose} and behavior descriptors can route through
476
+ * the runtime without threading the handle around.
477
+ */
478
+ wasmStageRef: BehaviorRuntime | null;
1016
479
  protected eventDelegate: EventEmitterDelegate<EntityEvents>;
1017
480
  private behaviorRefs;
1018
481
  private cloneFactory;
@@ -1051,6 +514,34 @@ declare class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implem
1051
514
  setRotation: (x: number, y: number, z: number) => void;
1052
515
  getRotation: () => any;
1053
516
  constructor();
517
+ /**
518
+ * Read the entity's pose from the wasm simulation. Returns `null` when
519
+ * the entity has not been spawned into the runtime yet.
520
+ */
521
+ getPose(): {
522
+ position: Vec3;
523
+ rotation: {
524
+ x: number;
525
+ y: number;
526
+ z: number;
527
+ w: number;
528
+ };
529
+ } | null;
530
+ /**
531
+ * Write the entity's pose into the wasm simulation.
532
+ *
533
+ * Either or both of `position` and `rotation` may be omitted to leave
534
+ * that component unchanged.
535
+ */
536
+ setPose(input: {
537
+ position?: Vec3Input;
538
+ rotation?: {
539
+ x: number;
540
+ y: number;
541
+ z: number;
542
+ w: number;
543
+ };
544
+ }): boolean;
1054
545
  /**
1055
546
  * Add meshes, collision components, or child entities to this entity.
1056
547
  * Supports fluent chaining: `entity.add(boxMesh()).add(boxCollision())`.
@@ -1076,6 +567,8 @@ declare class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implem
1076
567
  * @example `const press = entity.action(onPress())`
1077
568
  */
1078
569
  action<A extends Action>(action: A): A;
570
+ /** Remove all registered actions (fire-and-forget and persistent). */
571
+ clearActions(): void;
1079
572
  /**
1080
573
  * Tick all registered actions. Called automatically before user onUpdate callbacks.
1081
574
  *
@@ -1166,4 +659,4 @@ declare class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implem
1166
659
  */
1167
660
  declare function create(options?: Partial<GameEntityOptions>): GameEntity<GameEntityOptions>;
1168
661
 
1169
- export { sphereCollision as $, type Action as A, setRotationZ as B, setRotationDegrees as C, setRotationDegreesY as D, setRotationDegreesX as E, setRotationDegreesZ as F, setRotation as G, getRotation as H, GameEntity as I, type UpdateFunction as J, type DestroyFunction as K, type SetupContext as L, type DestroyContext as M, type LoadingEvent as N, BaseNode as O, type GameEntityOptions as P, type StageEvents as Q, type MaterialOptions as R, type SetupFunction as S, type TransformState as T, type UpdateContext as U, type Vec3 as V, type MoveableEntity as W, type InputPlayer as X, create as Y, type ZylemShader as Z, boxCollision as _, moveX as a, coneCollision as a0, pyramidCollision as a1, cylinderCollision as a2, pillCollision as a3, planeCollision as a4, zoneCollision as a5, type CollisionComponent as a6, EventEmitterDelegate as a7, zylemEventBus as a8, type ZylemEvents as a9, type GameEvents as aa, type EntityEvents as ab, type GameLoadingPayload as ac, type StateDispatchPayload as ad, type StageConfigPayload as ae, type EntityConfigPayload as af, type ZylemShaderObject as ag, type ZylemTSLShader as ah, isTSLShader as ai, isGLSLShader as aj, type InputPlayerNumber as ak, type InputProvider as al, type Inputs as am, GameEntityLifeCycle as an, type IGame as ao, type LoadedContext as ap, type CleanupContext as aq, type NodeInterface as ar, type TexturePath as as, moveY as b, createTransformStore as c, moveZ as d, moveXY as e, moveXZ as f, resetVelocity as g, moveForwardXY as h, getPosition as i, getVelocity as j, setPositionX as k, setPositionY as l, move as m, setPositionZ as n, wrapAround3D as o, rotateInDirection as p, rotateYEuler as q, resetTransformStore as r, setPosition as s, rotateEuler as t, rotateX as u, rotateY as v, wrapAroundXY as w, rotateZ as x, setRotationY as y, setRotationX as z };
662
+ export { type Action as A, BaseNode as B, type CollisionComponent as C, EntityMeshBuilder as D, EntityBuilder as E, EntityCollisionBuilder as F, GameEntity as G, type NodeInterface as N, type GameEntityOptions as a, boxCollision as b, create as c, coneCollision as d, cylinderCollision as e, pillCollision as f, planeCollision as g, rotateYEuler as h, rotateEuler as i, rotateX as j, rotateY as k, rotateZ as l, setRotationY as m, setRotationX as n, setRotationZ as o, pyramidCollision as p, setRotationDegrees as q, rotateInDirection as r, sphereCollision as s, setRotationDegreesY as t, setRotationDegreesX as u, setRotationDegreesZ as v, setRotation as w, getRotation as x, GameEntityLifeCycle as y, zoneCollision as z };