@zylem/game-lib 0.7.0 → 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 (95) hide show
  1. package/README.md +15 -1
  2. package/dist/actions.d.ts +71 -8
  3. package/dist/actions.js +1 -1
  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.js +1 -1
  9. package/dist/{base-node-life-cycle-CnJ-7zX-.d.ts → base-node-life-cycle-D2NuN1VB.d.ts} +12 -4
  10. package/dist/behavior.d.ts +2 -3
  11. package/dist/behavior.js +1 -1
  12. package/dist/blueprints-TbGY-h53.d.ts +162 -0
  13. package/dist/chunk-7FR5JSQ2.js +1 -0
  14. package/dist/chunk-7GYFZKK7.js +1 -0
  15. package/dist/chunk-7WRQ2UAN.js +1 -0
  16. package/dist/chunk-BH53MBAZ.js +1 -0
  17. package/dist/chunk-BIGH6D34.js +0 -0
  18. package/dist/chunk-CM5YRNBJ.js +19 -0
  19. package/dist/chunk-COM6HJ2L.js +1 -0
  20. package/dist/chunk-D2PATZCC.js +1 -0
  21. package/dist/chunk-DFLI7ICU.js +0 -0
  22. package/dist/chunk-E3UBSUPX.js +1 -0
  23. package/dist/chunk-FKIKN7RP.js +24 -0
  24. package/dist/chunk-G4HONLWC.js +1 -0
  25. package/dist/chunk-IKWE2W6L.js +1 -0
  26. package/dist/chunk-IPWUDOV5.js +1 -0
  27. package/dist/chunk-JEHFHUH4.js +0 -0
  28. package/dist/chunk-JNKPTL77.js +1 -0
  29. package/dist/chunk-JQKS42G4.js +1 -0
  30. package/dist/chunk-M3XNO56P.js +1 -0
  31. package/dist/chunk-ORIDWL3T.js +0 -0
  32. package/dist/chunk-QB3NL7VQ.js +1 -0
  33. package/dist/chunk-TAUWDQZF.js +9 -0
  34. package/dist/chunk-VS2D4B3W.js +1 -0
  35. package/dist/chunk-WQ3WMMZD.js +1 -0
  36. package/dist/chunk-XK63E4SX.js +1 -0
  37. package/dist/chunk-XNDS4YFR.js +1 -0
  38. package/dist/chunk-XNHVRFAK.js +1 -0
  39. package/dist/chunk-ZRT3ZQVH.js +1 -0
  40. package/dist/collision-builder-jF-toPIl.d.ts +38 -0
  41. package/dist/core.d.ts +45 -30
  42. package/dist/core.js +1 -24
  43. package/dist/debug-state-BPT6jEog.d.ts +17 -0
  44. package/dist/debug.d.ts +71 -19
  45. package/dist/debug.js +1 -1
  46. package/dist/{default-controls-BGc61yYl.d.ts → default-controls-0-vCnli7.d.ts} +3 -3
  47. package/dist/{entity-DNkYKfdp.d.ts → entity-BdSI8CL3.d.ts} +63 -444
  48. package/dist/entity-DZbFQ1Wg.d.ts +28 -0
  49. package/dist/{entity-type-map-C94h2TDW.d.ts → entity-type-map-Bd69SpAS.d.ts} +153 -6
  50. package/dist/entity.d.ts +11 -8
  51. package/dist/entity.js +1 -1
  52. package/dist/events.d.ts +10 -1
  53. package/dist/events.js +1 -1
  54. package/dist/{game-Cuj5gy7U.d.ts → game-C1FHVqXl.d.ts} +429 -133
  55. package/dist/game-default-QHROHW2O.js +1 -0
  56. package/dist/{game-interfaces-tfpM5NBk.d.ts → game-interfaces-mchNYSZE.d.ts} +2 -2
  57. package/dist/globals.d.ts +12 -1
  58. package/dist/globals.js +1 -1
  59. package/dist/graphics.d.ts +16 -46
  60. package/dist/graphics.js +1 -1
  61. package/dist/input-ui.d.ts +5 -4
  62. package/dist/input-ui.js +1 -1
  63. package/dist/input.d.ts +4 -3
  64. package/dist/input.js +1 -1
  65. package/dist/{material-Wz83vTTp.d.ts → material-9vJ6SZaI.d.ts} +25 -50
  66. package/dist/public.d.ts +38 -0
  67. package/dist/public.js +1 -0
  68. package/dist/runtime.d.ts +7 -381
  69. package/dist/runtime.js +1 -1
  70. package/dist/schema/entity.schema.json +244 -0
  71. package/dist/schema/game-config.schema.json +625 -0
  72. package/dist/schema/input-config.schema.json +499 -0
  73. package/dist/schema/stage-config.schema.json +93 -0
  74. package/dist/schema/stage.schema.json +271 -0
  75. package/dist/schema.d.ts +538 -0
  76. package/dist/schema.js +1 -0
  77. package/dist/stage-transition-CmGpV4tc.d.ts +46 -0
  78. package/dist/vector-CiSHbivc.d.ts +133 -0
  79. package/dist/web-components.d.ts +15 -12
  80. package/dist/web-components.js +1 -9
  81. package/dist/{zylem-stage-runtime-Cs-UDEVU.d.ts → zylem-camera-C3bn6BTI.d.ts} +62 -264
  82. package/package.json +28 -20
  83. package/dist/chunk-73VZQZUL.js +0 -1
  84. package/dist/chunk-A34ZG3L4.js +0 -1
  85. package/dist/chunk-CDPY4VOQ.js +0 -1
  86. package/dist/chunk-DR6XXZE7.js +0 -19
  87. package/dist/chunk-FM5TBEPO.js +0 -1
  88. package/dist/chunk-G2IIMSUH.js +0 -1
  89. package/dist/chunk-NIH5CONO.js +0 -1
  90. package/dist/chunk-ONWXGBWB.js +0 -1
  91. package/dist/chunk-QEDQDR27.js +0 -1
  92. package/dist/chunk-WKHW2QO2.js +0 -1
  93. package/dist/chunk-YHKXQ2ZN.js +0 -1
  94. package/dist/game-default-PZLLHYL7.js +0 -1
  95. package/dist/world-C9zdyl5d.d.ts +0 -103
@@ -1,15 +1,16 @@
1
- import { d as InputPlayerNumber, e as InputProvider, a as Inputs, U as UpdateFunction, h as SetupFunction, j as DestroyFunction, S as SetupContext, f as UpdateContext, D as DestroyContext, g as LoadingEvent, l as IGame } from './base-node-life-cycle-CnJ-7zX-.js';
2
- import { G as GameInputConfig, B as BaseGlobals, Z as ZylemGameConfig } from './game-interfaces-tfpM5NBk.js';
3
- import { G as GameEntity, I as GameEntityOptions, W as WasmStageRuntimeOptions, M as BaseNode, p as WasmStageRuntime, _ as GameEntityLifeCycle } from './entity-DNkYKfdp.js';
4
- import { Object3D, BufferGeometry, Material, Group, Vector3, Texture, Color } from 'three';
5
- import { S as StageEntity, Z as ZylemWorld } from './world-C9zdyl5d.js';
6
- import { k as CameraPerspective, j as CameraContext, g as CameraPose, P as PerspectiveType, o as ZylemCamera, C as CameraBehavior, l as CameraAction, m as CameraPipelineState, e as RendererType, V as Viewport, S as StageRuntimeAdapter, R as RuntimeDebugBinding, p as ZylemScene, f as CameraManager, q as RendererManager } from './zylem-stage-runtime-Cs-UDEVU.js';
7
- import { RigidBody, Collider } from '@dimforge/rapier3d-compat';
8
- import { a as Vec3Input, b as Vec2Input, o as ZylemShader, V as Vec3Components } from './material-Wz83vTTp.js';
9
- import { BehaviorSystem, BehaviorEntityLink, BehaviorSystemFactory } from '@zylem/behaviors/core';
10
- import { ac as EntityTypeMap } from './entity-type-map-C94h2TDW.js';
1
+ import { e as InputPlayerNumber, f as InputProvider, I as Inputs, h as SetupFunction, g as UpdateFunction, j as DestroyFunction, a as SetupContext, U as UpdateContext, D as DestroyContext, L as LoadingEvent, m as IGame, S as StageNavigationOptions } from './base-node-life-cycle-D2NuN1VB.js';
2
+ import { G as GameInputConfig, B as BaseGlobals, Z as ZylemGameConfig } from './game-interfaces-mchNYSZE.js';
3
+ import { G as GameEntity, a as GameEntityOptions, B as BaseNode, y as GameEntityLifeCycle } from './entity-BdSI8CL3.js';
4
+ import { Scene, Color, Object3D, Vector3, BufferGeometry, Material, Group, Texture } from 'three';
5
+ import { ak as ZylemWorld, ai as EntityTypeMap } from './entity-type-map-Bd69SpAS.js';
6
+ import { E as Entity, L as LifecycleFunction, S as StageEntity } from './entity-DZbFQ1Wg.js';
7
+ import { k as ZylemCamera, R as RendererManager, e as CameraPerspective, d as CameraContext, C as CameraPose, P as PerspectiveType, f as CameraBehavior, g as CameraAction, h as CameraPipelineState, V as Viewport, Z as ZylemPostEffect } from './zylem-camera-C3bn6BTI.js';
8
+ import { d as ZylemShader } from './material-9vJ6SZaI.js';
9
+ import { l as SimulationBody, e as Vec3Input, b as Vec2Input, d as Vec3Components } from './vector-CiSHbivc.js';
10
+ import { BehaviorSystem, BehaviorEntityLink, BehaviorRuntime, BehaviorSystemFactory, Simulation } from '@zylem/behaviors/core';
11
11
  import { StageEvents, GameEvents } from './events.js';
12
- import { D as DefaultTouchControlsOptions } from './default-controls-BGc61yYl.js';
12
+ import { D as DefaultTouchControlsOptions } from './default-controls-0-vCnli7.js';
13
+ import { S as StageTransitionConfig } from './stage-transition-CmGpV4tc.js';
13
14
 
14
15
  declare class InputManager {
15
16
  private inputMap;
@@ -127,91 +128,291 @@ declare class Timer {
127
128
  }
128
129
 
129
130
  /**
130
- * Configuration for batch key generation
131
+ * CameraManager orchestrates multiple cameras per stage.
132
+ *
133
+ * Responsibilities:
134
+ * - Named camera registry (add/remove/get by name or reference)
135
+ * - Active camera list management (determines which cameras render)
136
+ * - Always-available debug camera with orbit controls
137
+ * - Per-frame update of all active cameras' perspective controllers
138
+ * - Coordinating rendering via RendererManager for all active viewports
131
139
  */
132
- interface BatchKeyConfig {
140
+ declare class CameraManager {
141
+ /** Named camera registry */
142
+ private cameras;
143
+ /** Currently active cameras, ordered by render layer (first = bottom) */
144
+ private _activeCameras;
145
+ /** Auto-created debug camera with orbit controls */
146
+ private _debugCamera;
147
+ /** Reference to the shared renderer manager */
148
+ private _rendererManager;
149
+ /** Scene reference */
150
+ private _sceneRef;
151
+ /** Counter for auto-generated camera names */
152
+ private _autoNameCounter;
153
+ constructor();
154
+ /**
155
+ * Get the list of currently active cameras.
156
+ */
157
+ get activeCameras(): ReadonlyArray<ZylemCamera>;
158
+ /**
159
+ * Get the primary active camera (first in the active list).
160
+ */
161
+ get primaryCamera(): ZylemCamera | null;
162
+ /**
163
+ * Get the debug camera.
164
+ */
165
+ get debugCamera(): ZylemCamera | null;
166
+ /**
167
+ * Get all registered cameras.
168
+ */
169
+ get allCameras(): ReadonlyArray<ZylemCamera>;
170
+ /**
171
+ * Add a camera to the manager.
172
+ * If no name is provided, one is auto-generated.
173
+ * The first camera added becomes the active camera.
174
+ *
175
+ * @param camera The ZylemCamera instance to add
176
+ * @param name Optional name for lookup
177
+ * @returns The assigned name
178
+ */
179
+ addCamera(camera: ZylemCamera, name?: string): string;
180
+ /**
181
+ * Remove a camera by name or reference.
182
+ * Cannot remove the debug camera via this method.
183
+ */
184
+ removeCamera(nameOrRef: string | ZylemCamera): boolean;
185
+ /**
186
+ * Set a camera as the primary active camera (replaces all active cameras
187
+ * except additional viewport cameras).
188
+ *
189
+ * @param nameOrRef Camera name or reference to activate
190
+ */
191
+ setActiveCamera(nameOrRef: string | ZylemCamera): boolean;
192
+ /**
193
+ * Add a camera as an additional active camera (for split-screen or PiP).
194
+ */
195
+ addActiveCamera(nameOrRef: string | ZylemCamera): boolean;
196
+ /**
197
+ * Remove a camera from the active render list (does not remove from registry).
198
+ */
199
+ deactivateCamera(nameOrRef: string | ZylemCamera): boolean;
200
+ /**
201
+ * Get a camera by name.
202
+ */
203
+ getCamera(name: string): ZylemCamera | null;
204
+ /**
205
+ * Setup all cameras with the given scene and renderer manager.
206
+ * Also creates the debug camera.
207
+ */
208
+ setup(scene: Scene, rendererManager: RendererManager): Promise<void>;
209
+ /**
210
+ * Update all active cameras' controllers.
211
+ */
212
+ update(delta: number): void;
213
+ /**
214
+ * Render all active cameras through the renderer manager.
215
+ * RTT cameras (those with a renderTarget) are rendered first to their
216
+ * offscreen textures, then viewport cameras are rendered to the screen.
217
+ */
218
+ render(scene: Scene): void;
219
+ private updateOrbitingCamerasForRender;
220
+ /**
221
+ * Create a default third-person camera if no cameras have been added.
222
+ */
223
+ ensureDefaultCamera(): ZylemCamera;
224
+ /**
225
+ * Dispose all cameras and cleanup.
226
+ */
227
+ dispose(): void;
228
+ /**
229
+ * Create the always-available debug camera with orbit controls.
230
+ */
231
+ private createDebugCamera;
232
+ /**
233
+ * Resolve a camera from a name or reference.
234
+ */
235
+ private resolveCamera;
236
+ }
237
+
238
+ interface SceneState {
239
+ backgroundColor: Color | string;
240
+ backgroundImage: string | null;
241
+ backgroundShader?: ZylemShader | null;
242
+ /**
243
+ * When `false`, skip the engine's built-in ambient + directional lights so
244
+ * the caller can configure the scene's lighting entirely via
245
+ * `createLight(...)` entities. Defaults to `true` for backward
246
+ * compatibility with existing demos.
247
+ */
248
+ defaultLighting?: boolean;
249
+ }
250
+ declare class ZylemScene implements Entity<ZylemScene> {
251
+ type: string;
252
+ _setup?: SetupFunction<ZylemScene>;
253
+ scene: Scene;
254
+ /** @deprecated Use cameraManager instead */
255
+ zylemCamera: ZylemCamera;
256
+ cameraManager: CameraManager | null;
257
+ containerElement: HTMLElement | null;
258
+ update: LifecycleFunction<ZylemScene>;
259
+ _collision?: ((entity: any, other: any, globals?: any) => void) | undefined;
260
+ _destroy?: ((globals?: any) => void) | undefined;
261
+ name?: string | undefined;
262
+ tag?: Set<string> | undefined;
263
+ constructor(id: string, camera: ZylemCamera, state: SceneState);
264
+ /**
265
+ * Render the shader as a true skybox via the WebGPU renderer's
266
+ * `scene.backgroundNode`. The node is evaluated per background pixel at
267
+ * infinite depth — inside it, `normalWorld` (from `three/tsl`) is the
268
+ * per-pixel view direction, so the sky is stable under camera movement
269
+ * with no skybox mesh, far-plane sizing, or camera-follow logic.
270
+ *
271
+ * WebGPU-only: background shaders must be authored in TSL
272
+ * ({@link ZylemTSLShader}). A GLSL shader logs a warning and is ignored
273
+ * (the solid background color is kept).
274
+ */
275
+ private setupBackgroundShader;
276
+ setup(): void;
277
+ destroy(): void;
278
+ /**
279
+ * Setup camera with the scene.
280
+ * Supports both legacy single camera and CameraManager modes.
281
+ */
282
+ setupCamera(scene: Scene, camera: ZylemCamera, rendererManager?: RendererManager): Promise<void>;
283
+ /**
284
+ * Setup with a CameraManager (multi-camera support).
285
+ */
286
+ setupCameraManager(scene: Scene, cameraManager: CameraManager, rendererManager: RendererManager): Promise<void>;
287
+ /**
288
+ * Add a camera (rig or direct) to the scene graph.
289
+ */
290
+ private addCameraToScene;
291
+ /**
292
+ * Setup scene lighting
293
+ */
294
+ setupLighting(scene: Scene): void;
295
+ /**
296
+ * Update renderer size - delegates to camera manager or camera
297
+ */
298
+ updateRenderer(width: number, height: number): void;
299
+ /**
300
+ * Add object to scene
301
+ */
302
+ add(object: Object3D, position?: Vector3): void;
303
+ /**
304
+ * Add game entity to scene
305
+ */
306
+ addEntity(entity: GameEntity<any>): void;
307
+ /**
308
+ * Add an entity's group or mesh to the scene (for late-loaded models).
309
+ * Uses entity's current body position if physics is active.
310
+ *
311
+ * Fog entities ({@link ZylemFog}) are routed through the normal add
312
+ * pipeline so their empty placeholder group is parented for cleanup,
313
+ * but they also get an `attachToScene` call that wires `scene.fog`
314
+ * and starts the optional material patcher.
315
+ */
316
+ addEntityGroup(entity: GameEntity<any>): void;
317
+ private isAttachedOutsideScene;
318
+ /**
319
+ * Add debug helpers to scene
320
+ */
321
+ debugScene(): void;
322
+ }
323
+
324
+ /** Configuration for pack key generation */
325
+ interface PackKeyConfig {
133
326
  geometryType: string;
134
327
  dimensions: Record<string, number>;
135
328
  materialPath?: string | null;
136
329
  shaderType?: 'standard' | 'custom';
137
330
  colorHex?: number;
138
331
  }
139
- /**
140
- * Manages instanced mesh batching for entities
141
- */
332
+ /** Manages instanced mesh packs for `category: 'pack'` entities */
142
333
  declare class InstanceManager {
143
- private batches;
144
- private entityToBatch;
334
+ private packs;
335
+ private entityToPack;
145
336
  private scene;
146
- /** Default initial capacity for new batches */
337
+ /** Default initial capacity for new packs */
147
338
  static DEFAULT_CAPACITY: number;
148
- /** Factor to grow batch when full */
339
+ /** Factor to grow a pack when full */
149
340
  static GROWTH_FACTOR: number;
150
- /**
151
- * Set the scene to add instanced meshes to
152
- */
153
341
  setScene(scene: Object3D): void;
154
- /**
155
- * Generate a batch key from configuration
156
- */
157
- static generateBatchKey(config: BatchKeyConfig): string;
158
- static generateEntityBatchKey(entity: Pick<GameEntity<GameEntityOptions>, 'options' | 'materials'> & {
342
+ static generatePackKey(config: PackKeyConfig): string;
343
+ static generateEntityPackKey(entity: Pick<GameEntity<GameEntityOptions>, 'options' | 'materials'> & {
159
344
  constructor: any;
160
345
  }): string;
161
346
  /**
162
- * Register an entity with the instance manager
347
+ * Register an entity with the instance manager.
163
348
  * @returns The instance index, or -1 if registration failed
164
349
  */
165
- register(entity: GameEntity<any>, geometry: BufferGeometry, material: Material, batchKey: string): number;
166
- /**
167
- * Unregister an entity from the instance manager
168
- */
350
+ register(entity: GameEntity<any>, geometry: BufferGeometry, material: Material, packKey: string): number;
169
351
  unregister(entity: GameEntity<any>): void;
170
- /**
171
- * Mark an entity's transform as dirty (needs syncing)
172
- */
173
352
  markDirty(entity: GameEntity<any>): void;
174
353
  /**
175
- * Update all dirty instance transforms
176
- * Call this once per frame
177
- */
178
- /**
179
- * Update all active instance transforms
180
- * Call this once per frame
354
+ * Update all active instance transforms.
355
+ * Call once per frame after the simulation step and render-buffer sync.
181
356
  */
182
- update(): void;
357
+ update(interpolationAlpha?: number): void;
183
358
  private updateInstanceMatrix;
184
- /**
185
- * Get batch info for an entity
186
- */
187
- getBatchInfo(entity: GameEntity<any>): {
188
- batchKey: string;
359
+ getPackInfo(entity: GameEntity<any>): {
360
+ packKey: string;
189
361
  instanceId: number;
190
362
  } | null;
191
- /**
192
- * Get statistics about current batching
193
- */
194
363
  getStats(): {
195
- batchCount: number;
364
+ packCount: number;
196
365
  totalInstances: number;
197
- batches: {
366
+ packs: {
198
367
  key: string;
199
368
  count: number;
200
369
  capacity: number;
201
370
  }[];
202
371
  };
203
- /**
204
- * Dispose all batches and release resources
205
- */
206
372
  dispose(): void;
373
+ private createPack;
374
+ private growPack;
375
+ }
376
+
377
+ /**
378
+ * Groups static environment meshes into WebGPU `BundleGroup`s for record-once
379
+ * replay. Dynamic entities must use `pack` (instancing) or `none` (scene-direct).
380
+ */
381
+ declare class RenderBundleManager {
382
+ private readonly bundles;
383
+ private readonly entityToBundle;
384
+ private scene;
385
+ setScene(scene: Object3D): void;
207
386
  /**
208
- * Create a new batch group
387
+ * Parent the entity's renderable into a static bundle group.
388
+ * @returns `true` when registration succeeded.
209
389
  */
210
- private createBatch;
390
+ register(entity: GameEntity<any>, _geometry: BufferGeometry, _material: Material, bundleKey: string): boolean;
391
+ unregister(entity: GameEntity<any>): void;
392
+ getStats(): {
393
+ bundleCount: number;
394
+ entityCount: number;
395
+ };
396
+ dispose(): void;
397
+ private getOrCreateBundle;
398
+ }
399
+
400
+ /**
401
+ * Routes entities to scene-direct (`none`), WebGPU bundles (`environment`), or
402
+ * instanced meshes (`pack`) based on `options.category`.
403
+ */
404
+ declare class RenderStrategyManager {
405
+ readonly bundles: RenderBundleManager;
406
+ readonly instances: InstanceManager;
407
+ setScene(scene: Object3D): void;
211
408
  /**
212
- * Grow a batch's capacity
409
+ * Register an entity with the appropriate managed render path.
410
+ * @returns `true` when the entity was placed into bundle or instanced rendering.
213
411
  */
214
- private growBatch;
412
+ register(entity: GameEntity<any>): boolean;
413
+ unregister(entity: GameEntity<any>): void;
414
+ update(interpolationAlpha?: number): void;
415
+ dispose(): void;
215
416
  }
216
417
 
217
418
  /**
@@ -221,8 +422,7 @@ interface BaseEntityInterface {
221
422
  uuid: string;
222
423
  name: string;
223
424
  group: Group | null | undefined;
224
- body: RigidBody | null | undefined;
225
- collider: Collider | null | undefined;
425
+ body: SimulationBody | null | undefined;
226
426
  }
227
427
  /**
228
428
  * Game entity interface - minimal interface to break circular dependencies
@@ -478,15 +678,6 @@ interface CameraOptions {
478
678
  target?: Vec3Input;
479
679
  zoom?: number;
480
680
  screenResolution?: Vec2Input;
481
- /**
482
- * Renderer type.
483
- *
484
- * @deprecated game-lib always renders with WebGPU (Three.js keeps its own
485
- * internal WebGL2 fallback for devices without WebGPU). This option is
486
- * ignored and retained only for backward compatibility.
487
- * @default 'webgpu'
488
- */
489
- rendererType?: RendererType;
490
681
  /**
491
682
  * Enable orbital controls for this camera.
492
683
  * Can be toggled at runtime via enableOrbitalControls() / disableOrbitalControls().
@@ -626,6 +817,18 @@ declare class CameraWrapper {
626
817
  */
627
818
  declare function createCamera(options: CameraOptions): CameraWrapper;
628
819
 
820
+ /**
821
+ * Owns the stage's in-world debug/editor interaction layer.
822
+ *
823
+ * Self-manages around the global `debugState`: when debug is enabled it draws
824
+ * the wasm simulation's collider wireframes, attaches mouse listeners,
825
+ * raycasts into the physics world to hover/select/delete/spawn entities, and
826
+ * drives the `DebugEntityCursor` highlight. When disabled it tears down
827
+ * visuals but stays alive to re-activate. Centralizes all debug-tool plumbing
828
+ * so `ZylemStage` doesn't have to know about raycasting, DOM input, or debug
829
+ * rendering.
830
+ */
831
+
629
832
  type AddEntityFactory = (params: {
630
833
  position: Vector3;
631
834
  normal?: Vector3;
@@ -651,10 +854,14 @@ declare class StageDebugDelegate {
651
854
  private domListenersAttached;
652
855
  private debugCursor;
653
856
  private debugLines;
654
- private runtimeDebugLines;
655
857
  private cameraDebugDelegate;
656
858
  private debugStateUnsubscribe;
859
+ private focusContextUnregister;
657
860
  constructor(stage: ZylemStage, options?: StageDebugDelegateOptions);
861
+ private resolveEntity;
862
+ /** Copy all stage children into debugMap so raycast/select tools work after enabling debug mid-session. */
863
+ private populateDebugMap;
864
+ private ensureCameraDebugDelegate;
658
865
  private syncWithDebugState;
659
866
  /** Initialize DOM listeners and camera debug delegate when debug is turned on. */
660
867
  private activate;
@@ -669,15 +876,16 @@ declare class StageDebugDelegate {
669
876
  private attachDomListeners;
670
877
  }
671
878
 
672
- /** Source for the unified-Stage wasm runtime: bytes, fetch URL, or a builder. */
673
- type StageWasmSource = ArrayBuffer | RequestInfo | URL | (() => Promise<ArrayBuffer | RequestInfo | URL>);
674
- /** Authoring-side configuration for the unified-Stage wasm runtime. */
675
- interface StageWasmRuntimeConfig {
676
- /** wasm bytes (ArrayBuffer) or a URL/`fetch` input that resolves to bytes. */
677
- source: StageWasmSource;
678
- /** Forwarded to {@link WasmStageRuntime} construction. */
679
- options?: Omit<WasmStageRuntimeOptions, 'imports'>;
680
- }
879
+ /**
880
+ * Stage configuration: types, defaults, and option parsing.
881
+ *
882
+ * Defines the user-facing stage config shape (`StageConfigLike`), the internal
883
+ * `StageConfig` class, and the engine defaults applied to every stage. Its core
884
+ * job is `parseStageOptions`, which untangles the heterogeneous `createStage(...)`
885
+ * argument list (config objects, camera wrappers, sync/async entities) into a
886
+ * normalized `ParsedStageOptions` that `ZylemStage` can consume directly.
887
+ */
888
+
681
889
  type StageGLTFAssetLoaderConfig = {
682
890
  meshopt?: boolean;
683
891
  ktx2TranscoderPath?: URL | string;
@@ -698,21 +906,18 @@ type StageConfigLike = Partial<{
698
906
  /** Physics update rate in Hz (default 60). */
699
907
  physicsRate: number;
700
908
  assetLoaders: StageAssetLoaderConfig;
701
- runtimeAdapter: StageRuntimeAdapter;
702
- /** Binds stage debug policy into wasm runtime adapters (see {@link RuntimeDebugBinding}). */
703
- runtimeDebugBinding?: RuntimeDebugBinding;
704
- /**
705
- * When set, the stage instantiates a {@link WasmStageRuntime} from the given
706
- * source during `load()`. Behavior descriptors that have been ported to the
707
- * unified-Stage Rust runtime read this via `BehaviorSystemContext.wasmStage`.
708
- */
709
- wasmRuntime?: StageWasmRuntimeConfig;
710
909
  /**
711
910
  * When `false`, the engine's built-in ambient + directional lights are
712
911
  * suppressed so the stage can be lit entirely via `createLight(...)`
713
912
  * entities. Defaults to `true`.
714
913
  */
715
914
  defaultLighting: boolean;
915
+ /**
916
+ * Postprocessing effects applied in order between the scene pass and the
917
+ * display output (e.g. effects from `@zylem/shaders`). Only active for
918
+ * single fullscreen-camera rendering.
919
+ */
920
+ postProcessingEffects: ZylemPostEffect[];
716
921
  }>;
717
922
  /**
718
923
  * Factory for authoring stage configuration objects in user code.
@@ -720,6 +925,16 @@ type StageConfigLike = Partial<{
720
925
  */
721
926
  declare function stageConfig(config: StageConfigLike): StageConfigLike;
722
927
 
928
+ /**
929
+ * Fan-out hub for a stage's loading lifecycle events.
930
+ *
931
+ * Collects start/progress/complete loading events and broadcasts them both to
932
+ * direct per-stage subscribers and to the global `gameEventBus` (tagged with
933
+ * stage name/index) for game-level loading UIs. Exists so the entity-load
934
+ * generator and stage code can emit progress through one place without knowing
935
+ * who is listening.
936
+ */
937
+
723
938
  /**
724
939
  * Delegate for managing loading events and progress within a stage.
725
940
  * Handles subscription to loading events and broadcasting progress.
@@ -797,6 +1012,17 @@ declare class StageEntityModelDelegate {
797
1012
  dispose(): void;
798
1013
  }
799
1014
 
1015
+ /**
1016
+ * The stage's entity lifecycle engine.
1017
+ *
1018
+ * Owns everything about entities within a stage: queuing (sync, async, and
1019
+ * factory inputs), progressive load via a yielding generator, spawning into
1020
+ * scene/world/runtime, instanced-mesh batching, deferred-model handling,
1021
+ * removal, name/UUID lookup, and ECS behavior-system registration/indexing.
1022
+ * Extracted from `ZylemStage` so entity bookkeeping lives in one cohesive place
1023
+ * and can be shared with the debug delegate and transform system.
1024
+ */
1025
+
800
1026
  type NodeLike$1 = {
801
1027
  create: Function;
802
1028
  };
@@ -807,12 +1033,9 @@ type StageEntityInput = NodeLike$1 | Promise<any> | (() => NodeLike$1 | Promise<
807
1033
  interface EntityDelegateContext {
808
1034
  scene: ZylemScene;
809
1035
  world: ZylemWorld;
810
- instanceManager: InstanceManager | null;
1036
+ renderStrategy: RenderStrategyManager | null;
811
1037
  /** Resolved camera for entity setup contexts. */
812
1038
  camera: ZylemCamera;
813
- runtimeAdapter?: StageRuntimeAdapter | null;
814
- /** Optional unified-Stage wasm runtime (Phase 2+ of the runtime-only migration). */
815
- wasmStage?: WasmStageRuntime | null;
816
1039
  }
817
1040
  /**
818
1041
  * Delegate responsible for entity spawning, tracking, queuing, removal, and lookup.
@@ -840,11 +1063,13 @@ declare class StageEntityDelegate {
840
1063
  private readonly behaviorLinksByUuid;
841
1064
  private scene;
842
1065
  private world;
843
- private instanceManager;
1066
+ private renderStrategy;
844
1067
  private camera;
845
- private runtimeAdapter;
846
- /** Unified-Stage wasm runtime; shared with descriptor `systemFactory` calls. */
847
- wasmStage: WasmStageRuntime | null;
1068
+ /**
1069
+ * The behaviors runtime adapter backing the world's Simulation; shared with
1070
+ * descriptor `systemFactory` calls as `ctx.wasmStage`.
1071
+ */
1072
+ wasmStage: BehaviorRuntime | null;
848
1073
  private loadingDelegate;
849
1074
  private entityModelDelegate;
850
1075
  constructor(loadingDelegate: StageLoadingDelegate, entityModelDelegate: StageEntityModelDelegate);
@@ -862,9 +1087,15 @@ declare class StageEntityDelegate {
862
1087
  spawnEntity(child: BaseNode): Promise<void>;
863
1088
  handleLateModelReady(entity: GameEntity<any>): void;
864
1089
  /**
865
- * Register an entity for instanced rendering if opted in with `batched: true`.
1090
+ * Register an entity for bundle or instanced rendering when opted in via
1091
+ * `category: 'environment'` or `category: 'pack'`.
1092
+ */
1093
+ private tryRegisterRenderStrategy;
1094
+ /**
1095
+ * Environment bundles require static bodies. Force static collision and
1096
+ * patch any already-built body description.
866
1097
  */
867
- private tryRegisterInstance;
1098
+ private ensureEnvironmentStatic;
868
1099
  private maybeAttachEntityPhysics;
869
1100
  /** Add the entity to internal maps and notify listeners. */
870
1101
  addEntityToStage(entity: BaseNode): void;
@@ -895,15 +1126,12 @@ declare class StageEntityDelegate {
895
1126
  enqueue(...items: StageEntityInput[]): void;
896
1127
  private handleEntityImmediatelyOrQueue;
897
1128
  private handlePromiseWithSpawnOnResolve;
898
- /**
899
- * Generator that yields between entity loads for real-time progress updates.
900
- */
901
- private entityLoadGenerator;
902
1129
  /** Yields to the event loop via MessageChannel (~0.1ms vs ~4ms for setTimeout). */
903
1130
  private yieldToEventLoop;
904
1131
  /**
905
- * Runs the entity load generator, yielding to the event loop in batches.
906
- * Emits progress events through the loading delegate.
1132
+ * Spawns all queued entities, awaiting each attach before the stage is
1133
+ * marked loaded so the game loop never steps wasm while bodies are still
1134
+ * being added. Yields to the event loop in batches for loading UI updates.
907
1135
  */
908
1136
  runEntityLoadGenerator(): Promise<void>;
909
1137
  /**
@@ -920,6 +1148,18 @@ declare class StageEntityDelegate {
920
1148
  private unregisterBehaviorLinks;
921
1149
  }
922
1150
 
1151
+ /**
1152
+ * The runtime heart of a loaded stage.
1153
+ *
1154
+ * `ZylemStage` is the disposable per-load object that actually owns and drives
1155
+ * the scene, physics world, cameras, optional wasm runtime, and the suite of
1156
+ * delegates (entity, camera, loading, model, debug). It parses options into
1157
+ * config, builds scene/world during `load()`, runs the per-frame update loop
1158
+ * (physics step, behavior systems, entity updates, transform sync, camera
1159
+ * updates, render), and tears everything down on destroy. The author-facing
1160
+ * `Stage` wraps and recreates one of these on each load.
1161
+ */
1162
+
923
1163
  interface ZylemStageConfig {
924
1164
  inputs: Record<string, string[]>;
925
1165
  backgroundColor: Color | string;
@@ -931,22 +1171,18 @@ interface ZylemStageConfig {
931
1171
  physicsRate: number;
932
1172
  /** Optional runtime loader configuration for stage-managed assets. */
933
1173
  assetLoaders?: StageAssetLoaderConfig;
934
- /** Optional runtime adapter for wasm-driven simulation/rendering. */
935
- runtimeAdapter?: StageRuntimeAdapter;
936
- /** Optional debug binding for wasm runtime adapters (heat tint, etc.). */
937
- runtimeDebugBinding?: RuntimeDebugBinding;
938
- /**
939
- * Optional unified-Stage wasm runtime configuration. When set, the stage
940
- * instantiates a {@link WasmStageRuntime} during `load()` and exposes it
941
- * to behavior systems via `BehaviorSystemContext.wasmStage`.
942
- */
943
- wasmRuntime?: StageWasmRuntimeConfig;
944
1174
  /**
945
1175
  * When `false`, suppress the engine's built-in ambient + directional
946
1176
  * lights so the stage owns its lighting rig entirely (usually via
947
1177
  * `createLight(...)` entities). Defaults to `true`.
948
1178
  */
949
1179
  defaultLighting: boolean;
1180
+ /**
1181
+ * Postprocessing effects applied in order between the scene pass and the
1182
+ * display output (e.g. effects from `@zylem/shaders`). Only active for
1183
+ * single fullscreen-camera rendering.
1184
+ */
1185
+ postProcessingEffects?: ZylemPostEffect[];
950
1186
  stageRef?: Stage;
951
1187
  }
952
1188
  type StageOptionItem = Partial<ZylemStageConfig> | CameraWrapper | StageEntityInput;
@@ -969,9 +1205,7 @@ declare class ZylemStage extends LifeCycleBase<ZylemStage> {
969
1205
  gravity: Vector3 | Vec3Components;
970
1206
  world: ZylemWorld | null;
971
1207
  scene: ZylemScene | null;
972
- instanceManager: InstanceManager | null;
973
- /** Unified-Stage wasm runtime; non-null only when `wasmRuntime` was configured. */
974
- wasmStage: WasmStageRuntime | null;
1208
+ renderStrategy: RenderStrategyManager | null;
975
1209
  debugDelegate: StageDebugDelegate | null;
976
1210
  uuid: string;
977
1211
  wrapperRef: Stage | null;
@@ -982,7 +1216,6 @@ declare class ZylemStage extends LifeCycleBase<ZylemStage> {
982
1216
  cameraManagerRef: CameraManager | null;
983
1217
  /** Shared renderer manager (injected by the game) */
984
1218
  rendererManager: RendererManager | null;
985
- runtimeAdapter: StageRuntimeAdapter | null;
986
1219
  private cameraDelegate;
987
1220
  private loadingDelegate;
988
1221
  private entityModelDelegate;
@@ -1045,14 +1278,6 @@ declare class ZylemStage extends LifeCycleBase<ZylemStage> {
1045
1278
  /** Forward to entity delegate. */
1046
1279
  enqueue(...items: StageEntityInput[]): void;
1047
1280
  logMissingEntities(): void;
1048
- private runtimeContext;
1049
- /**
1050
- * Resolve a {@link StageWasmRuntimeConfig} into a live {@link WasmStageRuntime}.
1051
- * Accepts wasm bytes (`ArrayBuffer`), a fetch URL, or a deferred async
1052
- * builder so demos can `?url`-import a Vite asset without forcing the engine
1053
- * to bundle the wasm itself.
1054
- */
1055
- private loadWasmStage;
1056
1281
  /** Add a camera to this stage's camera manager. */
1057
1282
  addCamera(camera: ZylemCamera, name?: string): string | null;
1058
1283
  /** Remove a camera from this stage's camera manager. */
@@ -1065,6 +1290,17 @@ declare class ZylemStage extends LifeCycleBase<ZylemStage> {
1065
1290
  resize(width: number, height: number): void;
1066
1291
  }
1067
1292
 
1293
+ /**
1294
+ * The user-facing stage handle and its fluent authoring API.
1295
+ *
1296
+ * `Stage` is the durable, author-time wrapper game code holds onto: it stores
1297
+ * options, pending entities, and lifecycle/loading callbacks, then constructs
1298
+ * and drives a fresh internal `ZylemStage` on each `load()`. Exists to give a
1299
+ * stable, ergonomic surface (`add`, `onSetup/onUpdate/onDestroy`, camera, input,
1300
+ * and event helpers) that survives stage reloads, while `ZylemStage` owns the
1301
+ * disposable per-load runtime. `createStage(...)` is the entry point.
1302
+ */
1303
+
1068
1304
  type NodeLike = {
1069
1305
  create: Function;
1070
1306
  };
@@ -1410,6 +1646,13 @@ declare class ZylemGame<TGlobals extends BaseGlobals> {
1410
1646
  gameCanvas: GameCanvas | null;
1411
1647
  private animationFrameId;
1412
1648
  private isDisposed;
1649
+ /**
1650
+ * True while a `loadStage` is in progress. Used to reject re-entrant stage
1651
+ * navigation (e.g. a button press during a transition), which would race
1652
+ * two loads on `stageMap`/the render loop and, because `currentStageId` is
1653
+ * transiently `''`, misresolve the target stage.
1654
+ */
1655
+ private loadInFlight;
1413
1656
  /**
1414
1657
  * True once `start()` has been invoked for this game's initial stage.
1415
1658
  * Used by `loadStage` to decide whether to drive the stage's `_setup`
@@ -1421,6 +1664,17 @@ declare class ZylemGame<TGlobals extends BaseGlobals> {
1421
1664
  private loadingDelegate;
1422
1665
  private rendererObserver;
1423
1666
  private eventBusUnsubscribes;
1667
+ private thumbnailUnsubscribes;
1668
+ /**
1669
+ * Trailing-debounce timer for entity-driven state dispatches. Building a
1670
+ * `state:dispatch` payload is O(entities) (and downstream editor stores
1671
+ * re-proxy/reconcile every entity), so bursts of thumbnail/destroy events
1672
+ * must coalesce into a single dispatch instead of one per entity.
1673
+ */
1674
+ private entityDispatchTimer;
1675
+ private pendingEntityDispatchPath;
1676
+ /** Debounce window (ms) for coalescing entity-driven state dispatches. */
1677
+ private static readonly ENTITY_DISPATCH_DEBOUNCE_MS;
1424
1678
  private readonly gameUpdateParams;
1425
1679
  private readonly stageSetupParams;
1426
1680
  private readonly stageUpdateParams;
@@ -1434,7 +1688,10 @@ declare class ZylemGame<TGlobals extends BaseGlobals> {
1434
1688
  setDisplayRuntime(runtime: ResolveGameConfigRuntime): void;
1435
1689
  loadGameCanvas(config: GameConfig): void;
1436
1690
  loadDebugOptions(options: ZylemGameOptions<TGlobals>): void;
1437
- loadStage(stage: Stage, stageIndex?: number): Promise<void>;
1691
+ /** Whether a stage load is currently in progress. */
1692
+ isLoading(): boolean;
1693
+ loadStage(stage: Stage, stageIndex?: number, transition?: StageTransitionConfig): Promise<void>;
1694
+ private performLoadStage;
1438
1695
  /**
1439
1696
  * Merges game-level global input config with the stage's per-stage overrides
1440
1697
  * and reconfigures the InputManager.
@@ -1474,6 +1731,16 @@ declare class ZylemGame<TGlobals extends BaseGlobals> {
1474
1731
  * Build the entities payload for the current stage.
1475
1732
  */
1476
1733
  private buildEntitiesPayload;
1734
+ /**
1735
+ * Generate entity thumbnails as entities become available, then refresh editor state.
1736
+ */
1737
+ private wireEntityThumbnails;
1738
+ private clearEntityThumbnailWiring;
1739
+ /**
1740
+ * Coalesce entity-driven state dispatches (thumbnail resolutions, entity
1741
+ * destruction) into one trailing `emitStateDispatch` per burst.
1742
+ */
1743
+ private queueEntityStateDispatch;
1477
1744
  /**
1478
1745
  * Emit a state:dispatch event to the zylemEventBus.
1479
1746
  * Called after stage load and on global state changes.
@@ -1544,6 +1811,18 @@ declare class Game<TGlobals extends BaseGlobals> implements IGame<TGlobals> {
1544
1811
  * Get the current stage wrapper.
1545
1812
  */
1546
1813
  getCurrentStage(): Stage | null;
1814
+ /**
1815
+ * Experimental escape hatches. APIs here are unstable and may change or be
1816
+ * removed without a major version bump.
1817
+ */
1818
+ readonly experimental: {
1819
+ /**
1820
+ * The `@zylem/behaviors` {@link Simulation} backing the current stage's
1821
+ * physics world, or `null` before a stage is loaded. Intended for debug
1822
+ * tooling and the editor; games should not need it.
1823
+ */
1824
+ getRuntime: () => Simulation | null;
1825
+ };
1547
1826
  pause(): Promise<void>;
1548
1827
  resume(): Promise<void>;
1549
1828
  /**
@@ -1552,10 +1831,27 @@ declare class Game<TGlobals extends BaseGlobals> implements IGame<TGlobals> {
1552
1831
  * @param deltaTime Optional delta time in seconds (defaults to 1/60)
1553
1832
  */
1554
1833
  step(deltaTime?: number): void;
1555
- reset(): Promise<void>;
1556
- previousStage(): void;
1834
+ /**
1835
+ * Reload the first stage. Pass `{ transition }` to blend from the current
1836
+ * stage instead of cutting.
1837
+ * @example game.reset({ transition: { duration: 1 } });
1838
+ */
1839
+ reset(options?: StageNavigationOptions): Promise<void>;
1840
+ /**
1841
+ * Go to the previous stage in the stage array. Pass `{ transition }` to
1842
+ * blend from the current stage instead of cutting.
1843
+ */
1844
+ previousStage(options?: StageNavigationOptions): void;
1557
1845
  loadStageFromId(stageId: string): Promise<void>;
1558
- nextStage(): void;
1846
+ /**
1847
+ * Go to the next stage. Pass `{ transition }` to blend from the current
1848
+ * stage instead of cutting.
1849
+ * @example
1850
+ * game.nextStage({
1851
+ * transition: { duration: 1.2, shader: createStageTransition({ pattern: 'noise' }) },
1852
+ * });
1853
+ */
1854
+ nextStage(options?: StageNavigationOptions): void;
1559
1855
  goToStage(): Promise<void>;
1560
1856
  end(): Promise<void>;
1561
1857
  dispose(): void;
@@ -1587,4 +1883,4 @@ declare class Game<TGlobals extends BaseGlobals> implements IGame<TGlobals> {
1587
1883
  */
1588
1884
  declare function createGame<TGlobals extends BaseGlobals>(...options: GameOptions<TGlobals>): Game<TGlobals>;
1589
1885
 
1590
- export { AspectRatio as A, CameraWrapper as C, type DeviceProfile as D, Fixed2DPerspective as F, Game as G, type PerspectiveOptions as P, type ResolutionInput as R, Stage as S, ThirdPersonPerspective as T, type StageStateInterface as a, type GameLoadingEvent as b, createGame as c, type GameConfigLike as d, type GameDeviceConfig as e, type ResolveGameConfigRuntime as f, gameConfig as g, createStage as h, type StageConfigLike as i, type StageOptions as j, createCamera as k, type CameraOptions as l, FirstPersonPerspective as m, createPerspective as n, type ThirdPersonOptions as o, type Fixed2DOptions as p, type FirstPersonOptions as q, type AspectRatioValue as r, stageConfig as s, getDisplayAspect as t, getPresetResolution as u, parseResolution as v, type RetroPreset as w, type RetroPresetKey as x, type RetroResolution as y };
1886
+ export { AspectRatio as A, Stage as B, CameraWrapper as C, type DeviceProfile as D, type StageStateInterface as E, Fixed2DPerspective as F, Game as G, type PerspectiveOptions as P, type ResolutionInput as R, type StageConfigLike as S, ThirdPersonPerspective as T, type GameLoadingEvent as a, type GameConfigLike as b, createGame as c, type GameDeviceConfig as d, type ResolveGameConfigRuntime as e, createStage as f, gameConfig as g, type StageOptions as h, createCamera as i, type CameraOptions as j, CameraManager as k, FirstPersonPerspective as l, createPerspective as m, type ThirdPersonOptions as n, type Fixed2DOptions as o, type FirstPersonOptions as p, type AspectRatioValue as q, getDisplayAspect as r, stageConfig as s, getPresetResolution as t, parseResolution as u, type RetroPreset as v, type RetroPresetKey as w, type RetroResolution as x, RenderBundleManager as y, RenderStrategyManager as z };