@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
package/dist/main.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/lib/core/utility/path-utils.ts","../src/lib/game/game-event-bus.ts","../src/lib/game/game-state.ts","../src/lib/debug/debug-state.ts","../src/lib/input/input-presets.ts","../src/lib/graphics/shaders/vertex/object.shader.ts","../src/lib/graphics/shaders/standard.shader.ts","../src/lib/graphics/render-pass.ts","../src/lib/camera/renderer-manager.ts","../src/lib/core/utility/options-parser.ts","../../../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/src/index.ts","../src/lib/events/event-emitter-delegate.ts","../src/lib/events/zylem-events.ts","../src/lib/events/index.ts","../src/lib/core/flags.ts","../src/lib/core/base-node.ts","../src/lib/physics/physics-pose.ts","../src/lib/systems/transformable.system.ts","../src/lib/actions/capabilities/transform-store.ts","../src/lib/actions/capabilities/velocity-intents.ts","../src/lib/actions/capabilities/moveable.ts","../src/lib/actions/capabilities/rotatable.ts","../src/lib/actions/capabilities/transformable.ts","../src/lib/collision/collision-builder.ts","../src/lib/core/clone-utils.ts","../src/lib/entities/parts/collision-factories.ts","../src/lib/entities/common.ts","../src/lib/entities/entity.ts","../src/lib/entities/delegates/loader.ts","../src/lib/entities/create.ts","../src/lib/core/loaders/texture-loader.ts","../src/lib/core/loaders/model-clone.ts","../src/lib/core/loaders/gltf-loader.ts","../src/lib/core/loaders/fbx-loader.ts","../src/lib/core/loaders/obj-loader.ts","../src/lib/core/loaders/audio-loader.ts","../src/lib/core/loaders/file-loader.ts","../src/lib/core/loaders/index.ts","../src/lib/core/asset-manager.ts","../src/lib/core/entity-asset-loader.ts","../src/lib/entities/delegates/animation.ts","../src/lib/graphics/mesh.ts","../src/lib/core/utility/strings.ts","../src/lib/graphics/material.ts","../src/lib/entities/builder.ts","../src/lib/entities/actor.ts","../src/lib/physics/physics-protocol.ts","../src/lib/physics/physics-body-handle.ts","../src/lib/physics/physics-proxy.ts","../src/lib/physics/serialize-descriptors.ts","../src/lib/collision/world.ts","../src/lib/graphics/zylem-scene.ts","../src/lib/graphics/instance-manager.ts","../src/lib/core/utility/vector.ts","../src/lib/stage/stage-state.ts","../src/lib/core/lifecycle-base.ts","../src/lib/stage/stage-camera-debug-delegate.ts","../src/lib/stage/debug-entity-cursor.ts","../src/lib/stage/stage-debug-delegate.ts","../src/lib/camera/perspective.ts","../src/lib/camera/camera-debug-delegate.ts","../src/lib/camera/smoothing.ts","../src/lib/camera/camera-pipeline.ts","../src/lib/camera/perspectives/third-person-perspective.ts","../src/lib/camera/perspectives/fixed-2d-perspective.ts","../src/lib/camera/perspectives/first-person-perspective.ts","../src/lib/camera/perspectives/index.ts","../src/lib/camera/zylem-camera.ts","../src/lib/camera/camera-manager.ts","../src/lib/stage/stage-camera-delegate.ts","../src/lib/stage/stage-loading-delegate.ts","../src/lib/stage/stage-entity-model-delegate.ts","../src/lib/stage/stage-config.ts","../src/lib/actions/capabilities/apply-transform.ts","../src/lib/core/vessel.ts","../src/lib/stage/stage-entity-delegate.ts","../src/lib/stage/zylem-stage.ts","../src/lib/camera/camera.ts","../src/lib/stage/stage-default.ts","../src/lib/stage/stage.ts","../src/lib/game/game-default.ts","../src/lib/game/zylem-game.ts","../src/lib/input/input-state.ts","../src/lib/input/keyboard-provider.ts","../src/lib/input/gamepad-provider.ts","../src/lib/input/mouse-provider.ts","../src/lib/input/input-manager.ts","../src/lib/core/three-addons/Timer.ts","../src/lib/device/aspect-ratio.ts","../src/lib/device/mobile.ts","../src/lib/game/game-retro-resolutions.ts","../src/lib/game/game-config.ts","../src/lib/game/game-canvas.ts","../src/lib/game/game-debug-delegate.ts","../src/lib/game/game-loading-delegate.ts","../src/lib/game/game-renderer-observer.ts","../src/lib/game/game.ts","../src/lib/core/utility/nodes.ts","../src/lib/stage/stage-manager.ts","../src/lib/stage/stage-factory.ts","../src/lib/entities/text.ts","../src/lib/entities/delegates/debug.ts","../src/lib/entities/sprite.ts","../src/lib/entities/entity-factory.ts","../src/api/main.ts","../src/lib/stage/entity-spawner.ts","../src/lib/camera/behaviors/follow-target.ts","../src/lib/camera/camera-feed.ts","../src/lib/entities/box.ts","../src/lib/entities/parts/mesh-factories.ts","../src/lib/entities/sphere.ts","../src/lib/entities/plane.ts","../src/lib/graphics/geometries/XZPlaneGeometry.ts","../src/lib/entities/zone.ts","../src/lib/entities/rect.ts","../src/lib/entities/disk.ts","../src/lib/entities/cone.ts","../src/lib/entities/pyramid.ts","../src/lib/entities/cylinder.ts","../src/lib/entities/pill.ts","../src/lib/entities/parts/index.ts","../src/lib/behaviors/behavior-descriptor.ts","../src/lib/behaviors/use-behavior.ts","../src/lib/behaviors/components.ts","../src/lib/behaviors/thruster/components.ts","../src/lib/core/utility/sync-state-machine.ts","../src/lib/behaviors/thruster/thruster-fsm.ts","../src/lib/behaviors/shared/direction-2d.ts","../src/lib/behaviors/thruster/thruster-movement.behavior.ts","../src/lib/behaviors/thruster/thruster.descriptor.ts","../src/lib/behaviors/top-down-movement/components.ts","../src/lib/behaviors/top-down-movement/top-down-movement.behavior.ts","../src/lib/behaviors/top-down-movement/top-down-movement.descriptor.ts","../src/lib/behaviors/shooter-2d/components.ts","../src/lib/behaviors/shooter-2d/shooter-2d.descriptor.ts","../src/lib/behaviors/screen-wrap/screen-wrap-fsm.ts","../src/lib/behaviors/shared/bounds-2d.ts","../src/lib/behaviors/screen-wrap/screen-wrap.descriptor.ts","../src/lib/behaviors/screen-visibility/screen-visibility.descriptor.ts","../src/lib/behaviors/screen-visibility/screen-visibility-fsm.ts","../src/lib/behaviors/world-boundary-2d/world-boundary-2d-fsm.ts","../src/lib/behaviors/world-boundary-2d/world-boundary-2d.descriptor.ts","../src/lib/behaviors/shared/bounds-3d.ts","../src/lib/behaviors/world-boundary-3d/world-boundary-3d-fsm.ts","../src/lib/behaviors/world-boundary-3d/world-boundary-3d.descriptor.ts","../src/lib/behaviors/ricochet-2d/ricochet-2d-fsm.ts","../src/lib/behaviors/ricochet-2d/ricochet-2d.descriptor.ts","../src/lib/behaviors/ricochet-3d/ricochet-3d-fsm.ts","../src/lib/behaviors/ricochet-3d/ricochet-3d.descriptor.ts","../src/lib/behaviors/platformer-3d/components.ts","../src/lib/behaviors/platformer-3d/platformer-3d-fsm.ts","../src/lib/behaviors/shared/ground-probe-3d.ts","../src/lib/behaviors/platformer-3d/platformer-3d.behavior.ts","../src/lib/behaviors/platformer-3d/platformer-3d.descriptor.ts","../src/lib/behaviors/first-person/components.ts","../src/lib/behaviors/first-person/first-person-fsm.ts","../src/lib/behaviors/first-person/first-person.behavior.ts","../src/lib/behaviors/first-person/first-person.descriptor.ts","../src/lib/behaviors/jumper-3d/components.ts","../src/lib/behaviors/jumper-3d/jumper-3d.behavior.ts","../src/lib/behaviors/jumper-3d/jumper-3d-fsm.ts","../src/lib/behaviors/jumper-3d/jumper-3d.descriptor.ts","../src/lib/behaviors/jumper-2d/components.ts","../src/lib/behaviors/jumper-2d/jumper-2d.behavior.ts","../src/lib/behaviors/jumper-2d/jumper-2d-fsm.ts","../src/lib/behaviors/jumper-2d/jumper-2d.descriptor.ts","../src/lib/behaviors/cooldown/cooldown-store.ts","../src/lib/behaviors/cooldown/cooldown-behavior.ts","../src/lib/coordinators/boundary-ricochet.coordinator.ts","../src/lib/coordinators/boundary-ricochet-3d.coordinator.ts","../src/lib/coordinators/first-person-shooter.coordinator.ts","../src/lib/coordinators/shared/top-down-aim.ts","../src/lib/coordinators/top-down-shooter.coordinator.ts","../src/lib/coordinators/multidirectional-space-shooter.coordinator.ts","../src/lib/actions/action.ts","../src/lib/actions/interval-actions.ts","../src/lib/actions/persistent-actions.ts","../src/lib/actions/composition.ts","../src/lib/entities/cooldown-icon.ts","../src/lib/entities/destroy.ts","../src/lib/sounds/ricochet-sound.ts","../src/lib/sounds/ping-pong-sound.ts","../src/lib/actions/global-change.ts","../src/web-components/zylem-game.ts","../src/lib/types/entity-type-map.ts","../src/lib/graphics/shaders/fire.shader.ts","../src/lib/graphics/shaders/star.shader.ts","../src/lib/graphics/shaders/vertex/debug.shader.ts","../src/lib/graphics/shaders/debug.shader.ts"],"sourcesContent":["/**\n * Lodash-style path utilities for getting/setting nested object values.\n */\n\n/**\n * Get a value from an object by path string.\n * @example getByPath({ player: { health: 100 } }, 'player.health') // 100\n */\nexport function getByPath<T = unknown>(obj: object, path: string): T | undefined {\n\tif (!path) return undefined;\n\tconst keys = path.split('.');\n\tlet current: any = obj;\n\tfor (const key of keys) {\n\t\tif (current == null || typeof current !== 'object') {\n\t\t\treturn undefined;\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\treturn current as T;\n}\n\n/**\n * Set a value on an object by path string, creating intermediate objects as needed.\n * @example setByPath({}, 'player.health', 100) // { player: { health: 100 } }\n */\nexport function setByPath(obj: object, path: string, value: unknown): void {\n\tif (!path) return;\n\tconst keys = path.split('.');\n\tlet current: any = obj;\n\tfor (let i = 0; i < keys.length - 1; i++) {\n\t\tconst key = keys[i];\n\t\tif (current[key] == null || typeof current[key] !== 'object') {\n\t\t\tcurrent[key] = {};\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\tcurrent[keys[keys.length - 1]] = value;\n}\n\n/**\n * Check if a path exists in an object.\n */\nexport function hasPath(obj: object, path: string): boolean {\n\tif (!path) return false;\n\tconst keys = path.split('.');\n\tlet current: any = obj;\n\tfor (const key of keys) {\n\t\tif (current == null || typeof current !== 'object' || !(key in current)) {\n\t\t\treturn false;\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\treturn true;\n}\n","import { LoadingEvent } from '../core/interfaces';\n\n/**\n * Event types for the game event bus.\n */\nexport type GameEventType = \n\t| 'stage:loading:start'\n\t| 'stage:loading:progress'\n\t| 'stage:loading:complete'\n\t| 'game:state:updated';\n\n/**\n * Payload for stage loading events.\n */\nexport interface StageLoadingPayload extends LoadingEvent {\n\tstageName?: string;\n\tstageIndex?: number;\n}\n\n/**\n * Payload for game state update events.\n */\nexport interface GameStateUpdatedPayload {\n\tpath: string;\n\tvalue: unknown;\n\tpreviousValue?: unknown;\n}\n\n/**\n * Event map for typed event handling.\n */\nexport interface GameEventMap {\n\t'stage:loading:start': StageLoadingPayload;\n\t'stage:loading:progress': StageLoadingPayload;\n\t'stage:loading:complete': StageLoadingPayload;\n\t'game:state:updated': GameStateUpdatedPayload;\n}\n\ntype EventCallback<T> = (payload: T) => void;\n\n/**\n * Simple event bus for game-stage communication.\n * Used to decouple stage loading events from direct coupling.\n */\nexport class GameEventBus {\n\tprivate listeners: Map<GameEventType, Set<EventCallback<any>>> = new Map();\n\n\t/**\n\t * Subscribe to an event type.\n\t */\n\ton<K extends GameEventType>(event: K, callback: EventCallback<GameEventMap[K]>): () => void {\n\t\tif (!this.listeners.has(event)) {\n\t\t\tthis.listeners.set(event, new Set());\n\t\t}\n\t\tthis.listeners.get(event)!.add(callback);\n\t\treturn () => this.off(event, callback);\n\t}\n\n\t/**\n\t * Unsubscribe from an event type.\n\t */\n\toff<K extends GameEventType>(event: K, callback: EventCallback<GameEventMap[K]>): void {\n\t\tthis.listeners.get(event)?.delete(callback);\n\t}\n\n\t/**\n\t * Emit an event to all subscribers.\n\t */\n\temit<K extends GameEventType>(event: K, payload: GameEventMap[K]): void {\n\t\tconst callbacks = this.listeners.get(event);\n\t\tif (!callbacks) return;\n\t\tfor (const cb of callbacks) {\n\t\t\ttry {\n\t\t\t\tcb(payload);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error(`Error in event handler for ${event}`, e);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Clear all listeners.\n\t */\n\tdispose(): void {\n\t\tthis.listeners.clear();\n\t}\n}\n\n/**\n * Singleton event bus instance for global game events.\n */\nexport const gameEventBus = new GameEventBus();\n","import { proxy, subscribe } from 'valtio/vanilla';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\nimport { gameEventBus } from './game-event-bus';\n\n/**\n * Internal game state store using valtio proxy for reactivity.\n */\nconst state = proxy({\n\tid: '',\n\tglobals: {} as Record<string, unknown>,\n\ttime: 0,\n});\n\n/**\n * Track active subscriptions for cleanup on game dispose.\n */\nconst activeSubscriptions: Set<() => void> = new Set();\n\n/**\n * Set a global value by path.\n * Emits a 'game:state:updated' event when the value changes.\n * @example setGlobal('score', 100)\n * @example setGlobal('player.health', 50)\n */\nexport function setGlobal(path: string, value: unknown): void {\n\tconst previousValue = getByPath(state.globals, path);\n\tsetByPath(state.globals, path, value);\n\n\tgameEventBus.emit('game:state:updated', {\n\t\tpath,\n\t\tvalue,\n\t\tpreviousValue,\n\t});\n}\n\n/**\n * Create/initialize a global with a default value.\n * Only sets the value if it doesn't already exist.\n * Use this to ensure globals have initial values before game starts.\n * @example createGlobal('score', 0)\n * @example createGlobal('player.health', 100)\n */\nexport function createGlobal<T>(path: string, defaultValue: T): T {\n\tconst existing = getByPath<T>(state.globals, path);\n\tif (existing === undefined) {\n\t\tsetByPath(state.globals, path, defaultValue);\n\t\treturn defaultValue;\n\t}\n\treturn existing;\n}\n\n/**\n * Get a global value by path.\n * @example getGlobal('score') // 100\n * @example getGlobal<number>('player.health') // 50\n */\nexport function getGlobal<T = unknown>(path: string): T | undefined {\n\treturn getByPath<T>(state.globals, path);\n}\n\n/**\n * Subscribe to changes on a global value at a specific path.\n * Returns an unsubscribe function. Subscriptions are automatically\n * cleaned up when the game is disposed.\n * @example const unsub = onGlobalChange('score', (val) => console.log(val));\n */\nexport function onGlobalChange<T = unknown>(\n\tpath: string,\n\tcallback: (value: T) => void\n): () => void {\n\tlet previous = getByPath<T>(state.globals, path);\n\tconst unsub = subscribe(state.globals, () => {\n\t\tconst current = getByPath<T>(state.globals, path);\n\t\tif (current !== previous) {\n\t\t\tprevious = current;\n\t\t\tcallback(current as T);\n\t\t}\n\t});\n\tactiveSubscriptions.add(unsub);\n\treturn () => {\n\t\tunsub();\n\t\tactiveSubscriptions.delete(unsub);\n\t};\n}\n\n/**\n * Subscribe to changes on multiple global paths.\n * Callback fires when any of the paths change, receiving all current values.\n * Subscriptions are automatically cleaned up when the game is disposed.\n * @example const unsub = onGlobalChanges(['score', 'lives'], ([score, lives]) => console.log(score, lives));\n */\nexport function onGlobalChanges<T extends unknown[] = unknown[]>(\n\tpaths: string[],\n\tcallback: (values: T) => void\n): () => void {\n\tlet previousValues = paths.map(p => getByPath(state.globals, p));\n\tconst unsub = subscribe(state.globals, () => {\n\t\tconst currentValues = paths.map(p => getByPath(state.globals, p));\n\t\tconst hasChange = currentValues.some((val, i) => val !== previousValues[i]);\n\t\tif (hasChange) {\n\t\t\tpreviousValues = currentValues;\n\t\t\tcallback(currentValues as T);\n\t\t}\n\t});\n\tactiveSubscriptions.add(unsub);\n\treturn () => {\n\t\tunsub();\n\t\tactiveSubscriptions.delete(unsub);\n\t};\n}\n\n/**\n * Get the entire globals object (read-only snapshot).\n */\nexport function getGlobals<T = Record<string, unknown>>(): T {\n\treturn state.globals as T;\n}\n\n/**\n * Initialize globals from an object. Used internally during game setup.\n */\nexport function initGlobals(globals: Record<string, unknown>): void {\n\tfor (const [key, value] of Object.entries(globals)) {\n\t\tsetByPath(state.globals, key, value);\n\t}\n}\n\n/**\n * Reset all globals. Used internally on game dispose.\n */\nexport function resetGlobals(): void {\n\tstate.globals = {};\n}\n\n/**\n * Unsubscribe all active global subscriptions.\n * Used internally on game dispose to prevent old callbacks from firing.\n */\nexport function clearGlobalSubscriptions(): void {\n\tfor (const unsub of activeSubscriptions) {\n\t\tunsub();\n\t}\n\tactiveSubscriptions.clear();\n}\n\nexport { state };","import { proxy } from 'valtio';\nimport type { GameEntity } from '../entities/entity';\n\nexport type DebugTools = 'select' | 'translate' | 'rotate' | 'scale' | 'delete' | 'none';\n\nexport interface DebugState {\n\tenabled: boolean;\n\tpaused: boolean;\n\ttool: DebugTools;\n\tselectedEntity: GameEntity<any> | null;\n\thoveredEntity: GameEntity<any> | null;\n\tflags: Set<string>;\n}\n\nexport const debugState = proxy<DebugState>({\n\tenabled: false,\n\tpaused: false,\n\ttool: 'none',\n\tselectedEntity: null,\n\thoveredEntity: null,\n\tflags: new Set(),\n});\n\nexport function isPaused(): boolean {\n\treturn debugState.paused;\n}\n\nexport function setPaused(paused: boolean): void {\n\tdebugState.paused = paused;\n}\n\nexport function setDebugFlag(flag: string, value: boolean): void {\n\tif (value) {\n\t\tdebugState.flags.add(flag);\n\t} else {\n\t\tdebugState.flags.delete(flag);\n\t}\n}\n\nexport function getDebugTool(): DebugTools {\n\treturn debugState.tool;\n}\n\nexport function setDebugTool(tool: DebugTools): void {\n\tdebugState.tool = tool;\n}\n\nexport function getSelectedEntity(): GameEntity<any> | null {\n\treturn debugState.selectedEntity;\n}\n\nexport function setSelectedEntity(entity: GameEntity<any> | null): void {\n\tdebugState.selectedEntity = entity;\n}\n\nexport function getHoveredEntity(): GameEntity<any> | null {\n\treturn debugState.hoveredEntity;\n}\n\nexport function setHoveredEntity(entity: GameEntity<any> | null): void {\n\tdebugState.hoveredEntity = entity;\n}\n\nexport function resetHoveredEntity(): void {\n\tdebugState.hoveredEntity = null;\n}\n","import { InputPlayer } from './input';\nimport { GameInputConfig, GameInputPlayerConfig, KeyboardMapping, MouseConfig } from '../game/game-interfaces';\n\n/**\n * Creates a GameInputConfig scoped to a single player.\n */\nfunction playerKeyMapping(player: InputPlayer, keyMapping: KeyboardMapping): GameInputConfig {\n\treturn { [player]: { key: keyMapping } } as GameInputConfig;\n}\n\n/**\n * Maps arrow keys to axes (Horizontal/Vertical) for the given player.\n * @example stage.setInputConfiguration(useArrowsForAxes('p1'));\n */\nexport function useArrowsForAxes(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'ArrowLeft': ['axes.Left'],\n\t\t'ArrowRight': ['axes.Right'],\n\t\t'ArrowUp': ['axes.Up'],\n\t\t'ArrowDown': ['axes.Down'],\n\t});\n}\n\n/**\n * Maps arrow keys to secondary axes for the given player.\n * @example stage.setInputConfiguration(useArrowsForSecondaryAxes('p1'));\n */\nexport function useArrowsForSecondaryAxes(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'ArrowLeft': ['axes.SecondaryLeft'],\n\t\t'ArrowRight': ['axes.SecondaryRight'],\n\t\t'ArrowUp': ['axes.SecondaryUp'],\n\t\t'ArrowDown': ['axes.SecondaryDown'],\n\t});\n}\n\n/**\n * Maps arrow keys to directions (Up/Down/Left/Right) for the given player.\n * Useful when `includeDefaults` is false and you still want arrow-key directions.\n * @example stage.setInputConfiguration(useArrowsForDirections('p1'));\n */\nexport function useArrowsForDirections(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'ArrowLeft': ['directions.Left'],\n\t\t'ArrowRight': ['directions.Right'],\n\t\t'ArrowUp': ['directions.Up'],\n\t\t'ArrowDown': ['directions.Down'],\n\t});\n}\n\n/**\n * Maps W/A/S/D keys to directions (Up/Down/Left/Right) for the given player.\n * @example stage.setInputConfiguration(useWASDForDirections('p1'));\n */\nexport function useWASDForDirections(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'w': ['directions.Up'],\n\t\t's': ['directions.Down'],\n\t\t'a': ['directions.Left'],\n\t\t'd': ['directions.Right'],\n\t});\n}\n\n/**\n * Maps W/A/S/D keys to axes (Horizontal/Vertical) for the given player.\n * @example stage.setInputConfiguration(useWASDForAxes('p1'));\n */\nexport function useWASDForAxes(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'a': ['axes.Left'],\n\t\t'd': ['axes.Right'],\n\t\t'w': ['axes.Up'],\n\t\t's': ['axes.Down'],\n\t});\n}\n\n/**\n * Maps I/J/K/L keys to axes (Horizontal/Vertical) for the given player.\n * @example stage.setInputConfiguration(useIJKLForAxes('p1'));\n */\nexport function useIJKLForAxes(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'j': ['axes.Left'],\n\t\t'l': ['axes.Right'],\n\t\t'i': ['axes.Up'],\n\t\t'k': ['axes.Down'],\n\t});\n}\n\n/**\n * Maps I/J/K/L keys to directions (Up/Down/Left/Right) for the given player.\n * @example stage.setInputConfiguration(useIJKLForDirections('p1'));\n */\nexport function useIJKLForDirections(player: InputPlayer): GameInputConfig {\n\treturn playerKeyMapping(player, {\n\t\t'j': ['directions.Left'],\n\t\t'l': ['directions.Right'],\n\t\t'i': ['directions.Up'],\n\t\t'k': ['directions.Down'],\n\t});\n}\n\n/**\n * Enables mouse-look with pointer lock for the given player.\n * Mouse movement maps to SecondaryHorizontal/SecondaryVertical axes;\n * left click maps to LTrigger, right click to RTrigger.\n * @example stage.setInputConfiguration(useMouseLook('p1'));\n */\nexport function useMouseLook(player: InputPlayer, options?: { sensitivity?: number }): GameInputConfig {\n\treturn {\n\t\t[player]: {\n\t\t\tmouse: {\n\t\t\t\tpointerLock: true,\n\t\t\t\tsensitivity: options?.sensitivity,\n\t\t\t} satisfies MouseConfig,\n\t\t},\n\t} as GameInputConfig;\n}\n\n/**\n * Enables basic mouse input (no pointer lock) for the given player.\n * @example stage.setInputConfiguration(useMouse('p1'));\n */\nexport function useMouse(player: InputPlayer, options?: { sensitivity?: number }): GameInputConfig {\n\treturn {\n\t\t[player]: {\n\t\t\tmouse: {\n\t\t\t\tpointerLock: false,\n\t\t\t\tsensitivity: options?.sensitivity,\n\t\t\t} satisfies MouseConfig,\n\t\t},\n\t} as GameInputConfig;\n}\n\nconst INPUT_PLAYERS: (keyof GameInputConfig)[] = ['p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8'];\n\n/**\n * Deep-merges multiple GameInputConfig objects into one.\n * At the player level, configs are merged (both apply).\n * At the key level, later configs win on conflict.\n * @example mergeInputConfigs(useArrowsForAxes('p1'), useWASDForDirections('p1'));\n */\nexport function mergeInputConfigs(...configs: GameInputConfig[]): GameInputConfig {\n\tconst result: GameInputConfig = {};\n\n\tfor (const config of configs) {\n\t\tfor (const player of INPUT_PLAYERS) {\n\t\t\tconst source = config[player];\n\t\t\tif (!source) continue;\n\n\t\t\tconst target: GameInputPlayerConfig = result[player] ?? {};\n\t\t\tconst mergedMouse: MouseConfig | undefined =\n\t\t\t\t(target.mouse || source.mouse)\n\t\t\t\t\t? {\n\t\t\t\t\t\t...target.mouse,\n\t\t\t\t\t\t...source.mouse,\n\t\t\t\t\t\tmapping: { ...target.mouse?.mapping, ...source.mouse?.mapping },\n\t\t\t\t\t}\n\t\t\t\t\t: undefined;\n\t\t\tresult[player] = {\n\t\t\t\tkey: { ...target.key, ...source.key },\n\t\t\t\tmouse: mergedMouse,\n\t\t\t\tincludeDefaults: source.includeDefaults ?? target.includeDefaults,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn result;\n}\n","export const objectVertexShader = `\nuniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n\tvUv = uv;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n}\n`;\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\nuniform sampler2D tDiffuse;\nvarying vec2 vUv;\n\nvoid main() {\n\tvec4 texel = texture2D( tDiffuse, vUv );\n\n\tgl_FragColor = texel;\n}\n`;\n\nexport const standardShader = {\n vertex: objectVertexShader,\n fragment\n};\n","import * as THREE from 'three';\nimport { standardShader } from './shaders/standard.shader';\nimport { WebGLRenderer, WebGLRenderTarget } from 'three';\nimport { Pass, FullScreenQuad } from 'three/addons/postprocessing/Pass.js';\n\nexport default class RenderPass extends Pass {\n\tfsQuad: FullScreenQuad;\n\tresolution: THREE.Vector2;\n\tscene: THREE.Scene;\n\tcamera: THREE.Camera;\n\trgbRenderTarget: WebGLRenderTarget;\n\tnormalRenderTarget: WebGLRenderTarget;\n\tnormalMaterial: THREE.Material;\n\n\tconstructor(resolution: THREE.Vector2, scene: THREE.Scene, camera: THREE.Camera) {\n\t\tsuper();\n\t\tthis.resolution = resolution;\n\t\tthis.fsQuad = new FullScreenQuad(this.material());\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\n\t\tthis.rgbRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\t\tthis.normalRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\n\t\tthis.normalMaterial = new THREE.MeshNormalMaterial();\n\t}\n\n\trender(\n\t\trenderer: WebGLRenderer,\n\t\twriteBuffer: WebGLRenderTarget\n\t) {\n\t\trenderer.setRenderTarget(this.rgbRenderTarget);\n\t\trenderer.render(this.scene, this.camera);\n\n\t\tconst overrideMaterial_old = this.scene.overrideMaterial;\n\t\trenderer.setRenderTarget(this.normalRenderTarget);\n\t\tthis.scene.overrideMaterial = this.normalMaterial;\n\t\trenderer.render(this.scene, this.camera);\n\t\tthis.scene.overrideMaterial = overrideMaterial_old;\n\n\t\t// @ts-ignore\n\t\tconst uniforms = this.fsQuad.material.uniforms;\n\t\tuniforms.tDiffuse.value = this.rgbRenderTarget.texture;\n\t\tuniforms.tDepth.value = this.rgbRenderTarget.depthTexture;\n\t\tuniforms.tNormal.value = this.normalRenderTarget.texture;\n\t\tuniforms.iTime.value += 0.01;\n\n\t\tif (this.renderToScreen) {\n\t\t\trenderer.setRenderTarget(null);\n\t\t} else {\n\t\t\trenderer.setRenderTarget(writeBuffer);\n\t\t}\n\t\tthis.fsQuad.render(renderer);\n\t}\n\n\tmaterial() {\n\t\treturn new THREE.ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null },\n\t\t\t\tresolution: {\n\t\t\t\t\tvalue: new THREE.Vector4(\n\t\t\t\t\t\tthis.resolution.x,\n\t\t\t\t\t\tthis.resolution.y,\n\t\t\t\t\t\t1 / this.resolution.x,\n\t\t\t\t\t\t1 / this.resolution.y,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t},\n\t\t\tvertexShader: standardShader.vertex,\n\t\t\tfragmentShader: standardShader.fragment\n\t\t});\n\t}\n\n\tdispose() {\n\t\ttry {\n\t\t\tthis.fsQuad?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.rgbRenderTarget as any)?.dispose?.();\n\t\t\t(this.normalRenderTarget as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.normalMaterial as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t}\n}\n","import { Vector2, WebGLRenderer, Scene, Camera, PerspectiveCamera } from 'three';\nimport { WebGPURenderer } from 'three/webgpu';\nimport { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';\nimport RenderPass from '../graphics/render-pass';\nimport type { ZylemCamera } from './zylem-camera';\n\n/**\n * Renderer type option for choosing rendering backend\n * - 'auto': Try WebGPU first, fall back to WebGL\n * - 'webgpu': Force WebGPU (error if not supported)\n * - 'webgl': Force WebGL\n */\nexport type RendererType = 'auto' | 'webgpu' | 'webgl';\n\n/**\n * Union type for renderer instances\n */\nexport type ZylemRenderer = WebGLRenderer | WebGPURenderer;\n\n/**\n * Viewport definition in normalized coordinates (0-1).\n * Represents a rectangular region of the canvas for camera rendering.\n */\nexport interface Viewport {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\n/** Default fullscreen viewport */\nexport const DEFAULT_VIEWPORT: Viewport = { x: 0, y: 0, width: 1, height: 1 };\n\n/**\n * Check if WebGPU is supported in the current browser\n */\nexport async function isWebGPUSupported(): Promise<boolean> {\n\tif (!('gpu' in navigator)) return false;\n\ttry {\n\t\tconst adapter = await (navigator as any).gpu.requestAdapter();\n\t\treturn adapter !== null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * RendererManager owns the shared WebGL/WebGPU renderer, canvas element,\n * effect composer, and render loop. There is one RendererManager per game.\n *\n * It iterates active cameras and renders each with its configured viewport.\n */\nexport class RendererManager {\n\trenderer!: ZylemRenderer;\n\tcomposer!: EffectComposer;\n\tscreenResolution: Vector2;\n\trendererType: RendererType;\n\tprivate _isWebGPU = false;\n\tprivate _initialized = false;\n\tprivate _sceneRef: Scene | null = null;\n\tprivate _lastAnimationTimestamp: number | null = null;\n\n\tconstructor(screenResolution?: Vector2, rendererType: RendererType = 'webgl') {\n\t\tthis.screenResolution = screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\t\tthis.rendererType = rendererType;\n\t}\n\n\t/**\n\t * Check if the renderer has been initialized\n\t */\n\tget initialized(): boolean {\n\t\treturn this._initialized;\n\t}\n\n\t/**\n\t * Check if using WebGPU renderer\n\t */\n\tget isWebGPU(): boolean {\n\t\treturn this._isWebGPU;\n\t}\n\n\t/**\n\t * Initialize the renderer (must be called before rendering).\n\t * Async because WebGPU requires async initialization.\n\t */\n\tasync initRenderer(): Promise<void> {\n\t\tif (this._initialized) return;\n\n\t\tlet useWebGPU = false;\n\n\t\tif (this.rendererType === 'webgpu') {\n\t\t\tuseWebGPU = true;\n\t\t} else if (this.rendererType === 'auto') {\n\t\t\tuseWebGPU = await isWebGPUSupported();\n\t\t}\n\n\t\tif (useWebGPU) {\n\t\t\ttry {\n\t\t\t\tthis.renderer = new WebGPURenderer({ antialias: true });\n\t\t\t\tawait this.renderer.init();\n\t\t\t\tthis._isWebGPU = true;\n\t\t\t\tconsole.log('RendererManager: Using WebGPU renderer');\n\t\t\t} catch (e) {\n\t\t\t\tconsole.warn('RendererManager: WebGPU init failed, falling back to WebGL', e);\n\t\t\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\t\t\tthis._isWebGPU = false;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\t\tthis._isWebGPU = false;\n\t\t\tconsole.log('RendererManager: Using WebGL renderer');\n\t\t}\n\n\t\tthis.renderer.setSize(this.screenResolution.x, this.screenResolution.y);\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.shadowMap.enabled = true;\n\t\t}\n\n\t\t// Initialize composer (WebGPU uses different post-processing)\n\t\tif (!this._isWebGPU) {\n\t\t\tthis.composer = new EffectComposer(this.renderer as WebGLRenderer);\n\t\t}\n\n\t\tthis._initialized = true;\n\t}\n\n\t/**\n\t * Set the current scene reference for rendering.\n\t */\n\tsetScene(scene: Scene): void {\n\t\tthis._sceneRef = scene;\n\t}\n\n\t/**\n\t * Setup post-processing render pass for a camera (WebGL only).\n\t */\n\tsetupRenderPass(scene: Scene, camera: Camera): void {\n\t\tif (this._isWebGPU || !this.composer) return;\n\n\t\t// Dispose old passes before adding new ones (prevents GPU leak on stage transitions)\n\t\tif (this.composer.passes.length > 0) {\n\t\t\tthis.composer.passes.forEach((p: any) => { try { p.dispose?.(); } catch { /* noop */ } });\n\t\t\tthis.composer.passes.length = 0;\n\t\t}\n\n\t\tconst renderResolution = this.screenResolution.clone().divideScalar(2);\n\t\trenderResolution.x |= 0;\n\t\trenderResolution.y |= 0;\n\t\tconst pass = new RenderPass(renderResolution, scene, camera);\n\t\tthis.composer.addPass(pass);\n\t}\n\n\t/**\n\t * Start the render loop. Calls the provided callback each frame.\n\t */\n\tstartRenderLoop(onFrame: (delta: number) => void): void {\n\t\tthis._lastAnimationTimestamp = null;\n\t\tthis.renderer.setAnimationLoop((timestamp: number) => {\n\t\t\tconst deltaSeconds = this._lastAnimationTimestamp === null\n\t\t\t\t? 0\n\t\t\t\t: Math.max(0, (timestamp - this._lastAnimationTimestamp) / 1000);\n\t\t\tthis._lastAnimationTimestamp = timestamp;\n\t\t\tonFrame(deltaSeconds);\n\t\t});\n\t}\n\n\t/**\n\t * Stop the render loop.\n\t */\n\tstopRenderLoop(): void {\n\t\tthis._lastAnimationTimestamp = null;\n\t\ttry {\n\t\t\tthis.renderer.setAnimationLoop(null as any);\n\t\t} catch { /* noop */ }\n\t}\n\n\t/**\n\t * Render a scene from a single camera's perspective.\n\t * Sets the viewport based on the camera's viewport config.\n\t */\n\trenderCamera(scene: Scene, camera: ZylemCamera): void {\n\t\tconst vp = camera.viewport;\n\t\tconst w = this.screenResolution.x;\n\t\tconst h = this.screenResolution.y;\n\n\t\t// Set scissor and viewport for this camera\n\t\tconst pixelX = Math.floor(vp.x * w);\n\t\tconst pixelY = Math.floor(vp.y * h);\n\t\tconst pixelW = Math.floor(vp.width * w);\n\t\tconst pixelH = Math.floor(vp.height * h);\n\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setViewport(pixelX, pixelY, pixelW, pixelH);\n\t\t\tthis.renderer.setScissor(pixelX, pixelY, pixelW, pixelH);\n\t\t\tthis.renderer.setScissorTest(true);\n\t\t}\n\n\t\tif (this._isWebGPU) {\n\t\t\tthis.renderer.render(scene, camera.camera);\n\t\t} else if (this.composer) {\n\t\t\tthis.composer.render(0);\n\t\t}\n\t}\n\n\t/**\n\t * Render a camera to its offscreen render target (WebGL only).\n\t * Bypasses the EffectComposer since post-processing is not needed\n\t * for render-to-texture output.\n\t *\n\t * The camera must have a non-null renderTarget.\n\t */\n\trenderCameraToTarget(scene: Scene, camera: ZylemCamera): void {\n\t\tif (!camera.renderTarget) return;\n\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tconst prevTarget = this.renderer.getRenderTarget();\n\t\t\tthis.renderer.setRenderTarget(camera.renderTarget);\n\t\t\tthis.renderer.clear();\n\t\t\tthis.renderer.render(scene, camera.camera);\n\t\t\tthis.renderer.setRenderTarget(prevTarget);\n\t\t} else {\n\t\t\t// WebGPU RTT not yet supported\n\t\t\tconsole.warn('RendererManager: Render-to-texture is not yet supported for WebGPU');\n\t\t}\n\t}\n\n\t/**\n\t * Render a scene from multiple cameras, each with their own viewport.\n\t * Cameras are rendered in order (first = bottom layer, last = top layer).\n\t */\n\trenderCameras(scene: Scene, cameras: ZylemCamera[]): void {\n\t\tif (!scene || cameras.length === 0) return;\n\n\t\t// Clear the full canvas first\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setScissorTest(false);\n\t\t\tthis.renderer.clear();\n\t\t}\n\n\t\tfor (const cam of cameras) {\n\t\t\tthis.renderCamera(scene, cam);\n\t\t}\n\n\t\t// Restore scissor test state\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setScissorTest(false);\n\t\t}\n\t}\n\n\t/**\n\t * Simple single-camera render (backwards compatible).\n\t * Uses the full viewport for a single camera.\n\t */\n\trender(scene: Scene, camera: Camera): void {\n\t\tif (this._isWebGPU) {\n\t\t\tthis.renderer.render(scene, camera);\n\t\t} else if (this.composer) {\n\t\t\tthis.composer.render(0);\n\t\t}\n\t}\n\n\t/**\n\t * Resize the renderer and update resolution.\n\t */\n\tresize(width: number, height: number): void {\n\t\tthis.screenResolution.set(width, height);\n\t\tthis.renderer.setSize(width, height, false);\n\t\tif (this.composer) {\n\t\t\tthis.composer.setSize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Update renderer pixel ratio (DPR).\n\t */\n\tsetPixelRatio(dpr: number): void {\n\t\tconst safe = Math.max(1, Number.isFinite(dpr) ? dpr : 1);\n\t\tthis.renderer.setPixelRatio(safe);\n\t}\n\n\t/**\n\t * Get the DOM element for the renderer.\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\treturn this.renderer.domElement;\n\t}\n\n\t/**\n\t * Dispose renderer, composer, and related resources.\n\t */\n\tdispose(): void {\n\t\tthis.stopRenderLoop();\n\t\ttry {\n\t\t\tthis.composer?.passes?.forEach((p: any) => p.dispose?.());\n\t\t\t(this.composer as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.renderer.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis._sceneRef = null;\n\t\tthis._initialized = false;\n\t}\n}\n","import { BaseNode } from '../base-node';\nimport { CameraWrapper } from '../../camera/camera';\n\n/**\n * Check if an item is a BaseNode (has a create function).\n */\nexport function isBaseNode(item: unknown): item is BaseNode {\n\treturn !!item && typeof item === 'object' && typeof (item as any).create === 'function';\n}\n\n/**\n * Check if an item is a Promise-like (thenable).\n */\nexport function isThenable(item: unknown): item is Promise<any> {\n\treturn !!item && typeof (item as any).then === 'function';\n}\n\n/**\n * Check if an item is a CameraWrapper.\n */\nexport function isCameraWrapper(item: unknown): item is CameraWrapper {\n\treturn !!item && typeof item === 'object' && (item as any).constructor?.name === 'CameraWrapper';\n}\n\n/**\n * Check if an item is a plain config object (not a special type).\n * Excludes BaseNode, CameraWrapper, functions, and promises.\n */\nexport function isConfigObject(item: unknown): boolean {\n\tif (!item || typeof item !== 'object') return false;\n\tif (isBaseNode(item)) return false;\n\tif (isCameraWrapper(item)) return false;\n\tif (isThenable(item)) return false;\n\tif (typeof (item as any).then === 'function') return false;\n\t// Must be a plain object\n\treturn (item as any).constructor === Object || (item as any).constructor?.name === 'Object';\n}\n\n/**\n * Check if an item is an entity input (BaseNode, Promise, or factory function).\n */\nexport function isEntityInput(item: unknown): boolean {\n\tif (!item) return false;\n\tif (isBaseNode(item)) return true;\n\tif (typeof item === 'function') return true;\n\tif (isThenable(item)) return true;\n\treturn false;\n}\n","export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<\n\tWildcardHandler<T>\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n\tall: EventHandlerMap<Events>;\n\n\ton<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n\ton(type: '*', handler: WildcardHandler<Events>): void;\n\n\toff<Key extends keyof Events>(\n\t\ttype: Key,\n\t\thandler?: Handler<Events[Key]>\n\t): void;\n\toff(type: '*', handler: WildcardHandler<Events>): void;\n\n\temit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n\temit<Key extends keyof Events>(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt<Events extends Record<EventType, unknown>>(\n\tall?: EventHandlerMap<Events>\n): Emitter<Events> {\n\ttype GenericEventHandler =\n\t\t| Handler<Events[keyof Events]>\n\t\t| WildcardHandler<Events>;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList<Events[keyof Events]>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList<Events>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n","import mitt, { Emitter } from 'mitt';\n\n/**\n * Event scope identifier for routing events.\n */\nexport type EventScope = 'game' | 'stage' | 'entity';\n\n/**\n * Reusable delegate for event emission and subscription.\n * Use via composition in Game, Stage, and Entity classes.\n * \n * @example\n * class Game {\n * private eventDelegate = new EventEmitterDelegate<GameEvents>();\n * \n * dispatch<K extends keyof GameEvents>(event: K, payload: GameEvents[K]) {\n * this.eventDelegate.dispatch(event, payload);\n * }\n * }\n */\nexport class EventEmitterDelegate<TEvents extends Record<string, unknown>> {\n\tprivate emitter: Emitter<TEvents>;\n\tprivate unsubscribes: (() => void)[] = [];\n\n\tconstructor() {\n\t\tthis.emitter = mitt<TEvents>();\n\t}\n\n\t/**\n\t * Dispatch an event to all listeners.\n\t */\n\tdispatch<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n\t\tthis.emitter.emit(event, payload);\n\t}\n\n\t/**\n\t * Subscribe to an event. Returns an unsubscribe function.\n\t */\n\tlisten<K extends keyof TEvents>(\n\t\tevent: K,\n\t\thandler: (payload: TEvents[K]) => void\n\t): () => void {\n\t\tthis.emitter.on(event, handler);\n\t\tconst unsub = () => this.emitter.off(event, handler);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Subscribe to all events.\n\t */\n\tlistenAll(handler: (type: keyof TEvents, payload: TEvents[keyof TEvents]) => void): () => void {\n\t\tthis.emitter.on('*', handler as any);\n\t\tconst unsub = () => this.emitter.off('*', handler as any);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Clean up all subscriptions.\n\t */\n\tdispose(): void {\n\t\tthis.unsubscribes.forEach(fn => fn());\n\t\tthis.unsubscribes = [];\n\t\tthis.emitter.all.clear();\n\t}\n}\n","import mitt from 'mitt';\nimport type { LoadingEvent } from '../core/interfaces';\n\n/**\n * Payload for game loading events with stage context.\n */\nexport interface GameLoadingPayload extends LoadingEvent {\n\tstageName?: string;\n\tstageIndex?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Game Events\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Payload for stage configuration sent to editor. */\nexport interface StageConfigPayload {\n\tid: string;\n\tbackgroundColor: string;\n\tbackgroundImage: string | null;\n\tgravity: { x: number; y: number; z: number };\n\tinputs: Record<string, string[]>;\n\tvariables: Record<string, unknown>;\n}\n\n/** Payload for entity configuration sent to editor. */\nexport interface EntityConfigPayload {\n\tuuid: string;\n\tname: string;\n\ttype: string;\n\tposition: { x: number; y: number; z: number };\n\trotation: { x: number; y: number; z: number };\n\tscale: { x: number; y: number; z: number };\n}\n\n/** Payload for state dispatch events from game to editor. */\nexport interface StateDispatchPayload {\n\tscope: 'game' | 'stage' | 'entity';\n\tpath: string;\n\tvalue: unknown;\n\tpreviousValue?: unknown;\n\tconfig?: {\n\t\tid: string;\n\t\taspectRatio: number;\n\t\tfullscreen: boolean;\n\t\tbodyBackground: string | undefined;\n\t\tinternalResolution: { width: number; height: number } | undefined;\n\t\tdebug: boolean;\n\t} | null;\n\tstageConfig?: StageConfigPayload | null;\n\tentities?: EntityConfigPayload[] | null;\n}\n\nexport type GameEvents = {\n\t'loading:start': GameLoadingPayload;\n\t'loading:progress': GameLoadingPayload;\n\t'loading:complete': GameLoadingPayload;\n\t'paused': { paused: boolean };\n\t'debug': { enabled: boolean };\n\t'state:dispatch': StateDispatchPayload;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Stage Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type StageEvents = {\n\t'stage:loaded': { stageId: string };\n\t'stage:unloaded': { stageId: string };\n\t'stage:variable:changed': { key: string; value: unknown };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Entity Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type EntityEvents = {\n\t'entity:spawned': { entityId: string; name: string };\n\t'entity:destroyed': { entityId: string };\n\t'entity:collision': { entityId: string; otherId: string };\n\t'entity:model:loading': { entityId: string; files: string[] };\n\t'entity:model:loaded': { entityId: string; success: boolean; meshCount?: number };\n\t'entity:animation:loaded': { entityId: string; animationCount: number };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Combined Event Map\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type ZylemEvents = GameEvents & StageEvents & EntityEvents;\n\n/**\n * Global event bus for cross-package communication.\n * \n * Usage:\n * ```ts\n * import { zylemEventBus } from '@zylem/game-lib';\n * \n * // Subscribe\n * const unsub = zylemEventBus.on('loading:progress', (e) => console.log(e));\n * \n * // Emit\n * zylemEventBus.emit('loading:progress', { type: 'progress', progress: 0.5 });\n * \n * // Cleanup\n * unsub();\n * ```\n */\nexport const zylemEventBus = mitt<ZylemEvents>();\n","export { EventEmitterDelegate, type EventScope } from './event-emitter-delegate';\nexport {\n\tzylemEventBus,\n\ttype ZylemEvents,\n\ttype GameEvents,\n\ttype StageEvents,\n\ttype EntityEvents,\n\ttype GameLoadingPayload,\n\ttype StateDispatchPayload,\n\ttype StageConfigPayload,\n\ttype EntityConfigPayload,\n} from './zylem-events';\n","/** Vite build flags */\nexport const DEBUG_FLAG = import.meta.env.VITE_DEBUG_FLAG === 'true';","import {\n\tCleanupContext,\n\tCleanupFunction,\n\tDestroyContext,\n\tDestroyFunction,\n\tLoadedContext,\n\tLoadedFunction,\n\tSetupContext,\n\tSetupFunction,\n\tUpdateContext,\n\tUpdateFunction,\n} from \"./base-node-life-cycle\";\nimport { DEBUG_FLAG } from \"./flags\";\nimport { nanoid } from \"nanoid\";\nimport { NodeInterface } from \"./node-interface\";\n\nexport type BaseNodeOptions<T = any> = BaseNode | Partial<T>;\nexport type LifecycleRegistrationMethod =\n\t| 'onSetup'\n\t| 'onLoaded'\n\t| 'onUpdate'\n\t| 'onDestroy'\n\t| 'onCleanup'\n\t| 'prependSetup'\n\t| 'prependUpdate';\n\nexport interface LifecycleRegistration {\n\tmethod: LifecycleRegistrationMethod;\n\tcallbacks: Function[];\n}\n\n/**\n * Lifecycle callback arrays - each lifecycle event can have multiple callbacks\n * that execute in order.\n */\nexport interface LifecycleCallbacks<T> {\n\tsetup: Array<SetupFunction<T>>;\n\tloaded: Array<LoadedFunction<T>>;\n\tupdate: Array<UpdateFunction<T>>;\n\tdestroy: Array<DestroyFunction<T>>;\n\tcleanup: Array<CleanupFunction<T>>;\n}\n\nexport abstract class BaseNode<Options = any, T = any> implements NodeInterface {\n\tprotected parent: NodeInterface | null = null;\n\tprotected children: NodeInterface[] = [];\n\tpublic options: Options;\n\tpublic eid: number = 0;\n\tpublic uuid: string = '';\n\tpublic name: string = '';\n\tpublic markedForRemoval: boolean = false;\n\n\t/**\n\t * Lifecycle callback arrays - use onSetup(), onUpdate(), etc. to add callbacks\n\t * Uses `any` for the type parameter to avoid invariance issues when subclasses\n\t * are assigned to BaseNode references. Type safety is enforced by the public\n\t * onSetup/onUpdate/etc. methods which are typed with `this`.\n\t */\n\tprotected lifecycleCallbacks: LifecycleCallbacks<any> = {\n\t\tsetup: [],\n\t\tloaded: [],\n\t\tupdate: [],\n\t\tdestroy: [],\n\t\tcleanup: [],\n\t};\n\tprivate trackLifecycleRegistrations: boolean = false;\n\tprivate userLifecycleRegistrations: LifecycleRegistration[] = [];\n\n\tconstructor(args: BaseNodeOptions[] = []) {\n\t\tconst options = args\n\t\t\t.filter(arg => !(arg instanceof BaseNode))\n\t\t\t.reduce((acc, opt) => ({ ...acc, ...opt }), {});\n\t\tthis.options = options as Options;\n\t\tthis.uuid = nanoid();\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Fluent API for adding lifecycle callbacks\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add setup callbacks to be executed in order during nodeSetup\n\t */\n\tpublic onSetup(...callbacks: Array<SetupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.setup.push(...callbacks);\n\t\tthis.recordLifecycleRegistration('onSetup', callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add loaded callbacks to be executed in order during nodeLoaded\n\t */\n\tpublic onLoaded(...callbacks: Array<LoadedFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.loaded.push(...callbacks);\n\t\tthis.recordLifecycleRegistration('onLoaded', callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add update callbacks to be executed in order during nodeUpdate\n\t */\n\tpublic onUpdate(...callbacks: Array<UpdateFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.update.push(...callbacks);\n\t\tthis.recordLifecycleRegistration('onUpdate', callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add destroy callbacks to be executed in order during nodeDestroy\n\t */\n\tpublic onDestroy(...callbacks: Array<DestroyFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.destroy.push(...callbacks);\n\t\tthis.recordLifecycleRegistration('onDestroy', callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add cleanup callbacks to be executed in order during nodeCleanup\n\t */\n\tpublic onCleanup(...callbacks: Array<CleanupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.cleanup.push(...callbacks);\n\t\tthis.recordLifecycleRegistration('onCleanup', callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepend setup callbacks (run before existing ones)\n\t */\n\tpublic prependSetup(...callbacks: Array<SetupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.setup.unshift(...callbacks);\n\t\tthis.recordLifecycleRegistration('prependSetup', callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepend update callbacks (run before existing ones)\n\t */\n\tpublic prependUpdate(...callbacks: Array<UpdateFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.update.unshift(...callbacks);\n\t\tthis.recordLifecycleRegistration('prependUpdate', callbacks);\n\t\treturn this;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Tree structure\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic setParent(parent: NodeInterface | null): void {\n\t\tthis.parent = parent;\n\t}\n\n\tpublic getParent(): NodeInterface | null {\n\t\treturn this.parent;\n\t}\n\n\tpublic add(baseNode: NodeInterface): void {\n\t\tthis.children.push(baseNode);\n\t\tbaseNode.setParent(this);\n\t}\n\n\tpublic remove(baseNode: NodeInterface): void {\n\t\tconst index = this.children.indexOf(baseNode);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tbaseNode.setParent(null);\n\t\t}\n\t}\n\n\tpublic getChildren(): NodeInterface[] {\n\t\treturn this.children;\n\t}\n\n\tpublic isComposite(): boolean {\n\t\treturn this.children.length > 0;\n\t}\n\n\tpublic enableUserLifecycleTracking(): void {\n\t\tthis.trackLifecycleRegistrations = true;\n\t}\n\n\tprotected replayUserLifecycleRegistrationsTo(\n\t\ttarget: BaseNode<any, any>,\n\t\twrap?: <T extends Function>(callback: T) => T,\n\t): void {\n\t\tfor (const registration of this.userLifecycleRegistrations) {\n\t\t\tconst callbacks = wrap\n\t\t\t\t? registration.callbacks.map((callback) => wrap(callback as never))\n\t\t\t\t: [...registration.callbacks];\n\n\t\t\tswitch (registration.method) {\n\t\t\t\tcase 'onSetup':\n\t\t\t\t\ttarget.onSetup(...callbacks as Array<SetupFunction<any>>);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'onLoaded':\n\t\t\t\t\ttarget.onLoaded(...callbacks as Array<LoadedFunction<any>>);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'onUpdate':\n\t\t\t\t\ttarget.onUpdate(...callbacks as Array<UpdateFunction<any>>);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'onDestroy':\n\t\t\t\t\ttarget.onDestroy(...callbacks as Array<DestroyFunction<any>>);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'onCleanup':\n\t\t\t\t\ttarget.onCleanup(...callbacks as Array<CleanupFunction<any>>);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'prependSetup':\n\t\t\t\t\ttarget.prependSetup(...callbacks as Array<SetupFunction<any>>);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'prependUpdate':\n\t\t\t\t\ttarget.prependUpdate(...callbacks as Array<UpdateFunction<any>>);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected cloneChildrenInto(target: BaseNode<any, any>): void {\n\t\tfor (const child of this.children) {\n\t\t\ttarget.add(cloneNode(child));\n\t\t}\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Abstract methods for subclass implementation\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic abstract create(): T;\n\n\tprotected abstract _setup(params: SetupContext<this>): void;\n\n\tprotected abstract _loaded(params: LoadedContext<this>): Promise<void>;\n\n\tprotected abstract _update(params: UpdateContext<this>): void;\n\n\tprotected abstract _destroy(params: DestroyContext<this>): void;\n\n\tprotected abstract _cleanup(params: CleanupContext<this>): void;\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Node lifecycle execution - runs internal + callback arrays\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic nodeSetup(params: SetupContext<this>) {\n\t\tif (DEBUG_FLAG) { /** */ }\n\t\tthis.markedForRemoval = false;\n\t\tif (typeof this._setup === 'function') {\n\t\t\tthis._setup(params);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.setup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tthis.children.forEach(child => child.nodeSetup(params));\n\t}\n\n\tpublic nodeUpdate(params: UpdateContext<this>): void {\n\t\tif (this.markedForRemoval) {\n\t\t\treturn;\n\t\t}\n\t\tif (typeof this._update === 'function') {\n\t\t\tthis._update(params);\n\t\t}\n\t\t// Tick entity actions before user callbacks so state is fresh\n\t\tif (typeof (this as any)._tickActions === 'function') {\n\t\t\t(this as any)._tickActions(params.delta);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.update) {\n\t\t\tcallback(params);\n\t\t}\n\t\tthis.children.forEach(child => child.nodeUpdate(params));\n\t}\n\n\tpublic nodeDestroy(params: DestroyContext<this>): void {\n\t\t// Guard against re-entry (e.g. destroy called twice during collision loop)\n\t\tif (this.markedForRemoval) return;\n\n\t\tthis.children.forEach(child => child.nodeDestroy(params));\n\n\t\t// Destroy phase -- consumer game logic (onDestroy callbacks + _destroy override)\n\t\tfor (const callback of this.lifecycleCallbacks.destroy) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._destroy === 'function') {\n\t\t\tthis._destroy(params);\n\t\t}\n\t\tthis.markedForRemoval = true;\n\n\t\t// Cleanup phase -- engine-internal resource disposal (onCleanup callbacks + _cleanup override)\n\t\tfor (const callback of this.lifecycleCallbacks.cleanup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._cleanup === 'function') {\n\t\t\tthis._cleanup(params);\n\t\t}\n\t}\n\n\tpublic async nodeLoaded(params: LoadedContext<this>): Promise<void> {\n\t\tif (typeof this._loaded === 'function') {\n\t\t\tawait this._loaded(params);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.loaded) {\n\t\t\tcallback(params);\n\t\t}\n\t}\n\n\tpublic nodeCleanup(params: CleanupContext<this>): void {\n\t\tthis.children.forEach(child => (child as any).nodeCleanup?.(params));\n\t\tfor (const callback of this.lifecycleCallbacks.cleanup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._cleanup === 'function') {\n\t\t\tthis._cleanup(params);\n\t\t}\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Options\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic getOptions(): Options {\n\t\treturn this.options;\n\t}\n\n\tpublic setOptions(options: Partial<Options>): void {\n\t\tthis.options = { ...this.options, ...options };\n\t}\n\n\tprivate recordLifecycleRegistration(\n\t\tmethod: LifecycleRegistrationMethod,\n\t\tcallbacks: Function[],\n\t): void {\n\t\tif (!this.trackLifecycleRegistrations || callbacks.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.userLifecycleRegistrations.push({\n\t\t\tmethod,\n\t\t\tcallbacks: [...callbacks],\n\t\t});\n\t}\n}\n\nexport function cloneNode(node: NodeInterface): NodeInterface {\n\tconst maybeClone = (node as any)?.clone;\n\tif (typeof maybeClone !== 'function') {\n\t\tthrow new Error(\n\t\t\t`Cannot clone child node \"${node.name || node.uuid || 'unknown'}\": missing clone() support.`,\n\t\t);\n\t}\n\treturn maybeClone.call(node);\n}\n","import { Quaternion } from 'three';\n\nexport interface PhysicsVector3 {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\nexport interface PhysicsQuaternion {\n\tx: number;\n\ty: number;\n\tz: number;\n\tw: number;\n}\n\nexport interface PhysicsPose {\n\tposition: PhysicsVector3;\n\trotation: PhysicsQuaternion;\n}\n\nexport interface PhysicsPoseHistory {\n\tprevious: PhysicsPose;\n\tcurrent: PhysicsPose;\n}\n\nexport interface PhysicsPoseReadable {\n\ttranslation(): PhysicsVector3;\n\trotation(): PhysicsQuaternion;\n}\n\nexport interface PhysicsRenderPoseProvider {\n\tgetPoseHistory(): PhysicsPoseHistory;\n\tgetRenderPose(alpha: number): PhysicsPose;\n}\n\nconst directBodyPoseHistory = new WeakMap<object, PhysicsPoseHistory>();\nconst _previousQuaternion = new Quaternion();\nconst _currentQuaternion = new Quaternion();\nconst _renderQuaternion = new Quaternion();\n\nexport function createPhysicsPose(\n\tposition: Partial<PhysicsVector3> = {},\n\trotation: Partial<PhysicsQuaternion> = {},\n): PhysicsPose {\n\treturn {\n\t\tposition: {\n\t\t\tx: position.x ?? 0,\n\t\t\ty: position.y ?? 0,\n\t\t\tz: position.z ?? 0,\n\t\t},\n\t\trotation: {\n\t\t\tx: rotation.x ?? 0,\n\t\t\ty: rotation.y ?? 0,\n\t\t\tz: rotation.z ?? 0,\n\t\t\tw: rotation.w ?? 1,\n\t\t},\n\t};\n}\n\nexport function clonePhysicsVector3(vector: PhysicsVector3): PhysicsVector3 {\n\treturn { x: vector.x, y: vector.y, z: vector.z };\n}\n\nexport function clonePhysicsQuaternion(\n\trotation: PhysicsQuaternion,\n): PhysicsQuaternion {\n\treturn { x: rotation.x, y: rotation.y, z: rotation.z, w: rotation.w };\n}\n\nexport function clonePhysicsPose(pose: PhysicsPose): PhysicsPose {\n\treturn {\n\t\tposition: clonePhysicsVector3(pose.position),\n\t\trotation: clonePhysicsQuaternion(pose.rotation),\n\t};\n}\n\nexport function clampInterpolationAlpha(alpha: number): number {\n\tif (!Number.isFinite(alpha)) return 0;\n\treturn Math.max(0, Math.min(1, alpha));\n}\n\nexport function capturePhysicsPose(body: PhysicsPoseReadable): PhysicsPose {\n\treturn {\n\t\tposition: clonePhysicsVector3(body.translation()),\n\t\trotation: clonePhysicsQuaternion(body.rotation()),\n\t};\n}\n\nexport function createCollapsedPhysicsPoseHistory(\n\tpose: PhysicsPose,\n): PhysicsPoseHistory {\n\tconst current = clonePhysicsPose(pose);\n\treturn {\n\t\tprevious: clonePhysicsPose(current),\n\t\tcurrent,\n\t};\n}\n\nexport function registerDirectBodyPoseHistory(\n\tbody: object & PhysicsPoseReadable,\n): PhysicsPoseHistory {\n\tconst history = createCollapsedPhysicsPoseHistory(capturePhysicsPose(body));\n\tdirectBodyPoseHistory.set(body, history);\n\treturn history;\n}\n\nexport function getDirectBodyPoseHistory(\n\tbody: object,\n): PhysicsPoseHistory | null {\n\treturn directBodyPoseHistory.get(body) ?? null;\n}\n\nexport function collapseDirectBodyPoseHistory(\n\tbody: object & PhysicsPoseReadable,\n): PhysicsPoseHistory {\n\tconst pose = capturePhysicsPose(body);\n\tconst history =\n\t\tdirectBodyPoseHistory.get(body) ?? createCollapsedPhysicsPoseHistory(pose);\n\n\thistory.previous = clonePhysicsPose(pose);\n\thistory.current = clonePhysicsPose(pose);\n\tdirectBodyPoseHistory.set(body, history);\n\n\treturn history;\n}\n\nexport function prepareDirectBodyPoseHistoryStep(\n\tbody: object & PhysicsPoseReadable,\n): PhysicsPoseHistory {\n\treturn collapseDirectBodyPoseHistory(body);\n}\n\nexport function commitDirectBodyPoseHistoryStep(\n\tbody: object & PhysicsPoseReadable,\n): PhysicsPoseHistory {\n\tconst pose = capturePhysicsPose(body);\n\tconst history =\n\t\tdirectBodyPoseHistory.get(body) ?? createCollapsedPhysicsPoseHistory(pose);\n\n\thistory.current = clonePhysicsPose(pose);\n\tdirectBodyPoseHistory.set(body, history);\n\n\treturn history;\n}\n\nexport function interpolatePhysicsPose(\n\tprevious: PhysicsPose,\n\tcurrent: PhysicsPose,\n\talpha: number,\n): PhysicsPose {\n\tconst t = clampInterpolationAlpha(alpha);\n\n\t_previousQuaternion.set(\n\t\tprevious.rotation.x,\n\t\tprevious.rotation.y,\n\t\tprevious.rotation.z,\n\t\tprevious.rotation.w,\n\t);\n\t_currentQuaternion.set(\n\t\tcurrent.rotation.x,\n\t\tcurrent.rotation.y,\n\t\tcurrent.rotation.z,\n\t\tcurrent.rotation.w,\n\t);\n\t_renderQuaternion.slerpQuaternions(\n\t\t_previousQuaternion,\n\t\t_currentQuaternion,\n\t\tt,\n\t);\n\n\treturn {\n\t\tposition: {\n\t\t\tx: previous.position.x + (current.position.x - previous.position.x) * t,\n\t\t\ty: previous.position.y + (current.position.y - previous.position.y) * t,\n\t\t\tz: previous.position.z + (current.position.z - previous.position.z) * t,\n\t\t},\n\t\trotation: {\n\t\t\tx: _renderQuaternion.x,\n\t\t\ty: _renderQuaternion.y,\n\t\t\tz: _renderQuaternion.z,\n\t\t\tw: _renderQuaternion.w,\n\t\t},\n\t};\n}\n\nexport function getBodyPoseHistory(body: unknown): PhysicsPoseHistory | null {\n\tif (isRenderPoseProvider(body)) {\n\t\treturn body.getPoseHistory();\n\t}\n\tif (isPhysicsPoseReadable(body)) {\n\t\treturn directBodyPoseHistory.get(body as object) ?? null;\n\t}\n\treturn null;\n}\n\nexport function getBodyRenderPose(\n\tbody: PhysicsPoseReadable | PhysicsRenderPoseProvider,\n\talpha: number,\n): PhysicsPose {\n\tif (isRenderPoseProvider(body)) {\n\t\treturn body.getRenderPose(alpha);\n\t}\n\n\tconst history = directBodyPoseHistory.get(body as object);\n\tif (!history) {\n\t\treturn capturePhysicsPose(body);\n\t}\n\n\tconst latestPose = capturePhysicsPose(body);\n\tif (!posesEqual(latestPose, history.current)) {\n\t\tconst collapsed = collapseDirectBodyPoseHistory(body as object & PhysicsPoseReadable);\n\t\treturn clonePhysicsPose(collapsed.current);\n\t}\n\n\treturn interpolatePhysicsPose(history.previous, history.current, alpha);\n}\n\nfunction isPhysicsPoseReadable(value: unknown): value is PhysicsPoseReadable {\n\treturn (\n\t\tvalue != null &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof (value as PhysicsPoseReadable).translation === 'function' &&\n\t\ttypeof (value as PhysicsPoseReadable).rotation === 'function'\n\t);\n}\n\nfunction isRenderPoseProvider(value: unknown): value is PhysicsRenderPoseProvider {\n\treturn (\n\t\tvalue != null &&\n\t\ttypeof value === 'object' &&\n\t\ttypeof (value as PhysicsRenderPoseProvider).getPoseHistory === 'function' &&\n\t\ttypeof (value as PhysicsRenderPoseProvider).getRenderPose === 'function'\n\t);\n}\n\nfunction posesEqual(a: PhysicsPose, b: PhysicsPose): boolean {\n\treturn (\n\t\ta.position.x === b.position.x &&\n\t\ta.position.y === b.position.y &&\n\t\ta.position.z === b.position.z &&\n\t\ta.rotation.x === b.rotation.x &&\n\t\ta.rotation.y === b.rotation.y &&\n\t\ta.rotation.z === b.rotation.z &&\n\t\ta.rotation.w === b.rotation.w\n\t);\n}\n","import {\n\tdefineSystem,\n\tdefineQuery,\n\tdefineComponent,\n\tTypes,\n\tremoveQuery,\n\ttype IWorld,\n} from 'bitecs';\nimport { Quaternion } from 'three';\nimport { StageEntity } from '../interfaces/entity';\nimport {\n\tgetBodyRenderPose,\n\ttype PhysicsPoseReadable,\n} from '../physics/physics-pose';\n\nexport type StageSystem = {\n\t_childrenMap: Map<number, StageEntity & { body: PhysicsPoseReadable | null }>;\n\t_world: { interpolationAlpha: number } | null;\n}\n\nexport const position = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32\n});\n\nexport const rotation = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32,\n\tw: Types.f32\n});\n\nexport const scale = defineComponent({\n\tx: Types.f32,\n\ty: Types.f32,\n\tz: Types.f32\n});\n\n// Reusable quaternion to avoid allocations per frame\nconst _tempQuaternion = new Quaternion();\n\nexport type TransformSystemResult = {\n\tsystem: ReturnType<typeof defineSystem>;\n\tdestroy: (world: IWorld) => void;\n};\n\nexport default function createTransformSystem(stage: StageSystem): TransformSystemResult {\n\tconst queryTerms = [position, rotation];\n\tconst transformQuery = defineQuery(queryTerms);\n\tconst stageEntities = stage._childrenMap;\n\tconst interpolationSource = stage._world;\n\n\tconst system = defineSystem((world) => {\n\t\tconst entities = transformQuery(world);\n\t\tif (stageEntities === undefined) {\n\t\t\treturn world;\n\t\t}\n\n\t\tfor (const [key, stageEntity] of stageEntities) {\n\t\t\t// Early bailout - combine conditions\n\t\t\tif (!stageEntity?.body || stageEntity.markedForRemoval) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst id = entities[key];\n\t\t\tconst body = stageEntity.body;\n\t\t\tconst target = stageEntity.group ?? stageEntity.mesh;\n\t\t\tconst renderPose = target\n\t\t\t\t? getBodyRenderPose(body, interpolationSource?.interpolationAlpha ?? 0)\n\t\t\t\t: null;\n\n\t\t\t// Position sync\n\t\t\tconst translation = body.translation();\n\t\t\tposition.x[id] = translation.x;\n\t\t\tposition.y[id] = translation.y;\n\t\t\tposition.z[id] = translation.z;\n\n\t\t\tif (target && renderPose) {\n\t\t\t\ttarget.position.set(\n\t\t\t\t\trenderPose.position.x,\n\t\t\t\t\trenderPose.position.y,\n\t\t\t\t\trenderPose.position.z,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Skip rotation if controlled externally\n\t\t\tif (stageEntity.controlledRotation) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Rotation sync - reuse quaternion\n\t\t\tconst rot = body.rotation();\n\t\t\trotation.x[id] = rot.x;\n\t\t\trotation.y[id] = rot.y;\n\t\t\trotation.z[id] = rot.z;\n\t\t\trotation.w[id] = rot.w;\n\n\t\t\tif (target && renderPose) {\n\t\t\t\t_tempQuaternion.set(\n\t\t\t\t\trenderPose.rotation.x,\n\t\t\t\t\trenderPose.rotation.y,\n\t\t\t\t\trenderPose.rotation.z,\n\t\t\t\t\trenderPose.rotation.w,\n\t\t\t\t);\n\t\t\t\ttarget.setRotationFromQuaternion(_tempQuaternion);\n\t\t\t}\n\t\t}\n\n\t\treturn world;\n\t});\n\n\tconst destroy = (world: IWorld) => {\n\t\t// Remove the query from bitecs world tracking\n\t\tremoveQuery(world, transformQuery);\n\t};\n\n\treturn { system, destroy };\n}\n","import { proxy } from 'valtio';\n\nexport type VelocityIntentMode = 'replace' | 'add';\n\nexport interface VelocityIntent {\n\tx?: number;\n\ty?: number;\n\tz?: number;\n\tmode: VelocityIntentMode;\n\tpriority?: number;\n}\n\n/**\n * Transform state managed by Valtio for batched physics updates.\n * \n * This store accumulates transformation intents during the frame,\n * then applies them all at once after onUpdate() callbacks complete.\n * \n * Design decisions:\n * - Position: Accumulated deltas (additive)\n * - Rotation: Last value wins (replacement)\n * - Velocity: Accumulated deltas (additive)\n * - Angular velocity: Accumulated deltas (additive)\n */\nexport interface TransformState {\n\t/** Position deltas to be applied (accumulated) */\n\tposition: { x: number; y: number; z: number };\n\t\n\t/** Rotation quaternion (last value wins) */\n\trotation: { x: number; y: number; z: number; w: number };\n\t\n\t/** Linear velocity (accumulated) */\n\tvelocity: { x: number; y: number; z: number };\n\t\n\t/** Angular velocity (accumulated) */\n\tangularVelocity: { x: number; y: number; z: number };\n\n\t/** Per-source velocity intents composed once per frame */\n\tvelocityChannels: Record<string, VelocityIntent>;\n\t\n\t/** Dirty flags to track what needs to be applied */\n\tdirty: {\n\t\tposition: boolean;\n\t\trotation: boolean;\n\t\t/** @deprecated Use per-axis velocityX/Y/Z flags for new code */\n\t\tvelocity: boolean;\n\t\tvelocityX: boolean;\n\t\tvelocityY: boolean;\n\t\tvelocityZ: boolean;\n\t\tvelocityChannels: boolean;\n\t\tangularVelocity: boolean;\n\t};\n}\n\n/**\n * Create a new transform store with optional initial values.\n * The store is a Valtio proxy, making it reactive for debugging/visualization.\n * \n * @param initial Optional initial state values\n * @returns Reactive transform state\n */\nexport function createTransformStore(initial?: Partial<TransformState>): TransformState {\n\tconst defaultState: TransformState = {\n\t\tposition: { x: 0, y: 0, z: 0 },\n\t\trotation: { x: 0, y: 0, z: 0, w: 1 },\n\t\tvelocity: { x: 0, y: 0, z: 0 },\n\t\tangularVelocity: { x: 0, y: 0, z: 0 },\n\t\tvelocityChannels: {},\n\t\tdirty: {\n\t\t\tposition: false,\n\t\t\trotation: false,\n\t\t\tvelocity: false,\n\t\t\tvelocityX: false,\n\t\t\tvelocityY: false,\n\t\t\tvelocityZ: false,\n\t\t\tvelocityChannels: false,\n\t\t\tangularVelocity: false,\n\t\t},\n\t};\n\n\treturn proxy({\n\t\t...defaultState,\n\t\t...initial,\n\t\t// Ensure dirty flags are properly initialized even if partial initial state\n\t\tdirty: {\n\t\t\t...defaultState.dirty,\n\t\t\t...initial?.dirty,\n\t\t},\n\t});\n}\n\n/**\n * Reset a transform store to its initial clean state.\n * Called after applying changes to prepare for the next frame.\n * \n * @param store The transform store to reset\n */\nexport function resetTransformStore(store: TransformState): void {\n\t// Reset position deltas\n\tstore.position.x = 0;\n\tstore.position.y = 0;\n\tstore.position.z = 0;\n\n\t// Reset rotation to identity quaternion\n\tstore.rotation.x = 0;\n\tstore.rotation.y = 0;\n\tstore.rotation.z = 0;\n\tstore.rotation.w = 1;\n\n\t// Reset velocity\n\tstore.velocity.x = 0;\n\tstore.velocity.y = 0;\n\tstore.velocity.z = 0;\n\n\t// Reset angular velocity\n\tstore.angularVelocity.x = 0;\n\tstore.angularVelocity.y = 0;\n\tstore.angularVelocity.z = 0;\n\n\t// Reset per-source velocity intents\n\tfor (const sourceId of Object.keys(store.velocityChannels)) {\n\t\tdelete store.velocityChannels[sourceId];\n\t}\n\n\t// Clear all dirty flags\n\tstore.dirty.position = false;\n\tstore.dirty.rotation = false;\n\tstore.dirty.velocity = false;\n\tstore.dirty.velocityX = false;\n\tstore.dirty.velocityY = false;\n\tstore.dirty.velocityZ = false;\n\tstore.dirty.velocityChannels = false;\n\tstore.dirty.angularVelocity = false;\n}\n","import { TransformState, VelocityIntentMode } from './transform-store';\n\nexport interface VelocityIntentOptions {\n\tmode?: VelocityIntentMode;\n\tpriority?: number;\n}\n\nexport interface VelocityIntentVector {\n\tx?: number;\n\ty?: number;\n\tz?: number;\n}\n\nexport function setVelocityIntent(\n\tstore: TransformState,\n\tsourceId: string,\n\tvector: VelocityIntentVector,\n\toptions: VelocityIntentOptions = {},\n): void {\n\tconst prev = store.velocityChannels[sourceId];\n\tconst mode = options.mode ?? prev?.mode ?? 'replace';\n\tconst priority = options.priority ?? prev?.priority ?? 0;\n\tconst isAdditiveMerge = mode === 'add' && prev?.mode === 'add';\n\n\tconst x =\n\t\tvector.x == null\n\t\t\t? prev?.x\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.x ?? 0) + vector.x\n\t\t\t\t: vector.x;\n\tconst y =\n\t\tvector.y == null\n\t\t\t? prev?.y\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.y ?? 0) + vector.y\n\t\t\t\t: vector.y;\n\tconst z =\n\t\tvector.z == null\n\t\t\t? prev?.z\n\t\t\t: isAdditiveMerge\n\t\t\t\t? (prev?.z ?? 0) + vector.z\n\t\t\t\t: vector.z;\n\n\tstore.velocityChannels[sourceId] = {\n\t\tx,\n\t\ty,\n\t\tz,\n\t\tmode,\n\t\tpriority,\n\t};\n\tstore.dirty.velocityChannels = true;\n}\n\nexport function clearVelocityIntent(store: TransformState, sourceId: string): void {\n\tif (!(sourceId in store.velocityChannels)) return;\n\tdelete store.velocityChannels[sourceId];\n\tstore.dirty.velocityChannels = true;\n}\n","import { Vector3 } from 'three';\nimport { RigidBody, Vector } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\nimport { setVelocityIntent } from './velocity-intents';\n\nexport interface EntityWithBody {\n\tbody: RigidBody | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Move an entity along the X axis, preserving other velocities.\n */\nexport function moveX(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { x: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Y axis, preserving other velocities.\n */\nexport function moveY(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { y: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the Z axis, preserving other velocities.\n */\nexport function moveZ(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(entity.transformStore, 'actions', { z: delta }, { mode: 'replace' });\n}\n\n/**\n * Move an entity along the X and Y axis, preserving Z velocity.\n */\nexport function moveXY(entity: EntityWithBody, deltaX: number, deltaY: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, y: deltaY },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move an entity along the X and Z axis, preserving Y velocity.\n */\nexport function moveXZ(entity: EntityWithBody, deltaX: number, deltaZ: number): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: deltaX, z: deltaZ },\n\t\t{ mode: 'replace' },\n\t);\n}\n\n/**\n * Move entity based on a vector, adding to existing velocities.\n */\nexport function move(entity: EntityWithBody, vector: Vector3): void {\n\tif (!entity.transformStore) return;\n\tsetVelocityIntent(\n\t\tentity.transformStore,\n\t\t'actions',\n\t\t{ x: vector.x, y: vector.y, z: vector.z },\n\t\t{ mode: 'add' },\n\t);\n}\n\n/**\n * Reset entity velocity\n */\nexport function resetVelocity(entity: EntityWithBody): void {\n\tif (!entity.body) return;\n\tentity.body.setLinvel(new Vector3(0, 0, 0), true);\n\tentity.body.setLinearDamping(5);\n}\n\n/**\n * Move entity forward in 2D space, preserving Z velocity\n */\nexport function moveForwardXY(entity: EntityWithBody, delta: number, rotation2DAngle: number): void {\n\tconst deltaX = Math.sin(-rotation2DAngle) * delta;\n\tconst deltaY = Math.cos(-rotation2DAngle) * delta;\n\tmoveXY(entity, deltaX, deltaY);\n}\n\n/**\n * Get entity position\n */\nexport function getPosition(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.translation();\n}\n\n/**\n * Get entity velocity\n */\nexport function getVelocity(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.linvel();\n}\n\n/**\n * Set entity position\n */\nexport function setPosition(entity: EntityWithBody, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity X position\n */\nexport function setPositionX(entity: EntityWithBody, x: number): void {\n\tif (!entity.body) return;\n\tconst { y, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Y position\n */\nexport function setPositionY(entity: EntityWithBody, y: number): void {\n\tif (!entity.body) return;\n\tconst { x, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Z position\n */\nexport function setPositionZ(entity: EntityWithBody, z: number): void {\n\tif (!entity.body) return;\n\tconst { x, y } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Wrap entity around 2D bounds\n */\nexport function wrapAroundXY(entity: EntityWithBody, boundsX: number, boundsY: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\n\tif (newX !== x || newY !== y) {\n\t\tsetPosition(entity, newX, newY, 0);\n\t}\n}\n\n/**\n * Wrap entity around 3D bounds\n */\nexport function wrapAround3D(entity: EntityWithBody, boundsX: number, boundsY: number, boundsZ: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y, z } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\tconst newZ = z > boundsZ ? -boundsZ : (z < -boundsZ ? boundsZ : z);\n\n\tif (newX !== x || newY !== y || newZ !== z) {\n\t\tsetPosition(entity, newX, newY, newZ);\n\t}\n}\n\n/**\n * Enhanced moveable entity with bound methods\n */\nexport interface MoveableEntity extends EntityWithBody {\n\tmoveX(delta: number): void;\n\tmoveY(delta: number): void;\n\tmoveZ(delta: number): void;\n\tmoveXY(deltaX: number, deltaY: number): void;\n\tmoveXZ(deltaX: number, deltaZ: number): void;\n\tmove(vector: Vector3): void;\n\tresetVelocity(): void;\n\tmoveForwardXY(delta: number, rotation2DAngle: number): void;\n\tgetPosition(): Vector | null;\n\tgetVelocity(): Vector | null;\n\tsetPosition(x: number, y: number, z: number): void;\n\tsetPositionX(x: number): void;\n\tsetPositionY(y: number): void;\n\tsetPositionZ(z: number): void;\n\twrapAroundXY(boundsX: number, boundsY: number): void;\n\twrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void;\n}\n\n/**\n * Enhance an entity with additive movement methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeMoveable<T extends EntityWithBody>(entity: T): T & MoveableEntity {\n\tconst moveable = entity as T & MoveableEntity;\n\n\t// Create transform store if it doesn't exist\n\tif (!moveable.transformStore) {\n\t\tmoveable.transformStore = createTransformStore();\n\t}\n\n\tmoveable.moveX = (delta: number) => moveX(entity, delta);\n\tmoveable.moveY = (delta: number) => moveY(entity, delta);\n\tmoveable.moveZ = (delta: number) => moveZ(entity, delta);\n\tmoveable.moveXY = (deltaX: number, deltaY: number) => moveXY(entity, deltaX, deltaY);\n\tmoveable.moveXZ = (deltaX: number, deltaZ: number) => moveXZ(entity, deltaX, deltaZ);\n\tmoveable.move = (vector: Vector3) => move(entity, vector);\n\tmoveable.resetVelocity = () => resetVelocity(entity);\n\tmoveable.moveForwardXY = (delta: number, rotation2DAngle: number) => moveForwardXY(entity, delta, rotation2DAngle);\n\tmoveable.getPosition = () => getPosition(entity);\n\tmoveable.getVelocity = () => getVelocity(entity);\n\tmoveable.setPosition = (x: number, y: number, z: number) => setPosition(entity, x, y, z);\n\tmoveable.setPositionX = (x: number) => setPositionX(entity, x);\n\tmoveable.setPositionY = (y: number) => setPositionY(entity, y);\n\tmoveable.setPositionZ = (z: number) => setPositionZ(entity, z);\n\tmoveable.wrapAroundXY = (boundsX: number, boundsY: number) => wrapAroundXY(entity, boundsX, boundsY);\n\tmoveable.wrapAround3D = (boundsX: number, boundsY: number, boundsZ: number) => wrapAround3D(entity, boundsX, boundsY, boundsZ);\n\n\treturn moveable;\n}","import { Euler, Vector3, MathUtils, Quaternion } from 'three';\nimport { RigidBody } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\n\nexport interface RotatableEntity {\n\tbody: RigidBody | null;\n\tgroup: any;\n\ttransformStore?: TransformState;\n}\n\nfunction syncImmediateRotation(entity: RotatableEntity): void {\n\tif (!entity.group || !entity.transformStore) return;\n\n\tentity.group.setRotationFromQuaternion(\n\t\tnew Quaternion(\n\t\t\tentity.transformStore.rotation.x,\n\t\t\tentity.transformStore.rotation.y,\n\t\t\tentity.transformStore.rotation.z,\n\t\t\tentity.transformStore.rotation.w,\n\t\t),\n\t);\n}\n\n/**\n * Rotate an entity in the direction of a movement vector\n */\nexport function rotateInDirection(entity: RotatableEntity, moveVector: Vector3): void {\n\tif (!entity.body) return;\n\tconst rotate = Math.atan2(-moveVector.x, moveVector.z);\n\trotateYEuler(entity, rotate);\n}\n\n/**\n * Rotate an entity around the Y axis using Euler angles\n */\nexport function rotateYEuler(entity: RotatableEntity, amount: number): void {\n\trotateEuler(entity, new Vector3(0, -amount, 0));\n}\n\n/**\n * Rotate an entity using Euler angles\n */\nexport function rotateEuler(entity: RotatableEntity, rotation: Vector3): void {\n\tif (!entity.transformStore) return;\n\tconst quat = new Quaternion().setFromEuler(\n\t\tnew Euler(rotation.x, rotation.y, rotation.z),\n\t);\n\tentity.transformStore.rotation.w = quat.w;\n\tentity.transformStore.rotation.x = quat.x;\n\tentity.transformStore.rotation.y = quat.y;\n\tentity.transformStore.rotation.z = quat.z;\n\tentity.transformStore.dirty.rotation = true;\n\tsyncImmediateRotation(entity);\n}\n\n/**\n * Rotate an entity around the Y axis.\n */\nexport function rotateY(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaY = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For Y-axis rotation: q_delta = (0, deltaY, 0, deltaW)\n\tconst newW = q.w * deltaW - q.y * deltaY;\n\tconst newX = q.x * deltaW + q.z * deltaY;\n\tconst newY = q.y * deltaW + q.w * deltaY;\n\tconst newZ = q.z * deltaW - q.x * deltaY;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n\tsyncImmediateRotation(entity);\n}\n\n/**\n * Rotate an entity around the X axis.\n */\nexport function rotateX(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaX = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For X-axis rotation: q_delta = (deltaX, 0, 0, deltaW)\n\tconst newW = q.w * deltaW - q.x * deltaX;\n\tconst newX = q.x * deltaW + q.w * deltaX;\n\tconst newY = q.y * deltaW + q.z * deltaX;\n\tconst newZ = q.z * deltaW - q.y * deltaX;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n\tsyncImmediateRotation(entity);\n}\n\n/**\n * Rotate an entity around the Z axis.\n */\nexport function rotateZ(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaZ = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For Z-axis rotation: q_delta = (0, 0, deltaZ, deltaW)\n\tconst newW = q.w * deltaW - q.z * deltaZ;\n\tconst newX = q.x * deltaW - q.y * deltaZ;\n\tconst newY = q.y * deltaW + q.x * deltaZ;\n\tconst newZ = q.z * deltaW + q.w * deltaZ;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n\t(entity as any)._rotation2DAngle = ((entity as any)._rotation2DAngle ?? 0) + delta;\n\tsyncImmediateRotation(entity);\n}\n\n/**\n * Set rotation around Y axis.\n */\nexport function setRotationY(entity: RotatableEntity, y: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = y / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst yComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = 0;\n\tentity.transformStore.rotation.y = yComponent;\n\tentity.transformStore.rotation.z = 0;\n\tentity.transformStore.dirty.rotation = true;\n\tsyncImmediateRotation(entity);\n}\n\n/**\n * Set rotation around Y axis\n */\nexport function setRotationDegreesY(entity: RotatableEntity, y: number): void {\n\tif (!entity.body) return;\n\tsetRotationY(entity, MathUtils.degToRad(y));\n}\n\n/**\n * Set rotation around X axis.\n */\nexport function setRotationX(entity: RotatableEntity, x: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = x / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst xComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = xComponent;\n\tentity.transformStore.rotation.y = 0;\n\tentity.transformStore.rotation.z = 0;\n\tentity.transformStore.dirty.rotation = true;\n\tsyncImmediateRotation(entity);\n}\n\n/**\n * Set rotation around X axis\n */\nexport function setRotationDegreesX(entity: RotatableEntity, x: number): void {\n\tif (!entity.body) return;\n\tsetRotationX(entity, MathUtils.degToRad(x));\n}\n\n/**\n * Set rotation around Z axis.\n */\nexport function setRotationZ(entity: RotatableEntity, z: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = z / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst zComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = 0;\n\tentity.transformStore.rotation.y = 0;\n\tentity.transformStore.rotation.z = zComponent;\n\tentity.transformStore.dirty.rotation = true;\n\t(entity as any)._rotation2DAngle = z;\n\tsyncImmediateRotation(entity);\n}\n\n/**\n * Set rotation around Z axis\n */\nexport function setRotationDegreesZ(entity: RotatableEntity, z: number): void {\n\tif (!entity.body) return;\n\tsetRotationZ(entity, MathUtils.degToRad(z));\n}\n\n/**\n * Set rotation for all axes.\n */\nexport function setRotation(entity: RotatableEntity, x: number, y: number, z: number): void {\n\tif (!entity.transformStore) return;\n\tconst quat = new Quaternion().setFromEuler(new Euler(x, y, z));\n\tentity.transformStore.rotation.w = quat.w;\n\tentity.transformStore.rotation.x = quat.x;\n\tentity.transformStore.rotation.y = quat.y;\n\tentity.transformStore.rotation.z = quat.z;\n\tentity.transformStore.dirty.rotation = true;\n\t(entity as any)._rotation2DAngle = z;\n\tsyncImmediateRotation(entity);\n}\n\n/**\n * Set rotation for all axes\n */\nexport function setRotationDegrees(entity: RotatableEntity, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tsetRotation(entity, MathUtils.degToRad(x), MathUtils.degToRad(y), MathUtils.degToRad(z));\n}\n\n/**\n * Get current rotation\n */\nexport function getRotation(entity: RotatableEntity): any {\n\tif (!entity.body) return null;\n\treturn entity.body.rotation();\n}\n\n/**\n * Rotatable entity API with bound methods\n */\nexport interface RotatableEntityAPI extends RotatableEntity {\n\trotateInDirection(moveVector: Vector3): void;\n\trotateYEuler(amount: number): void;\n\trotateEuler(rotation: Vector3): void;\n\trotateY(delta: number): void;\n\trotateX(delta: number): void;\n\trotateZ(delta: number): void;\n\tsetRotationY(y: number): void;\n\tsetRotationX(x: number): void;\n\tsetRotationZ(z: number): void;\n\tsetRotationDegrees(x: number, y: number, z: number): void;\n\tsetRotationDegreesY(y: number): void;\n\tsetRotationDegreesX(x: number): void;\n\tsetRotationDegreesZ(z: number): void;\n\tsetRotation(x: number, y: number, z: number): void;\n\tgetRotation(): any;\n}\n\n/**\n * Enhance an entity instance with rotatable methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeRotatable<T extends RotatableEntity>(entity: T): T & RotatableEntityAPI {\n\tconst rotatableEntity = entity as T & RotatableEntityAPI;\n\n\t// Create transform store if it doesn't exist\n\tif (!rotatableEntity.transformStore) {\n\t\trotatableEntity.transformStore = createTransformStore();\n\t}\n\n\trotatableEntity.rotateInDirection = (moveVector: Vector3) => rotateInDirection(entity, moveVector);\n\trotatableEntity.rotateYEuler = (amount: number) => rotateYEuler(entity, amount);\n\trotatableEntity.rotateEuler = (rotation: Vector3) => rotateEuler(entity, rotation);\n\trotatableEntity.rotateX = (delta: number) => rotateX(entity, delta);\n\trotatableEntity.rotateY = (delta: number) => rotateY(entity, delta);\n\trotatableEntity.rotateZ = (delta: number) => rotateZ(entity, delta);\n\trotatableEntity.setRotationY = (y: number) => setRotationY(entity, y);\n\trotatableEntity.setRotationX = (x: number) => setRotationX(entity, x);\n\trotatableEntity.setRotationZ = (z: number) => setRotationZ(entity, z);\n\trotatableEntity.setRotationDegreesY = (y: number) => setRotationDegreesY(entity, y);\n\trotatableEntity.setRotationDegreesX = (x: number) => setRotationDegreesX(entity, x);\n\trotatableEntity.setRotationDegreesZ = (z: number) => setRotationDegreesZ(entity, z);\n\trotatableEntity.setRotationDegrees = (x: number, y: number, z: number) => setRotationDegrees(entity, x, y, z);\n\trotatableEntity.setRotation = (x: number, y: number, z: number) => setRotation(entity, x, y, z);\n\trotatableEntity.getRotation = () => getRotation(entity);\n\n\treturn rotatableEntity;\n}\n","import { makeMoveable, EntityWithBody, MoveableEntity } from './moveable';\nimport { makeRotatable, RotatableEntity, RotatableEntityAPI } from './rotatable';\n\n/**\n * Enhance an entity with both movement and rotation capabilities.\n * Transform store is automatically created by makeMoveable and makeRotatable.\n */\nexport function makeTransformable<\n\tT extends RotatableEntity & EntityWithBody\n>(entity: T): T & MoveableEntity & RotatableEntityAPI {\n\tconst withMovement = makeMoveable(entity);\n\tconst withRotation = makeRotatable(withMovement);\n\treturn withRotation;\n}\n\n","import { ActiveCollisionTypes, ColliderDesc, RigidBodyDesc, RigidBodyType, Vector3 } from \"@dimforge/rapier3d-compat\";\nimport { Vec3 } from \"../core/vector\";\n\n/**\n * Options for configuring entity collision behavior.\n */\nexport interface CollisionOptions {\n\tstatic?: boolean;\n\tsensor?: boolean;\n\tsize?: Vector3;\n\tposition?: Vector3;\n\tcollisionType?: string;\n\tcollisionFilter?: string[];\n}\n\nconst typeToGroup = new Map<string, number>();\nlet nextGroupId = 0;\n\nexport function getOrCreateCollisionGroupId(type: string): number {\n\tlet groupId = typeToGroup.get(type);\n\tif (groupId === undefined) {\n\t\tgroupId = nextGroupId++ % 16;\n\t\ttypeToGroup.set(type, groupId);\n\t}\n\treturn groupId;\n}\n\nexport function createCollisionFilter(allowedTypes: string[]): number {\n\tlet filter = 0;\n\tallowedTypes.forEach(type => {\n\t\tconst groupId = getOrCreateCollisionGroupId(type);\n\t\tfilter |= (1 << groupId);\n\t});\n\treturn filter;\n}\n\nexport class CollisionBuilder {\n\tstatic: boolean = false;\n\tsensor: boolean = false;\n\tgravity: Vec3 = new Vector3(0, 0, 0);\n\n\tbuild(options: Partial<CollisionOptions>): [RigidBodyDesc, ColliderDesc] {\n\t\tconst bodyDesc = this.bodyDesc({\n\t\t\tisDynamicBody: !this.static\n\t\t});\n\t\tconst collider = this.collider(options);\n\t\tconst type = options.collisionType;\n\t\tif (type) {\n\t\t\tlet groupId = getOrCreateCollisionGroupId(type);\n\t\t\tlet filter = 0b1111111111111111;\n\t\t\tif (options.collisionFilter) {\n\t\t\t\tfilter = createCollisionFilter(options.collisionFilter);\n\t\t\t}\n\t\t\tcollider.setCollisionGroups((groupId << 16) | filter);\n\t\t}\n\t\tconst { KINEMATIC_FIXED, DEFAULT } = ActiveCollisionTypes;\n\t\tcollider.activeCollisionTypes = (this.sensor) ? KINEMATIC_FIXED : DEFAULT;\n\t\treturn [bodyDesc, collider];\n\t}\n\n\twithCollision(collisionOptions: Partial<CollisionOptions>): this {\n\t\tthis.sensor = collisionOptions?.sensor ?? this.sensor;\n\t\tthis.static = collisionOptions?.static ?? this.static;\n\t\treturn this;\n\t}\n\n\tcollider(options: CollisionOptions): ColliderDesc {\n\t\tconst size = options.size ?? new Vector3(1, 1, 1);\n\t\tconst half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };\n\t\tlet colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);\n\t\treturn colliderDesc;\n\t}\n\n\tbodyDesc({ isDynamicBody = true }): RigidBodyDesc {\n\t\tconst type = isDynamicBody ? RigidBodyType.Dynamic : RigidBodyType.Fixed;\n\t\tconst bodyDesc = new RigidBodyDesc(type)\n\t\t\t.setTranslation(0, 0, 0)\n\t\t\t.setGravityScale(1.0)\n\t\t\t.setCanSleep(false)\n\t\t\t.setCcdEnabled(true);\n\t\treturn bodyDesc;\n\t}\n}","import { Color, Vector2, Vector3 } from 'three';\n\ntype PlainObject = Record<string, unknown>;\n\nfunction isPlainObject(value: unknown): value is PlainObject {\n\tif (!value || typeof value !== 'object') {\n\t\treturn false;\n\t}\n\tconst proto = Object.getPrototypeOf(value);\n\treturn proto === Object.prototype || proto === null;\n}\n\nexport function deepCloneValue<T>(value: T): T {\n\tif (value === null || value === undefined) {\n\t\treturn value;\n\t}\n\n\tif (typeof value === 'function' || typeof value !== 'object') {\n\t\treturn value;\n\t}\n\n\tif (value instanceof Color || value instanceof Vector2 || value instanceof Vector3) {\n\t\treturn value.clone() as T;\n\t}\n\n\tif (value instanceof Float32Array) {\n\t\treturn new Float32Array(value) as T;\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.map((item) => deepCloneValue(item)) as T;\n\t}\n\n\tif (isPlainObject(value)) {\n\t\tconst cloned: PlainObject = {};\n\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\tif (key === '_builders') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcloned[key] = deepCloneValue(entry);\n\t\t}\n\t\treturn cloned as T;\n\t}\n\n\treturn value;\n}\n\nexport function deepMergeValues<T>(base: T, overrides?: Partial<T>): T {\n\tconst clonedBase = deepCloneValue(base);\n\tif (!overrides) {\n\t\treturn clonedBase;\n\t}\n\n\tif (!isPlainObject(clonedBase) || !isPlainObject(overrides)) {\n\t\treturn deepCloneValue(overrides as T);\n\t}\n\n\tconst result = clonedBase as PlainObject;\n\n\tfor (const [key, overrideValue] of Object.entries(overrides)) {\n\t\tif (key === '_builders' || overrideValue === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst currentValue = result[key];\n\t\tif (isPlainObject(currentValue) && isPlainObject(overrideValue)) {\n\t\t\tresult[key] = deepMergeValues(currentValue, overrideValue);\n\t\t\tcontinue;\n\t\t}\n\n\t\tresult[key] = deepCloneValue(overrideValue);\n\t}\n\n\treturn result as T;\n}\n","import {\n\tActiveCollisionTypes,\n\tColliderDesc,\n\tRigidBodyDesc,\n\tRigidBodyType,\n} from '@dimforge/rapier3d-compat';\nimport { Vector3 } from 'three';\nimport type { Vec3 } from '../../core/vector';\nimport {\n\tgetOrCreateCollisionGroupId,\n\tcreateCollisionFilter,\n\ttype CollisionOptions,\n} from '../../collision/collision-builder';\nimport { deepCloneValue } from '../../core/clone-utils';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CollisionComponent type returned by all collision factories\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * A built collision component containing a rigid body description and collider description.\n * Returned by collision factory functions (boxCollision, sphereCollision, etc.)\n * and consumed by GameEntity.add().\n */\nexport interface CollisionComponent {\n\t__kind: 'collision';\n\tbodyDesc: RigidBodyDesc;\n\tcolliderDesc: ColliderDesc;\n\tcloneComponent: () => CollisionComponent;\n}\n\n/**\n * Type guard for CollisionComponent.\n */\nexport function isCollisionComponent(obj: any): obj is CollisionComponent {\n\treturn obj && obj.__kind === 'collision';\n}\n\nexport function cloneCollisionComponent(component: CollisionComponent): CollisionComponent {\n\treturn component.cloneComponent();\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface BaseCollisionOptions {\n\t/** Whether the body is static (fixed) or dynamic */\n\tstatic?: boolean;\n\t/** Whether this collider is a sensor */\n\tsensor?: boolean;\n\t/** Position offset relative to the entity origin */\n\toffset?: Vec3;\n\t/** Collision type string for group filtering */\n\tcollisionType?: string;\n\t/** Allowed collision types for filtering */\n\tcollisionFilter?: string[];\n}\n\nfunction buildBodyDesc(isStatic: boolean): RigidBodyDesc {\n\tconst type = isStatic ? RigidBodyType.Fixed : RigidBodyType.Dynamic;\n\treturn new RigidBodyDesc(type)\n\t\t.setTranslation(0, 0, 0)\n\t\t.setGravityScale(1.0)\n\t\t.setCanSleep(false)\n\t\t.setCcdEnabled(true);\n}\n\nfunction applyCollisionOptions(\n\tcolliderDesc: ColliderDesc,\n\topts: BaseCollisionOptions,\n): void {\n\tif (opts.offset) {\n\t\tcolliderDesc.setTranslation(opts.offset.x, opts.offset.y, opts.offset.z);\n\t}\n\tif (opts.sensor) {\n\t\tcolliderDesc.setSensor(true);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.KINEMATIC_FIXED;\n\t}\n\tif (opts.collisionType) {\n\t\tconst groupId = getOrCreateCollisionGroupId(opts.collisionType);\n\t\tlet filter = 0b1111111111111111;\n\t\tif (opts.collisionFilter) {\n\t\t\tfilter = createCollisionFilter(opts.collisionFilter);\n\t\t}\n\t\tcolliderDesc.setCollisionGroups((groupId << 16) | filter);\n\t}\n}\n\nfunction makeComponent(\n\tcolliderDesc: ColliderDesc,\n\topts: BaseCollisionOptions,\n\tcloneComponentFactory: () => CollisionComponent,\n): CollisionComponent {\n\tapplyCollisionOptions(colliderDesc, opts);\n\treturn {\n\t\t__kind: 'collision',\n\t\tbodyDesc: buildBodyDesc(opts.static ?? false),\n\t\tcolliderDesc,\n\t\tcloneComponent: cloneComponentFactory,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Box\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BoxCollisionOptions extends BaseCollisionOptions {\n\t/** Box dimensions (default: 1x1x1) */\n\tsize?: Vec3;\n}\n\n/**\n * Create a box (cuboid) collision component.\n */\nexport function boxCollision(opts: BoxCollisionOptions = {}): CollisionComponent {\n\tconst size = opts.size ?? { x: 1, y: 1, z: 1 };\n\tconst desc = ColliderDesc.cuboid(size.x / 2, size.y / 2, size.z / 2);\n\tconst clonedOpts = deepCloneValue(opts);\n\treturn makeComponent(desc, opts, () => boxCollision(clonedOpts));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Sphere\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SphereCollisionOptions extends BaseCollisionOptions {\n\t/** Sphere radius (default: 1) */\n\tradius?: number;\n}\n\n/**\n * Create a sphere (ball) collision component.\n */\nexport function sphereCollision(opts: SphereCollisionOptions = {}): CollisionComponent {\n\tconst desc = ColliderDesc.ball(opts.radius ?? 1);\n\tconst clonedOpts = deepCloneValue(opts);\n\treturn makeComponent(desc, opts, () => sphereCollision(clonedOpts));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cone\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ConeCollisionOptions extends BaseCollisionOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a cone collision component.\n */\nexport function coneCollision(opts: ConeCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 1;\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cone(height / 2, radius);\n\tconst clonedOpts = deepCloneValue(opts);\n\treturn makeComponent(desc, opts, () => coneCollision(clonedOpts));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pyramid (cone collider with 4-sided visual approximation)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PyramidCollisionOptions extends BaseCollisionOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a pyramid collision component (approximated as a cone).\n */\nexport function pyramidCollision(opts: PyramidCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 1;\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cone(height / 2, radius);\n\tconst clonedOpts = deepCloneValue(opts);\n\treturn makeComponent(desc, opts, () => pyramidCollision(clonedOpts));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cylinder\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface CylinderCollisionOptions extends BaseCollisionOptions {\n\t/** Top radius (default: 1) */\n\tradiusTop?: number;\n\t/** Bottom radius (default: 1) */\n\tradiusBottom?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a cylinder collision component.\n */\nexport function cylinderCollision(opts: CylinderCollisionOptions = {}): CollisionComponent {\n\tconst radius = Math.max(opts.radiusTop ?? 1, opts.radiusBottom ?? 1);\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cylinder(height / 2, radius);\n\tconst clonedOpts = deepCloneValue(opts);\n\treturn makeComponent(desc, opts, () => cylinderCollision(clonedOpts));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pill (capsule)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PillCollisionOptions extends BaseCollisionOptions {\n\t/** Capsule hemisphere radius (default: 0.5) */\n\tradius?: number;\n\t/** Cylindrical section length (default: 1) */\n\tlength?: number;\n}\n\n/**\n * Create a pill (capsule) collision component.\n */\nexport function pillCollision(opts: PillCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 0.5;\n\tconst length = opts.length ?? 1;\n\tconst desc = ColliderDesc.capsule(length / 2, radius);\n\tconst clonedOpts = deepCloneValue(opts);\n\treturn makeComponent(desc, opts, () => pillCollision(clonedOpts));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Plane (heightfield)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PlaneCollisionOptions extends BaseCollisionOptions {\n\t/** Tile dimensions (default: 10x10) */\n\ttile?: { x: number; y: number };\n\t/** Number of subdivisions per axis (default: 10) */\n\tsubdivisions?: number;\n\t/** Pre-computed height data for the heightfield */\n\theightData?: Float32Array;\n}\n\n/**\n * Create a plane (heightfield) collision component.\n * For flat planes, pass no heightData — a zeroed heightfield is used.\n */\nexport function planeCollision(opts: PlaneCollisionOptions = {}): CollisionComponent {\n\tconst tile = opts.tile ?? { x: 10, y: 10 };\n\tconst subdivisions = opts.subdivisions ?? 10;\n\tconst size = new Vector3(tile.x, 1, tile.y);\n\n\tconst totalVerts = (subdivisions + 1) * (subdivisions + 1);\n\tconst heightData = opts.heightData ?? new Float32Array(totalVerts);\n\n\tconst desc = ColliderDesc.heightfield(\n\t\tsubdivisions,\n\t\tsubdivisions,\n\t\theightData,\n\t\tsize,\n\t);\n\n\tconst effectiveOpts = { ...opts, static: opts.static ?? true };\n\tconst clonedOpts = deepCloneValue(effectiveOpts);\n\treturn makeComponent(desc, effectiveOpts, () => planeCollision(clonedOpts));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Zone (sensor cuboid)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ZoneCollisionOptions extends BaseCollisionOptions {\n\t/** Zone dimensions (default: 1x1x1) */\n\tsize?: Vec3;\n}\n\n/**\n * Create a zone (sensor cuboid) collision component.\n * Always a sensor; static by default.\n */\nexport function zoneCollision(opts: ZoneCollisionOptions = {}): CollisionComponent {\n\tconst size = opts.size ?? { x: 1, y: 1, z: 1 };\n\tconst desc = ColliderDesc.cuboid(size.x / 2, size.y / 2, size.z / 2);\n\tdesc.setSensor(true);\n\tdesc.activeCollisionTypes = ActiveCollisionTypes.KINEMATIC_FIXED;\n\tconst effectiveOpts = { ...opts, static: opts.static ?? true, sensor: true };\n\tconst clonedOpts = deepCloneValue(effectiveOpts);\n\treturn makeComponent(desc, effectiveOpts, () => zoneCollision(clonedOpts));\n}\n","import { Color, Vector3 } from 'three';\nimport { standardShader } from '../graphics/shaders/standard.shader';\nimport { GameEntityOptions } from './entity';\nimport { BaseNode } from '../core/base-node';\n\nexport const commonDefaults: Partial<GameEntityOptions> = {\n position: new Vector3(0, 0, 0),\n material: {\n color: new Color('#ffffff'),\n shader: standardShader\n },\n collision: {\n static: false,\n },\n};\n\n/**\n * Merge a variadic args array (BaseNode children + options object) with defaults.\n * Returns the merged options. This replaces the createEntity() arg parsing logic.\n */\nexport function mergeArgs<T extends GameEntityOptions>(\n args: Array<BaseNode | Partial<T>>,\n defaults: Partial<T>,\n): T {\n const configArgs = args.filter(\n (arg): arg is Partial<T> => !(arg instanceof BaseNode),\n );\n let merged: Partial<T> = { ...defaults };\n for (const opt of configArgs) {\n merged = { ...merged, ...opt };\n }\n return merged as T;\n}\n","import { Mesh, Material, ShaderMaterial, Group, Color, Vector3 } from 'three';\nimport {\n\tCollider,\n\tColliderDesc,\n\tRigidBody,\n\tRigidBodyDesc,\n\tVector,\n} from '@dimforge/rapier3d-compat';\nimport { position, rotation, scale } from '../systems/transformable.system';\nimport { Vec3 } from '../core/vector';\nimport { MaterialBuilder, MaterialOptions } from '../graphics/material';\nimport { CollisionOptions } from '../collision/collision-builder';\nimport { BaseNode } from '../core/base-node';\nimport {\n\tDestroyContext,\n\tSetupContext,\n\tUpdateContext,\n\tLoadedContext,\n\tCleanupContext,\n} from '../core/base-node-life-cycle';\nimport type { EntityMeshBuilder, EntityCollisionBuilder } from './builder';\nimport { Behavior } from '../behaviors/behavior';\nimport {\n\tEventEmitterDelegate,\n\tzylemEventBus,\n\ttype EntityEvents,\n} from '../events';\nimport type {\n\tBehaviorDescriptor,\n\tBehaviorRef,\n\tBehaviorHandle,\n} from '../behaviors/behavior-descriptor';\nimport type { TransformState } from '../actions/capabilities/transform-store';\nimport { createTransformStore } from '../actions/capabilities/transform-store';\nimport { makeTransformable } from '../actions/capabilities/transformable';\nimport { clearVelocityIntent } from '../actions/capabilities/velocity-intents';\nimport type { MoveableEntity } from '../actions/capabilities/moveable';\nimport type { RotatableEntityAPI } from '../actions/capabilities/rotatable';\nimport {\n\tcloneCollisionComponent,\n\tisCollisionComponent,\n\ttype CollisionComponent,\n} from './parts/collision-factories';\nimport type { NodeInterface } from '../core/node-interface';\nimport { commonDefaults } from './common';\nimport type { Action } from '../actions/action';\nimport { deepCloneValue, deepMergeValues } from '../core/clone-utils';\n\nexport interface CollisionContext<\n\tT,\n\tO extends GameEntityOptions,\n\tTGlobals extends Record<string, unknown> = any,\n> {\n\tentity: T;\n\t// Use 'any' for other's options type to break recursive type variance issues\n\tother: GameEntity<O | any>;\n\tglobals: TGlobals;\n}\n\nexport type CollisionPhase = 'enter' | 'stay';\n\nexport interface CollisionRegistrationOptions {\n\tphase?: CollisionPhase;\n\tcooldownMs?: number;\n}\n\ninterface NormalizedCollisionRegistrationOptions {\n\tphase: CollisionPhase;\n\tcooldownMs?: number;\n}\n\nexport interface CollisionRegistration<T, O extends GameEntityOptions> {\n\tid: number;\n\tcallback: (params: CollisionContext<T, O>) => void;\n\toptions: NormalizedCollisionRegistrationOptions;\n}\n\nexport interface CollisionDispatchMetadata {\n\tphase: CollisionPhase;\n\tnowMs: number;\n}\n\nexport interface CollisionDelegate<T, O extends GameEntityOptions> {\n\t// Use 'any' for entity and options types to avoid contravariance issues\n\t// with function parameters. Type safety is still enforced at the call site via onCollision()\n\tcollision?: CollisionRegistration<any, any>[];\n\tcooldowns?: Map<string, number>;\n\tnextId?: number;\n}\n\nexport type IBuilder<BuilderOptions = any> = {\n\tpreBuild: (options: BuilderOptions) => BuilderOptions;\n\tbuild: (options: BuilderOptions) => BuilderOptions;\n\tpostBuild: (options: BuilderOptions) => BuilderOptions;\n};\n\nexport type GameEntityOptions = {\n\tname?: string;\n\tcolor?: Color;\n\tsize?: Vec3;\n\tposition?: Vec3;\n\tbatched?: boolean;\n\tcollision?: Partial<CollisionOptions>;\n\tmaterial?: Partial<MaterialOptions>;\n\tcustom?: { [key: string]: any };\n\tcollisionType?: string;\n\tcollisionGroup?: string;\n\tcollisionFilter?: string[];\n\t_builders?: {\n\t\tmeshBuilder?: IBuilder | EntityMeshBuilder | null;\n\t\tcollisionBuilder?: IBuilder | EntityCollisionBuilder | null;\n\t\tmaterialBuilder?: MaterialBuilder | null;\n\t};\n};\n\nexport abstract class GameEntityLifeCycle {\n\tabstract _setup(params: SetupContext<this>): void;\n\tabstract _update(params: UpdateContext<this>): void;\n\tabstract _destroy(params: DestroyContext<this>): void;\n}\n\nexport interface EntityDebugInfo {\n\tbuildInfo: () => Record<string, string>;\n}\n\ntype EntityCloneFactory<O extends GameEntityOptions, E extends GameEntity<O>> = (\n\toptions?: Partial<O>,\n) => E;\n\ntype TrackedEntityComponent =\n\t| { kind: 'mesh'; component: Mesh }\n\t| { kind: 'collision'; component: CollisionComponent };\n\nfunction isCollisionRegistrationOptions(\n\tvalue: unknown,\n): value is CollisionRegistrationOptions {\n\treturn value != null && typeof value === 'object';\n}\n\nfunction normalizeCollisionRegistrationOptions(\n\toptions?: CollisionRegistrationOptions,\n): NormalizedCollisionRegistrationOptions {\n\treturn {\n\t\tphase: options?.phase ?? 'stay',\n\t\tcooldownMs: options?.cooldownMs,\n\t};\n}\n\nfunction getCollisionNowMs(): number {\n\tif (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n\t\treturn performance.now();\n\t}\n\treturn Date.now();\n}\n\nexport class GameEntity<O extends GameEntityOptions>\n\textends BaseNode<O>\n\timplements GameEntityLifeCycle, EntityDebugInfo, MoveableEntity, RotatableEntityAPI {\n\tpublic behaviors: Behavior[] = [];\n\tpublic group: Group | undefined;\n\tpublic mesh: Mesh | undefined;\n\tpublic materials: Material[] | undefined;\n\tpublic bodyDesc: RigidBodyDesc | null = null;\n\tpublic body: RigidBody | null = null;\n\tpublic physicsAttached = false;\n\tpublic colliderDesc: ColliderDesc | undefined;\n\tpublic collider: Collider | undefined;\n\tpublic custom: Record<string, any> = {};\n\n\t// Compound entity support: multiple colliders and meshes\n\t/** All collider descriptions for this entity (including primary) */\n\tpublic colliderDescs: ColliderDesc[] = [];\n\t/** All colliders attached to this entity's rigid body */\n\tpublic colliders: Collider[] = [];\n\t/** Additional meshes for compound visual entities (added via add()) */\n\tpublic compoundMeshes: Mesh[] = [];\n\n\tpublic debugInfo: Record<string, any> = {};\n\tpublic debugMaterial: ShaderMaterial | undefined;\n\n\tpublic collisionDelegate: CollisionDelegate<this, O> = {\n\t\tcollision: [],\n\t\tcooldowns: new Map(),\n\t\tnextId: 0,\n\t};\n\tpublic collisionType?: string;\n\n\t// Instancing support\n\t/** Batch key for instanced rendering (null if not instanced) */\n\tpublic batchKey: string | null = null;\n\t/** Index within the instanced mesh batch */\n\tpublic instanceId: number = -1;\n\t/** Whether this entity uses instanced rendering */\n\tpublic isInstanced: boolean = false;\n\n\t// Event delegate for dispatch/listen API\n\tprotected eventDelegate = new EventEmitterDelegate<EntityEvents>();\n\n\t// Behavior references (new ECS pattern)\n\tprivate behaviorRefs: BehaviorRef[] = [];\n\tprivate cloneFactory: EntityCloneFactory<O, this> | null = null;\n\tprivate trackAddedComponents: boolean = false;\n\tprivate trackedComponents: TrackedEntityComponent[] = [];\n\n\t// Transform store for batched physics updates (auto-created in create())\n\tpublic transformStore: TransformState;\n\n\t// Movement & rotation methods are assigned at runtime by makeTransformable.\n\t// The `implements` clause above ensures the type contract; declarations below\n\t// satisfy the compiler while the constructor fills them in.\n\tmoveX!: (delta: number) => void;\n\tmoveY!: (delta: number) => void;\n\tmoveZ!: (delta: number) => void;\n\tmoveXY!: (deltaX: number, deltaY: number) => void;\n\tmoveXZ!: (deltaX: number, deltaZ: number) => void;\n\tmove!: (vector: Vector3) => void;\n\tresetVelocity!: () => void;\n\tmoveForwardXY!: (delta: number, rotation2DAngle: number) => void;\n\tgetPosition!: () => Vector | null;\n\tgetVelocity!: () => Vector | null;\n\tsetPosition!: (x: number, y: number, z: number) => void;\n\tsetPositionX!: (x: number) => void;\n\tsetPositionY!: (y: number) => void;\n\tsetPositionZ!: (z: number) => void;\n\twrapAroundXY!: (boundsX: number, boundsY: number) => void;\n\twrapAround3D!: (boundsX: number, boundsY: number, boundsZ: number) => void;\n\trotateInDirection!: (moveVector: Vector3) => void;\n\trotateYEuler!: (amount: number) => void;\n\trotateEuler!: (eulerRotation: Vector3) => void;\n\trotateX!: (delta: number) => void;\n\trotateY!: (delta: number) => void;\n\trotateZ!: (delta: number) => void;\n\tsetRotationY!: (y: number) => void;\n\tsetRotationX!: (x: number) => void;\n\tsetRotationZ!: (z: number) => void;\n\tsetRotationDegrees!: (x: number, y: number, z: number) => void;\n\tsetRotationDegreesY!: (y: number) => void;\n\tsetRotationDegreesX!: (x: number) => void;\n\tsetRotationDegreesZ!: (z: number) => void;\n\tsetRotation!: (x: number, y: number, z: number) => void;\n\tgetRotation!: () => any;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.transformStore = createTransformStore();\n\t\tmakeTransformable(this);\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Composable add() - accepts Mesh, CollisionComponent, or child entities\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add meshes, collision components, or child entities to this entity.\n\t * Supports fluent chaining: `entity.add(boxMesh()).add(boxCollision())`.\n\t *\n\t * - `Mesh`: First mesh becomes the primary mesh; subsequent meshes are\n\t * compound meshes grouped together.\n\t * - `CollisionComponent`: First sets bodyDesc + colliderDesc; subsequent\n\t * add extra colliders to the same rigid body.\n\t * - `NodeInterface`: Added as a child entity (delegates to BaseNode.add).\n\t */\n\tpublic add(...components: Array<NodeInterface | Mesh | CollisionComponent>): this {\n\t\tfor (const component of components) {\n\t\t\tif (component instanceof Mesh) {\n\t\t\t\tthis.addMeshComponent(component);\n\t\t\t\tthis.trackComponent(component);\n\t\t\t} else if (isCollisionComponent(component)) {\n\t\t\t\tthis.addCollisionComponent(component);\n\t\t\t\tthis.trackComponent(component);\n\t\t\t} else {\n\t\t\t\tsuper.add(component as NodeInterface);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\tprivate addMeshComponent(mesh: Mesh): void {\n\t\tif (!this.mesh) {\n\t\t\t// First mesh becomes the primary mesh\n\t\t\tthis.mesh = mesh;\n\t\t\tif (!this.materials) {\n\t\t\t\tthis.materials = [];\n\t\t\t}\n\t\t\tif (mesh.material) {\n\t\t\t\tconst mat = mesh.material;\n\t\t\t\tif (Array.isArray(mat)) {\n\t\t\t\t\tthis.materials.push(...mat);\n\t\t\t\t} else {\n\t\t\t\t\tthis.materials.push(mat);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Subsequent meshes are compound meshes\n\t\t\tthis.compoundMeshes.push(mesh);\n\t\t\t// Ensure the entity has a group so all meshes are parented together\n\t\t\tif (!this.group) {\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.add(this.mesh);\n\t\t\t}\n\t\t\tthis.group.add(mesh);\n\t\t}\n\t}\n\n\tprivate addCollisionComponent(collision: CollisionComponent): void {\n\t\tif (!this.bodyDesc) {\n\t\t\t// First collision sets the body description and primary collider\n\t\t\tthis.bodyDesc = collision.bodyDesc;\n\t\t\tthis.colliderDesc = collision.colliderDesc;\n\t\t\tthis.colliderDescs.push(collision.colliderDesc);\n\t\t\t// Apply entity position to the body\n\t\t\tconst pos = this.options?.position ?? { x: 0, y: 0, z: 0 };\n\t\t\tthis.bodyDesc.setTranslation(pos.x, pos.y, pos.z);\n\t\t} else {\n\t\t\t// Subsequent collisions add extra colliders to the same body\n\t\t\tthis.colliderDescs.push(collision.colliderDesc);\n\t\t}\n\t}\n\n\tprivate trackComponent(component: Mesh | CollisionComponent): void {\n\t\tif (!this.trackAddedComponents) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (component instanceof Mesh) {\n\t\t\tthis.trackedComponents.push({\n\t\t\t\tkind: 'mesh',\n\t\t\t\tcomponent: cloneMeshComponent(component),\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tthis.trackedComponents.push({\n\t\t\tkind: 'collision',\n\t\t\tcomponent: cloneCollisionComponent(component),\n\t\t});\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Actions API -- entity-scoped, self-contained stateful actions\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tprivate _actions: Action[] = [];\n\n\t/**\n\t * Run a fire-and-forget action. Auto-removed when done.\n\t * @example `me.runAction(moveBy({ x: 10, duration: 0.3 }))`\n\t */\n\tpublic runAction<A extends Action>(action: A): A {\n\t\tthis._actions.push(action);\n\t\treturn action;\n\t}\n\n\t/**\n\t * Register a persistent action (throttle, onPress). Not removed when done.\n\t * @example `const press = entity.action(onPress())`\n\t */\n\tpublic action<A extends Action>(action: A): A {\n\t\taction.persistent = true;\n\t\tthis._actions.push(action);\n\t\treturn action;\n\t}\n\n\t/**\n\t * Tick all registered actions. Called automatically before user onUpdate callbacks.\n\t *\n\t * Resets velocity/angularVelocity accumulation before ticking so that\n\t * actions can compose via `+=` without cross-frame build-up.\n\t * (The existing move helpers like `moveXY` use `=` which doesn't accumulate,\n\t * but action composition needs additive writes on a clean slate each frame.)\n\t */\n\tpublic _tickActions(delta: number): void {\n\t\tif (this._actions.length === 0) return;\n\n\t\t// Clear accumulation from the previous frame so that\n\t\t// actions can compose via `+=` on a clean slate each frame.\n\t\tconst store = this.transformStore;\n\t\tstore.velocity.x = 0;\n\t\tstore.velocity.y = 0;\n\t\tstore.velocity.z = 0;\n\t\tclearVelocityIntent(store, 'actions');\n\t\tstore.angularVelocity.x = 0;\n\t\tstore.angularVelocity.y = 0;\n\t\tstore.angularVelocity.z = 0;\n\t\tstore.dirty.angularVelocity = false;\n\n\t\tfor (let i = this._actions.length - 1; i >= 0; i--) {\n\t\t\tconst act = this._actions[i];\n\t\t\tact.tick(this, delta);\n\t\t\tif (act.done && !act.persistent) {\n\t\t\t\tthis._actions.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\tif (this._actions.length === 0) {\n\t\t\tstore.velocity.x = 0;\n\t\t\tstore.velocity.y = 0;\n\t\t\tstore.velocity.z = 0;\n\t\t\tclearVelocityIntent(store, 'actions');\n\t\t\tstore.angularVelocity.x = 0;\n\t\t\tstore.angularVelocity.y = 0;\n\t\t\tstore.angularVelocity.z = 0;\n\t\t\tstore.dirty.angularVelocity = false;\n\t\t}\n\t}\n\n\tpublic create(): this {\n\t\tconst { position: setupPosition } = this.options;\n\t\tconst { x, y, z } = setupPosition || { x: 0, y: 0, z: 0 };\n\t\tthis.behaviors = [\n\t\t\t{ component: position, values: { x, y, z } },\n\t\t\t{ component: scale, values: { x: 0, y: 0, z: 0 } },\n\t\t\t{ component: rotation, values: { x: 0, y: 0, z: 0, w: 0 } },\n\t\t];\n\t\tthis.name = this.options.name || '';\n\t\treturn this;\n\t}\n\n\tpublic clone(overrides?: Partial<O>): this {\n\t\tif (!this.cloneFactory) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot clone ${this.constructor.name}: clone() is only supported for entities created by official factory helpers.`,\n\t\t\t);\n\t\t}\n\n\t\tconst clone = this.cloneFactory(\n\t\t\tdeepMergeValues(this.options, overrides),\n\t\t) as this;\n\n\t\tconst behaviorAliases = this.copyBehaviorRefsTo(clone);\n\t\tconst wrapCallback = <T extends Function>(callback: T): T =>\n\t\t\twrapBehaviorCallback(callback, behaviorAliases);\n\n\t\tthis.replayUserLifecycleRegistrationsTo(clone, wrapCallback);\n\n\t\tconst collisionRegistrations = this.getCollisionRegistrations();\n\t\tif (collisionRegistrations.length > 0) {\n\t\t\tfor (const registration of collisionRegistrations) {\n\t\t\t\tclone.onCollision(\n\t\t\t\t\twrapCallback(registration.callback),\n\t\t\t\t\tregistration.options,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tfor (const trackedComponent of this.trackedComponents) {\n\t\t\tif (trackedComponent.kind === 'mesh') {\n\t\t\t\tclone.add(cloneMeshComponent(trackedComponent.component));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tclone.add(cloneCollisionComponent(trackedComponent.component));\n\t\t}\n\n\t\tthis.cloneChildrenInto(clone);\n\n\t\treturn clone;\n\t}\n\n\tpublic finalizeCloneSupport(factory: (options?: Partial<O>) => GameEntity<O>): this {\n\t\tthis.cloneFactory = factory as EntityCloneFactory<O, this>;\n\t\tthis.enableUserLifecycleTracking();\n\t\tthis.trackAddedComponents = true;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add collision callbacks\n\t */\n\tpublic onCollision(\n\t\tcallback: (params: CollisionContext<this, O>) => void,\n\t\toptions?: CollisionRegistrationOptions,\n\t): this;\n\tpublic onCollision(\n\t\t...callbacks: ((params: CollisionContext<this, O>) => void)[]\n\t): this;\n\tpublic onCollision(\n\t\t...args: Array<((params: CollisionContext<this, O>) => void) | CollisionRegistrationOptions | undefined>\n\t): this {\n\t\tconst existing = [...(this.collisionDelegate.collision ?? [])];\n\t\tlet nextId = this.collisionDelegate.nextId ?? 0;\n\n\t\tif (\n\t\t\targs.length === 1\n\t\t\t|| (\n\t\t\t\targs.length === 2\n\t\t\t\t&& (\n\t\t\t\t\targs[1] == null\n\t\t\t\t\t|| isCollisionRegistrationOptions(args[1])\n\t\t\t\t)\n\t\t\t)\n\t\t) {\n\t\t\tconst callback = args[0] as ((params: CollisionContext<this, O>) => void) | undefined;\n\t\t\tif (!callback) {\n\t\t\t\treturn this;\n\t\t\t}\n\n\t\t\tconst options = args[1] as CollisionRegistrationOptions | undefined;\n\t\t\texisting.push({\n\t\t\t\tid: nextId,\n\t\t\t\tcallback,\n\t\t\t\toptions: normalizeCollisionRegistrationOptions(options),\n\t\t\t});\n\t\t\tnextId += 1;\n\t\t\tthis.collisionDelegate.collision = existing;\n\t\t\tthis.collisionDelegate.nextId = nextId;\n\t\t\treturn this;\n\t\t}\n\n\t\tfor (const callback of args as Array<(params: CollisionContext<this, O>) => void>) {\n\t\t\texisting.push({\n\t\t\t\tid: nextId,\n\t\t\t\tcallback,\n\t\t\t\toptions: normalizeCollisionRegistrationOptions(),\n\t\t\t});\n\t\t\tnextId += 1;\n\t\t}\n\n\t\tthis.collisionDelegate.collision = existing;\n\t\tthis.collisionDelegate.nextId = nextId;\n\t\treturn this;\n\t}\n\n\t/**\n\t * Use a behavior on this entity via typed descriptor.\n\t * Behaviors will be auto-registered as systems when the entity is spawned.\n\t * @param descriptor The behavior descriptor (import from behaviors module)\n\t * @param options Optional overrides for the behavior's default options\n\t * @returns BehaviorHandle with behavior-specific methods for lazy FSM access\n\t */\n\tpublic use<\n\t\tO extends Record<string, any>,\n\t\tH extends Record<string, any> = Record<string, never>,\n\t>(\n\t\tdescriptor: BehaviorDescriptor<O, H>,\n\t\toptions?: Partial<O>,\n\t): BehaviorHandle<O, H> {\n\t\tconst behaviorRef: BehaviorRef<O> = {\n\t\t\tdescriptor: descriptor as BehaviorDescriptor<O, any>,\n\t\t\toptions: { ...descriptor.defaultOptions, ...options } as O,\n\t\t};\n\t\tthis.behaviorRefs.push(behaviorRef as BehaviorRef<any>);\n\n\t\t// Create base handle\n\t\tconst baseHandle = {\n\t\t\tgetFSM: () => behaviorRef.fsm ?? null,\n\t\t\tgetOptions: () => behaviorRef.options,\n\t\t\tref: behaviorRef,\n\t\t};\n\n\t\t// Merge behavior-specific methods if createHandle is provided\n\t\tconst customMethods = descriptor.createHandle?.(behaviorRef) ?? ({} as H);\n\n\t\treturn {\n\t\t\t...baseHandle,\n\t\t\t...customMethods,\n\t\t} as BehaviorHandle<O, H>;\n\t}\n\n\t/**\n\t * Get all behavior references attached to this entity.\n\t * Used by the stage to auto-register required systems.\n\t */\n\tpublic getBehaviorRefs(): BehaviorRef[] {\n\t\treturn this.behaviorRefs;\n\t}\n\n\tpublic getCollisionCallbacks(): Array<(params: CollisionContext<this, O>) => void> {\n\t\treturn this.getCollisionRegistrations().map((registration) => registration.callback);\n\t}\n\n\tpublic getCollisionRegistrations(): Array<CollisionRegistration<this, O>> {\n\t\treturn (this.collisionDelegate.collision ?? []).map((registration) => ({\n\t\t\tid: registration.id,\n\t\t\tcallback: registration.callback,\n\t\t\toptions: { ...registration.options },\n\t\t}));\n\t}\n\n\tprivate copyBehaviorRefsTo(target: GameEntity<any>): Map<BehaviorRef, BehaviorRef> {\n\t\tconst aliases = new Map<BehaviorRef, BehaviorRef>();\n\n\t\tfor (const ref of this.behaviorRefs) {\n\t\t\ttarget.use(ref.descriptor, deepCloneValue(ref.options));\n\t\t\tconst targetRef = target.getBehaviorRefs().at(-1);\n\t\t\tif (targetRef) {\n\t\t\t\taliases.set(ref, targetRef);\n\t\t\t}\n\t\t}\n\n\t\treturn aliases;\n\t}\n\n\t/**\n\t * Entity-specific setup - resets actions for a fresh stage session.\n\t * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)\n\t */\n\tpublic _setup(params: SetupContext<this>): void {\n\t\t// Reset actions for the new stage session.\n\t\t// Remove completed fire-and-forget actions; reset all others\n\t\t// so they replay from the beginning.\n\t\tfor (let i = this._actions.length - 1; i >= 0; i--) {\n\t\t\tconst act = this._actions[i];\n\t\t\tif (act.done && !act.persistent) {\n\t\t\t\tthis._actions.splice(i, 1);\n\t\t\t} else {\n\t\t\t\tact.reset();\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected async _loaded(_params: LoadedContext<this>): Promise<void> { }\n\n\t/**\n\t * Entity-specific update - updates materials.\n\t * Transform changes are applied by the stage after all update callbacks complete.\n\t * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)\n\t */\n\tpublic _update(params: UpdateContext<this>): void {\n\t\tthis.updateMaterials(params);\n\t}\n\n\t/**\n\t * Entity-specific destroy -- reserved for consumer game logic.\n\t * Engine-internal resource disposal runs in _cleanup() instead.\n\t */\n\tpublic _destroy(params: DestroyContext<this>): void { }\n\n\t/**\n\t * Engine-internal resource cleanup -- runs automatically after destroy.\n\t * Disposes GPU/DOM resources (meshes, materials, debug material).\n\t *\n\t * Note: actions, collision callbacks, and behavior refs are intentionally\n\t * NOT cleared here -- they are registered by consumer code at module level\n\t * and must persist across stage reloads. Actions are reset in _setup().\n\t */\n\tprotected _cleanup(_params: CleanupContext<this>): void {\n\t\t// Dispose entity event emitter & subscriptions\n\t\tthis.disposeEvents();\n\n\t\t// Dispose compound meshes\n\t\tfor (const m of this.compoundMeshes) {\n\t\t\tm.geometry?.dispose();\n\t\t\tif (Array.isArray(m.material)) {\n\t\t\t\tm.material.forEach(mat => mat.dispose());\n\t\t\t} else {\n\t\t\t\tm.material?.dispose();\n\t\t\t}\n\t\t}\n\t\tthis.compoundMeshes.length = 0;\n\n\t\t// Dispose debug material\n\t\tthis.debugMaterial?.dispose();\n\t\tthis.debugMaterial = undefined;\n\n\t\t// Remove group from parent (camera or scene)\n\t\tthis.group?.removeFromParent();\n\n\t\t// Note: physics references (body, collider, colliders) are intentionally\n\t\t// NOT nulled here. They are needed by removeEntityByUuid() → world.destroyEntity()\n\t\t// which runs later when the stage processes markedForRemoval entities.\n\t}\n\n\tpublic _collision(\n\t\tother: GameEntity<O>,\n\t\tglobals?: any,\n\t\tdispatch: CollisionDispatchMetadata = {\n\t\t\tphase: 'stay',\n\t\t\tnowMs: getCollisionNowMs(),\n\t\t},\n\t): void {\n\t\tif (!this.collisionDelegate.collision?.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst cooldowns = this.collisionDelegate.cooldowns ?? new Map<string, number>();\n\t\tthis.collisionDelegate.cooldowns = cooldowns;\n\n\t\tfor (const registration of this.collisionDelegate.collision) {\n\t\t\tif (registration.options.phase !== dispatch.phase) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst cooldownMs = registration.options.cooldownMs;\n\t\t\tif (cooldownMs != null) {\n\t\t\t\tconst cooldownKey = `${registration.id}:${other.uuid}`;\n\t\t\t\tconst lastTriggeredAt = cooldowns.get(cooldownKey);\n\t\t\t\tif (\n\t\t\t\t\tlastTriggeredAt != null\n\t\t\t\t\t&& (dispatch.nowMs - lastTriggeredAt) < cooldownMs\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcooldowns.set(cooldownKey, dispatch.nowMs);\n\t\t\t}\n\n\t\t\tregistration.callback({ entity: this, other, globals });\n\t\t}\n\t}\n\n\tprotected updateMaterials(params: any) {\n\t\tif (!this.materials?.length) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const material of this.materials) {\n\t\t\tif (material instanceof ShaderMaterial) {\n\t\t\t\tif (material.uniforms) {\n\t\t\t\t\tmaterial.uniforms.iTime &&\n\t\t\t\t\t\t(material.uniforms.iTime.value += params.delta);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic buildInfo(): Record<string, string> {\n\t\tconst info: Record<string, string> = {};\n\t\tinfo.name = this.name;\n\t\tinfo.uuid = this.uuid;\n\t\tinfo.eid = this.eid.toString();\n\t\treturn info;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Events API\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispatch an event from this entity.\n\t * Events are emitted both locally and to the global event bus.\n\t */\n\tdispatch<K extends keyof EntityEvents>(\n\t\tevent: K,\n\t\tpayload: EntityEvents[K],\n\t): void {\n\t\tthis.eventDelegate.dispatch(event, payload);\n\t\t(zylemEventBus as any).emit(event, payload);\n\t}\n\n\t/**\n\t * Listen for events on this entity instance.\n\t * @returns Unsubscribe function\n\t */\n\tlisten<K extends keyof EntityEvents>(\n\t\tevent: K,\n\t\thandler: (payload: EntityEvents[K]) => void,\n\t): () => void {\n\t\treturn this.eventDelegate.listen(event, handler);\n\t}\n\n\t/**\n\t * Clean up entity event subscriptions.\n\t */\n\tdisposeEvents(): void {\n\t\tthis.eventDelegate.dispose();\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Bare entity factory\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a bare entity with no mesh or collision.\n * Use `.add(boxMesh(), boxCollision())` to compose its shape.\n *\n * @example\n * ```ts\n * const box = create({ position: { x: 0, y: 5, z: 0 } })\n * .add(boxMesh({ size: { x: 2, y: 2, z: 2 } }))\n * .add(boxCollision({ size: { x: 2, y: 2, z: 2 } }));\n * ```\n */\nexport function create(options?: Partial<GameEntityOptions>): GameEntity<GameEntityOptions> {\n\tconst entity = new (GameEntity as any)() as GameEntity<GameEntityOptions>;\n\tentity.options = { ...commonDefaults, ...options } as GameEntityOptions;\n\treturn finalizeEntityCloneSupport(\n\t\tentity,\n\t\t(cloneOptions) => create(cloneOptions ?? {}),\n\t);\n}\n\nfunction cloneMeshComponent(mesh: Mesh): Mesh {\n\tconst clonedMesh = mesh.clone(true);\n\tconst originalNodes: any[] = [];\n\tconst clonedNodes: any[] = [];\n\n\tmesh.traverse((node) => originalNodes.push(node));\n\tclonedMesh.traverse((node) => clonedNodes.push(node));\n\n\tfor (let i = 0; i < originalNodes.length; i++) {\n\t\tconst originalNode = originalNodes[i];\n\t\tconst clonedNode = clonedNodes[i];\n\n\t\tif (originalNode?.geometry?.clone) {\n\t\t\tclonedNode.geometry = originalNode.geometry.clone();\n\t\t}\n\n\t\tif (originalNode?.material) {\n\t\t\tclonedNode.material = Array.isArray(originalNode.material)\n\t\t\t\t? originalNode.material.map((material: Material) => material.clone())\n\t\t\t\t: originalNode.material.clone();\n\t\t}\n\t}\n\n\treturn clonedMesh;\n}\n\nfunction wrapBehaviorCallback<T extends Function>(\n\tcallback: T,\n\taliases: Map<BehaviorRef, BehaviorRef>,\n): T {\n\tif (aliases.size === 0) {\n\t\treturn callback;\n\t}\n\n\treturn ((...args: any[]) => {\n\t\tconst previousValues = Array.from(aliases.entries()).map(([sourceRef, targetRef]) => ({\n\t\t\tsourceRef,\n\t\t\toptions: sourceRef.options,\n\t\t\tfsm: sourceRef.fsm,\n\t\t\thasFSM: Object.prototype.hasOwnProperty.call(sourceRef, 'fsm'),\n\t\t\ttargetRef,\n\t\t}));\n\n\t\tfor (const entry of previousValues) {\n\t\t\tentry.sourceRef.options = entry.targetRef.options;\n\t\t\tif (entry.targetRef.fsm === undefined) {\n\t\t\t\tdelete entry.sourceRef.fsm;\n\t\t\t} else {\n\t\t\t\tentry.sourceRef.fsm = entry.targetRef.fsm;\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\treturn callback(...args);\n\t\t} finally {\n\t\t\tfor (let i = previousValues.length - 1; i >= 0; i--) {\n\t\t\t\tconst entry = previousValues[i];\n\t\t\t\tentry.sourceRef.options = entry.options;\n\t\t\t\tif (!entry.hasFSM) {\n\t\t\t\t\tdelete entry.sourceRef.fsm;\n\t\t\t\t} else {\n\t\t\t\t\tentry.sourceRef.fsm = entry.fsm;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}) as unknown as T;\n}\n\nexport function finalizeEntityCloneSupport<E extends GameEntity<any>>(\n\tentity: E,\n\tfactory: (options?: Partial<E['options']>) => E,\n): E {\n\tentity.finalizeCloneSupport(factory as any);\n\treturn entity;\n}\n","// this class is not for asset loading, it is for loading entity specific data\n// this is to keep the entity class focused purely on entity logic\n\nexport function isLoadable(obj: any): obj is EntityLoaderDelegate {\n\treturn typeof obj?.load === \"function\" && typeof obj?.data === \"function\";\n}\n\nexport interface EntityLoaderDelegate {\n\t/** Initiates loading (may be async internally, but call returns immediately) */\n\tload(): void;\n\t/** Returns data synchronously (may be null if still loading) */\n\tdata(): any;\n}\n\nexport class EntityLoader {\n\tentityReference: EntityLoaderDelegate;\n\n\tconstructor(entity: EntityLoaderDelegate) {\n\t\tthis.entityReference = entity;\n\t}\n\n\tload(): void {\n\t\tif (this.entityReference.load) {\n\t\t\tthis.entityReference.load();\n\t\t}\n\t}\n\n\tdata(): any {\n\t\tif (this.entityReference.data) {\n\t\t\treturn this.entityReference.data();\n\t\t}\n\t\treturn null;\n\t}\n}","import {\n\tfinalizeEntityCloneSupport,\n\tGameEntityOptions,\n\tGameEntity,\n} from \"./entity\";\nimport { BaseNode } from \"../core/base-node\";\nimport { EntityBuilder } from \"./builder\";\nimport { EntityCollisionBuilder } from \"./builder\";\nimport { EntityMeshBuilder } from \"./builder\";\nimport { EntityLoader, isLoadable } from \"./delegates/loader\";\n\nexport interface CreateGameEntityOptions<T extends GameEntity<any>, CreateOptions extends GameEntityOptions> {\n\targs: Array<any>;\n\tdefaultConfig: GameEntityOptions;\n\tEntityClass: new (options: any) => T;\n\tBuilderClass: new (options: any, entity: T, meshBuilder: any, collisionBuilder: any) => EntityBuilder<T, CreateOptions>;\n\tMeshBuilderClass?: new (data: any) => EntityMeshBuilder;\n\tCollisionBuilderClass?: new (data: any) => EntityCollisionBuilder;\n\tentityType: symbol;\n\tcloneFactory: (options?: Partial<CreateOptions>) => T;\n};\n\nexport function createEntity<T extends GameEntity<any>, CreateOptions extends GameEntityOptions>(params: CreateGameEntityOptions<T, CreateOptions>): T {\n\tconst {\n\t\targs,\n\t\tdefaultConfig,\n\t\tEntityClass,\n\t\tBuilderClass,\n\t\tentityType,\n\t\tMeshBuilderClass,\n\t\tCollisionBuilderClass,\n\t\tcloneFactory,\n\t} = params;\n\n\tlet builder: EntityBuilder<T, CreateOptions> | null = null;\n\tlet configuration;\n\n\tconst configurationIndex = args.findIndex(node => !(node instanceof BaseNode));\n\tif (configurationIndex !== -1) {\n\t\tconst subArgs = args.splice(configurationIndex, 1);\n\t\tconfiguration = subArgs.find(node => !(node instanceof BaseNode));\n\t}\n\n\tconst mergedConfiguration = configuration ? { ...defaultConfig, ...configuration } : defaultConfig;\n\targs.push(mergedConfiguration);\n\n\tfor (const arg of args) {\n\t\tif (arg instanceof BaseNode) {\n\t\t\tcontinue;\n\t\t}\n\t\tlet entityData = null;\n\t\tconst entity = new EntityClass(arg);\n\t\ttry {\n\t\t\tif (isLoadable(entity)) {\n\t\t\t\tconst loader = new EntityLoader(entity);\n\t\t\t\tloader.load();\n\t\t\t\tentityData = loader.data();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error creating entity with loader:\", error);\n\t\t}\n\t\tbuilder = new BuilderClass(\n\t\t\targ,\n\t\t\tentity,\n\t\t\tMeshBuilderClass ? new MeshBuilderClass(entityData) : null,\n\t\t\tCollisionBuilderClass ? new CollisionBuilderClass(entityData) : null,\n\t\t);\n\t\tif (arg.material) {\n\t\t\tbuilder.withMaterial(arg.material, entityType);\n\t\t}\n\t}\n\n\tif (!builder) {\n\t\tthrow new Error(`missing options for ${String(entityType)}, builder is not initialized.`);\n\t}\n\n\treturn finalizeEntityCloneSupport(\n\t\tbuilder.build(),\n\t\t(options) => cloneFactory(options as Partial<CreateOptions> | undefined),\n\t);\n}\n","/**\n * Texture loader adapter for the Asset Manager\n */\n\nimport { TextureLoader, Texture, RepeatWrapping, Vector2, Wrapping } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface TextureOptions extends AssetLoadOptions {\n\trepeat?: Vector2;\n\twrapS?: Wrapping;\n\twrapT?: Wrapping;\n}\n\nexport class TextureLoaderAdapter implements LoaderAdapter<Texture> {\n\tprivate loader: TextureLoader;\n\n\tconstructor() {\n\t\tthis.loader = new TextureLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'tga'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: TextureOptions): Promise<Texture> {\n\t\tconst texture = await this.loader.loadAsync(url, (event) => {\n\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t}\n\t\t});\n\n\t\t// Apply texture options\n\t\tif (options?.repeat) {\n\t\t\ttexture.repeat.copy(options.repeat);\n\t\t}\n\t\ttexture.wrapS = options?.wrapS ?? RepeatWrapping;\n\t\ttexture.wrapT = options?.wrapT ?? RepeatWrapping;\n\n\t\treturn texture;\n\t}\n\n\t/**\n\t * Clone a texture for independent usage\n\t */\n\tclone(texture: Texture): Texture {\n\t\tconst cloned = texture.clone();\n\t\tcloned.needsUpdate = true;\n\t\treturn cloned;\n\t}\n}\n","import { Material, Mesh, Object3D } from 'three';\nimport { clone as cloneSkeleton } from 'three/addons/utils/SkeletonUtils.js';\n\n/**\n * Clone a model hierarchy with independent mesh resources.\n *\n * SkeletonUtils preserves skinned mesh bindings, then we deep-clone\n * geometry/material so per-instance overrides and disposal are safe.\n */\nexport function cloneModelObject(object: Object3D): Object3D {\n\tconst clonedObject = cloneSkeleton(object);\n\tconst originalNodes: Object3D[] = [];\n\tconst clonedNodes: Object3D[] = [];\n\n\tobject.traverse((node) => originalNodes.push(node));\n\tclonedObject.traverse((node) => clonedNodes.push(node));\n\n\tfor (let i = 0; i < originalNodes.length; i++) {\n\t\tconst originalNode = originalNodes[i];\n\t\tconst clonedNode = clonedNodes[i];\n\t\tif (!(originalNode instanceof Mesh) || !(clonedNode instanceof Mesh)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (originalNode.geometry?.clone) {\n\t\t\tclonedNode.geometry = originalNode.geometry.clone();\n\t\t}\n\n\t\tif (!originalNode.material) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tclonedNode.material = Array.isArray(originalNode.material)\n\t\t\t? originalNode.material.map((material: Material) => material.clone())\n\t\t\t: originalNode.material.clone();\n\t}\n\n\treturn clonedObject;\n}\n","/**\n * GLTF loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parseAsync.\n * Automatically configures DRACOLoader for Draco-compressed meshes.\n */\n\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\nimport { cloneModelObject } from './model-clone';\n\nconst DRACO_DECODER_PATH = 'https://www.gstatic.com/draco/v1/decoders/';\n\nexport interface GLTFLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parseAsync pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers, so this mainly\n\t * provides a cleaner async/await pattern rather than performance gains\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class GLTFLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: GLTFLoader;\n\tprivate dracoLoader: DRACOLoader;\n\n\tconstructor() {\n\t\tthis.dracoLoader = new DRACOLoader();\n\t\tthis.dracoLoader.setDecoderPath(DRACO_DECODER_PATH);\n\n\t\tthis.loader = new GLTFLoader();\n\t\tthis.loader.setDRACOLoader(this.dracoLoader);\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['gltf', 'glb'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parseAsync\n\t * Both fetch and parsing are async, keeping the main thread responsive\n\t */\n\tprivate async loadWithAsyncFetch(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using GLTFLoader.parseAsync\n\t\t\t// The url is passed as the path for resolving relative resources\n\t\t\tconst gltf = await this.loader.parseAsync(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject: gltf.scene,\n\t\t\t\tanimations: gltf.animations,\n\t\t\t\tgltf\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch GLTF load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(gltf: GLTF) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject: gltf.scene,\n\t\t\t\t\t\tanimations: gltf.animations,\n\t\t\t\t\t\tgltf\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded GLTF scene for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: cloneModelObject(result.object),\n\t\t\tanimations: result.animations?.map(anim => anim.clone()),\n\t\t\tgltf: result.gltf\n\t\t};\n\t}\n}\n","/**\n * FBX loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parse\n */\n\nimport { Object3D } from 'three';\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\nimport { cloneModelObject } from './model-clone';\n\nexport interface FBXLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parse pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class FBXLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: FBXLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FBXLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'fbx';\n\t}\n\n\tasync load(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parse\n\t */\n\tprivate async loadWithAsyncFetch(url: string, _options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using FBXLoader.parse\n\t\t\tconst object = this.loader.parse(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject,\n\t\t\t\tanimations: (object as any).animations || []\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch FBX load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, _options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Object3D) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: (object as any).animations || []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded FBX object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: cloneModelObject(result.object),\n\t\t\tanimations: result.animations?.map(anim => anim.clone())\n\t\t};\n\t}\n}\n","/**\n * OBJ loader adapter for the Asset Manager\n * Supports optional MTL (material) file loading\n */\n\nimport { Object3D, Group } from 'three';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { MTLLoader } from 'three/addons/loaders/MTLLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\nimport { cloneModelObject } from './model-clone';\n\nexport interface OBJLoadOptions extends AssetLoadOptions {\n\t/** Path to MTL material file */\n\tmtlPath?: string;\n}\n\nexport class OBJLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: OBJLoader;\n\tprivate mtlLoader: MTLLoader;\n\n\tconstructor() {\n\t\tthis.loader = new OBJLoader();\n\t\tthis.mtlLoader = new MTLLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'obj';\n\t}\n\n\tasync load(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Load MTL first if provided\n\t\tif (options?.mtlPath) {\n\t\t\tawait this.loadMTL(options.mtlPath);\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Group) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate async loadMTL(url: string): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.mtlLoader.load(\n\t\t\t\turl,\n\t\t\t\t(materials) => {\n\t\t\t\t\tmaterials.preload();\n\t\t\t\t\tthis.loader.setMaterials(materials);\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded OBJ object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: cloneModelObject(result.object),\n\t\t\tanimations: []\n\t\t};\n\t}\n}\n","/**\n * Audio loader adapter for the Asset Manager\n */\n\nimport { AudioLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport class AudioLoaderAdapter implements LoaderAdapter<AudioBuffer> {\n\tprivate loader: AudioLoader;\n\n\tconstructor() {\n\t\tthis.loader = new AudioLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['mp3', 'ogg', 'wav', 'flac', 'aac', 'm4a'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(buffer) => resolve(buffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n","/**\n * File loader adapter for the Asset Manager\n */\n\nimport { FileLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface FileLoadOptions extends AssetLoadOptions {\n\tresponseType?: 'text' | 'arraybuffer' | 'blob' | 'json';\n}\n\nexport class FileLoaderAdapter implements LoaderAdapter<string | ArrayBuffer> {\n\tprivate loader: FileLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FileLoader();\n\t}\n\n\tisSupported(_url: string): boolean {\n\t\t// FileLoader can handle any file type\n\t\treturn true;\n\t}\n\n\tasync load(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst responseType = options?.responseType ?? 'text';\n\t\tthis.loader.setResponseType(responseType as any);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(data) => resolve(data as string | ArrayBuffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n\n/**\n * JSON loader using FileLoader\n */\nexport class JsonLoaderAdapter implements LoaderAdapter<unknown> {\n\tprivate fileLoader: FileLoaderAdapter;\n\n\tconstructor() {\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'json';\n\t}\n\n\tasync load<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\tconst data = await this.fileLoader.load(url, { ...options, responseType: 'json' });\n\t\treturn data as T;\n\t}\n}\n","/**\n * Loader adapters barrel export\n */\n\nexport { TextureLoaderAdapter, type TextureOptions } from './texture-loader';\nexport { GLTFLoaderAdapter, type GLTFLoadOptions } from './gltf-loader';\nexport { FBXLoaderAdapter, type FBXLoadOptions } from './fbx-loader';\nexport { OBJLoaderAdapter, type OBJLoadOptions } from './obj-loader';\nexport { AudioLoaderAdapter } from './audio-loader';\nexport { FileLoaderAdapter, JsonLoaderAdapter, type FileLoadOptions } from './file-loader';\n","/**\n * Centralized Asset Manager for Zylem\n * \n * Provides caching, parallel loading, and unified access to all asset types.\n * All asset loading should funnel through this manager.\n */\n\nimport { Texture, Object3D, LoadingManager, Cache } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport mitt, { Emitter } from 'mitt';\n\nimport {\n\tAssetType,\n\tAssetLoadOptions,\n\tAssetManagerEvents,\n\tBatchLoadItem,\n\tModelLoadResult\n} from './asset-types';\n\nimport {\n\tTextureLoaderAdapter,\n\tGLTFLoaderAdapter,\n\tFBXLoaderAdapter,\n\tOBJLoaderAdapter,\n\tAudioLoaderAdapter,\n\tFileLoaderAdapter,\n\tJsonLoaderAdapter,\n\tTextureOptions,\n\tGLTFLoadOptions,\n\tFBXLoadOptions,\n\tOBJLoadOptions,\n\tFileLoadOptions\n} from './loaders';\n\n/**\n * Asset cache entry\n */\ninterface CacheEntry<T> {\n\tpromise: Promise<T>;\n\tresult?: T;\n\tloadedAt: number;\n}\n\n/**\n * AssetManager - Singleton for all asset loading\n * \n * Features:\n * - URL-based caching with deduplication\n * - Typed load methods for each asset type\n * - Batch loading with Promise.all() for parallelism\n * - Progress events via LoadingManager\n * - Clone support for shared assets (textures, models)\n */\nexport class AssetManager {\n\tprivate static instance: AssetManager | null = null;\n\n\t// Caches for different asset types\n\tprivate textureCache: Map<string, CacheEntry<Texture>> = new Map();\n\tprivate modelCache: Map<string, CacheEntry<ModelLoadResult>> = new Map();\n\tprivate audioCache: Map<string, CacheEntry<AudioBuffer>> = new Map();\n\tprivate fileCache: Map<string, CacheEntry<string | ArrayBuffer>> = new Map();\n\tprivate jsonCache: Map<string, CacheEntry<unknown>> = new Map();\n\n\t// Loaders\n\tprivate textureLoader: TextureLoaderAdapter;\n\tprivate gltfLoader: GLTFLoaderAdapter;\n\tprivate fbxLoader: FBXLoaderAdapter;\n\tprivate objLoader: OBJLoaderAdapter;\n\tprivate audioLoader: AudioLoaderAdapter;\n\tprivate fileLoader: FileLoaderAdapter;\n\tprivate jsonLoader: JsonLoaderAdapter;\n\n\t// Loading manager for progress tracking\n\tprivate loadingManager: LoadingManager;\n\n\t// Event emitter\n\tprivate events: Emitter<AssetManagerEvents>;\n\n\t// Stats\n\tprivate stats = {\n\t\ttexturesLoaded: 0,\n\t\tmodelsLoaded: 0,\n\t\taudioLoaded: 0,\n\t\tfilesLoaded: 0,\n\t\tcacheHits: 0,\n\t\tcacheMisses: 0\n\t};\n\n\tprivate constructor() {\n\t\t// Initialize loaders\n\t\tthis.textureLoader = new TextureLoaderAdapter();\n\t\tthis.gltfLoader = new GLTFLoaderAdapter();\n\t\tthis.fbxLoader = new FBXLoaderAdapter();\n\t\tthis.objLoader = new OBJLoaderAdapter();\n\t\tthis.audioLoader = new AudioLoaderAdapter();\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t\tthis.jsonLoader = new JsonLoaderAdapter();\n\n\t\t// Initialize loading manager\n\t\tthis.loadingManager = new LoadingManager();\n\t\tthis.loadingManager.onProgress = (url, loaded, total) => {\n\t\t\tthis.events.emit('batch:progress', { loaded, total });\n\t\t};\n\n\t\t// Initialize event emitter\n\t\tthis.events = mitt<AssetManagerEvents>();\n\n\t\t// Enable Three.js built-in cache\n\t\tCache.enabled = true;\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tstatic getInstance(): AssetManager {\n\t\tif (!AssetManager.instance) {\n\t\t\tAssetManager.instance = new AssetManager();\n\t\t}\n\t\treturn AssetManager.instance;\n\t}\n\n\t/**\n\t * Reset the singleton (useful for testing)\n\t */\n\tstatic resetInstance(): void {\n\t\tif (AssetManager.instance) {\n\t\t\tAssetManager.instance.clearCache();\n\t\t\tAssetManager.instance = null;\n\t\t}\n\t}\n\n\t// ==================== TEXTURE LOADING ====================\n\n\t/**\n\t * Load a texture with caching\n\t */\n\tasync loadTexture(url: string, options?: TextureOptions): Promise<Texture> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.TEXTURE,\n\t\t\tthis.textureCache,\n\t\t\t() => this.textureLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(texture) => {\n\t\t\t\tif (!options?.clone) return texture;\n\t\t\t\tconst cloned = this.textureLoader.clone(texture);\n\t\t\t\t// Re-apply per-instance texture options to the clone so that\n\t\t\t\t// different callers sharing the same cached base texture can\n\t\t\t\t// use independent repeat / wrap values.\n\t\t\t\tif (options.repeat) {\n\t\t\t\t\tcloned.repeat.copy(options.repeat);\n\t\t\t\t}\n\t\t\t\tif (options.wrapS !== undefined) {\n\t\t\t\t\tcloned.wrapS = options.wrapS;\n\t\t\t\t}\n\t\t\t\tif (options.wrapT !== undefined) {\n\t\t\t\t\tcloned.wrapT = options.wrapT;\n\t\t\t\t}\n\t\t\t\treturn cloned;\n\t\t\t}\n\t\t);\n\t}\n\n\t// ==================== MODEL LOADING ====================\n\n\t/**\n\t * Load a GLTF/GLB model with caching\n\t */\n\tasync loadGLTF(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.GLTF,\n\t\t\tthis.modelCache,\n\t\t\t() => this.gltfLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.gltfLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an FBX model with caching\n\t */\n\tasync loadFBX(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.FBX,\n\t\t\tthis.modelCache,\n\t\t\t() => this.fbxLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.fbxLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an OBJ model with caching\n\t */\n\tasync loadOBJ(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Include mtlPath in cache key for OBJ files\n\t\tconst cacheKey = options?.mtlPath ? `${url}:${options.mtlPath}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.OBJ,\n\t\t\tthis.modelCache,\n\t\t\t() => this.objLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.objLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Auto-detect model type and load\n\t */\n\tasync loadModel(url: string, options?: AssetLoadOptions): Promise<ModelLoadResult> {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\t\n\t\tswitch (ext) {\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb':\n\t\t\t\treturn this.loadGLTF(url, options);\n\t\t\tcase 'fbx':\n\t\t\t\treturn this.loadFBX(url, options);\n\t\t\tcase 'obj':\n\t\t\t\treturn this.loadOBJ(url, options);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported model format: ${ext}`);\n\t\t}\n\t}\n\n\t// ==================== AUDIO LOADING ====================\n\n\t/**\n\t * Load an audio buffer with caching\n\t */\n\tasync loadAudio(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.AUDIO,\n\t\t\tthis.audioCache,\n\t\t\t() => this.audioLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t// ==================== FILE LOADING ====================\n\n\t/**\n\t * Load a raw file with caching\n\t */\n\tasync loadFile(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst cacheKey = options?.responseType ? `${url}:${options.responseType}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.FILE,\n\t\t\tthis.fileCache,\n\t\t\t() => this.fileLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Load a JSON file with caching\n\t */\n\tasync loadJSON<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.JSON,\n\t\t\tthis.jsonCache,\n\t\t\t() => this.jsonLoader.load<T>(url, options),\n\t\t\toptions\n\t\t) as Promise<T>;\n\t}\n\n\t// ==================== BATCH LOADING ====================\n\n\t/**\n\t * Load multiple assets in parallel\n\t */\n\tasync loadBatch(items: BatchLoadItem[]): Promise<Map<string, any>> {\n\t\tconst results = new Map<string, any>();\n\t\t\n\t\tconst promises = items.map(async (item) => {\n\t\t\ttry {\n\t\t\t\tlet result: any;\n\t\t\t\t\n\t\t\t\tswitch (item.type) {\n\t\t\t\t\tcase AssetType.TEXTURE:\n\t\t\t\t\t\tresult = await this.loadTexture(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.GLTF:\n\t\t\t\t\t\tresult = await this.loadGLTF(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FBX:\n\t\t\t\t\t\tresult = await this.loadFBX(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.OBJ:\n\t\t\t\t\t\tresult = await this.loadOBJ(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.AUDIO:\n\t\t\t\t\t\tresult = await this.loadAudio(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FILE:\n\t\t\t\t\t\tresult = await this.loadFile(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.JSON:\n\t\t\t\t\t\tresult = await this.loadJSON(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`Unknown asset type: ${item.type}`);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tresults.set(item.url, result);\n\t\t\t} catch (error) {\n\t\t\t\tthis.events.emit('asset:error', {\n\t\t\t\t\turl: item.url,\n\t\t\t\t\ttype: item.type,\n\t\t\t\t\terror: error as Error\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.all(promises);\n\t\t\n\t\tthis.events.emit('batch:complete', { urls: items.map(i => i.url) });\n\t\t\n\t\treturn results;\n\t}\n\n\t/**\n\t * Preload assets without returning results\n\t */\n\tasync preload(items: BatchLoadItem[]): Promise<void> {\n\t\tawait this.loadBatch(items);\n\t}\n\n\t// ==================== CACHE MANAGEMENT ====================\n\n\t/**\n\t * Check if an asset is cached\n\t */\n\tisCached(url: string): boolean {\n\t\treturn this.textureCache.has(url) ||\n\t\t\tthis.modelCache.has(url) ||\n\t\t\tthis.audioCache.has(url) ||\n\t\t\tthis.fileCache.has(url) ||\n\t\t\tthis.jsonCache.has(url);\n\t}\n\n\t/**\n\t * Clear all caches or a specific URL\n\t */\n\tclearCache(url?: string): void {\n\t\tif (url) {\n\t\t\tthis.textureCache.delete(url);\n\t\t\tthis.modelCache.delete(url);\n\t\t\tthis.audioCache.delete(url);\n\t\t\tthis.fileCache.delete(url);\n\t\t\tthis.jsonCache.delete(url);\n\t\t} else {\n\t\t\tthis.textureCache.clear();\n\t\t\tthis.modelCache.clear();\n\t\t\tthis.audioCache.clear();\n\t\t\tthis.fileCache.clear();\n\t\t\tthis.jsonCache.clear();\n\t\t\tCache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetStats(): typeof this.stats {\n\t\treturn { ...this.stats };\n\t}\n\n\t// ==================== EVENTS ====================\n\n\t/**\n\t * Subscribe to asset manager events\n\t */\n\ton<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.on(event, handler);\n\t}\n\n\t/**\n\t * Unsubscribe from asset manager events\n\t */\n\toff<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.off(event, handler);\n\t}\n\n\t// ==================== PRIVATE HELPERS ====================\n\n\t/**\n\t * Generic cache wrapper for loading assets\n\t */\n\tprivate async loadWithCache<T>(\n\t\turl: string,\n\t\ttype: AssetType,\n\t\tcache: Map<string, CacheEntry<T>>,\n\t\tloader: () => Promise<T>,\n\t\toptions?: AssetLoadOptions,\n\t\tcloner?: (result: T) => T\n\t): Promise<T> {\n\t\t// Check for force reload\n\t\tif (options?.forceReload) {\n\t\t\tcache.delete(url);\n\t\t}\n\n\t\t// Check cache\n\t\tconst cached = cache.get(url);\n\t\tif (cached) {\n\t\t\tthis.stats.cacheHits++;\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: true });\n\t\t\t\n\t\t\tconst result = await cached.promise;\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t}\n\n\t\t// Cache miss - start loading\n\t\tthis.stats.cacheMisses++;\n\t\tthis.events.emit('asset:loading', { url, type });\n\n\t\tconst promise = loader();\n\t\tconst entry: CacheEntry<T> = {\n\t\t\tpromise,\n\t\t\tloadedAt: Date.now()\n\t\t};\n\t\tcache.set(url, entry);\n\n\t\ttry {\n\t\t\tconst result = await promise;\n\t\t\tentry.result = result;\n\t\t\t\n\t\t\t// Update stats\n\t\t\tthis.updateStats(type);\n\t\t\t\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: false });\n\t\t\t\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t} catch (error) {\n\t\t\t// Remove failed entry from cache\n\t\t\tcache.delete(url);\n\t\t\tthis.events.emit('asset:error', { url, type, error: error as Error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate updateStats(type: AssetType): void {\n\t\tswitch (type) {\n\t\t\tcase AssetType.TEXTURE:\n\t\t\t\tthis.stats.texturesLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.GLTF:\n\t\t\tcase AssetType.FBX:\n\t\t\tcase AssetType.OBJ:\n\t\t\t\tthis.stats.modelsLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.AUDIO:\n\t\t\t\tthis.stats.audioLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.FILE:\n\t\t\tcase AssetType.JSON:\n\t\t\t\tthis.stats.filesLoaded++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Singleton instance export for convenience\n */\nexport const assetManager = AssetManager.getInstance();","/**\n * Entity Asset Loader - Refactored to use AssetManager\n * \n * This module provides a compatibility layer for existing code that uses EntityAssetLoader.\n * All loading now goes through the centralized AssetManager for caching.\n */\n\nimport { AnimationClip, Object3D } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport { assetManager } from './asset-manager';\nimport type { AssetLoadOptions } from './asset-types';\n\nexport interface AssetLoaderResult {\n\tobject?: Object3D;\n\tanimation?: AnimationClip;\n\tgltf?: GLTF;\n}\n\n/**\n * EntityAssetLoader - Uses AssetManager for all model loading\n * \n * This class is now a thin wrapper around AssetManager, providing backward\n * compatibility for existing code while benefiting from centralized caching.\n */\nexport class EntityAssetLoader {\n\t/**\n\t * Load a model file (FBX, GLTF, GLB, OBJ) using the asset manager\n\t */\n\tasync loadFile(file: string, options?: AssetLoadOptions): Promise<AssetLoaderResult> {\n\t\tconst ext = file.split('.').pop()?.toLowerCase();\n\n\t\tswitch (ext) {\n\t\t\tcase 'fbx': {\n\t\t\t\tconst result = await assetManager.loadFBX(file, options);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tanimation: result.animations?.[0]\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb': {\n\t\t\t\tconst result = await assetManager.loadGLTF(file, options);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tgltf: result.gltf\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'obj': {\n\t\t\t\tconst result = await assetManager.loadOBJ(file, options);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported file type: ${file}`);\n\t\t}\n\t}\n}\n","import {\n\tAnimationAction,\n\tAnimationClip,\n\tAnimationMixer,\n\tBone,\n\tLoopOnce,\n\tLoopRepeat,\n\tObject3D,\n} from 'three';\nimport { EntityAssetLoader, AssetLoaderResult } from '../../core/entity-asset-loader';\n\nexport type AnimationOptions = {\n\tkey: string;\n\tpauseAtEnd?: boolean;\n\tpauseAtPercentage?: number;\n\tfadeToKey?: string;\n\tfadeDuration?: number;\n};\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nfunction getTrackTargetName(trackName: string): string {\n\tconst propertyIndex = trackName.lastIndexOf('.');\n\treturn propertyIndex >= 0 ? trackName.slice(0, propertyIndex) : trackName;\n}\n\nfunction shouldStripRootMotion(track: any, targetByName: Map<string, Object3D>): boolean {\n\tif (!track?.name?.endsWith('.position')) {\n\t\treturn false;\n\t}\n\n\tconst targetName = getTrackTargetName(track.name);\n\tconst target = targetByName.get(targetName);\n\tif (target instanceof Bone) {\n\t\treturn !(target.parent instanceof Bone);\n\t}\n\n\treturn /hips\\.position$/i.test(track.name) || /root\\.position$/i.test(track.name);\n}\n\nfunction stripClipRootMotion(\n\tclip: AnimationClip,\n\ttargetByName: Map<string, Object3D>,\n): AnimationClip {\n\tfor (const track of clip.tracks) {\n\t\tif (!shouldStripRootMotion(track, targetByName)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!track.values || track.values.length < 3) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst baseX = track.values[0];\n\t\tconst baseZ = track.values[2];\n\t\tfor (let i = 0; i < track.values.length; i += 3) {\n\t\t\ttrack.values[i] = baseX;\n\t\t\ttrack.values[i + 2] = baseZ;\n\t\t}\n\t}\n\n\treturn clip;\n}\n\nexport class AnimationDelegate {\n\tprivate _mixer: AnimationMixer | null = null;\n\tprivate _actions: Record<string, AnimationAction> = {};\n\tprivate _animations: AnimationClip[] = [];\n\tprivate _currentAction: AnimationAction | null = null;\n\n\tprivate _pauseAtPercentage = 0;\n\tprivate _isPaused = false;\n\tprivate _queuedKey: string | null = null;\n\tprivate _fadeDuration = 0.5;\n\n\tprivate _currentKey: string = '';\n\tprivate _assetLoader = new EntityAssetLoader();\n\n\tconstructor(private target: Object3D) { }\n\n\tasync loadAnimations(animations: AnimationObject[]): Promise<void> {\n\t\tif (!animations.length) return;\n\n\t\tconst results = await Promise.all(animations.map(a => this._assetLoader.loadFile(a.path)));\n\t\tconst targetByName = new Map<string, Object3D>();\n\t\tthis.target.traverse((node) => {\n\t\t\tif (node.name) {\n\t\t\t\ttargetByName.set(node.name, node);\n\t\t\t}\n\t\t});\n\t\t\n\t\t// Build animations list while preserving original key mapping\n\t\t// Filter to only successful loads and pair with their original keys\n\t\tconst loadedAnimations: { key: string; clip: AnimationClip }[] = [];\n\t\tresults.forEach((result, i) => {\n\t\t\tif (result.animation) {\n\t\t\t\tloadedAnimations.push({\n\t\t\t\t\tkey: animations[i].key || i.toString(),\n\t\t\t\t\tclip: stripClipRootMotion(result.animation, targetByName),\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tif (!loadedAnimations.length) return;\n\n\t\tthis._animations = loadedAnimations.map(a => a.clip);\n\t\tthis._mixer = new AnimationMixer(this.target);\n\t\t\n\t\t// Create actions with correct key mapping\n\t\tloadedAnimations.forEach(({ key, clip }) => {\n\t\t\tthis._actions[key] = this._mixer!.clipAction(clip);\n\t\t});\n\n\t\tthis.playAnimation({ key: loadedAnimations[0].key });\n\t}\n\n\tupdate(delta: number): void {\n\t\tif (!this._mixer || !this._currentAction) return;\n\n\t\tthis._mixer.update(delta);\n\n\t\tconst pauseAtTime = this._currentAction.getClip().duration * (this._pauseAtPercentage / 100);\n\t\tif (\n\t\t\t!this._isPaused &&\n\t\t\tthis._pauseAtPercentage > 0 &&\n\t\t\tthis._currentAction.time >= pauseAtTime\n\t\t) {\n\t\t\tthis._currentAction.time = pauseAtTime;\n\t\t\tthis._currentAction.paused = true;\n\t\t\tthis._isPaused = true;\n\n\t\t\tif (this._queuedKey !== null) {\n\t\t\t\tconst next = this._actions[this._queuedKey];\n\t\t\t\tnext.reset().play();\n\t\t\t\tthis._currentAction.crossFadeTo(next, this._fadeDuration, false);\n\t\t\t\tthis._currentAction = next;\n\t\t\t\tthis._currentKey = this._queuedKey;\n\t\t\t\tthis._queuedKey = null;\n\t\t\t}\n\t\t}\n\t}\n\n\tplayAnimation(opts: AnimationOptions): void {\n\t\tif (!this._mixer) return;\n\t\tconst { key, pauseAtPercentage = 0, pauseAtEnd = false, fadeToKey, fadeDuration = 0.5 } = opts;\n\t\tif (key === this._currentKey) return;\n\n\t\t// Check if the new action exists BEFORE stopping the current animation\n\t\t// This prevents T-posing when an animation key doesn't exist\n\t\tconst action = this._actions[key];\n\t\tif (!action) return;\n\n\t\tthis._queuedKey = fadeToKey || null;\n\t\tthis._fadeDuration = fadeDuration;\n\n\t\tthis._pauseAtPercentage = pauseAtEnd ? 100 : pauseAtPercentage;\n\t\tthis._isPaused = false;\n\n\t\tconst prev = this._currentAction;\n\t\t// Don't stop prev here - crossFadeTo needs it playing for smooth transition\n\n\t\tif (this._pauseAtPercentage > 0) {\n\t\t\taction.setLoop(LoopOnce, Infinity);\n\t\t\taction.clampWhenFinished = true;\n\t\t} else {\n\t\t\taction.setLoop(LoopRepeat, Infinity);\n\t\t\taction.clampWhenFinished = false;\n\t\t}\n\n\t\t// Start the new action\n\t\taction.reset().play();\n\n\t\t// Crossfade from previous if it exists\n\t\tif (prev) {\n\t\t\tprev.crossFadeTo(action, fadeDuration, false);\n\t\t}\n\n\t\tthis._currentAction = action;\n\t\tthis._currentKey = key;\n\t}\n\n\t/**\n\t * Dispose of all animation resources\n\t */\n\tdispose(): void {\n\t\t// Stop all actions\n\t\tObject.values(this._actions).forEach(action => {\n\t\t\taction.stop();\n\t\t});\n\n\t\t// Stop and uncache mixer\n\t\tif (this._mixer) {\n\t\t\tthis._mixer.stopAllAction();\n\t\t\tthis._mixer.uncacheRoot(this.target);\n\t\t\tthis._mixer = null;\n\t\t}\n\n\t\t// Clear references\n\t\tthis._actions = {};\n\t\tthis._animations = [];\n\t\tthis._currentAction = null;\n\t\tthis._currentKey = '';\n\t}\n\n\tget currentAnimationKey() { return this._currentKey; }\n\tget animations() { return this._animations; }\n}\n","import { BufferGeometry, Material, Mesh } from 'three';\nimport { GameEntityOptions } from '../entities/entity';\n\n/**\n * TODO: allow for multiple materials requires geometry groups\n * TODO: allow for instanced uniforms\n * TODO: allow for geometry groups\n * TODO: allow for batched meshes\n * import { InstancedUniformsMesh } from 'three-instanced-uniforms-mesh';\n * may not need geometry groups for shaders though\n * setGeometry<T extends BufferGeometry>(geometry: T) {\n * MeshBuilder.bachedMesh = new BatchedMesh(10, 5000, 10000, material);\n * }\n */\n\nexport type MeshBuilderOptions = Partial<Pick<GameEntityOptions, 'batched' | 'material'>>;\n\nexport class MeshBuilder {\n\n\t_build(meshOptions: MeshBuilderOptions, geometry: BufferGeometry, materials: Material[]): Mesh {\n\t\tconst { batched, material } = meshOptions;\n\t\tif (batched) {\n\t\t\tconsole.warn('warning: mesh batching is not implemented');\n\t\t}\n\t\tconst mesh = new Mesh(geometry, materials.at(-1));\n\t\tmesh.position.set(0, 0, 0);\n\t\tmesh.castShadow = true;\n\t\tmesh.receiveShadow = true;\n\t\treturn mesh;\n\t}\n\n\t_postBuild(): void {\n\t\treturn;\n\t}\n}","export function sortedStringify(obj: Record<string, any>) {\n\tconst sortedObj = Object.keys(obj)\n\t\t.sort()\n\t\t.reduce((acc: Record<string, any>, key: string) => {\n\t\t\tacc[key] = obj[key];\n\t\t\treturn acc;\n\t\t}, {} as Record<string, any>);\n\n\treturn JSON.stringify(sortedObj);\n}\n\nexport function shortHash(objString: string) {\n\tlet hash = 0;\n\tfor (let i = 0; i < objString.length; i++) {\n\t\thash = Math.imul(31, hash) + objString.charCodeAt(i) | 0;\n\t}\n\treturn hash.toString(36);\n}","import { Color, Material, Vector2, Vector3 } from 'three';\nimport {\n\tMeshPhongMaterial,\n\tMeshStandardMaterial,\n\tRepeatWrapping,\n\tShaderMaterial,\n} from 'three';\nimport {\n\tMeshBasicNodeMaterial,\n\tMeshStandardNodeMaterial,\n} from 'three/webgpu';\nimport { shortHash, sortedStringify } from '../core/utility/strings';\nimport { standardShader } from './shaders/standard.shader';\nimport { assetManager } from '../core/asset-manager';\n\n/**\n * GLSL shader object (traditional approach for WebGL)\n */\nexport type ZylemShaderObject = { fragment: string; vertex: string };\n\n/**\n * TSL shader type (for WebGPU)\n * colorNode should be a TSL node that returns the fragment color\n */\nexport type ZylemTSLShader = {\n\tcolorNode: any; // TSL node - use any since Three.js types are still evolving\n\ttransparent?: boolean;\n};\n\n/**\n * Combined shader type supporting both GLSL and TSL\n */\nexport type ZylemShader = ZylemShaderObject | ZylemTSLShader;\n\n/**\n * Check if a shader is a TSL shader\n */\nexport function isTSLShader(shader: ZylemShader): shader is ZylemTSLShader {\n\treturn 'colorNode' in shader;\n}\n\n/**\n * Check if a shader is a GLSL shader\n */\nexport function isGLSLShader(shader: ZylemShader): shader is ZylemShaderObject {\n\treturn 'fragment' in shader && 'vertex' in shader;\n}\n\nexport interface MaterialOptions {\n\tpath?: string;\n\tnormalMap?: string;\n\trepeat?: Vector2;\n\tshader?: ZylemShader;\n\tcolor?: Color;\n\t/** Opacity from 0 (fully transparent) to 1 (fully opaque). */\n\topacity?: number;\n\t/**\n\t * When true, prefer TSL/NodeMaterial (for WebGPU)\n\t * When false, prefer GLSL/ShaderMaterial (for WebGL)\n\t */\n\tuseTSL?: boolean;\n}\n\ntype BatchGeometryMap = Map<symbol, number>;\n\ninterface BatchMaterialMapObject {\n\tgeometryMap: BatchGeometryMap;\n\tmaterial: Material;\n}\n\ntype BatchKey = ReturnType<typeof shortHash>;\n\nexport type TexturePath = string | null;\n\ntype OpacityCapableMaterial = Material & {\n\topacity: number;\n\ttransparent: boolean;\n\tneedsUpdate: boolean;\n};\n\nexport class MaterialBuilder {\n\tstatic batchMaterialMap: Map<BatchKey, BatchMaterialMapObject> = new Map();\n\n\t/**\n\t * Clear the static batch material cache.\n\t * Should be called during game disposal to prevent stale material references\n\t * from persisting across demo/stage switches.\n\t */\n\tstatic clearBatchCache(): void {\n\t\tMaterialBuilder.batchMaterialMap.clear();\n\t}\n\n\tmaterials: Material[] = [];\n\n\t/** Whether to use TSL/NodeMaterial (for WebGPU compatibility) */\n\tprivate useTSL: boolean;\n\n\tconstructor(useTSL: boolean = false) {\n\t\tthis.useTSL = useTSL;\n\t}\n\n\tbatchMaterial(options: Partial<MaterialOptions>, entityType: symbol) {\n\t\tconst batchKey = shortHash(sortedStringify(options));\n\t\tconst mappedObject = MaterialBuilder.batchMaterialMap.get(batchKey);\n\t\tif (mappedObject) {\n\t\t\tconst count = mappedObject.geometryMap.get(entityType);\n\t\t\tif (count) {\n\t\t\t\tmappedObject.geometryMap.set(entityType, count + 1);\n\t\t\t} else {\n\t\t\t\tmappedObject.geometryMap.set(entityType, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tMaterialBuilder.batchMaterialMap.set(batchKey, {\n\t\t\t\tgeometryMap: new Map([[entityType, 1]]),\n\t\t\t\tmaterial: this.materials[0],\n\t\t\t});\n\t\t}\n\t}\n\n\tbuild(options: Partial<MaterialOptions>, entityType: symbol): void {\n\t\tconst { path, normalMap, repeat, color, shader, opacity, useTSL } = options;\n\t\t\n\t\t// Override TSL preference if specified in options\n\t\tconst shouldUseTSL = useTSL ?? this.useTSL;\n\n\t\t// If shader is provided, use it\n\t\tif (shader) {\n\t\t\tif (isTSLShader(shader)) {\n\t\t\t\t// TSL shader provided directly\n\t\t\t\tthis.setTSLShader(shader, opacity);\n\t\t\t} else if (isGLSLShader(shader)) {\n\t\t\t\t// GLSL shader provided\n\t\t\t\tif (shouldUseTSL) {\n\t\t\t\t\tconsole.warn('MaterialBuilder: GLSL shader provided but TSL mode requested. Using GLSL.');\n\t\t\t\t}\n\t\t\t\tthis.setShader(shader, opacity);\n\t\t\t}\n\t\t} else if (path) {\n\t\t\t// Texture path provided\n\t\t\tthis.setTexture(path, repeat, shouldUseTSL, opacity);\n\t\t}\n\n\t\tif (color) {\n\t\t\tthis.withColor(color, shouldUseTSL, opacity);\n\t\t}\n\n\t\tif (this.materials.length === 0) {\n\t\t\tthis.setColor(new Color('#ffffff'), shouldUseTSL, opacity);\n\t\t}\n\n\t\t// Apply normal map if present (to the last added material)\n\t\tif (normalMap && this.materials.length > 0) {\n\t\t\tthis.setNormalMap(normalMap, repeat);\n\t\t}\n\n\t\tthis.batchMaterial(options, entityType);\n\t}\n\n\twithColor(color: Color, useTSL: boolean = false, opacity?: number): this {\n\t\tthis.setColor(color, useTSL, opacity);\n\t\treturn this;\n\t}\n\n\twithShader(shader: ZylemShaderObject, opacity?: number): this {\n\t\tthis.setShader(shader, opacity);\n\t\treturn this;\n\t}\n\n\twithTSLShader(shader: ZylemTSLShader, opacity?: number): this {\n\t\tthis.setTSLShader(shader, opacity);\n\t\treturn this;\n\t}\n\n\tprivate applyOpacity(material: OpacityCapableMaterial, opacity?: number, forceTransparent: boolean = false): void {\n\t\tif (opacity !== undefined) {\n\t\t\tmaterial.opacity = opacity;\n\t\t}\n\t\tmaterial.transparent = forceTransparent || opacity !== undefined && opacity < 1;\n\t\tmaterial.needsUpdate = true;\n\t}\n\n\t/**\n\t * Set texture - loads in background (deferred).\n\t * Material is created immediately with null map, texture applies when loaded.\n\t */\n\tsetTexture(\n\t\ttexturePath: TexturePath = null,\n\t\trepeat: Vector2 = new Vector2(1, 1),\n\t\tuseTSL: boolean = false,\n\t\topacity?: number,\n\t): void {\n\t\tif (!texturePath) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (useTSL) {\n\t\t\t// For TSL/WebGPU, use NodeMaterial\n\t\t\tconst material = new MeshStandardNodeMaterial();\n\t\t\tthis.applyOpacity(material as OpacityCapableMaterial, opacity);\n\t\t\tthis.materials.push(material);\n\n\t\t\t// Load texture in background and apply when ready\n\t\t\tassetManager.loadTexture(texturePath as string, {\n\t\t\t\tclone: true,\n\t\t\t\trepeat,\n\t\t\t}).then((texture) => {\n\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\tmaterial.map = texture;\n\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t});\n\t\t} else {\n\t\t\t// For WebGL, use traditional material\n\t\t\tconst material = new MeshPhongMaterial({\n\t\t\t\tmap: null,\n\t\t\t\topacity: opacity ?? 1,\n\t\t\t\ttransparent: opacity !== undefined && opacity < 1,\n\t\t\t});\n\t\t\tthis.materials.push(material);\n\n\t\t\t// Load texture in background and apply when ready\n\t\t\tassetManager\n\t\t\t\t.loadTexture(texturePath as string, {\n\t\t\t\t\tclone: true,\n\t\t\t\t\trepeat,\n\t\t\t\t})\n\t\t\t\t.then((texture) => {\n\t\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\t\tmaterial.map = texture;\n\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Set normal map for the current material\n\t */\n\tsetNormalMap(normalMapPath: string, repeat: Vector2 = new Vector2(1, 1)): void {\n\t\tconst material = this.materials[this.materials.length - 1];\n\t\tif (!material) return;\n\n\t\tassetManager\n\t\t\t.loadTexture(normalMapPath, {\n\t\t\t\tclone: true,\n\t\t\t\trepeat,\n\t\t\t})\n\t\t\t.then((texture) => {\n\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\t\n\t\t\t\tif (material instanceof MeshStandardMaterial \n\t\t\t\t\t|| material instanceof MeshPhongMaterial\n\t\t\t\t\t|| material instanceof MeshStandardNodeMaterial) {\n\t\t\t\t\tmaterial.normalMap = texture;\n\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t} else if (material instanceof ShaderMaterial) {\n\t\t\t\t\t// Support for custom shaders if they have tNormal or normalMap uniform\n\t\t\t\t\tif (material.uniforms.tNormal) {\n\t\t\t\t\t\tmaterial.uniforms.tNormal.value = texture;\n\t\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (material.uniforms.normalMap) {\n\t\t\t\t\t\tmaterial.uniforms.normalMap.value = texture;\n\t\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\tsetColor(color: Color, useTSL: boolean = false, opacity?: number) {\n\t\tif (useTSL) {\n\t\t\t// TSL/WebGPU compatible material\n\t\t\tconst material = new MeshStandardNodeMaterial();\n\t\t\tmaterial.color = color;\n\t\t\tthis.applyOpacity(material as OpacityCapableMaterial, opacity);\n\t\t\tthis.materials.push(material);\n\t\t} else {\n\t\t\t// WebGL compatible material\n\t\t\tconst material = new MeshStandardMaterial({\n\t\t\t\tcolor: color,\n\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\tfog: true,\n\t\t\t\topacity: opacity ?? 1,\n\t\t\t\ttransparent: opacity !== undefined && opacity < 1,\n\t\t\t});\n\t\t\tthis.materials.push(material);\n\t\t}\n\t}\n\n\t/**\n\t * Set GLSL shader (WebGL only)\n\t */\n\tsetShader(customShader: ZylemShaderObject, opacity?: number) {\n\t\tconst { fragment, vertex } = customShader ?? standardShader;\n\n\t\tconst shader = new ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiResolution: { value: new Vector3(1, 1, 1) },\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null },\n\t\t\t\tnormalMap: { value: null },\n\t\t\t\tlightDir: { value: new Vector3(1, 1, 1) },\n\t\t\t\tnormalStrength: { value: 1.0 },\n\t\t\t},\n\t\t\tvertexShader: vertex,\n\t\t\tfragmentShader: fragment,\n\t\t\ttransparent: true,\n\t\t\topacity: opacity ?? 1,\n\t\t});\n\t\tthis.materials.push(shader);\n\t}\n\n\t/**\n\t * Set TSL shader (WebGPU compatible)\n\t */\n\tsetTSLShader(tslShader: ZylemTSLShader, opacity?: number) {\n\t\tconst material = new MeshBasicNodeMaterial();\n\t\tmaterial.colorNode = tslShader.colorNode;\n\t\tthis.applyOpacity(\n\t\t\tmaterial as OpacityCapableMaterial,\n\t\t\topacity,\n\t\t\ttslShader.transparent,\n\t\t);\n\t\tthis.materials.push(material);\n\t}\n}\n\n// Re-export TSL utilities for shader authoring\nexport {\n\tuniform,\n\tuv,\n\ttime,\n\tvec3,\n\tvec4,\n\tfloat,\n\tFn,\n} from 'three/tsl';\n","import { ColliderDesc } from \"@dimforge/rapier3d-compat\";\nimport { GameEntity, GameEntityOptions } from \"./entity\";\nimport { BufferGeometry, Group, Material, Mesh, Color } from \"three\";\nimport { CollisionBuilder } from \"../collision/collision-builder\";\nimport { MeshBuilder } from \"../graphics/mesh\";\nimport { MaterialBuilder, MaterialOptions } from \"../graphics/material\";\nimport { Vec3 } from \"../core/vector\";\n\nexport abstract class EntityCollisionBuilder extends CollisionBuilder {\n\tabstract collider(options: GameEntityOptions): ColliderDesc;\n}\n\nexport abstract class EntityMeshBuilder extends MeshBuilder {\n\tbuild(options: GameEntityOptions): BufferGeometry {\n\t\treturn new BufferGeometry();\n\t}\n\n\tpostBuild(): void {\n\t\treturn;\n\t}\n}\n\nexport abstract class EntityBuilder<T extends GameEntity<U> & P, U extends GameEntityOptions, P = any> {\n\tprotected meshBuilder: EntityMeshBuilder | null;\n\tprotected collisionBuilder: EntityCollisionBuilder | null;\n\tprotected materialBuilder: MaterialBuilder | null;\n\tprotected options: Partial<U>;\n\tprotected entity: T;\n\n\tconstructor(\n\t\toptions: Partial<U>,\n\t\tentity: T,\n\t\tmeshBuilder: EntityMeshBuilder | null,\n\t\tcollisionBuilder: EntityCollisionBuilder | null,\n\t) {\n\t\tthis.options = options;\n\t\tthis.entity = entity;\n\t\tthis.meshBuilder = meshBuilder;\n\t\tthis.collisionBuilder = collisionBuilder;\n\t\tthis.materialBuilder = new MaterialBuilder();\n\t\tconst builders: NonNullable<GameEntityOptions[\"_builders\"]> = {\n\t\t\tmeshBuilder: this.meshBuilder,\n\t\t\tcollisionBuilder: this.collisionBuilder,\n\t\t\tmaterialBuilder: this.materialBuilder,\n\t\t};\n\t\t(this.options as Partial<GameEntityOptions>)._builders = builders;\n\t}\n\n\twithPosition(setupPosition: Vec3): this {\n\t\tthis.options.position = setupPosition;\n\t\treturn this;\n\t}\n\n\twithMaterial(options: Partial<MaterialOptions>, entityType: symbol): this {\n\t\tif (this.materialBuilder) {\n\t\t\tthis.materialBuilder.build(options, entityType);\n\t\t}\n\t\treturn this;\n\t}\n\n\tapplyMaterialToGroup(group: Group, materials: Material[]): void {\n\t\tgroup.traverse((child) => {\n\t\t\tif (child instanceof Mesh) {\n\t\t\t\tif (child.type === 'SkinnedMesh' && materials[0] && !child.material.map) {\n\t\t\t\t\tchild.material = materials[0];\n\t\t\t\t}\n\t\t\t}\n\t\t\tchild.castShadow = true;\n\t\t\tchild.receiveShadow = true;\n\t\t});\n\t}\n\n\tbuild(): T {\n\t\tconst entity = this.entity;\n\t\tif (this.materialBuilder) {\n\t\t\tentity.materials = this.materialBuilder.materials;\n\t\t}\n\t\tif (this.meshBuilder && entity.materials) {\n\t\t\tconst geometry = this.meshBuilder.build(this.options);\n\t\t\tentity.mesh = this.meshBuilder._build(this.options, geometry, entity.materials);\n\t\t\tthis.meshBuilder.postBuild();\n\t\t}\n\n\t\tif (entity.group && entity.materials) {\n\t\t\tthis.applyMaterialToGroup(entity.group, entity.materials);\n\t\t}\n\n\t\tif (this.collisionBuilder) {\n\t\t\tthis.collisionBuilder.withCollision(this.options?.collision || {});\n\t\t\tconst [bodyDesc, colliderDesc] = this.collisionBuilder.build(this.options as any);\n\t\t\tentity.bodyDesc = bodyDesc;\n\t\t\tentity.colliderDesc = colliderDesc;\n\t\t\tentity.colliderDescs.push(colliderDesc);\n\n\t\t\tconst { x, y, z } = this.options.position || { x: 0, y: 0, z: 0 };\n\t\t\tentity.bodyDesc.setTranslation(x, y, z);\n\t\t}\n\t\tif (this.options.collisionType) {\n\t\t\tentity.collisionType = this.options.collisionType;\n\t\t}\n\n\t\tif (this.options.color instanceof Color) {\n\t\t\tconst applyColor = (material: Material) => {\n\t\t\t\tconst anyMat = material as any;\n\t\t\t\tif (anyMat && anyMat.color && anyMat.color.set) {\n\t\t\t\t\tanyMat.color.set(this.options.color as Color);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (entity.materials?.length) {\n\t\t\t\tfor (const mat of entity.materials) applyColor(mat);\n\t\t\t}\n\t\t\tif (entity.mesh && entity.mesh.material) {\n\t\t\t\tconst mat = entity.mesh.material as any;\n\t\t\t\tif (Array.isArray(mat)) mat.forEach(applyColor); else applyColor(mat);\n\t\t\t}\n\t\t\tif (entity.group) {\n\t\t\t\tentity.group.traverse((child) => {\n\t\t\t\t\tif (child instanceof Mesh && child.material) {\n\t\t\t\t\t\tconst mat = child.material as any;\n\t\t\t\t\t\tif (Array.isArray(mat)) mat.forEach(applyColor); else applyColor(mat);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn entity;\n\t}\n\n\tprotected abstract createEntity(options: Partial<U>): T;\n}\n","import { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport {\n\tBox3,\n\tBufferAttribute,\n\tObject3D,\n\tSkinnedMesh,\n\tMesh,\n\tMeshStandardMaterial,\n\tGroup,\n\tVector3,\n\tMaterial,\n\tMatrix4,\n} from 'three';\n\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { createEntity } from './create';\nimport {\n\tCleanupContext,\n\tUpdateContext,\n\tUpdateFunction,\n} from '../core/base-node-life-cycle';\nimport { AssetLoaderResult, EntityAssetLoader } from '../core/entity-asset-loader';\nimport { EntityLoaderDelegate } from './delegates/loader';\nimport { Vec3 } from '../core/vector';\nimport { AnimationDelegate, AnimationOptions } from './delegates/animation';\nimport { MaterialOptions } from '../graphics/material';\nimport { DebugInfoProvider } from './delegates/debug';\nimport { EntityBuilder, EntityCollisionBuilder } from './builder';\nimport { commonDefaults } from './common';\nimport { standardShader } from '../graphics/shaders/standard.shader';\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport type CollisionShapeType = 'capsule' | 'bounds' | 'trimesh' | 'model';\ntype ResolvedCollisionShape = 'capsule' | 'bounds' | 'trimesh';\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n\tcollisionShape?: CollisionShapeType;\n};\n\ntype TransparentMaterial = Material & {\n\topacity: number;\n\ttransparent: boolean;\n\tneedsUpdate: boolean;\n};\n\ntype TrimeshMetadata = {\n\tshape: 'trimesh';\n\tvertices: number[];\n\tindices: number[];\n};\n\ntype ModelBounds = {\n\tsize: Vector3;\n\tcenter: Vector3;\n};\n\ntype ModelTrimesh = {\n\tvertices: Float32Array;\n\tindices: Uint32Array;\n\tcenter: Vector3;\n};\n\ntype CollisionSourceSelection = {\n\tfile: string | null;\n\treuseVisibleModel: boolean;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\t...commonDefaults,\n\tmaterial: {\n\t\tshader: standardShader,\n\t},\n\tanimations: [],\n\tmodels: [],\n\tcollisionShape: 'capsule',\n};\n\nfunction getActorScale(options: ZylemActorOptions): Vector3 {\n\treturn new Vector3(\n\t\toptions.scale?.x ?? 1,\n\t\toptions.scale?.y ?? 1,\n\t\toptions.scale?.z ?? 1,\n\t);\n}\n\nfunction getCollisionPosition(\n\toptions: ZylemActorOptions,\n): { x: number; y: number; z: number } | null {\n\tconst position = options.collision?.position;\n\tif (!position) {\n\t\treturn null;\n\t}\n\treturn {\n\t\tx: position.x ?? 0,\n\t\ty: position.y ?? 0,\n\t\tz: position.z ?? 0,\n\t};\n}\n\nfunction hasExplicitCollisionSize(options: ZylemActorOptions): boolean {\n\treturn Boolean(options.collision?.size);\n}\n\nfunction warnDynamicTrimeshOnce(actor: ZylemActor): void {\n\tif (actor.hasWarnedDynamicTrimesh) {\n\t\treturn;\n\t}\n\tactor.hasWarnedDynamicTrimesh = true;\n\tconsole.warn(\n\t\t`Actor \"${actor.name || actor.uuid}\" requested collisionShape=\"trimesh\" on a dynamic body; falling back to bounds.`,\n\t);\n}\n\nfunction resolveCollisionShape(\n\tshape: CollisionShapeType | undefined,\n\tisStatic: boolean,\n\tonDynamicTrimesh?: () => void,\n): ResolvedCollisionShape {\n\tconst normalized = shape === 'model' ? 'bounds' : (shape ?? 'capsule');\n\tif (normalized === 'trimesh' && !isStatic) {\n\t\tonDynamicTrimesh?.();\n\t\treturn 'bounds';\n\t}\n\treturn normalized;\n}\n\nfunction tagTrimeshCollider(\n\tcolliderDesc: ColliderDesc,\n\tvertices: Float32Array,\n\tindices: Uint32Array,\n): ColliderDesc {\n\t(colliderDesc as any).__zylemShapeData = {\n\t\tshape: 'trimesh',\n\t\tvertices: Array.from(vertices),\n\t\tindices: Array.from(indices),\n\t} as TrimeshMetadata;\n\treturn colliderDesc;\n}\n\nfunction createCapsuleColliderFromDimensions(\n\tsize: { x: number; y: number; z: number },\n\ttranslation: { x: number; y: number; z: number },\n): ColliderDesc {\n\tconst fullWidth = size.x || 0.5;\n\tconst fullHeight = size.y || 1;\n\tconst fullDepth = size.z || 0.5;\n\tconst radius = Math.max(fullWidth, fullDepth) / 2;\n\tconst halfTotalHeight = fullHeight / 2;\n\tconst halfCylinder = Math.max(0, halfTotalHeight - radius);\n\tconst colliderDesc = ColliderDesc.capsule(halfCylinder, radius);\n\tcolliderDesc.setSensor(false);\n\tcolliderDesc.setTranslation(translation.x, translation.y, translation.z);\n\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\treturn colliderDesc;\n}\n\nfunction createCapsuleCollider(options: ZylemActorOptions): ColliderDesc {\n\tconst size = options.collision?.size ?? options.size ?? { x: 0.5, y: 1, z: 0.5 };\n\tconst fullHeight = (size as any).y || 1;\n\tconst collisionPosition = getCollisionPosition(options);\n\n\treturn createCapsuleColliderFromDimensions(\n\t\t{\n\t\t\tx: (size as any).x || 0.5,\n\t\t\ty: fullHeight,\n\t\t\tz: (size as any).z || 0.5,\n\t\t},\n\t\tcollisionPosition ?? { x: 0, y: fullHeight / 2, z: 0 },\n\t);\n}\n\nfunction createExplicitBoxCollider(options: ZylemActorOptions): ColliderDesc | null {\n\tconst collisionSize = options.collision?.size;\n\tif (!collisionSize) {\n\t\treturn null;\n\t}\n\n\tconst halfWidth = (collisionSize as any).x / 2;\n\tconst halfHeight = (collisionSize as any).y / 2;\n\tconst halfDepth = (collisionSize as any).z / 2;\n\tconst colliderDesc = ColliderDesc.cuboid(halfWidth, halfHeight, halfDepth);\n\tconst collisionPosition = getCollisionPosition(options);\n\n\tcolliderDesc.setSensor(false);\n\tcolliderDesc.setTranslation(\n\t\tcollisionPosition?.x ?? 0,\n\t\tcollisionPosition?.y ?? halfHeight,\n\t\tcollisionPosition?.z ?? 0,\n\t);\n\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\treturn colliderDesc;\n}\n\nfunction computeActorSpaceMatrix(\n\tchild: Object3D,\n\tactorRoot: Object3D,\n\tactorScale: Vector3,\n): Matrix4 {\n\tconst actorRootInverse = actorRoot.matrixWorld.clone().invert();\n\tconst actorSpaceMatrix = actorRootInverse.multiply(child.matrixWorld);\n\treturn new Matrix4()\n\t\t.makeScale(actorScale.x, actorScale.y, actorScale.z)\n\t\t.multiply(actorSpaceMatrix);\n}\n\nfunction computeModelBounds(\n\tmodelRoot: Object3D,\n\tactorRoot: Object3D,\n\tactorScale: Vector3,\n): ModelBounds | null {\n\tmodelRoot.updateMatrixWorld(true);\n\n\tlet foundMesh = false;\n\tconst aggregated = new Box3();\n\tmodelRoot.traverse((child) => {\n\t\tif (!(child as any).isMesh) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mesh = child as Mesh;\n\t\tconst geometry = mesh.geometry;\n\t\tif (!geometry) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet localBounds: Box3 | null = null;\n\t\tif (mesh instanceof SkinnedMesh) {\n\t\t\tmesh.computeBoundingBox();\n\t\t\tlocalBounds = mesh.boundingBox?.clone() ?? null;\n\t\t} else {\n\t\t\tgeometry.computeBoundingBox();\n\t\t\tlocalBounds = geometry.boundingBox?.clone() ?? null;\n\t\t}\n\n\t\tif (!localBounds) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst transformedBounds = localBounds\n\t\t\t.applyMatrix4(computeActorSpaceMatrix(mesh, actorRoot, actorScale));\n\n\t\tif (!foundMesh) {\n\t\t\taggregated.copy(transformedBounds);\n\t\t\tfoundMesh = true;\n\t\t\treturn;\n\t\t}\n\n\t\taggregated.union(transformedBounds);\n\t});\n\n\tif (!foundMesh || aggregated.isEmpty()) {\n\t\treturn null;\n\t}\n\n\tconst size = new Vector3();\n\tconst center = new Vector3();\n\taggregated.getSize(size);\n\taggregated.getCenter(center);\n\treturn { size, center };\n}\n\nfunction computeModelTrimesh(\n\tmodelRoot: Object3D,\n\tactorRoot: Object3D,\n\tactorScale: Vector3,\n): ModelTrimesh | null {\n\tmodelRoot.updateMatrixWorld(true);\n\n\tconst vertices: number[] = [];\n\tconst indices: number[] = [];\n\tconst bounds = new Box3();\n\tconst point = new Vector3();\n\tlet foundMesh = false;\n\n\tmodelRoot.traverse((child) => {\n\t\tif (!(child as any).isMesh) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mesh = child as Mesh;\n\t\tconst geometry = mesh.geometry;\n\t\tif (!geometry) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = geometry.getAttribute('position');\n\t\tif (!(position instanceof BufferAttribute)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst transform = computeActorSpaceMatrix(mesh, actorRoot, actorScale);\n\t\tconst vertexOffset = vertices.length / 3;\n\n\t\tfor (let i = 0; i < position.count; i++) {\n\t\t\tpoint.set(position.getX(i), position.getY(i), position.getZ(i));\n\t\t\tpoint.applyMatrix4(transform);\n\t\t\tvertices.push(point.x, point.y, point.z);\n\t\t\tbounds.expandByPoint(point);\n\t\t}\n\n\t\tconst index = geometry.getIndex();\n\t\tif (index) {\n\t\t\tfor (let i = 0; i < index.count; i++) {\n\t\t\t\tindices.push(vertexOffset + index.getX(i));\n\t\t\t}\n\t\t} else {\n\t\t\tfor (let i = 0; i < position.count; i++) {\n\t\t\t\tindices.push(vertexOffset + i);\n\t\t\t}\n\t\t}\n\n\t\tfoundMesh = true;\n\t});\n\n\tif (!foundMesh || vertices.length === 0 || indices.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst center = new Vector3();\n\tbounds.getCenter(center);\n\n\treturn {\n\t\tvertices: new Float32Array(vertices),\n\t\tindices: new Uint32Array(indices),\n\t\tcenter,\n\t};\n}\n\nfunction createBoundsColliderFromModel(\n\tmodelRoot: Object3D | null,\n\tactorRoot: Object3D | null,\n\toptions: ZylemActorOptions,\n): ColliderDesc {\n\tconst explicitCollider = createExplicitBoxCollider(options);\n\tif (explicitCollider) {\n\t\treturn explicitCollider;\n\t}\n\n\tif (!modelRoot || !actorRoot) {\n\t\treturn createCapsuleCollider(options);\n\t}\n\n\tconst bounds = computeModelBounds(modelRoot, actorRoot, getActorScale(options));\n\tif (!bounds) {\n\t\treturn createCapsuleCollider(options);\n\t}\n\n\tconst colliderDesc = ColliderDesc.cuboid(\n\t\tbounds.size.x / 2,\n\t\tbounds.size.y / 2,\n\t\tbounds.size.z / 2,\n\t);\n\tconst collisionPosition = getCollisionPosition(options);\n\tcolliderDesc.setSensor(false);\n\tcolliderDesc.setTranslation(\n\t\tcollisionPosition?.x ?? bounds.center.x,\n\t\tcollisionPosition?.y ?? bounds.center.y,\n\t\tcollisionPosition?.z ?? bounds.center.z,\n\t);\n\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\treturn colliderDesc;\n}\n\nfunction createCapsuleColliderFromModel(\n\tsizingRoot: Object3D | null,\n\tsizingActorRoot: Object3D | null,\n\talignmentRoot: Object3D | null,\n\talignmentActorRoot: Object3D | null,\n\toptions: ZylemActorOptions,\n): ColliderDesc {\n\tif (hasExplicitCollisionSize(options)) {\n\t\treturn createCapsuleCollider(options);\n\t}\n\n\tif (!sizingRoot || !sizingActorRoot) {\n\t\treturn createCapsuleCollider(options);\n\t}\n\n\tconst sizingBounds = computeModelBounds(\n\t\tsizingRoot,\n\t\tsizingActorRoot,\n\t\tgetActorScale(options),\n\t);\n\tif (!sizingBounds) {\n\t\treturn createCapsuleCollider(options);\n\t}\n\n\tconst collisionPosition = getCollisionPosition(options);\n\tlet translation = collisionPosition;\n\tif (!translation) {\n\t\tconst alignmentBounds = alignmentRoot && alignmentActorRoot\n\t\t\t? computeModelBounds(alignmentRoot, alignmentActorRoot, getActorScale(options))\n\t\t\t: null;\n\t\ttranslation = alignmentBounds\n\t\t\t? {\n\t\t\t\tx: alignmentBounds.center.x,\n\t\t\t\ty: alignmentBounds.center.y,\n\t\t\t\tz: alignmentBounds.center.z,\n\t\t\t}\n\t\t\t: {\n\t\t\t\tx: sizingBounds.center.x,\n\t\t\t\ty: sizingBounds.center.y,\n\t\t\t\tz: sizingBounds.center.z,\n\t\t\t};\n\t}\n\n\treturn createCapsuleColliderFromDimensions(\n\t\t{\n\t\t\tx: sizingBounds.size.x,\n\t\t\ty: sizingBounds.size.y,\n\t\t\tz: sizingBounds.size.z,\n\t\t},\n\t\ttranslation,\n\t);\n}\n\nfunction createTrimeshColliderFromModel(\n\tmodelRoot: Object3D | null,\n\tactorRoot: Object3D | null,\n\toptions: ZylemActorOptions,\n): ColliderDesc {\n\tconst explicitCollider = createExplicitBoxCollider(options);\n\tif (explicitCollider) {\n\t\treturn explicitCollider;\n\t}\n\n\tif (!modelRoot || !actorRoot) {\n\t\treturn createCapsuleCollider(options);\n\t}\n\n\tconst trimesh = computeModelTrimesh(modelRoot, actorRoot, getActorScale(options));\n\tif (!trimesh) {\n\t\treturn createCapsuleCollider(options);\n\t}\n\n\tconst colliderDesc = tagTrimeshCollider(\n\t\tColliderDesc.trimesh(trimesh.vertices, trimesh.indices),\n\t\ttrimesh.vertices,\n\t\ttrimesh.indices,\n\t);\n\tconst collisionPosition = getCollisionPosition(options);\n\tif (collisionPosition) {\n\t\tcolliderDesc.setTranslation(\n\t\t\tcollisionPosition.x - trimesh.center.x,\n\t\t\tcollisionPosition.y - trimesh.center.y,\n\t\t\tcollisionPosition.z - trimesh.center.z,\n\t\t);\n\t}\n\tcolliderDesc.setSensor(false);\n\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\treturn colliderDesc;\n}\n\nfunction disposeObjectResources(object: Object3D | null): void {\n\tif (!object) {\n\t\treturn;\n\t}\n\n\tobject.traverse((child) => {\n\t\tif (!(child as any).isMesh) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst mesh = child as SkinnedMesh;\n\t\tmesh.geometry?.dispose();\n\t\tif (Array.isArray(mesh.material)) {\n\t\t\tmesh.material.forEach((material) => material.dispose());\n\t\t} else {\n\t\t\tmesh.material?.dispose();\n\t\t}\n\t});\n}\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate objectModel: Object3D | null = null;\n\tprivate collisionSource: Object3D | null = null;\n\tprivate collisionShape: CollisionShapeType = 'capsule';\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t\tthis.collisionSource = data.collisionSource ?? data.objectModel ?? null;\n\t\tthis.collisionShape = data.collisionShape ?? 'capsule';\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tconst resolvedShape = resolveCollisionShape(\n\t\t\tthis.collisionShape,\n\t\t\tBoolean(options.collision?.static),\n\t\t);\n\n\t\tif (resolvedShape === 'bounds') {\n\t\t\treturn createBoundsColliderFromModel(this.objectModel, this.objectModel, options);\n\t\t}\n\n\t\tif (resolvedShape === 'trimesh') {\n\t\t\treturn createTrimeshColliderFromModel(this.objectModel, this.objectModel, options);\n\t\t}\n\n\t\treturn createCapsuleColliderFromModel(\n\t\t\tthis.collisionSource,\n\t\t\tthis.collisionSource,\n\t\t\tthis.objectModel,\n\t\t\tthis.objectModel,\n\t\t\toptions,\n\t\t);\n\t}\n}\n\nclass ActorBuilder extends EntityBuilder<ZylemActor, ZylemActorOptions> {\n\tprotected createEntity(options: Partial<ZylemActorOptions>): ZylemActor {\n\t\treturn new ZylemActor(options);\n\t}\n}\n\nexport const ACTOR_TYPE = Symbol('Actor');\n\nexport class ZylemActor extends GameEntity<ZylemActorOptions> implements EntityLoaderDelegate, DebugInfoProvider {\n\tstatic type = ACTOR_TYPE;\n\n\tprivate _object: Object3D | null = null;\n\tprivate _collisionSource: Object3D | null = null;\n\tprivate _animationDelegate: AnimationDelegate | null = null;\n\tprivate _modelFileNames: string[] = [];\n\tprivate _assetLoader: EntityAssetLoader = new EntityAssetLoader();\n\tprivate _loadGeneration = 0;\n\tprivate _loadStatus: 'idle' | 'loading' | 'loaded' = 'idle';\n\n\tcontrolledRotation: boolean = false;\n\thasWarnedDynamicTrimesh = false;\n\n\tconstructor(options?: ZylemActorOptions) {\n\t\tsuper();\n\t\tthis.options = { ...actorDefaults, ...options };\n\t\tthis.prependUpdate(this.actorUpdate.bind(this) as UpdateFunction<this>);\n\t\tthis.controlledRotation = true;\n\t}\n\n\toverride create(): this {\n\t\tif (this._loadStatus === 'idle' && (this.options.models?.length ?? 0) > 0) {\n\t\t\tthis.load();\n\t\t}\n\t\treturn super.create();\n\t}\n\n\tload(): void {\n\t\tif (this._loadStatus === 'loading' || this._loadStatus === 'loaded') {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._modelFileNames = [...(this.options.models || [])];\n\t\tif (this._modelFileNames.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.disposeRuntimeState(true);\n\t\tthis._loadStatus = 'loading';\n\t\tthis.loadModelsDeferred(++this._loadGeneration);\n\t}\n\n\tdata(): any {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t\tcollisionSource: this._collisionSource ?? this._object,\n\t\t\tcollisionShape: this.options.collisionShape,\n\t\t};\n\t}\n\n\tneedsDeferredModelCollision(): boolean {\n\t\tif (!this.requiresLoadedCollisionSource()) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn !this.getRuntimeCollisionSource();\n\t}\n\n\tsynchronizeRuntimeCollider(): void {\n\t\tconst resolvedShape = this.getResolvedCollisionShape();\n\t\tlet colliderDesc: ColliderDesc;\n\n\t\tif (resolvedShape === 'bounds') {\n\t\t\tcolliderDesc = createBoundsColliderFromModel(\n\t\t\t\tthis._object,\n\t\t\t\tthis.group ?? this._object,\n\t\t\t\tthis.options,\n\t\t\t);\n\t\t} else if (resolvedShape === 'trimesh') {\n\t\t\tcolliderDesc = createTrimeshColliderFromModel(\n\t\t\t\tthis._object,\n\t\t\t\tthis.group ?? this._object,\n\t\t\t\tthis.options,\n\t\t\t);\n\t\t} else {\n\t\t\tconst collisionSource = this.getRuntimeCollisionSource();\n\t\t\tcolliderDesc = createCapsuleColliderFromModel(\n\t\t\t\tcollisionSource,\n\t\t\t\tcollisionSource,\n\t\t\t\tthis._object,\n\t\t\t\tthis._object,\n\t\t\t\tthis.options,\n\t\t\t);\n\t\t}\n\n\t\tthis.colliderDesc = colliderDesc;\n\t\tif (this.colliderDescs.length > 0) {\n\t\t\tthis.colliderDescs[0] = colliderDesc;\n\t\t} else {\n\t\t\tthis.colliderDescs.push(colliderDesc);\n\t\t}\n\t}\n\n\tactorUpdate(params: UpdateContext<ZylemActorOptions>): void {\n\t\tthis._animationDelegate?.update(params.delta);\n\t}\n\n\tactorDestroy(): void {\n\t\tthis._loadGeneration += 1;\n\t\tthis._loadStatus = 'idle';\n\t\tthis.disposeRuntimeState(true);\n\t\tthis._modelFileNames = [];\n\t}\n\n\toverride _cleanup(params: CleanupContext<this>): void {\n\t\tsuper._cleanup(params);\n\t\tthis.actorDestroy();\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\tget collisionSource(): Object3D | null {\n\t\treturn this._collisionSource ?? this._object;\n\t}\n\n\tgetDebugInfo(): Record<string, any> {\n\t\tconst debugInfo: Record<string, any> = {\n\t\t\ttype: 'Actor',\n\t\t\tmodels: this._modelFileNames.length > 0 ? this._modelFileNames : 'none',\n\t\t\tmodelLoaded: !!this._object,\n\t\t\tscale: this.options.scale\n\t\t\t\t? `${this.options.scale.x}, ${this.options.scale.y}, ${this.options.scale.z}`\n\t\t\t\t: '1, 1, 1',\n\t\t\tcollisionShape: this.getResolvedCollisionShape(),\n\t\t};\n\n\t\tif (this._animationDelegate) {\n\t\t\tdebugInfo.currentAnimation = this._animationDelegate.currentAnimationKey || 'none';\n\t\t\tdebugInfo.animationsCount = this.options.animations?.length || 0;\n\t\t}\n\n\t\tif (this._object) {\n\t\t\tlet meshCount = 0;\n\t\t\tlet vertexCount = 0;\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif (!(child as any).isMesh) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmeshCount++;\n\t\t\t\tconst geometry = (child as SkinnedMesh).geometry;\n\t\t\t\tif (geometry?.attributes.position) {\n\t\t\t\t\tvertexCount += geometry.attributes.position.count;\n\t\t\t\t}\n\t\t\t});\n\t\t\tdebugInfo.meshCount = meshCount;\n\t\t\tdebugInfo.vertexCount = vertexCount;\n\t\t}\n\n\t\treturn debugInfo;\n\t}\n\n\tprivate getResolvedCollisionShape(): ResolvedCollisionShape {\n\t\treturn resolveCollisionShape(\n\t\t\tthis.options.collisionShape,\n\t\t\tBoolean(this.options.collision?.static),\n\t\t\t() => warnDynamicTrimeshOnce(this),\n\t\t);\n\t}\n\n\tprivate requiresLoadedCollisionSource(): boolean {\n\t\tconst resolvedShape = this.getResolvedCollisionShape();\n\t\tif (resolvedShape === 'bounds' || resolvedShape === 'trimesh') {\n\t\t\treturn !hasExplicitCollisionSize(this.options);\n\t\t}\n\t\tif (resolvedShape === 'capsule') {\n\t\t\treturn !hasExplicitCollisionSize(this.options)\n\t\t\t\t&& this.getCollisionSourceSelection().file !== null;\n\t\t}\n\t\treturn false;\n\t}\n\n\tprivate getRuntimeCollisionSource(): Object3D | null {\n\t\tconst resolvedShape = this.getResolvedCollisionShape();\n\t\tif (resolvedShape === 'bounds' || resolvedShape === 'trimesh') {\n\t\t\treturn this._object;\n\t\t}\n\t\treturn this._collisionSource ?? this._object;\n\t}\n\n\tprivate getCollisionSourceSelection(): CollisionSourceSelection {\n\t\tconst modelFile = this.options.models?.[0] ?? null;\n\t\tconst animationFile = this.options.animations?.[0]?.path ?? null;\n\n\t\tif (animationFile) {\n\t\t\treturn {\n\t\t\t\tfile: animationFile,\n\t\t\t\treuseVisibleModel: animationFile === modelFile,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tfile: modelFile,\n\t\t\treuseVisibleModel: true,\n\t\t};\n\t}\n\n\tprivate disposeRuntimeState(clearGroup: boolean): void {\n\t\tif (this._animationDelegate) {\n\t\t\tthis._animationDelegate.dispose();\n\t\t\tthis._animationDelegate = null;\n\t\t}\n\n\t\tconst collisionSource = this._collisionSource;\n\t\tdisposeObjectResources(this._object);\n\t\tif (collisionSource && collisionSource !== this._object) {\n\t\t\tdisposeObjectResources(collisionSource);\n\t\t}\n\n\t\tthis._object = null;\n\t\tthis._collisionSource = null;\n\n\t\tif (clearGroup && this.group) {\n\t\t\tthis.group.clear();\n\t\t\tthis.group = undefined;\n\t\t}\n\t}\n\n\tprivate loadModelsDeferred(loadGeneration: number): void {\n\t\tthis.dispatch('entity:model:loading', {\n\t\t\tentityId: this.uuid,\n\t\t\tfiles: this._modelFileNames,\n\t\t});\n\n\t\tconst collisionSourceSelection = this.getCollisionSourceSelection();\n\t\tconst promises = this._modelFileNames.map((file) =>\n\t\t\tthis._assetLoader.loadFile(file, { clone: true }),\n\t\t);\n\t\tconst collisionSourcePromise = collisionSourceSelection.file && !collisionSourceSelection.reuseVisibleModel\n\t\t\t? this._assetLoader.loadFile(collisionSourceSelection.file, { clone: true })\n\t\t\t: Promise.resolve<AssetLoaderResult | null>(null);\n\n\t\tPromise.all([Promise.all(promises), collisionSourcePromise])\n\t\t\t.then(([results, collisionSourceResult]) => {\n\t\t\t\tif (loadGeneration !== this._loadGeneration) {\n\t\t\t\t\tresults.forEach((result) => disposeObjectResources(result.object ?? null));\n\t\t\t\t\tif (collisionSourceResult?.object) {\n\t\t\t\t\t\tdisposeObjectResources(collisionSourceResult.object);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._object = results[0]?.object ?? null;\n\t\t\t\tthis._collisionSource = collisionSourceSelection.reuseVisibleModel\n\t\t\t\t\t? this._object\n\t\t\t\t\t: collisionSourceResult?.object ?? this._object;\n\t\t\t\tthis._loadStatus = this._object ? 'loaded' : 'idle';\n\n\t\t\t\tlet meshCount = 0;\n\t\t\t\tif (this._object) {\n\t\t\t\t\tthis._object.traverse((child) => {\n\t\t\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\t\t\tmeshCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.group = new Group();\n\t\t\t\t\tthis.group.add(this._object);\n\t\t\t\t\tthis.group.scale.copy(getActorScale(this.options));\n\n\t\t\t\t\tthis.applyMaterialOverrides();\n\n\t\t\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\t\t\tvoid this._animationDelegate.loadAnimations(this.options.animations || []).then(() => {\n\t\t\t\t\t\tif (loadGeneration !== this._loadGeneration) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.dispatch('entity:animation:loaded', {\n\t\t\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\t\t\tanimationCount: this.options.animations?.length || 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tthis.dispatch('entity:model:loaded', {\n\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\tsuccess: !!this._object,\n\t\t\t\t\tmeshCount,\n\t\t\t\t});\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tif (loadGeneration !== this._loadGeneration) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._loadStatus = 'idle';\n\t\t\t\tconsole.error('Failed to load actor model', error);\n\t\t\t\tthis.dispatch('entity:model:loaded', {\n\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmeshCount: 0,\n\t\t\t\t});\n\t\t\t});\n\t}\n\n\tprivate applyMaterialOverrides(): void {\n\t\tconst materialOptions = this.options.material;\n\t\tif (\n\t\t\t!materialOptions\n\t\t\t|| (!materialOptions.color && !materialOptions.path && materialOptions.opacity === undefined)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._object) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._object.traverse((child) => {\n\t\t\tif (!(child as any).isMesh) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst mesh = child as Mesh;\n\t\t\tif (materialOptions.color) {\n\t\t\t\tconst newMaterial = new MeshStandardMaterial({\n\t\t\t\t\tcolor: materialOptions.color,\n\t\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\t\tfog: true,\n\t\t\t\t\topacity: materialOptions.opacity ?? 1,\n\t\t\t\t\ttransparent: materialOptions.opacity !== undefined && materialOptions.opacity < 1,\n\t\t\t\t});\n\t\t\t\tmesh.castShadow = true;\n\t\t\t\tmesh.receiveShadow = true;\n\t\t\t\tmesh.material = newMaterial;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (materialOptions.opacity === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst applyOpacity = (material: Material): Material => {\n\t\t\t\tconst clonedMaterial = material.clone();\n\t\t\t\tif ('opacity' in clonedMaterial && 'transparent' in clonedMaterial) {\n\t\t\t\t\tconst transparentMaterial = clonedMaterial as TransparentMaterial;\n\t\t\t\t\ttransparentMaterial.opacity = materialOptions.opacity!;\n\t\t\t\t\ttransparentMaterial.transparent = materialOptions.opacity! < 1;\n\t\t\t\t\ttransparentMaterial.needsUpdate = true;\n\t\t\t\t}\n\t\t\t\treturn clonedMaterial;\n\t\t\t};\n\n\t\t\tmesh.material = Array.isArray(mesh.material)\n\t\t\t\t? mesh.material.map(applyOpacity)\n\t\t\t\t: applyOpacity(mesh.material);\n\t\t});\n\t}\n}\n\ntype ActorOptions = BaseNode | ZylemActorOptions;\n\nexport function createActor(...args: Array<ActorOptions>): ZylemActor {\n\treturn createEntity<ZylemActor, ZylemActorOptions>({\n\t\targs,\n\t\tdefaultConfig: actorDefaults,\n\t\tEntityClass: ZylemActor,\n\t\tBuilderClass: ActorBuilder,\n\t\tCollisionBuilderClass: ActorCollisionBuilder,\n\t\tentityType: ZylemActor.type,\n\t\tcloneFactory: (options) => createActor(options ?? {}),\n\t});\n}\n","/**\n * Message protocol for communication between the main thread and the\n * physics Web Worker.\n *\n * Data flows in two directions:\n * Main → Worker: {@link PhysicsCommand} (init, entity CRUD, per-frame step)\n * Worker → Main: {@link PhysicsEvent} (ready, step results, errors)\n *\n * All types are plain JSON-serializable objects so they can cross the\n * postMessage boundary without structured-clone issues.\n */\n\n// ─── Serializable Descriptor Types ─────────────────────────────────────────\n\n/** Rigid body type mirroring Rapier's RigidBodyType enum values. */\nexport type SerializableBodyType = 'dynamic' | 'fixed' | 'kinematicPositionBased' | 'kinematicVelocityBased';\n\n/**\n * Plain-object representation of a Rapier RigidBodyDesc.\n * Created on the main thread and reconstructed in the worker.\n */\nexport interface SerializableBodyDesc {\n\ttype: SerializableBodyType;\n\ttranslation: [number, number, number];\n\tgravityScale: number;\n\tcanSleep: boolean;\n\tccdEnabled: boolean;\n\tlockTranslations?: boolean;\n\tlockRotations?: boolean;\n}\n\n/** Collider shape kind. Matches the factory functions in collision-factories. */\nexport type ColliderShapeKind =\n\t| 'cuboid'\n\t| 'ball'\n\t| 'capsule'\n\t| 'cone'\n\t| 'cylinder'\n\t| 'trimesh'\n\t| 'heightfield';\n\n/**\n * Plain-object representation of a Rapier ColliderDesc.\n * Shape-specific dimensions are stored in {@link dimensions}.\n */\nexport interface SerializableColliderDesc {\n\tshape: ColliderShapeKind;\n\t/** Shape-specific numeric dimensions (e.g. halfExtents, radius, halfHeight). */\n\tdimensions: number[];\n\t/** For trimesh: flattened xyz vertex array. */\n\tvertices?: number[];\n\t/** For trimesh: triangle indices referencing {@link vertices}. */\n\tindices?: number[];\n\t/** Collider offset translation relative to the body. */\n\ttranslation?: [number, number, number];\n\tsensor?: boolean;\n\tcollisionGroups?: number;\n\tactiveCollisionTypes?: number;\n\t/** For heightfield: number of rows and columns. */\n\theightfieldMeta?: { nrows: number; ncols: number };\n}\n\n/** Describes a character controller to be created alongside the body. */\nexport interface SerializableCharacterController {\n\toffset: number;\n\tmaxSlopeClimbAngle: number;\n\tminSlopeSlideAngle: number;\n\tsnapToGroundDistance: number;\n\tslideEnabled: boolean;\n\tapplyImpulsesToDynamic: boolean;\n\tcharacterMass: number;\n}\n\n// ─── Per-Body Commands (batched inside a step) ─────────────────────────────\n\nexport type BodyCommand =\n\t| { kind: 'setLinvel'; uuid: string; x: number; y: number; z: number }\n\t| { kind: 'setAngvel'; uuid: string; x: number; y: number; z: number }\n\t| { kind: 'setTranslation'; uuid: string; x: number; y: number; z: number }\n\t| { kind: 'setRotation'; uuid: string; x: number; y: number; z: number; w: number }\n\t| { kind: 'applyImpulse'; uuid: string; x: number; y: number; z: number }\n\t| { kind: 'applyTorqueImpulse'; uuid: string; x: number; y: number; z: number }\n\t| { kind: 'lockTranslations'; uuid: string; locked: boolean }\n\t| { kind: 'lockRotations'; uuid: string; locked: boolean }\n\t| { kind: 'addTranslation'; uuid: string; dx: number; dy: number; dz: number }\n\t| { kind: 'setLinearDamping'; uuid: string; damping: number }\n\t| { kind: 'setGravityScale'; uuid: string; scale: number };\n\n// ─── Main → Worker Commands ────────────────────────────────────────────────\n\nexport type PhysicsCommand =\n\t| PhysicsInitCommand\n\t| PhysicsAddBodyCommand\n\t| PhysicsRemoveBodyCommand\n\t| PhysicsStepCommand\n\t| PhysicsDisposeCommand;\n\nexport interface PhysicsInitCommand {\n\ttype: 'init';\n\tgravity: [number, number, number];\n\tphysicsRate: number;\n}\n\nexport interface PhysicsAddBodyCommand {\n\ttype: 'addBody';\n\tuuid: string;\n\tbody: SerializableBodyDesc;\n\tcolliders: SerializableColliderDesc[];\n\tcharacterController?: SerializableCharacterController;\n}\n\nexport interface PhysicsRemoveBodyCommand {\n\ttype: 'removeBody';\n\tuuid: string;\n}\n\nexport interface PhysicsStepCommand {\n\ttype: 'step';\n\tdelta: number;\n\tcommands: BodyCommand[];\n}\n\nexport interface PhysicsDisposeCommand {\n\ttype: 'dispose';\n}\n\n// ─── Worker → Main Events ──────────────────────────────────────────────────\n\nexport type PhysicsEvent =\n\t| PhysicsReadyEvent\n\t| PhysicsStepResultEvent\n\t| PhysicsErrorEvent;\n\nexport interface PhysicsReadyEvent {\n\ttype: 'ready';\n}\n\n/**\n * Result of a physics step sent from the worker each frame.\n *\n * `transforms` is a flat Float32Array with 13 floats per body:\n * [posX, posY, posZ, rotX, rotY, rotZ, rotW, linvelX, linvelY, linvelZ, angvelX, angvelY, angvelZ]\n *\n * The order matches {@link bodyOrder} — an array of UUIDs in the same\n * index order as the transform buffer.\n */\nexport interface PhysicsStepResultEvent {\n\ttype: 'stepResult';\n\t/** Flat buffer: 13 floats per body (pos3, rot4, linvel3, angvel3). */\n\ttransforms: Float32Array;\n\t/** UUID order matching the transforms buffer. */\n\tbodyOrder: string[];\n\t/** Collision pairs detected this frame. */\n\tcollisions: CollisionPair[];\n\t/** Interpolation alpha for rendering (0..1). */\n\tinterpolationAlpha: number;\n}\n\nexport interface PhysicsErrorEvent {\n\ttype: 'error';\n\tmessage: string;\n}\n\n/** A collision pair detected during the physics step. */\nexport interface CollisionPair {\n\tuuidA: string;\n\tuuidB: string;\n\tcontactType: 'contact' | 'intersection';\n}\n\n// ─── Transform Buffer Layout ───────────────────────────────────────────────\n\n/** Number of floats per body in the transforms buffer. */\nexport const FLOATS_PER_BODY = 13;\n\n/** Offsets into the per-body segment of the transforms buffer. */\nexport const TransformOffset = {\n\tPOS_X: 0,\n\tPOS_Y: 1,\n\tPOS_Z: 2,\n\tROT_X: 3,\n\tROT_Y: 4,\n\tROT_Z: 5,\n\tROT_W: 6,\n\tLINVEL_X: 7,\n\tLINVEL_Y: 8,\n\tLINVEL_Z: 9,\n\tANGVEL_X: 10,\n\tANGVEL_Y: 11,\n\tANGVEL_Z: 12,\n} as const;\n","import type { BodyCommand } from './physics-protocol';\nimport {\n\tcreatePhysicsPose,\n\tinterpolatePhysicsPose,\n\ttype PhysicsPose,\n\ttype PhysicsPoseHistory,\n\ttype PhysicsQuaternion,\n\ttype PhysicsVector3,\n} from './physics-pose';\n\n/**\n * Lightweight read-only view of a physics body's state.\n *\n * These values are synced from the worker each frame and represent\n * the body's state after the latest physics step.\n */\nexport interface PhysicsSnapshot {\n\tprevious: PhysicsPose;\n\tcurrent: PhysicsPose;\n\tlinvel: { x: number; y: number; z: number };\n\tangvel: { x: number; y: number; z: number };\n}\n\n/**\n * Main-thread handle for a physics body that lives in a Web Worker.\n *\n * Provides the same read interface as a Rapier RigidBody (translation,\n * rotation, linvel, angvel) by returning cached values that are synced\n * from the worker each frame.\n *\n * Write operations (setLinvel, setTranslation, etc.) are queued as\n * {@link BodyCommand}s and sent to the worker on the next step.\n */\nexport class PhysicsBodyHandle {\n\treadonly uuid: string;\n\n\t/** Last-known physics state, updated from worker each frame. */\n\tprivate _snapshot: PhysicsSnapshot = {\n\t\tprevious: createPhysicsPose(),\n\t\tcurrent: createPhysicsPose(),\n\t\tlinvel: { x: 0, y: 0, z: 0 },\n\t\tangvel: { x: 0, y: 0, z: 0 },\n\t};\n\n\t/** Queued commands to be sent to the worker on next step. */\n\tprivate _pendingCommands: BodyCommand[] = [];\n\n\t/** Optional reference to the proxy's shared command queue. */\n\tprivate _sharedQueue: BodyCommand[] | null = null;\n\n\tconstructor(uuid: string, sharedQueue?: BodyCommand[]) {\n\t\tthis.uuid = uuid;\n\t\tthis._sharedQueue = sharedQueue ?? null;\n\t}\n\n\t// ─── Read API (returns cached values) ────────────────────────────────\n\n\t/** Cached position from last physics step. */\n\ttranslation(): { x: number; y: number; z: number } {\n\t\treturn this._snapshot.current.position;\n\t}\n\n\t/** Cached rotation quaternion from last physics step. */\n\trotation(): { x: number; y: number; z: number; w: number } {\n\t\treturn this._snapshot.current.rotation;\n\t}\n\n\t/** Cached linear velocity from last physics step. */\n\tlinvel(): { x: number; y: number; z: number } {\n\t\treturn this._snapshot.linvel;\n\t}\n\n\t/** Cached angular velocity from last physics step. */\n\tangvel(): { x: number; y: number; z: number } {\n\t\treturn this._snapshot.angvel;\n\t}\n\n\tgetPoseHistory(): PhysicsPoseHistory {\n\t\treturn this._snapshot;\n\t}\n\n\tgetRenderPose(alpha: number): PhysicsPose {\n\t\treturn interpolatePhysicsPose(\n\t\t\tthis._snapshot.previous,\n\t\t\tthis._snapshot.current,\n\t\t\talpha,\n\t\t);\n\t}\n\n\t// ─── Write API (queues commands) ─────────────────────────────────────\n\n\tsetLinvel(v: { x: number; y: number; z: number }, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'setLinvel', uuid: this.uuid, x: v.x, y: v.y, z: v.z });\n\t\tthis._snapshot.linvel = { ...v };\n\t}\n\n\tsetAngvel(v: { x: number; y: number; z: number }, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'setAngvel', uuid: this.uuid, x: v.x, y: v.y, z: v.z });\n\t\tthis._snapshot.angvel = { ...v };\n\t}\n\n\tsetTranslation(v: { x: number; y: number; z: number }, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'setTranslation', uuid: this.uuid, x: v.x, y: v.y, z: v.z });\n\t\tthis.setCollapsedTranslation(v);\n\t}\n\n\tsetRotation(q: { x: number; y: number; z: number; w: number }, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'setRotation', uuid: this.uuid, x: q.x, y: q.y, z: q.z, w: q.w });\n\t\tthis.setCollapsedRotation(q);\n\t}\n\n\tapplyImpulse(v: { x: number; y: number; z: number }, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'applyImpulse', uuid: this.uuid, x: v.x, y: v.y, z: v.z });\n\t}\n\n\tapplyTorqueImpulse(v: { x: number; y: number; z: number }, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'applyTorqueImpulse', uuid: this.uuid, x: v.x, y: v.y, z: v.z });\n\t}\n\n\tlockTranslations(locked: boolean, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'lockTranslations', uuid: this.uuid, locked });\n\t}\n\n\tlockRotations(locked: boolean, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'lockRotations', uuid: this.uuid, locked });\n\t}\n\n\tsetLinearDamping(damping: number): void {\n\t\tthis.enqueue({ kind: 'setLinearDamping', uuid: this.uuid, damping });\n\t}\n\n\tsetGravityScale(scale: number, _wakeUp?: boolean): void {\n\t\tthis.enqueue({ kind: 'setGravityScale', uuid: this.uuid, scale });\n\t}\n\n\t// ─── Stubbed read-only methods for compatibility ─────────────────────\n\n\t/** Returns 'Dynamic' for compatibility; actual type is not synced. */\n\tbodyType(): number {\n\t\treturn 0;\n\t}\n\n\tmass(): number {\n\t\treturn 1;\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn true;\n\t}\n\n\tisSleeping(): boolean {\n\t\treturn false;\n\t}\n\n\t/** Collider access is not available through the handle. Returns null. */\n\tcollider(_index: number): null {\n\t\treturn null;\n\t}\n\n\t// ─── Internal ────────────────────────────────────────────────────────\n\n\t/**\n\t * Update the cached snapshot from worker data.\n\t * Called by the PhysicsProxy after receiving a stepResult.\n\t */\n\t_seedSnapshot(\n\t\tpx: number,\n\t\tpy: number,\n\t\tpz: number,\n\t\trx: number,\n\t\try: number,\n\t\trz: number,\n\t\trw: number,\n\t\tlvx: number,\n\t\tlvy: number,\n\t\tlvz: number,\n\t\tavx: number,\n\t\tavy: number,\n\t\tavz: number,\n\t): void {\n\t\tthis.writePose(this._snapshot.previous, px, py, pz, rx, ry, rz, rw);\n\t\tthis.writePose(this._snapshot.current, px, py, pz, rx, ry, rz, rw);\n\t\tthis._snapshot.linvel.x = lvx;\n\t\tthis._snapshot.linvel.y = lvy;\n\t\tthis._snapshot.linvel.z = lvz;\n\t\tthis._snapshot.angvel.x = avx;\n\t\tthis._snapshot.angvel.y = avy;\n\t\tthis._snapshot.angvel.z = avz;\n\t}\n\n\t_updateSnapshot(\n\t\tpx: number, py: number, pz: number,\n\t\trx: number, ry: number, rz: number, rw: number,\n\t\tlvx: number, lvy: number, lvz: number,\n\t\tavx: number, avy: number, avz: number,\n\t): void {\n\t\tthis.copyPose(this._snapshot.current, this._snapshot.previous);\n\t\tthis.writePose(this._snapshot.current, px, py, pz, rx, ry, rz, rw);\n\t\tthis._snapshot.linvel.x = lvx;\n\t\tthis._snapshot.linvel.y = lvy;\n\t\tthis._snapshot.linvel.z = lvz;\n\t\tthis._snapshot.angvel.x = avx;\n\t\tthis._snapshot.angvel.y = avy;\n\t\tthis._snapshot.angvel.z = avz;\n\t}\n\n\t/** Drain pending commands. */\n\t_drainCommands(): BodyCommand[] {\n\t\tconst cmds = this._pendingCommands;\n\t\tthis._pendingCommands = [];\n\t\treturn cmds;\n\t}\n\n\tprivate enqueue(cmd: BodyCommand): void {\n\t\tif (this._sharedQueue) {\n\t\t\tthis._sharedQueue.push(cmd);\n\t\t} else {\n\t\t\tthis._pendingCommands.push(cmd);\n\t\t}\n\t}\n\n\tprivate copyPose(source: PhysicsPose, target: PhysicsPose): void {\n\t\ttarget.position.x = source.position.x;\n\t\ttarget.position.y = source.position.y;\n\t\ttarget.position.z = source.position.z;\n\t\ttarget.rotation.x = source.rotation.x;\n\t\ttarget.rotation.y = source.rotation.y;\n\t\ttarget.rotation.z = source.rotation.z;\n\t\ttarget.rotation.w = source.rotation.w;\n\t}\n\n\tprivate writePose(\n\t\ttarget: PhysicsPose,\n\t\tpx: number,\n\t\tpy: number,\n\t\tpz: number,\n\t\trx: number,\n\t\try: number,\n\t\trz: number,\n\t\trw: number,\n\t): void {\n\t\ttarget.position.x = px;\n\t\ttarget.position.y = py;\n\t\ttarget.position.z = pz;\n\t\ttarget.rotation.x = rx;\n\t\ttarget.rotation.y = ry;\n\t\ttarget.rotation.z = rz;\n\t\ttarget.rotation.w = rw;\n\t}\n\n\tprivate setCollapsedTranslation(translation: PhysicsVector3): void {\n\t\tthis._snapshot.previous.position.x = translation.x;\n\t\tthis._snapshot.previous.position.y = translation.y;\n\t\tthis._snapshot.previous.position.z = translation.z;\n\t\tthis._snapshot.current.position.x = translation.x;\n\t\tthis._snapshot.current.position.y = translation.y;\n\t\tthis._snapshot.current.position.z = translation.z;\n\t}\n\n\tprivate setCollapsedRotation(rotation: PhysicsQuaternion): void {\n\t\tthis._snapshot.previous.rotation.x = rotation.x;\n\t\tthis._snapshot.previous.rotation.y = rotation.y;\n\t\tthis._snapshot.previous.rotation.z = rotation.z;\n\t\tthis._snapshot.previous.rotation.w = rotation.w;\n\t\tthis._snapshot.current.rotation.x = rotation.x;\n\t\tthis._snapshot.current.rotation.y = rotation.y;\n\t\tthis._snapshot.current.rotation.z = rotation.z;\n\t\tthis._snapshot.current.rotation.w = rotation.w;\n\t}\n}\n","import type {\n\tPhysicsCommand,\n\tPhysicsEvent,\n\tPhysicsStepResultEvent,\n\tPhysicsAddBodyCommand,\n\tBodyCommand,\n\tCollisionPair,\n\tSerializableBodyDesc,\n\tSerializableColliderDesc,\n\tSerializableCharacterController,\n} from './physics-protocol';\nimport { FLOATS_PER_BODY, TransformOffset } from './physics-protocol';\nimport { PhysicsBodyHandle } from './physics-body-handle';\n\n/**\n * Callback signature for collision events dispatched by the proxy.\n */\nexport type CollisionCallback = (pair: CollisionPair) => void;\n\n/**\n * Main-thread proxy that communicates with the physics Web Worker.\n *\n * Usage:\n * ```ts\n * const proxy = new PhysicsProxy();\n * await proxy.init([0, -9.81, 0], 60);\n * const handle = proxy.addBody(uuid, bodyDesc, colliderDescs);\n * // each frame:\n * await proxy.step(delta);\n * ```\n *\n * The proxy owns the worker lifecycle and manages body handles.\n * After each step, all handles are updated with fresh transform data\n * and collision callbacks are fired.\n */\nexport class PhysicsProxy {\n\tprivate worker: Worker | null = null;\n\tprivate handles = new Map<string, PhysicsBodyHandle>();\n\tprivate commandQueue: BodyCommand[] = [];\n\tprivate collisionListeners: CollisionCallback[] = [];\n\tprivate pendingStep: {\n\t\tresolve: (result: PhysicsStepResultEvent) => void;\n\t\treject: (err: Error) => void;\n\t} | null = null;\n\n\t/** Latest interpolation alpha from the worker (0..1). */\n\tinterpolationAlpha = 0;\n\n\t/**\n\t * Spawn the worker and initialize the Rapier world inside it.\n\t * Resolves when the worker reports `ready`.\n\t *\n\t * @param gravity World gravity as [x, y, z].\n\t * @param physicsRate Physics tick rate in Hz (default 60).\n\t * @param workerUrl URL to the physics worker script. The consuming\n\t * application must provide this because bundlers (Vite, Webpack)\n\t * can only resolve worker URLs from application source code.\n\t * Example for Vite:\n\t * ```ts\n\t * new URL('@zylem/game-lib/dist/physics-worker.js', import.meta.url)\n\t * ```\n\t */\n\tasync init(\n\t\tgravity: [number, number, number],\n\t\tphysicsRate = 60,\n\t\tworkerUrl?: URL,\n\t): Promise<void> {\n\t\tif (!workerUrl) {\n\t\t\tthrow new Error(\n\t\t\t\t'[PhysicsProxy] workerUrl is required. Provide physicsWorkerUrl in your stage config.\\n' +\n\t\t\t\t'For Vite: physicsWorkerUrl: new URL(\"@zylem/game-lib/dist/physics-worker.js\", import.meta.url)'\n\t\t\t);\n\t\t}\n\t\tthis.worker = new Worker(workerUrl, { type: 'module' });\n\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\tconst onMessage = (e: MessageEvent<PhysicsEvent>) => {\n\t\t\t\tif (e.data.type === 'ready') {\n\t\t\t\t\tthis.worker!.removeEventListener('message', onMessage);\n\t\t\t\t\tthis.worker!.addEventListener('message', this.onWorkerMessage.bind(this));\n\t\t\t\t\tresolve();\n\t\t\t\t} else if (e.data.type === 'error') {\n\t\t\t\t\treject(new Error(e.data.message));\n\t\t\t\t}\n\t\t\t};\n\t\t\tthis.worker!.addEventListener('message', onMessage);\n\n\t\t\tthis.send({ type: 'init', gravity, physicsRate });\n\t\t});\n\t}\n\n\t/**\n\t * Register a body in the worker and return a main-thread handle.\n\t *\n\t * @returns A {@link PhysicsBodyHandle} for reading cached transforms\n\t * and queuing write commands.\n\t */\n\taddBody(\n\t\tuuid: string,\n\t\tbody: SerializableBodyDesc,\n\t\tcolliders: SerializableColliderDesc[],\n\t\tcharacterController?: SerializableCharacterController,\n\t): PhysicsBodyHandle {\n\t\tconst cmd: PhysicsAddBodyCommand = {\n\t\t\ttype: 'addBody',\n\t\t\tuuid,\n\t\t\tbody,\n\t\t\tcolliders,\n\t\t\tcharacterController,\n\t\t};\n\t\tthis.send(cmd);\n\n\t\tconst handle = new PhysicsBodyHandle(uuid, this.commandQueue);\n\t\thandle._seedSnapshot(\n\t\t\tbody.translation[0], body.translation[1], body.translation[2],\n\t\t\t0, 0, 0, 1,\n\t\t\t0, 0, 0,\n\t\t\t0, 0, 0,\n\t\t);\n\t\tthis.handles.set(uuid, handle);\n\t\treturn handle;\n\t}\n\n\t/** Remove a body from the worker and discard its handle. */\n\tremoveBody(uuid: string): void {\n\t\tthis.send({ type: 'removeBody', uuid });\n\t\tthis.handles.delete(uuid);\n\t}\n\n\t/** Get a body handle by entity UUID. */\n\tgetHandle(uuid: string): PhysicsBodyHandle | undefined {\n\t\treturn this.handles.get(uuid);\n\t}\n\n\t/**\n\t * Send a step command to the worker with the current frame delta\n\t * and all queued body commands.\n\t *\n\t * Returns a promise that resolves after the worker replies with\n\t * the step result. Handles are updated and collision callbacks\n\t * are fired before the promise resolves.\n\t */\n\tstep(delta: number): Promise<PhysicsStepResultEvent> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.pendingStep = { resolve, reject };\n\n\t\t\tconst commands = this.commandQueue.splice(0);\n\n\t\t\tfor (const handle of this.handles.values()) {\n\t\t\t\tcommands.push(...handle._drainCommands());\n\t\t\t}\n\n\t\t\tthis.send({ type: 'step', delta, commands });\n\t\t});\n\t}\n\n\t/**\n\t * Subscribe to collision events.\n\t * @returns Unsubscribe function.\n\t */\n\tonCollision(callback: CollisionCallback): () => void {\n\t\tthis.collisionListeners.push(callback);\n\t\treturn () => {\n\t\t\tthis.collisionListeners = this.collisionListeners.filter((cb) => cb !== callback);\n\t\t};\n\t}\n\n\t/** Terminate the worker and release all handles. */\n\tdispose(): void {\n\t\tif (this.worker) {\n\t\t\tthis.send({ type: 'dispose' });\n\t\t\tthis.worker.terminate();\n\t\t\tthis.worker = null;\n\t\t}\n\t\tthis.handles.clear();\n\t\tthis.commandQueue.length = 0;\n\t\tthis.collisionListeners.length = 0;\n\t\tthis.pendingStep = null;\n\t}\n\n\t// ─── Internal ────────────────────────────────────────────────────────\n\n\tprivate send(cmd: PhysicsCommand): void {\n\t\tthis.worker?.postMessage(cmd);\n\t}\n\n\tprivate onWorkerMessage(e: MessageEvent<PhysicsEvent>): void {\n\t\tconst event = e.data;\n\n\t\tswitch (event.type) {\n\t\t\tcase 'stepResult':\n\t\t\t\tthis.applyStepResult(event);\n\t\t\t\tbreak;\n\t\t\tcase 'error':\n\t\t\t\tif (this.pendingStep) {\n\t\t\t\t\tthis.pendingStep.reject(new Error(event.message));\n\t\t\t\t\tthis.pendingStep = null;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('[PhysicsProxy] Worker error:', event.message);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate applyStepResult(result: PhysicsStepResultEvent): void {\n\t\tconst { transforms, bodyOrder, collisions, interpolationAlpha } = result;\n\t\tthis.interpolationAlpha = interpolationAlpha;\n\n\t\tfor (let i = 0; i < bodyOrder.length; i++) {\n\t\t\tconst handle = this.handles.get(bodyOrder[i]);\n\t\t\tif (!handle) continue;\n\n\t\t\tconst o = i * FLOATS_PER_BODY;\n\t\t\thandle._updateSnapshot(\n\t\t\t\ttransforms[o + TransformOffset.POS_X],\n\t\t\t\ttransforms[o + TransformOffset.POS_Y],\n\t\t\t\ttransforms[o + TransformOffset.POS_Z],\n\t\t\t\ttransforms[o + TransformOffset.ROT_X],\n\t\t\t\ttransforms[o + TransformOffset.ROT_Y],\n\t\t\t\ttransforms[o + TransformOffset.ROT_Z],\n\t\t\t\ttransforms[o + TransformOffset.ROT_W],\n\t\t\t\ttransforms[o + TransformOffset.LINVEL_X],\n\t\t\t\ttransforms[o + TransformOffset.LINVEL_Y],\n\t\t\t\ttransforms[o + TransformOffset.LINVEL_Z],\n\t\t\t\ttransforms[o + TransformOffset.ANGVEL_X],\n\t\t\t\ttransforms[o + TransformOffset.ANGVEL_Y],\n\t\t\t\ttransforms[o + TransformOffset.ANGVEL_Z],\n\t\t\t);\n\t\t}\n\n\t\tfor (const pair of collisions) {\n\t\t\tfor (const listener of this.collisionListeners) {\n\t\t\t\ttry {\n\t\t\t\t\tlistener(pair);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error('[PhysicsProxy] Collision listener error:', err);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.pendingStep) {\n\t\t\tthis.pendingStep.resolve(result);\n\t\t\tthis.pendingStep = null;\n\t\t}\n\t}\n}\n","import type { RigidBodyDesc, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { RigidBodyType } from '@dimforge/rapier3d-compat';\nimport type {\n\tSerializableBodyDesc,\n\tSerializableBodyType,\n\tSerializableColliderDesc,\n\tColliderShapeKind,\n\tSerializableCharacterController,\n} from './physics-protocol';\n\n/**\n * Convert a Rapier RigidBodyDesc to a plain serializable object.\n *\n * Rapier descriptors are WASM-backed class instances that cannot cross\n * the postMessage boundary. This extracts the relevant data into a\n * JSON-safe format that the worker can reconstruct.\n */\nexport function serializeBodyDesc(desc: RigidBodyDesc): SerializableBodyDesc {\n\tconst status = (desc as any).status as number;\n\tlet type: SerializableBodyType = 'dynamic';\n\tif (status === RigidBodyType.Fixed) type = 'fixed';\n\telse if (status === RigidBodyType.KinematicPositionBased) type = 'kinematicPositionBased';\n\telse if (status === RigidBodyType.KinematicVelocityBased) type = 'kinematicVelocityBased';\n\n\tconst t = (desc as any).translation ?? { x: 0, y: 0, z: 0 };\n\n\treturn {\n\t\ttype,\n\t\ttranslation: [t.x ?? 0, t.y ?? 0, t.z ?? 0],\n\t\tgravityScale: (desc as any).gravityScale ?? 1,\n\t\tcanSleep: (desc as any).canSleep ?? false,\n\t\tccdEnabled: (desc as any).ccdEnabled ?? true,\n\t};\n}\n\n/**\n * Convert a Rapier ColliderDesc to a plain serializable object.\n *\n * Because Rapier's ColliderDesc uses opaque shape enums and internal\n * buffers, we infer the shape from the descriptor's internal type tag\n * and extract the numeric dimensions.\n */\nexport function serializeColliderDesc(desc: ColliderDesc): SerializableColliderDesc {\n\tconst internal = desc as any;\n\tconst customShapeData = internal.__zylemShapeData as\n\t\t| { shape: 'trimesh'; vertices: number[]; indices: number[] }\n\t\t| undefined;\n\tif (customShapeData?.shape === 'trimesh') {\n\t\tconst result: SerializableColliderDesc = {\n\t\t\tshape: 'trimesh',\n\t\t\tdimensions: [],\n\t\t\tvertices: [...customShapeData.vertices],\n\t\t\tindices: [...customShapeData.indices],\n\t\t};\n\n\t\tconst translation = internal.translation;\n\t\tif (\n\t\t\ttranslation\n\t\t\t&& (translation.x !== 0 || translation.y !== 0 || translation.z !== 0)\n\t\t) {\n\t\t\tresult.translation = [translation.x, translation.y, translation.z];\n\t\t}\n\n\t\tif (internal.isSensor) {\n\t\t\tresult.sensor = true;\n\t\t}\n\n\t\tif (internal.collisionGroups !== undefined && internal.collisionGroups !== 0xFFFFFFFF) {\n\t\t\tresult.collisionGroups = internal.collisionGroups;\n\t\t}\n\n\t\tif (internal.activeCollisionTypes !== undefined) {\n\t\t\tresult.activeCollisionTypes = internal.activeCollisionTypes;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tconst shapeType = internal.shape?.type ?? internal.shapeType ?? 0;\n\n\tconst { shape, dimensions, heightfieldMeta } = extractShapeData(shapeType, internal);\n\n\tconst result: SerializableColliderDesc = {\n\t\tshape,\n\t\tdimensions,\n\t};\n\n\tconst t = internal.translation;\n\tif (t && (t.x !== 0 || t.y !== 0 || t.z !== 0)) {\n\t\tresult.translation = [t.x, t.y, t.z];\n\t}\n\n\tif (internal.isSensor) {\n\t\tresult.sensor = true;\n\t}\n\n\tif (internal.collisionGroups !== undefined && internal.collisionGroups !== 0xFFFFFFFF) {\n\t\tresult.collisionGroups = internal.collisionGroups;\n\t}\n\n\tif (internal.activeCollisionTypes !== undefined) {\n\t\tresult.activeCollisionTypes = internal.activeCollisionTypes;\n\t}\n\n\tif (heightfieldMeta) {\n\t\tresult.heightfieldMeta = heightfieldMeta;\n\t}\n\n\treturn result;\n}\n\n/**\n * Create a serializable character controller descriptor.\n */\nexport function serializeCharacterController(): SerializableCharacterController {\n\treturn {\n\t\toffset: 0.01,\n\t\tmaxSlopeClimbAngle: 45 * Math.PI / 180,\n\t\tminSlopeSlideAngle: 30 * Math.PI / 180,\n\t\tsnapToGroundDistance: 0.01,\n\t\tslideEnabled: true,\n\t\tapplyImpulsesToDynamic: true,\n\t\tcharacterMass: 1,\n\t};\n}\n\n// ─── Shape Extraction ──────────────────────────────────────────────────────\n\n/**\n * Rapier shape type enum values (from rapier internals):\n * 0 = Ball, 1 = Cuboid, 2 = Capsule, 6 = Cone, 7 = Cylinder,\n * 11 = HeightField\n */\nfunction extractShapeData(\n\tshapeType: number,\n\tinternal: any,\n): { shape: ColliderShapeKind; dimensions: number[]; heightfieldMeta?: { nrows: number; ncols: number } } {\n\tswitch (shapeType) {\n\t\tcase 0: // Ball\n\t\t\treturn {\n\t\t\t\tshape: 'ball',\n\t\t\t\tdimensions: [internal.shape?.radius ?? internal.halfExtents?.x ?? 1],\n\t\t\t};\n\t\tcase 1: // Cuboid\n\t\t\treturn {\n\t\t\t\tshape: 'cuboid',\n\t\t\t\tdimensions: [\n\t\t\t\t\tinternal.shape?.halfExtents?.x ?? internal.halfExtents?.x ?? 0.5,\n\t\t\t\t\tinternal.shape?.halfExtents?.y ?? internal.halfExtents?.y ?? 0.5,\n\t\t\t\t\tinternal.shape?.halfExtents?.z ?? internal.halfExtents?.z ?? 0.5,\n\t\t\t\t],\n\t\t\t};\n\t\tcase 2: // Capsule\n\t\t\treturn {\n\t\t\t\tshape: 'capsule',\n\t\t\t\tdimensions: [\n\t\t\t\t\tinternal.shape?.halfHeight ?? 0.5,\n\t\t\t\t\tinternal.shape?.radius ?? 0.5,\n\t\t\t\t],\n\t\t\t};\n\t\tcase 6: // Cone\n\t\t\treturn {\n\t\t\t\tshape: 'cone',\n\t\t\t\tdimensions: [\n\t\t\t\t\tinternal.shape?.halfHeight ?? 1,\n\t\t\t\t\tinternal.shape?.radius ?? 1,\n\t\t\t\t],\n\t\t\t};\n\t\tcase 7: // Cylinder\n\t\t\treturn {\n\t\t\t\tshape: 'cylinder',\n\t\t\t\tdimensions: [\n\t\t\t\t\tinternal.shape?.halfHeight ?? 1,\n\t\t\t\t\tinternal.shape?.radius ?? 1,\n\t\t\t\t],\n\t\t\t};\n\t\tcase 11: { // HeightField\n\t\t\tconst nrows = internal.shape?.nrows ?? 10;\n\t\t\tconst ncols = internal.shape?.ncols ?? 10;\n\t\t\tconst heights = internal.shape?.heights;\n\t\t\treturn {\n\t\t\t\tshape: 'heightfield',\n\t\t\t\tdimensions: heights ? Array.from(heights) : [],\n\t\t\t\theightfieldMeta: { nrows, ncols },\n\t\t\t};\n\t\t}\n\t\tdefault:\n\t\t\treturn { shape: 'cuboid', dimensions: [0.5, 0.5, 0.5] };\n\t}\n}\n","import { Vector3 } from 'three';\nimport RAPIER, { World } from '@dimforge/rapier3d-compat';\n\nimport { Entity } from '../interfaces/entity';\nimport { state } from '../game/game-state';\nimport { UpdateContext } from '../core/base-node-life-cycle';\nimport { ZylemActor } from '../entities/actor';\nimport {\n\tGameEntity,\n\ttype CollisionDispatchMetadata,\n\ttype CollisionPhase,\n} from '../entities/entity';\nimport { PhysicsProxy } from '../physics/physics-proxy';\nimport { serializeBodyDesc, serializeColliderDesc, serializeCharacterController } from '../physics/serialize-descriptors';\nimport type { CollisionPair } from '../physics/physics-protocol';\nimport {\n\tcommitDirectBodyPoseHistoryStep,\n\tcollapseDirectBodyPoseHistory,\n\tprepareDirectBodyPoseHistoryStep,\n\tregisterDirectBodyPoseHistory,\n} from '../physics/physics-pose';\n\n/**\n * Interface for entities that handle collision events.\n */\nexport interface CollisionHandlerDelegate {\n\thandlePostCollision(params: any): boolean;\n\thandleIntersectionEvent(params: any): void;\n}\n\n/**\n * Type guard to check if an object implements CollisionHandlerDelegate.\n */\nexport function isCollisionHandlerDelegate(obj: any): obj is CollisionHandlerDelegate {\n\treturn typeof obj?.handlePostCollision === \"function\" && typeof obj?.handleIntersectionEvent === \"function\";\n}\n\nexport interface CollisionSnapshotEntry {\n\tuuidA: string;\n\tuuidB: string;\n\thasContact: boolean;\n\thasIntersection: boolean;\n}\n\nfunction createCollisionSnapshotKey(uuidA: string, uuidB: string): string {\n\treturn uuidA < uuidB ? `${uuidA}|${uuidB}` : `${uuidB}|${uuidA}`;\n}\n\nexport function buildCollisionSnapshot(\n\tpairs: CollisionPair[],\n): Map<string, CollisionSnapshotEntry> {\n\tconst snapshot = new Map<string, CollisionSnapshotEntry>();\n\n\tfor (const pair of pairs) {\n\t\tif (pair.uuidA === pair.uuidB) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst key = createCollisionSnapshotKey(pair.uuidA, pair.uuidB);\n\t\tconst uuidA = pair.uuidA < pair.uuidB ? pair.uuidA : pair.uuidB;\n\t\tconst uuidB = pair.uuidA < pair.uuidB ? pair.uuidB : pair.uuidA;\n\t\tconst existing = snapshot.get(key);\n\n\t\tif (existing) {\n\t\t\tif (pair.contactType === 'contact') {\n\t\t\t\texisting.hasContact = true;\n\t\t\t} else {\n\t\t\t\texisting.hasIntersection = true;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tsnapshot.set(key, {\n\t\t\tuuidA,\n\t\t\tuuidB,\n\t\t\thasContact: pair.contactType === 'contact',\n\t\t\thasIntersection: pair.contactType === 'intersection',\n\t\t});\n\t}\n\n\treturn snapshot;\n}\n\n/**\n * Physics world wrapper supporting two modes:\n *\n * - **Direct mode** (default): Rapier world lives on the main thread.\n * This is the original behavior with the Phase-1 fixed-timestep accumulator.\n *\n * - **Worker mode**: Physics runs in a Web Worker via {@link PhysicsProxy}.\n * Entity bodies are replaced with {@link PhysicsBodyHandle} instances that\n * cache transforms and queue write commands. Collision events are delivered\n * asynchronously (one frame latency).\n */\nexport class ZylemWorld implements Entity<ZylemWorld> {\n\ttype = 'World';\n\n\t/** Rapier world instance (null in worker mode). */\n\tworld: World;\n\n\tcollisionMap: Map<string, GameEntity<any>> = new Map();\n\tcollisionBehaviorMap: Map<string, GameEntity<any>> = new Map();\n\t_removalMap: Map<string, GameEntity<any>> = new Map();\n\tprivate activeCollisionPairs: Map<string, CollisionSnapshotEntry> = new Map();\n\tprivate currentCollisionTimeMs = 0;\n\n\t/** Fixed timestep in seconds used for each physics step. */\n\treadonly fixedTimestep: number;\n\t/** Unprocessed time carried over between frames. */\n\tprivate accumulator = 0;\n\t/** Maximum number of physics steps allowed per frame to prevent spiral-of-death. */\n\tprivate static readonly MAX_STEPS_PER_FRAME = 5;\n\t/**\n\t * Interpolation alpha (0..1) representing the fraction of an unprocessed\n\t * timestep remaining after the last physics step. Can be used to interpolate\n\t * rendering transforms between the previous and current physics state.\n\t */\n\tinterpolationAlpha = 0;\n\n\t// ─── Worker Mode ─────────────────────────────────────────────────────\n\n\t/** When true, physics runs in a Web Worker via the proxy. */\n\treadonly workerMode: boolean;\n\t/** Physics worker proxy (only set in worker mode). */\n\tprivate proxy: PhysicsProxy | null = null;\n\t/** Pending step promise (worker mode). */\n\tprivate _pendingStep: Promise<void> | null = null;\n\tprivate readonly trackedDirectBodies = new WeakSet<RAPIER.RigidBody>();\n\n\tstatic async loadPhysics(gravity: Vector3) {\n\t\tawait RAPIER.init();\n\t\tconst physicsWorld = new RAPIER.World(gravity);\n\t\treturn physicsWorld;\n\t}\n\n\t/**\n\t * Initialize physics in worker mode. Returns a ZylemWorld that\n\t * delegates all physics to a Web Worker.\n\t *\n\t * @param gravity World gravity.\n\t * @param physicsRate Physics tick rate in Hz.\n\t * @param workerUrl Optional URL to the worker script.\n\t */\n\tstatic async loadPhysicsWorker(\n\t\tgravity: Vector3,\n\t\tphysicsRate = 60,\n\t\tworkerUrl?: URL,\n\t): Promise<ZylemWorld> {\n\t\tconst proxy = new PhysicsProxy();\n\t\tawait proxy.init(\n\t\t\t[gravity.x, gravity.y, gravity.z],\n\t\t\tphysicsRate,\n\t\t\tworkerUrl,\n\t\t);\n\n\t\tconst zw = new ZylemWorld(null as unknown as World, physicsRate, true);\n\t\tzw.proxy = proxy;\n\n\t\treturn zw;\n\t}\n\n\t/**\n\t * @param world The Rapier physics world instance (null in worker mode).\n\t * @param physicsRate Physics update rate in Hz (default 60).\n\t * @param useWorker Whether to use worker mode (default false).\n\t */\n\tconstructor(world: World, physicsRate = 60, useWorker = false) {\n\t\tthis.world = world;\n\t\tthis.workerMode = useWorker;\n\t\tthis.fixedTimestep = 1 / physicsRate;\n\t\tif (!useWorker && world) {\n\t\t\tthis.world.integrationParameters.dt = this.fixedTimestep;\n\t\t}\n\t}\n\n\t// ─── Entity Management ───────────────────────────────────────────────\n\n\taddEntity(entity: any) {\n\t\tif (this.workerMode) {\n\t\t\tthis.addEntityWorker(entity);\n\t\t\treturn;\n\t\t}\n\t\tthis.addEntityDirect(entity);\n\t}\n\n\tsetForRemoval(entity: any) {\n\t\tif (entity.physicsAttached) {\n\t\t\tthis._removalMap.set(entity.uuid, entity);\n\t\t}\n\t}\n\n\tdestroyEntity(entity: GameEntity<any>) {\n\t\tif (this.workerMode) {\n\t\t\tthis.destroyEntityWorker(entity);\n\t\t\treturn;\n\t\t}\n\t\tthis.destroyEntityDirect(entity);\n\t}\n\n\tsetup() { }\n\n\t// ─── Update ──────────────────────────────────────────────────────────\n\n\t/**\n\t * Advance the physics simulation.\n\t *\n\t * In direct mode, uses the fixed-timestep accumulator on the main thread.\n\t * In worker mode, sends a step command and awaits the result.\n\t */\n\tupdate(params: UpdateContext<any>) {\n\t\tif (this.workerMode) {\n\t\t\tthis.updateWorker(params);\n\t\t\treturn;\n\t\t}\n\t\tthis.updateDirect(params);\n\t}\n\n\t/**\n\t * In worker mode, the step is async. Call this to await the\n\t * pending step before reading transform data.\n\t */\n\tasync awaitStep(): Promise<void> {\n\t\tif (this._pendingStep) {\n\t\t\tawait this._pendingStep;\n\t\t\tthis._pendingStep = null;\n\t\t}\n\t}\n\n\t// ─── Direct Mode Implementation ──────────────────────────────────────\n\n\tprivate addEntityDirect(entity: any) {\n\t\tconst rigidBody = this.world.createRigidBody(entity.bodyDesc);\n\t\tentity.body = rigidBody;\n\t\tentity.physicsAttached = true;\n\t\tentity.body.userData = { uuid: entity.uuid, ref: entity };\n\t\tregisterDirectBodyPoseHistory(rigidBody);\n\t\tthis.patchDirectBodyPoseTracking(rigidBody);\n\t\tif (this.world.gravity.x === 0 && this.world.gravity.y === 0 && this.world.gravity.z === 0) {\n\t\t\tentity.body.lockTranslations(true, true);\n\t\t\tentity.body.lockRotations(true, true);\n\t\t}\n\n\t\tconst collider = this.world.createCollider(entity.colliderDesc, entity.body);\n\t\tentity.collider = collider;\n\t\tentity.colliders = [collider];\n\n\t\tif (entity.colliderDescs?.length > 1) {\n\t\t\tfor (let i = 1; i < entity.colliderDescs.length; i++) {\n\t\t\t\tconst additionalCollider = this.world.createCollider(entity.colliderDescs[i], entity.body);\n\t\t\t\tentity.colliders.push(additionalCollider);\n\t\t\t}\n\t\t}\n\n\t\tif (entity.controlledRotation || entity instanceof ZylemActor) {\n\t\t\tentity.body.lockRotations(true, true);\n\t\t\tentity.characterController = this.world.createCharacterController(0.01);\n\t\t\tentity.characterController.setMaxSlopeClimbAngle(45 * Math.PI / 180);\n\t\t\tentity.characterController.setMinSlopeSlideAngle(30 * Math.PI / 180);\n\t\t\tentity.characterController.enableSnapToGround(0.01);\n\t\t\tentity.characterController.setSlideEnabled(true);\n\t\t\tentity.characterController.setApplyImpulsesToDynamicBodies(true);\n\t\t\tentity.characterController.setCharacterMass(1);\n\t\t}\n\t\tthis.collisionMap.set(entity.uuid, entity);\n\t}\n\n\tprivate destroyEntityDirect(entity: GameEntity<any>) {\n\t\tif ((entity as any).characterController) {\n\t\t\ttry { (entity as any).characterController.free(); } catch { /* noop */ }\n\t\t\t(entity as any).characterController = null;\n\t\t}\n\t\tif (entity.colliders?.length) {\n\t\t\tfor (const collider of entity.colliders) {\n\t\t\t\ttry { this.world.removeCollider(collider, true); } catch { /* noop */ }\n\t\t\t}\n\t\t} else if (entity.collider) {\n\t\t\ttry { this.world.removeCollider(entity.collider, true); } catch { /* noop */ }\n\t\t}\n\t\tif (entity.body) {\n\t\t\ttry { this.world.removeRigidBody(entity.body); } catch { /* noop */ }\n\t\t\tthis.removeEntityFromTracking(entity.uuid);\n\t\t}\n\t\tthis.clearEntityPhysicsState(entity);\n\t}\n\n\tprivate updateDirect(params: UpdateContext<any>) {\n\t\tconst { delta } = params;\n\t\tif (!this.world) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.currentCollisionTimeMs += delta * 1000;\n\t\tthis.processPendingRemovals();\n\t\tthis.accumulator += delta;\n\n\t\tconst maxAccumulator = this.fixedTimestep * ZylemWorld.MAX_STEPS_PER_FRAME;\n\t\tthis.accumulator = Math.min(this.accumulator, maxAccumulator);\n\n\t\twhile (this.accumulator >= this.fixedTimestep) {\n\t\t\tthis.captureDirectBodyPreviousPoses();\n\t\t\tthis.world.step();\n\t\t\tthis.captureDirectBodyCurrentPoses();\n\t\t\tthis.accumulator -= this.fixedTimestep;\n\t\t}\n\n\t\tthis.processCollisionPairs(\n\t\t\tthis.collectCollisionPairsFromWorld(),\n\t\t\tdelta,\n\t\t\tthis.currentCollisionTimeMs,\n\t\t);\n\t\tthis.interpolationAlpha = this.accumulator / this.fixedTimestep;\n\t}\n\n\tprivate captureDirectBodyPreviousPoses() {\n\t\tfor (const [, collider] of this.collisionMap) {\n\t\t\tconst body = (collider as GameEntity<any>).body as RAPIER.RigidBody | null;\n\t\t\tif (body) {\n\t\t\t\tprepareDirectBodyPoseHistoryStep(body);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate captureDirectBodyCurrentPoses() {\n\t\tfor (const [, collider] of this.collisionMap) {\n\t\t\tconst body = (collider as GameEntity<any>).body as RAPIER.RigidBody | null;\n\t\t\tif (body) {\n\t\t\t\tcommitDirectBodyPoseHistoryStep(body);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate patchDirectBodyPoseTracking(body: RAPIER.RigidBody) {\n\t\tif (this.trackedDirectBodies.has(body)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst trackedBody = body as RAPIER.RigidBody & {\n\t\t\tsetTranslation: (\n\t\t\t\ttranslation: { x: number; y: number; z: number },\n\t\t\t\twakeUp: boolean,\n\t\t\t) => void;\n\t\t\tsetRotation: (\n\t\t\t\trotation: { x: number; y: number; z: number; w: number },\n\t\t\t\twakeUp: boolean,\n\t\t\t) => void;\n\t\t};\n\t\tconst originalSetTranslation = body.setTranslation.bind(body);\n\t\tconst originalSetRotation = body.setRotation.bind(body);\n\n\t\ttrackedBody.setTranslation = (translation, wakeUp) => {\n\t\t\toriginalSetTranslation(translation, wakeUp);\n\t\t\tcollapseDirectBodyPoseHistory(body);\n\t\t};\n\t\ttrackedBody.setRotation = (rotation, wakeUp) => {\n\t\t\toriginalSetRotation(rotation, wakeUp);\n\t\t\tcollapseDirectBodyPoseHistory(body);\n\t\t};\n\n\t\tthis.trackedDirectBodies.add(body);\n\t}\n\n\t// ─── Worker Mode Implementation ──────────────────────────────────────\n\n\tprivate addEntityWorker(entity: any) {\n\t\tif (!this.proxy) return;\n\n\t\tconst bodyDesc = serializeBodyDesc(entity.bodyDesc);\n\t\tconst colliderDescs = (entity.colliderDescs?.length > 0 ? entity.colliderDescs : [entity.colliderDesc])\n\t\t\t.filter(Boolean)\n\t\t\t.map(serializeColliderDesc);\n\n\t\tconst needsCharCtrl = entity.controlledRotation || entity instanceof ZylemActor;\n\t\tconst charCtrl = needsCharCtrl ? serializeCharacterController() : undefined;\n\n\t\tconst handle = this.proxy.addBody(entity.uuid, bodyDesc, colliderDescs, charCtrl);\n\n\t\t// Replace entity.body with the handle. The handle provides the same\n\t\t// read API (translation(), rotation(), linvel(), angvel()) and queues\n\t\t// write operations as commands for the worker.\n\t\tentity.body = handle as any;\n\t\tentity.physicsAttached = true;\n\t\tentity.collider = null;\n\t\tentity.colliders = [];\n\n\t\tthis.collisionMap.set(entity.uuid, entity);\n\t}\n\n\tprivate destroyEntityWorker(entity: GameEntity<any>) {\n\t\tif (!this.proxy) return;\n\t\tthis.proxy.removeBody(entity.uuid);\n\t\tthis.removeEntityFromTracking(entity.uuid);\n\t\tthis.clearEntityPhysicsState(entity);\n\t}\n\n\tprivate updateWorker(params: UpdateContext<any>) {\n\t\tif (!this.proxy) return;\n\n\t\tconst { delta } = params;\n\t\tthis.currentCollisionTimeMs += delta * 1000;\n\t\tthis.processPendingRemovals();\n\t\tconst collisionTimeMs = this.currentCollisionTimeMs;\n\t\tthis._pendingStep = this.proxy.step(delta).then((result) => {\n\t\t\tthis.interpolationAlpha = result.interpolationAlpha;\n\t\t\tthis.processCollisionPairs(result.collisions, delta, collisionTimeMs);\n\t\t});\n\t}\n\n\t// ─── Shared collision behavior processing ────────────────────────────\n\n\tupdatePostCollisionBehaviors(delta: number) {\n\t\tconst dictionaryRef = this.collisionBehaviorMap;\n\t\tfor (let [id, collider] of dictionaryRef) {\n\t\t\tconst gameEntity = collider as any;\n\t\t\tif (!isCollisionHandlerDelegate(gameEntity)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst active = gameEntity.handlePostCollision({ entity: gameEntity, delta });\n\t\t\tif (!active) {\n\t\t\t\tthis.collisionBehaviorMap.delete(id);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate processPendingRemovals() {\n\t\tif (this._removalMap.size === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const [, entity] of this._removalMap) {\n\t\t\tthis.destroyEntity(entity);\n\t\t}\n\t\tthis._removalMap.clear();\n\t}\n\n\tprivate removeEntityFromTracking(uuid: string) {\n\t\tthis.collisionMap.delete(uuid);\n\t\tthis._removalMap.delete(uuid);\n\t\tthis.pruneActiveCollisionPairs(uuid);\n\t}\n\n\tprivate pruneActiveCollisionPairs(uuid: string) {\n\t\tfor (const [key, pair] of this.activeCollisionPairs) {\n\t\t\tif (pair.uuidA === uuid || pair.uuidB === uuid) {\n\t\t\t\tthis.activeCollisionPairs.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate collectCollisionPairsFromWorld(): CollisionPair[] {\n\t\tconst pairs: CollisionPair[] = [];\n\t\tif (!this.world) {\n\t\t\treturn pairs;\n\t\t}\n\n\t\tfor (const [, collider] of this.collisionMap) {\n\t\t\tconst gameEntity = collider as GameEntity<any>;\n\t\t\tconst body = gameEntity.body as RAPIER.RigidBody | null;\n\t\t\tif (!body) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst primaryCollider = body.collider(0);\n\t\t\tif (!primaryCollider) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tthis.world.contactsWith(primaryCollider, (otherCollider) => {\n\t\t\t\tconst otherBody = otherCollider.parent();\n\t\t\t\tconst otherUuid = (otherBody?.userData as any)?.uuid as string | undefined;\n\t\t\t\tif (otherUuid) {\n\t\t\t\t\tpairs.push({\n\t\t\t\t\t\tuuidA: gameEntity.uuid,\n\t\t\t\t\t\tuuidB: otherUuid,\n\t\t\t\t\t\tcontactType: 'contact',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.world.intersectionsWith(primaryCollider, (otherCollider) => {\n\t\t\t\tconst otherBody = otherCollider.parent();\n\t\t\t\tconst otherUuid = (otherBody?.userData as any)?.uuid as string | undefined;\n\t\t\t\tif (otherUuid) {\n\t\t\t\t\tpairs.push({\n\t\t\t\t\t\tuuidA: gameEntity.uuid,\n\t\t\t\t\t\tuuidB: otherUuid,\n\t\t\t\t\t\tcontactType: 'intersection',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn pairs;\n\t}\n\n\tprivate processCollisionPairs(\n\t\tpairs: CollisionPair[],\n\t\tdelta: number,\n\t\tnowMs: number = this.currentCollisionTimeMs,\n\t) {\n\t\tconst snapshot = buildCollisionSnapshot(pairs);\n\n\t\tfor (const [key, pair] of snapshot) {\n\t\t\tconst wasActive = this.activeCollisionPairs.has(key);\n\t\t\tif (!wasActive) {\n\t\t\t\tthis.dispatchCollisionPhase(pair, 'enter', nowMs);\n\t\t\t}\n\t\t\tthis.dispatchCollisionPhase(pair, 'stay', nowMs);\n\n\t\t\tif (pair.hasIntersection) {\n\t\t\t\tthis.dispatchIntersectionDelegates(pair, delta);\n\t\t\t}\n\t\t}\n\n\t\tthis.updatePostCollisionBehaviors(delta);\n\t\tthis.activeCollisionPairs = snapshot;\n\t}\n\n\tprivate dispatchCollisionPhase(\n\t\tpair: CollisionSnapshotEntry,\n\t\tphase: CollisionPhase,\n\t\tnowMs: number,\n\t) {\n\t\tconst dispatch: CollisionDispatchMetadata = { phase, nowMs };\n\t\tconst entityA = this.collisionMap.get(pair.uuidA);\n\t\tconst entityB = this.collisionMap.get(pair.uuidB);\n\n\t\tif (entityA && entityB) {\n\t\t\tentityA._collision(entityB, state.globals, dispatch);\n\t\t}\n\n\t\tconst refreshedA = this.collisionMap.get(pair.uuidA);\n\t\tconst refreshedB = this.collisionMap.get(pair.uuidB);\n\t\tif (refreshedA && refreshedB) {\n\t\t\trefreshedB._collision(refreshedA, state.globals, dispatch);\n\t\t}\n\t}\n\n\tprivate dispatchIntersectionDelegates(\n\t\tpair: CollisionSnapshotEntry,\n\t\tdelta: number,\n\t) {\n\t\tconst entityA = this.collisionMap.get(pair.uuidA);\n\t\tconst entityB = this.collisionMap.get(pair.uuidB);\n\n\t\tif (entityA && entityB && isCollisionHandlerDelegate(entityA)) {\n\t\t\tentityA.handleIntersectionEvent({\n\t\t\t\tentity: entityA,\n\t\t\t\tother: entityB,\n\t\t\t\tdelta,\n\t\t\t});\n\t\t\tthis.collisionBehaviorMap.set(entityA.uuid, entityA);\n\t\t}\n\n\t\tconst refreshedA = this.collisionMap.get(pair.uuidA);\n\t\tconst refreshedB = this.collisionMap.get(pair.uuidB);\n\t\tif (refreshedA && refreshedB && isCollisionHandlerDelegate(refreshedB)) {\n\t\t\trefreshedB.handleIntersectionEvent({\n\t\t\t\tentity: refreshedB,\n\t\t\t\tother: refreshedA,\n\t\t\t\tdelta,\n\t\t\t});\n\t\t\tthis.collisionBehaviorMap.set(refreshedB.uuid, refreshedB);\n\t\t}\n\t}\n\n\t// ─── Cleanup ─────────────────────────────────────────────────────────\n\n\tdestroy() {\n\t\ttry {\n\t\t\tif (this.workerMode) {\n\t\t\t\tfor (const [, entity] of this.collisionMap) {\n\t\t\t\t\tthis.clearEntityPhysicsState(entity);\n\t\t\t\t}\n\t\t\t\tthis.proxy?.dispose();\n\t\t\t\tthis.proxy = null;\n\t\t\t} else {\n\t\t\t\tfor (const [, entity] of this.collisionMap) {\n\t\t\t\t\ttry { this.destroyEntityDirect(entity); } catch { /* noop */ }\n\t\t\t\t}\n\t\t\t\ttry { this.world?.free(); } catch { /* noop */ }\n\t\t\t\t// @ts-ignore\n\t\t\t\tthis.world = undefined as any;\n\t\t\t}\n\t\t\tthis.collisionMap.clear();\n\t\t\tthis.collisionBehaviorMap.clear();\n\t\t\tthis._removalMap.clear();\n\t\t\tthis.activeCollisionPairs.clear();\n\t\t} catch { /* noop */ }\n\t}\n\n\tprivate clearEntityPhysicsState(entity: GameEntity<any>): void {\n\t\tentity.physicsAttached = false;\n\t\tentity.body = null;\n\t\tentity.collider = undefined;\n\t\tentity.colliders = [];\n\t\t(entity as any).characterController = null;\n\t}\n\n}\n","import {\n\tScene,\n\tColor,\n\tAmbientLight,\n\tDirectionalLight,\n\tObject3D,\n\tVector3,\n\tGridHelper,\n\tBoxGeometry,\n\tShaderMaterial,\n\tMesh,\n\tBackSide,\n\tMaterial,\n\tTexture,\n\tLight,\n} from 'three';\nimport { MeshBasicNodeMaterial } from 'three/webgpu';\nimport { Entity, LifecycleFunction } from '../interfaces/entity';\nimport { GameEntity } from '../entities/entity';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { CameraManager } from '../camera/camera-manager';\nimport { RendererManager } from '../camera/renderer-manager';\nimport { debugState } from '../debug/debug-state';\nimport { SetupFunction } from '../core/base-node-life-cycle';\nimport { getGlobals } from '../game/game-state';\nimport { assetManager } from '../core/asset-manager';\nimport { ZylemShader, isTSLShader, isGLSLShader } from './material';\n\ninterface SceneState {\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader?: ZylemShader | null;\n}\n\nexport class ZylemScene implements Entity<ZylemScene> {\n\tpublic type = 'Scene';\n\n\t_setup?: SetupFunction<ZylemScene>;\n\tscene!: Scene;\n\t/** @deprecated Use cameraManager instead */\n\tzylemCamera!: ZylemCamera;\n\tcameraManager: CameraManager | null = null;\n\tcontainerElement: HTMLElement | null = null;\n\tupdate: LifecycleFunction<ZylemScene> = () => { };\n\t_collision?: ((entity: any, other: any, globals?: any) => void) | undefined;\n\t_destroy?: ((globals?: any) => void) | undefined;\n\tname?: string | undefined;\n\ttag?: Set<string> | undefined;\n\n\t// Skybox for background shaders (supports both GLSL ShaderMaterial and TSL MeshBasicNodeMaterial)\n\tprivate skyboxMaterial: Material | null = null;\n\n\tconstructor(id: string, camera: ZylemCamera, state: SceneState) {\n\t\tconst scene = new Scene();\n\t\tconst isColor = state.backgroundColor instanceof Color;\n\t\tconst backgroundColor = (isColor) ? state.backgroundColor : new Color(state.backgroundColor);\n\t\tscene.background = backgroundColor as Color;\n\t\t\n\t\tconsole.log('ZylemScene state.backgroundShader:', state.backgroundShader);\n\t\t\n\t\tif (state.backgroundShader) {\n\t\t\tthis.setupBackgroundShader(scene, state.backgroundShader);\n\t\t} else if (state.backgroundImage) {\n\t\t\t// Load background image asynchronously via asset manager\n\t\t\tassetManager.loadTexture(state.backgroundImage).then(texture => {\n\t\t\t\tscene.background = texture;\n\t\t\t});\n\t\t}\n\n\t\tthis.scene = scene;\n\t\tthis.zylemCamera = camera;\n\n\t\tthis.setupLighting(scene);\n\t\tif (debugState.enabled) {\n\t\t\tthis.debugScene();\n\t\t}\n\t}\n\n\t/**\n\t * Create a large inverted box with the shader for skybox effect\n\t * Supports both GLSL (ShaderMaterial) and TSL (MeshBasicNodeMaterial) shaders\n\t */\n\tprivate setupBackgroundShader(scene: Scene, shader: ZylemShader) {\n\t\t// Clear the solid color background\n\t\tscene.background = null;\n\n\t\tif (isTSLShader(shader)) {\n\t\t\t// TSL shader - use MeshBasicNodeMaterial for WebGPU\n\t\t\tthis.skyboxMaterial = new MeshBasicNodeMaterial();\n\t\t\t(this.skyboxMaterial as MeshBasicNodeMaterial).colorNode = shader.colorNode;\n\t\t\tif (shader.transparent) {\n\t\t\t\tthis.skyboxMaterial.transparent = true;\n\t\t\t}\n\t\t\tthis.skyboxMaterial.side = BackSide;\n\t\t\tthis.skyboxMaterial.depthWrite = false;\n\t\t\tconsole.log('Skybox created with TSL shader');\n\t\t} else if (isGLSLShader(shader)) {\n\t\t\t// GLSL shader - use ShaderMaterial for WebGL\n\t\t\t// Skybox vertex shader with depth trick (pos.xyww ensures depth = 1.0)\n\t\t\tconst skyboxVertexShader = `\n\t\t\t\tvarying vec2 vUv;\n\t\t\t\tvarying vec3 vWorldPosition;\n\t\t\t\t\n\t\t\t\tvoid main() {\n\t\t\t\t\tvUv = uv;\n\t\t\t\t\tvec4 worldPosition = modelMatrix * vec4(position, 1.0);\n\t\t\t\t\tvWorldPosition = worldPosition.xyz;\n\t\t\t\t\tvec4 pos = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n\t\t\t\t\tgl_Position = pos.xyww; // Ensures depth is always 1.0 (farthest)\n\t\t\t\t}\n\t\t\t`;\n\n\t\t\t// Create shader material with skybox-specific settings\n\t\t\tthis.skyboxMaterial = new ShaderMaterial({\n\t\t\t\tvertexShader: skyboxVertexShader,\n\t\t\t\tfragmentShader: shader.fragment,\n\t\t\t\tuniforms: {\n\t\t\t\t\tiTime: { value: 0.0 },\n\t\t\t\t},\n\t\t\t\tside: BackSide, // Render on inside of geometry\n\t\t\t\tdepthWrite: false, // Don't write to depth buffer\n\t\t\t\tdepthTest: true, // But do test depth\n\t\t\t});\n\t\t\tconsole.log('Skybox created with GLSL shader');\n\t\t}\n\n\t\t// Use BoxGeometry for skybox\n\t\tconst geometry = new BoxGeometry(1, 1, 1);\n\t\tconst skybox = new Mesh(geometry, this.skyboxMaterial!);\n\t\tskybox.scale.setScalar(100000); // Scale up significantly\n\t\tskybox.frustumCulled = false; // Always render\n\t\tscene.add(skybox);\n\t}\n\n\tsetup() {\n\t\tif (this._setup) {\n\t\t\tthis._setup({ me: this, camera: this.zylemCamera, globals: getGlobals() });\n\t\t}\n\t}\n\n\tdestroy() {\n\t\t// Destroy via camera manager if available, otherwise legacy single camera\n\t\tif (this.cameraManager) {\n\t\t\tthis.cameraManager.dispose();\n\t\t\tthis.cameraManager = null;\n\t\t} else if (this.zylemCamera && (this.zylemCamera as any).destroy) {\n\t\t\t(this.zylemCamera as any).destroy();\n\t\t}\n\t\tif (this.skyboxMaterial) {\n\t\t\tthis.skyboxMaterial.dispose();\n\t\t}\n\t\tif (this.scene) {\n\t\t\t// Dispose background texture if present\n\t\t\tif (this.scene.background instanceof Texture) {\n\t\t\t\tthis.scene.background.dispose();\n\t\t\t\tthis.scene.background = null;\n\t\t\t}\n\n\t\t\tthis.scene.traverse((obj: any) => {\n\t\t\t\tif (obj.geometry) {\n\t\t\t\t\tobj.geometry.dispose?.();\n\t\t\t\t}\n\t\t\t\tif (obj.material) {\n\t\t\t\t\tconst materials = Array.isArray(obj.material) ? obj.material : [obj.material];\n\t\t\t\t\tfor (const mat of materials) {\n\t\t\t\t\t\t// Dispose all texture maps on the material\n\t\t\t\t\t\tif (mat.map) mat.map.dispose?.();\n\t\t\t\t\t\tif (mat.normalMap) mat.normalMap.dispose?.();\n\t\t\t\t\t\tif (mat.aoMap) mat.aoMap.dispose?.();\n\t\t\t\t\t\tif (mat.emissiveMap) mat.emissiveMap.dispose?.();\n\t\t\t\t\t\tif (mat.roughnessMap) mat.roughnessMap.dispose?.();\n\t\t\t\t\t\tif (mat.metalnessMap) mat.metalnessMap.dispose?.();\n\t\t\t\t\t\tif (mat.envMap) mat.envMap.dispose?.();\n\t\t\t\t\t\tif (mat.lightMap) mat.lightMap.dispose?.();\n\t\t\t\t\t\tif (mat.bumpMap) mat.bumpMap.dispose?.();\n\t\t\t\t\t\tif (mat.displacementMap) mat.displacementMap.dispose?.();\n\t\t\t\t\t\tif (mat.alphaMap) mat.alphaMap.dispose?.();\n\t\t\t\t\t\tmat.dispose?.();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Dispose shadow map render targets on lights\n\t\t\t\tif ((obj as Light).isLight && (obj as any).shadow?.map) {\n\t\t\t\t\t(obj as any).shadow.map.dispose();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.scene.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Setup camera with the scene.\n\t * Supports both legacy single camera and CameraManager modes.\n\t */\n\tsetupCamera(scene: Scene, camera: ZylemCamera, rendererManager?: RendererManager) {\n\t\t// Add camera rig or camera directly to scene\n\t\tthis.addCameraToScene(scene, camera);\n\n\t\tif (rendererManager) {\n\t\t\t// New path: camera setup with shared renderer manager\n\t\t\tcamera.setup(scene, rendererManager);\n\t\t} else {\n\t\t\t// Legacy path: camera handles its own renderer\n\t\t\tcamera.setupLegacy(scene);\n\t\t}\n\t}\n\n\t/**\n\t * Setup with a CameraManager (multi-camera support).\n\t */\n\tasync setupCameraManager(scene: Scene, cameraManager: CameraManager, rendererManager: RendererManager): Promise<void> {\n\t\tthis.cameraManager = cameraManager;\n\n\t\t// Add all active cameras to the scene\n\t\tfor (const camera of cameraManager.activeCameras) {\n\t\t\tthis.addCameraToScene(scene, camera);\n\t\t}\n\n\t\t// Setup the camera manager (initializes all cameras)\n\t\tawait cameraManager.setup(scene, rendererManager);\n\t}\n\n\t/**\n\t * Add a camera (rig or direct) to the scene graph.\n\t */\n\tprivate addCameraToScene(scene: Scene, camera: ZylemCamera): void {\n\t\tif (camera.cameraRig) {\n\t\t\tscene.add(camera.cameraRig);\n\t\t} else {\n\t\t\tscene.add(camera.camera as Object3D);\n\t\t}\n\t}\n\n\t/**\n\t * Setup scene lighting\n\t */\n\tsetupLighting(scene: Scene) {\n\t\tconst ambientLight = new AmbientLight(0xffffff, 2);\n\t\tscene.add(ambientLight);\n\n\t\tconst directionalLight = new DirectionalLight(0xffffff, 2);\n\t\tdirectionalLight.name = 'Light';\n\t\tdirectionalLight.position.set(0, 100, 0);\n\t\tdirectionalLight.castShadow = true;\n\t\tdirectionalLight.shadow.camera.near = 0.1;\n\t\tdirectionalLight.shadow.camera.far = 2000;\n\t\tdirectionalLight.shadow.camera.left = -100;\n\t\tdirectionalLight.shadow.camera.right = 100;\n\t\tdirectionalLight.shadow.camera.top = 100;\n\t\tdirectionalLight.shadow.camera.bottom = -100;\n\t\tdirectionalLight.shadow.mapSize.width = 2048;\n\t\tdirectionalLight.shadow.mapSize.height = 2048;\n\t\tscene.add(directionalLight);\n\t}\n\n\t/**\n\t * Update renderer size - delegates to camera manager or camera\n\t */\n\tupdateRenderer(width: number, height: number) {\n\t\tif (this.cameraManager) {\n\t\t\t// Resize all cameras\n\t\t\tfor (const camera of this.cameraManager.allCameras) {\n\t\t\t\tcamera.resize(width, height);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.zylemCamera.resize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Add object to scene\n\t */\n\tadd(object: Object3D, position: Vector3 = new Vector3(0, 0, 0)) {\n\t\tobject.position.set(position.x, position.y, position.z);\n\t\tthis.scene.add(object);\n\t}\n\n\t/**\n\t * Add game entity to scene\n\t */\n\taddEntity(entity: GameEntity<any>) {\n\t\tconst target = entity.group ?? entity.mesh;\n\t\tif (!target || this.isAttachedOutsideScene(target)) return;\n\t\tthis.add(target, entity.options.position);\n\t}\n\n\t/**\n\t * Add an entity's group or mesh to the scene (for late-loaded models).\n\t * Uses entity's current body position if physics is active.\n\t */\n\taddEntityGroup(entity: GameEntity<any>): void {\n\t\tconst target = entity.group ?? entity.mesh;\n\t\tif (!target || this.isAttachedOutsideScene(target)) return;\n\n\t\tlet position = entity.options.position ?? new Vector3(0, 0, 0);\n\t\tif (entity.physicsAttached && entity.body) {\n\t\t\ttry {\n\t\t\t\tconst translation = entity.body.translation();\n\t\t\t\tposition = new Vector3(\n\t\t\t\t\ttranslation.x,\n\t\t\t\t\ttranslation.y,\n\t\t\t\t\ttranslation.z,\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\tposition = entity.options.position ?? new Vector3(0, 0, 0);\n\t\t\t}\n\t\t}\n\n\t\tthis.add(target, position);\n\t}\n\n\tprivate isAttachedOutsideScene(object: Object3D): boolean {\n\t\treturn object.parent != null && object.parent !== this.scene;\n\t}\n\n\t/**\n\t * Add debug helpers to scene\n\t */\n\tdebugScene() {\n\t\tconst size = 1000;\n\t\tconst divisions = 100;\n\n\t\tconst gridHelper = new GridHelper(size, divisions);\n\t\tthis.scene.add(gridHelper);\n\t}\n\n\t/**\n\t * Update skybox shader uniforms (only applies to GLSL ShaderMaterial)\n\t * TSL shaders use the time node which auto-updates\n\t */\n\tupdateSkybox(delta: number) {\n\t\tif (this.skyboxMaterial && this.skyboxMaterial instanceof ShaderMaterial) {\n\t\t\tif (this.skyboxMaterial.uniforms?.iTime) {\n\t\t\t\tthis.skyboxMaterial.uniforms.iTime.value += delta;\n\t\t\t}\n\t\t}\n\t}\n}\n","import { BufferGeometry, InstancedMesh, Material, Matrix4, Object3D, Vector3, Quaternion } from 'three';\nimport type { GameEntity, GameEntityOptions } from '../entities/entity';\nimport { shortHash, sortedStringify } from '../core/utility/strings';\n\n/**\n * Represents a batch of entities sharing the same geometry and material\n */\nexport interface BatchGroup {\n\t/** Unique key identifying this batch */\n\tkey: string;\n\t/** The instanced mesh for rendering */\n\tinstancedMesh: InstancedMesh;\n\t/** Original geometry */\n\tgeometry: BufferGeometry;\n\t/** Original material */\n\tmaterial: Material;\n\t/** Map of entity UUID to instance index */\n\tentityMap: Map<string, number>;\n\t/** List of entities in this batch (by their index) */\n\tentities: (GameEntity<any> | null)[];\n\t/** Indices that have been freed and can be reused */\n\tfreeIndices: number[];\n\t/** Active indices for fast iteration */\n\tactiveIndices: number[];\n\t/** Dirty flags for transforms that need syncing */\n\tdirtyIndices: Set<number>;\n\t/** Maximum capacity */\n\tcapacity: number;\n}\n\n/**\n * Configuration for batch key generation\n */\nexport interface BatchKeyConfig {\n\tgeometryType: string;\n\tdimensions: Record<string, number>;\n\tmaterialPath?: string | null;\n\tshaderType?: 'standard' | 'custom';\n\tcolorHex?: number;\n}\n\n/**\n * Manages instanced mesh batching for entities\n */\nexport class InstanceManager {\n\tprivate batches: Map<string, BatchGroup> = new Map();\n\tprivate entityToBatch: Map<string, string> = new Map(); // entity UUID -> batch key\n\tprivate scene: Object3D | null = null;\n\n\t/** Default initial capacity for new batches */\n\tstatic DEFAULT_CAPACITY = 128;\n\t/** Factor to grow batch when full */\n\tstatic GROWTH_FACTOR = 2;\n\n\t/**\n\t * Set the scene to add instanced meshes to\n\t */\n\tsetScene(scene: Object3D): void {\n\t\tthis.scene = scene;\n\t}\n\n\t/**\n\t * Generate a batch key from configuration\n\t */\n\tstatic generateBatchKey(config: BatchKeyConfig): string {\n\t\tconst keyData = {\n\t\t\tgeo: `${config.geometryType}:${sortedStringify(config.dimensions)}`,\n\t\t\tmat: config.materialPath || 'none',\n\t\t\tshader: config.shaderType || 'standard',\n\t\t\tcolor: config.colorHex ?? 0xffffff,\n\t\t};\n\t\treturn shortHash(sortedStringify(keyData));\n\t}\n\n\t/**\n\t * Register an entity with the instance manager\n\t * @returns The instance index, or -1 if registration failed\n\t */\n\tregister(\n\t\tentity: GameEntity<any>,\n\t\tgeometry: BufferGeometry,\n\t\tmaterial: Material,\n\t\tbatchKey: string\n\t): number {\n\t\tlet batch = this.batches.get(batchKey);\n\n\t\tif (!batch) {\n\t\t\tbatch = this.createBatch(batchKey, geometry, material);\n\t\t}\n\n\t\t// Get an index for this entity\n\t\tlet index: number;\n\t\tif (batch.freeIndices.length > 0) {\n\t\t\tindex = batch.freeIndices.pop()!;\n\t\t} else {\n\t\t\tindex = batch.entities.length;\n\t\t\tif (index >= batch.capacity) {\n\t\t\t\tthis.growBatch(batch);\n\t\t\t}\n\t\t\tbatch.entities.push(null);\n\t\t}\n\n\t\t// Store entity reference\n\t\tbatch.entities[index] = entity;\n\t\tbatch.entityMap.set(entity.uuid, index);\n\t\tthis.entityToBatch.set(entity.uuid, batchKey);\n\n\t\t// Update visible instance count\n\t\tbatch.instancedMesh.count = Math.max(batch.instancedMesh.count, index + 1);\n\n\t\t// Add to active list\n\t\tbatch.activeIndices.push(index);\n\n\t\t// Mark dirty for initial transform sync\n\t\tbatch.dirtyIndices.add(index);\n\n\t\treturn index;\n\t}\n\n\t/**\n\t * Unregister an entity from the instance manager\n\t */\n\tunregister(entity: GameEntity<any>): void {\n\t\tconst batchKey = this.entityToBatch.get(entity.uuid);\n\t\tif (!batchKey) return;\n\n\t\tconst batch = this.batches.get(batchKey);\n\t\tif (!batch) return;\n\n\t\tconst index = batch.entityMap.get(entity.uuid);\n\t\tif (index === undefined) return;\n\n\t\t// Clear the entity slot\n\t\tbatch.entities[index] = null;\n\t\tbatch.entityMap.delete(entity.uuid);\n\t\tthis.entityToBatch.delete(entity.uuid);\n\t\tbatch.freeIndices.push(index);\n\t\t// Remove from active list (swap and pop for O(1))\n\t\tconst idxInActive = batch.activeIndices.indexOf(index);\n\t\tif (idxInActive !== -1) {\n\t\t\tconst last = batch.activeIndices.pop()!;\n\t\t\tif (idxInActive < batch.activeIndices.length) {\n\t\t\t\tbatch.activeIndices[idxInActive] = last;\n\t\t\t}\n\t\t}\n\t\tbatch.dirtyIndices.delete(index);\n\n\t\t// Hide the instance by scaling to zero\n\t\tconst matrix = new Matrix4();\n\t\tmatrix.makeScale(0, 0, 0);\n\t\tbatch.instancedMesh.setMatrixAt(index, matrix);\n\t\tbatch.instancedMesh.instanceMatrix.needsUpdate = true;\n\t}\n\n\t/**\n\t * Mark an entity's transform as dirty (needs syncing)\n\t */\n\tmarkDirty(entity: GameEntity<any>): void {\n\t\tconst batchKey = this.entityToBatch.get(entity.uuid);\n\t\tif (!batchKey) return;\n\n\t\tconst batch = this.batches.get(batchKey);\n\t\tif (!batch) return;\n\n\t\tconst index = batch.entityMap.get(entity.uuid);\n\t\tif (index !== undefined) {\n\t\t\tbatch.dirtyIndices.add(index);\n\t\t}\n\t}\n\n\t/**\n\t * Update all dirty instance transforms\n\t * Call this once per frame\n\t */\n\t/**\n\t * Update all active instance transforms\n\t * Call this once per frame\n\t */\n\tupdate(): void {\n\t\tconst matrix = new Matrix4();\n\t\tconst pos = new Vector3();\n\t\tconst quat = new Quaternion();\n\t\tconst scale = new Vector3(1, 1, 1);\n\n\t\tfor (const batch of this.batches.values()) {\n\t\t\tif (batch.activeIndices.length === 0) continue;\n\n\t\t\tlet needsUpdate = false;\n\t\t\t// Check if we have explicit dirty updates\n\t\t\tif (batch.dirtyIndices.size > 0) {\n\t\t\t\tfor (const index of batch.dirtyIndices) {\n\t\t\t\t\tthis.updateInstanceMatrix(batch, index, matrix, pos, quat, scale);\n\t\t\t\t}\n\t\t\t\tbatch.dirtyIndices.clear();\n\t\t\t\tneedsUpdate = true;\n\t\t\t}\n\n\t\t\t// Also update all active dynamic entities (assumed dynamic if they have a body)\n\t\t\tfor (const index of batch.activeIndices) {\n\t\t\t\tconst entity = batch.entities[index];\n\t\t\t\t// Optimization: Only update if it has a physics body (dynamic)\n\t\t\t\tif (entity && entity.body) {\n\t\t\t\t\tthis.updateInstanceMatrix(batch, index, matrix, pos, quat, scale);\n\t\t\t\t\tneedsUpdate = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (needsUpdate) {\n\t\t\t\tbatch.instancedMesh.instanceMatrix.needsUpdate = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate updateInstanceMatrix(batch: BatchGroup, index: number, matrix: Matrix4, pos: Vector3, quat: Quaternion, scale: Vector3) {\n\t\tconst entity = batch.entities[index];\n\t\tif (!entity) return;\n\n\t\tif (entity.body) {\n\t\t\tconst translation = entity.body.translation();\n\t\t\tconst rotation = entity.body.rotation();\n\t\t\tpos.set(translation.x, translation.y, translation.z);\n\t\t\tquat.set(rotation.x, rotation.y, rotation.z, rotation.w);\n\t\t\tmatrix.compose(pos, quat, scale);\n\t\t} else if (entity.mesh) {\n\t\t\tentity.mesh.updateMatrix();\n\t\t\tmatrix.copy(entity.mesh.matrix);\n\t\t} else if (entity.group) {\n\t\t\tentity.group.updateMatrix();\n\t\t\tmatrix.copy(entity.group.matrix);\n\t\t}\n\n\t\tbatch.instancedMesh.setMatrixAt(index, matrix);\n\t}\n\n\t/**\n\t * Get batch info for an entity\n\t */\n\tgetBatchInfo(entity: GameEntity<any>): { batchKey: string; instanceId: number } | null {\n\t\tconst batchKey = this.entityToBatch.get(entity.uuid);\n\t\tif (!batchKey) return null;\n\n\t\tconst batch = this.batches.get(batchKey);\n\t\tif (!batch) return null;\n\n\t\tconst instanceId = batch.entityMap.get(entity.uuid);\n\t\tif (instanceId === undefined) return null;\n\n\t\treturn { batchKey, instanceId };\n\t}\n\n\t/**\n\t * Get statistics about current batching\n\t */\n\tgetStats(): { batchCount: number; totalInstances: number; batches: { key: string; count: number; capacity: number }[] } {\n\t\tlet totalInstances = 0;\n\t\tconst batches: { key: string; count: number; capacity: number }[] = [];\n\n\t\tfor (const [key, batch] of this.batches) {\n\t\t\tconst count = batch.entityMap.size;\n\t\t\ttotalInstances += count;\n\t\t\tbatches.push({ key, count, capacity: batch.capacity });\n\t\t}\n\n\t\treturn { batchCount: this.batches.size, totalInstances, batches };\n\t}\n\n\t/**\n\t * Dispose all batches and release resources\n\t */\n\tdispose(): void {\n\t\tfor (const batch of this.batches.values()) {\n\t\t\tif (this.scene) {\n\t\t\t\tthis.scene.remove(batch.instancedMesh);\n\t\t\t}\n\t\t\tbatch.instancedMesh.dispose();\n\t\t\tbatch.geometry.dispose();\n\t\t}\n\t\tthis.batches.clear();\n\t\tthis.entityToBatch.clear();\n\t}\n\n\t/**\n\t * Create a new batch group\n\t */\n\tprivate createBatch(key: string, geometry: BufferGeometry, material: Material): BatchGroup {\n\t\tconst capacity = InstanceManager.DEFAULT_CAPACITY;\n\t\tconst instancedMesh = new InstancedMesh(geometry, material, capacity);\n\t\tinstancedMesh.count = 0; // Start with zero visible instances\n\t\tinstancedMesh.frustumCulled = false; // Let individual instances handle culling\n\n\t\t// Initialize all matrices to hidden (zero scale)\n\t\tconst hiddenMatrix = new Matrix4().makeScale(0, 0, 0);\n\t\tfor (let i = 0; i < capacity; i++) {\n\t\t\tinstancedMesh.setMatrixAt(i, hiddenMatrix);\n\t\t}\n\t\tinstancedMesh.instanceMatrix.needsUpdate = true;\n\n\t\tconst batch: BatchGroup = {\n\t\t\tkey,\n\t\t\tinstancedMesh,\n\t\t\tgeometry,\n\t\t\tmaterial,\n\t\t\tentityMap: new Map(),\n\t\t\tentities: [],\n\t\t\tfreeIndices: [],\n\t\t\tactiveIndices: [],\n\t\t\tdirtyIndices: new Set(),\n\t\t\tcapacity,\n\t\t};\n\n\t\tthis.batches.set(key, batch);\n\n\t\tif (this.scene) {\n\t\t\tthis.scene.add(instancedMesh);\n\t\t}\n\n\t\treturn batch;\n\t}\n\n\t/**\n\t * Grow a batch's capacity\n\t */\n\tprivate growBatch(batch: BatchGroup): void {\n\t\tconst newCapacity = batch.capacity * InstanceManager.GROWTH_FACTOR;\n\n\t\t// Create new instanced mesh with larger capacity\n\t\tconst newInstancedMesh = new InstancedMesh(batch.geometry, batch.material, newCapacity);\n\t\tnewInstancedMesh.count = batch.instancedMesh.count;\n\t\tnewInstancedMesh.frustumCulled = false;\n\n\t\t// Copy existing matrices\n\t\tconst matrix = new Matrix4();\n\t\tfor (let i = 0; i < batch.capacity; i++) {\n\t\t\tbatch.instancedMesh.getMatrixAt(i, matrix);\n\t\t\tnewInstancedMesh.setMatrixAt(i, matrix);\n\t\t}\n\n\t\t// Initialize new slots as hidden\n\t\tconst hiddenMatrix = new Matrix4().makeScale(0, 0, 0);\n\t\tfor (let i = batch.capacity; i < newCapacity; i++) {\n\t\t\tnewInstancedMesh.setMatrixAt(i, hiddenMatrix);\n\t\t}\n\t\tnewInstancedMesh.instanceMatrix.needsUpdate = true;\n\n\t\t// Swap meshes\n\t\tif (this.scene) {\n\t\t\tthis.scene.remove(batch.instancedMesh);\n\t\t\tthis.scene.add(newInstancedMesh);\n\t\t}\n\t\tbatch.instancedMesh.dispose();\n\t\tbatch.instancedMesh = newInstancedMesh;\n\t\tbatch.capacity = newCapacity;\n\t}\n}\n","import { Color, Vector3 as ThreeVector3 } from 'three';\nimport { Vector3 } from '@dimforge/rapier3d-compat';\n\n// TODO: needs implementations\n/**\n * @deprecated This type is deprecated.\n */\nexport type Vect3 = ThreeVector3 | Vector3;\n\nexport const ZylemBlueColor = new Color('#0333EC');\nexport const ZylemBlue = '#0333EC';\nexport const ZylemBlueTransparent = '#0333ECA0';\nexport const ZylemGoldText = '#DAA420';\n\nexport const Vec0 = new Vector3(0, 0, 0);\nexport const Vec1 = new Vector3(1, 1, 1);","import { Color, Vector3 } from 'three';\nimport { proxy, subscribe } from 'valtio/vanilla';\nimport { BaseEntityInterface, GameEntityInterface } from '../types/entity-types';\nimport { StageStateInterface } from '../types/stage-types';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\nimport { ZylemBlueColor } from '../core/utility/vector';\n\n/**\n * Initial stage state with default values.\n * Exported for use in ZylemStage construction.\n */\nexport const initialStageState = {\n\tbackgroundColor: ZylemBlueColor,\n\tbackgroundImage: null,\n\tbackgroundShader: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard'],\n\t\tp2: ['gamepad-2', 'keyboard'],\n\t},\n\tgravity: new Vector3(0, 0, 0),\n\tvariables: {},\n\tphysicsRate: 60,\n\tusePhysicsWorker: false,\n\tphysicsWorkerUrl: undefined as URL | string | undefined,\n\tentities: [] as GameEntityInterface[],\n};\n\n/**\n * Stage state proxy for reactive updates.\n */\nconst stageState = proxy({\n\tbackgroundColor: new Color(Color.NAMES.cornflowerblue),\n\tbackgroundImage: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard-1'],\n\t\tp2: ['gamepad-2', 'keyboard-2'],\n\t},\n\tvariables: {},\n\tgravity: new Vector3(0, 0, 0),\n\tentities: [],\n} as StageStateInterface);\n\n// ============================================================\n// Stage state setters (internal use)\n// ============================================================\n\nconst setStageBackgroundColor = (value: Color) => {\n\tstageState.backgroundColor = value;\n};\n\nconst setStageBackgroundImage = (value: string | null) => {\n\tstageState.backgroundImage = value;\n};\n\nconst setEntitiesToStage = (entities: Partial<BaseEntityInterface>[]) => {\n\tstageState.entities = entities;\n};\n\n/** Replace the entire stage variables object (used on stage load). */\nconst setStageVariables = (variables: Record<string, any>) => {\n\tstageState.variables = { ...variables };\n};\n\n/** Reset all stage variables (used on stage unload). */\nconst resetStageVariables = () => {\n\tstageState.variables = {};\n};\n\nconst stageStateToString = (state: StageStateInterface) => {\n\tlet string = `\\n`;\n\tfor (const key in state) {\n\t\tconst value = state[key as keyof StageStateInterface];\n\t\tstring += `${key}:\\n`;\n\t\tif (key === 'entities') {\n\t\t\tfor (const entity of state.entities) {\n\t\t\t\tstring += ` ${entity.uuid}: ${entity.name}\\n`;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (typeof value === 'object' && value !== null) {\n\t\t\tfor (const subKey in value as Record<string, any>) {\n\t\t\t\tconst subValue = value?.[subKey as keyof typeof value];\n\t\t\t\tif (subValue) {\n\t\t\t\t\tstring += ` ${subKey}: ${subValue}\\n`;\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof value === 'string') {\n\t\t\tstring += ` ${key}: ${value}\\n`;\n\t\t}\n\t}\n\treturn string;\n};\n\n// ============================================================\n// Object-scoped variable storage (WeakMap-based)\n// ============================================================\n\n/**\n * WeakMap to store variables keyed by object reference.\n * Variables are automatically garbage collected when the target is collected.\n */\nconst variableStore = new WeakMap<object, Record<string, unknown>>();\n\n/**\n * Separate proxy store for reactivity. We need a regular Map for subscriptions\n * since WeakMap doesn't support iteration/subscriptions.\n */\nconst variableProxyStore = new Map<object, ReturnType<typeof proxy>>();\n\nfunction getOrCreateVariableProxy(target: object): Record<string, unknown> {\n\tlet store = variableProxyStore.get(target) as Record<string, unknown> | undefined;\n\tif (!store) {\n\t\tstore = proxy({});\n\t\tvariableProxyStore.set(target, store);\n\t}\n\treturn store;\n}\n\n/**\n * Set a variable on an object by path.\n * @example setVariable(stage1, 'totalAngle', 0.5)\n * @example setVariable(entity, 'enemy.count', 10)\n */\nexport function setVariable(target: object, path: string, value: unknown): void {\n\tconst store = getOrCreateVariableProxy(target);\n\tsetByPath(store, path, value);\n}\n\n/**\n * Create/initialize a variable with a default value on a target object.\n * Only sets the value if it doesn't already exist.\n * @example createVariable(stage1, 'totalAngle', 0)\n * @example createVariable(entity, 'enemy.count', 10)\n */\nexport function createVariable<T>(target: object, path: string, defaultValue: T): T {\n\tconst store = getOrCreateVariableProxy(target);\n\tconst existing = getByPath<T>(store, path);\n\tif (existing === undefined) {\n\t\tsetByPath(store, path, defaultValue);\n\t\treturn defaultValue;\n\t}\n\treturn existing;\n}\n\n/**\n * Get a variable from an object by path.\n * @example getVariable(stage1, 'totalAngle') // 0.5\n * @example getVariable<number>(entity, 'enemy.count') // 10\n */\nexport function getVariable<T = unknown>(target: object, path: string): T | undefined {\n\tconst store = variableProxyStore.get(target);\n\tif (!store) return undefined;\n\treturn getByPath<T>(store, path);\n}\n\n/**\n * Subscribe to changes on a variable at a specific path for a target object.\n * Returns an unsubscribe function.\n * @example const unsub = onVariableChange(stage1, 'score', (val) => console.log(val));\n */\nexport function onVariableChange<T = unknown>(\n\ttarget: object,\n\tpath: string,\n\tcallback: (value: T) => void\n): () => void {\n\tconst store = getOrCreateVariableProxy(target);\n\tlet previous = getByPath<T>(store, path);\n\treturn subscribe(store, () => {\n\t\tconst current = getByPath<T>(store, path);\n\t\tif (current !== previous) {\n\t\t\tprevious = current;\n\t\t\tcallback(current as T);\n\t\t}\n\t});\n}\n\n/**\n * Subscribe to changes on multiple variable paths for a target object.\n * Callback fires when any of the paths change, receiving all current values.\n * Returns an unsubscribe function.\n * @example const unsub = onVariableChanges(stage1, ['count', 'total'], ([count, total]) => console.log(count, total));\n */\nexport function onVariableChanges<T extends unknown[] = unknown[]>(\n\ttarget: object,\n\tpaths: string[],\n\tcallback: (values: T) => void\n): () => void {\n\tconst store = getOrCreateVariableProxy(target);\n\tlet previousValues = paths.map(p => getByPath(store, p));\n\treturn subscribe(store, () => {\n\t\tconst currentValues = paths.map(p => getByPath(store, p));\n\t\tconst hasChange = currentValues.some((val, i) => val !== previousValues[i]);\n\t\tif (hasChange) {\n\t\t\tpreviousValues = currentValues;\n\t\t\tcallback(currentValues as T);\n\t\t}\n\t});\n}\n\n/**\n * Clear all variables for a target object. Used on stage/entity dispose.\n */\nexport function clearVariables(target: object): void {\n\tvariableProxyStore.delete(target);\n}\n\n// ============================================================\n// Legacy stage variable functions (internal, for stage defaults)\n// ============================================================\n\nconst setStageVariable = (key: string, value: any) => {\n\tstageState.variables[key] = value;\n};\n\nconst getStageVariable = (key: string) => {\n\tif (stageState.variables.hasOwnProperty(key)) {\n\t\treturn stageState.variables[key];\n\t} else {\n\t\tconsole.warn(`Stage variable ${key} not found`);\n\t}\n};\n\nexport {\n\tstageState,\n\t\n\tsetStageBackgroundColor,\n\tsetStageBackgroundImage,\n\t\n\tstageStateToString,\n\tsetStageVariable,\n\tgetStageVariable,\n\tsetStageVariables,\n\tresetStageVariables,\n};","import { DestroyContext, DestroyFunction, SetupContext, SetupFunction, UpdateContext, UpdateFunction } from './base-node-life-cycle';\n\n/**\n * Provides BaseNode-like lifecycle without ECS/children. Consumers implement\n * the protected hooks and may assign public setup/update/destroy callbacks.\n */\nexport abstract class LifeCycleBase<TSelf> {\n\tupdate: UpdateFunction<TSelf> = () => { };\n\tsetup: SetupFunction<TSelf> = () => { };\n\tdestroy: DestroyFunction<TSelf> = () => { };\n\n\tprotected abstract _setup(context: SetupContext<TSelf>): void;\n\tprotected abstract _update(context: UpdateContext<TSelf>): void;\n\tprotected abstract _destroy(context: DestroyContext<TSelf>): void;\n\n\tnodeSetup(context: SetupContext<TSelf>) {\n\t\tif (typeof (this as any)._setup === 'function') {\n\t\t\tthis._setup(context);\n\t\t}\n\t\tif (this.setup) {\n\t\t\tthis.setup(context);\n\t\t}\n\t}\n\n\tnodeUpdate(context: UpdateContext<TSelf>) {\n\t\tif (typeof (this as any)._update === 'function') {\n\t\t\tthis._update(context);\n\t\t}\n\t\tif (this.update) {\n\t\t\tthis.update(context);\n\t\t}\n\t}\n\n\tnodeDestroy(context: DestroyContext<TSelf>) {\n\t\tif (this.destroy) {\n\t\t\tthis.destroy(context);\n\t\t}\n\t\tif (typeof (this as any)._destroy === 'function') {\n\t\t\tthis._destroy(context);\n\t\t}\n\t}\n}\n\n\n","import { Object3D } from 'three';\nimport { subscribe } from 'valtio/vanilla';\n\nimport type { CameraDebugDelegate, CameraDebugState } from '../camera/zylem-camera';\nimport { debugState } from '../debug/debug-state';\nimport type { ZylemStage } from './zylem-stage';\n\nconst cloneSelected = (selected: string[]): string[] => [...selected];\n\n/**\n * Debug delegate that bridges the stage's entity map and debug state to the camera.\n */\nexport class StageCameraDebugDelegate implements CameraDebugDelegate {\n\tprivate stage: ZylemStage;\n\n\tconstructor(stage: ZylemStage) {\n\t\tthis.stage = stage;\n\t}\n\n\tsubscribe(listener: (state: CameraDebugState) => void): () => void {\n\t\tconst notify = () => listener(this.snapshot());\n\t\tnotify();\n\t\treturn subscribe(debugState, notify);\n\t}\n\n\tresolveTarget(uuid: string): Object3D | null {\n\t\tconst entity: any = this.stage.entityDelegate.debugMap.get(uuid)\n\t\t\t|| this.stage.world?.collisionMap.get(uuid)\n\t\t\t|| null;\n\t\tconst target = entity?.group ?? entity?.mesh ?? null;\n\t\treturn target ?? null;\n\t}\n\n\tprivate snapshot(): CameraDebugState {\n\t\treturn {\n\t\t\tenabled: debugState.enabled,\n\t\t\tselected: debugState.selectedEntity ? [debugState.selectedEntity.uuid] : [],\n\t\t};\n\t}\n}\n\n","import {\n\tBox3,\n\tBoxGeometry,\n\tColor,\n\tEdgesGeometry,\n\tGroup,\n\tLineBasicMaterial,\n\tLineSegments,\n\tMesh,\n\tMeshBasicMaterial,\n\tObject3D,\n\tScene,\n\tVector3,\n} from 'three';\n\n/**\n * Debug overlay that displays an axis-aligned bounding box around a target Object3D.\n * Shows a semi-transparent fill plus a wireframe outline. Intended for SELECT/DELETE tools.\n */\nexport class DebugEntityCursor {\n\tprivate scene: Scene;\n\tprivate container: Group;\n\tprivate fillMesh: Mesh;\n\tprivate edgeLines: LineSegments;\n\tprivate currentColor: Color = new Color(0x00ff00);\n\tprivate bbox: Box3 = new Box3();\n\tprivate size: Vector3 = new Vector3();\n\tprivate center: Vector3 = new Vector3();\n\n\tconstructor(scene: Scene) {\n\t\tthis.scene = scene;\n\n\t\tconst initialGeometry = new BoxGeometry(1, 1, 1);\n\n\t\tthis.fillMesh = new Mesh(\n\t\t\tinitialGeometry,\n\t\t\tnew MeshBasicMaterial({\n\t\t\t\tcolor: this.currentColor,\n\t\t\t\ttransparent: true,\n\t\t\t\topacity: 0.12,\n\t\t\t\tdepthWrite: false,\n\t\t\t})\n\t\t);\n\n\t\tconst edges = new EdgesGeometry(initialGeometry);\n\t\tthis.edgeLines = new LineSegments(\n\t\t\tedges,\n\t\t\tnew LineBasicMaterial({ color: this.currentColor, linewidth: 1 })\n\t\t);\n\n\t\tthis.container = new Group();\n\t\tthis.container.name = 'DebugEntityCursor';\n\t\tthis.container.add(this.fillMesh);\n\t\tthis.container.add(this.edgeLines);\n\t\tthis.container.visible = false;\n\n\t\tthis.scene.add(this.container);\n\t}\n\n\tsetColor(color: Color | number): void {\n\t\tthis.currentColor.set(color as any);\n\t\t(this.fillMesh.material as MeshBasicMaterial).color.set(this.currentColor);\n\t\t(this.edgeLines.material as LineBasicMaterial).color.set(this.currentColor);\n\t}\n\n\t/**\n\t * Update the cursor to enclose the provided Object3D using a world-space AABB.\n\t */\n\tupdateFromObject(object: Object3D | null | undefined): void {\n\t\tif (!object) {\n\t\t\tthis.hide();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.bbox.setFromObject(object);\n\t\tif (!isFinite(this.bbox.min.x) || !isFinite(this.bbox.max.x)) {\n\t\t\tthis.hide();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.bbox.getSize(this.size);\n\t\tthis.bbox.getCenter(this.center);\n\n\t\tconst newGeom = new BoxGeometry(\n\t\t\tMath.max(this.size.x, 1e-6),\n\t\t\tMath.max(this.size.y, 1e-6),\n\t\t\tMath.max(this.size.z, 1e-6)\n\t\t);\n\t\tthis.fillMesh.geometry.dispose();\n\t\tthis.fillMesh.geometry = newGeom;\n\n\t\tconst newEdges = new EdgesGeometry(newGeom);\n\t\tthis.edgeLines.geometry.dispose();\n\t\tthis.edgeLines.geometry = newEdges;\n\n\t\tthis.container.position.copy(this.center);\n\t\tthis.container.visible = true;\n\t}\n\n\thide(): void {\n\t\tthis.container.visible = false;\n\t}\n\n\tdispose(): void {\n\t\tthis.scene.remove(this.container);\n\t\tthis.fillMesh.geometry.dispose();\n\t\t(this.fillMesh.material as MeshBasicMaterial).dispose();\n\t\tthis.edgeLines.geometry.dispose();\n\t\t(this.edgeLines.material as LineBasicMaterial).dispose();\n\t}\n}\n\n\n","import { Ray, RayColliderToi } from '@dimforge/rapier3d-compat';\nimport { BufferAttribute, BufferGeometry, LineBasicMaterial, LineSegments, Raycaster, Vector2, Vector3 } from 'three';\nimport { subscribe } from 'valtio/vanilla';\nimport { ZylemStage } from './zylem-stage';\nimport { StageCameraDebugDelegate } from './stage-camera-debug-delegate';\nimport { debugState, getDebugTool, getHoveredEntity, resetHoveredEntity, setHoveredEntity, setSelectedEntity } from '../debug/debug-state';\nimport { DebugEntityCursor } from './debug-entity-cursor';\n\nexport type AddEntityFactory = (params: { position: Vector3; normal?: Vector3 }) => Promise<any> | any;\n\nexport interface StageDebugDelegateOptions {\n\tmaxRayDistance?: number;\n\taddEntityFactory?: AddEntityFactory | null;\n}\n\nconst SELECT_TOOL_COLOR = 0x22ff22;\nconst DELETE_TOOL_COLOR = 0xff3333;\n\n/**\n * Self-managing debug delegate that subscribes to `debugState` internally.\n *\n * When debug is enabled it lazily initializes visuals and DOM listeners.\n * When debug is disabled it tears down visuals but stays alive so it can\n * re-activate without being recreated. Call `dispose()` to fully tear down.\n */\nexport class StageDebugDelegate {\n\tprivate stage: ZylemStage;\n\tprivate options: Required<StageDebugDelegateOptions>;\n\tprivate mouseNdc: Vector2 = new Vector2(-2, -2);\n\tprivate raycaster: Raycaster = new Raycaster();\n\tprivate isMouseDown = false;\n\tprivate domDisposeFns: Array<() => void> = [];\n\tprivate domListenersAttached = false;\n\tprivate debugCursor: DebugEntityCursor | null = null;\n\tprivate debugLines: LineSegments | null = null;\n\tprivate cameraDebugDelegate: StageCameraDebugDelegate | null = null;\n\tprivate debugStateUnsubscribe: (() => void) | null = null;\n\n\tconstructor(stage: ZylemStage, options?: StageDebugDelegateOptions) {\n\t\tthis.stage = stage;\n\t\tthis.options = {\n\t\t\tmaxRayDistance: options?.maxRayDistance ?? 5_000,\n\t\t\taddEntityFactory: options?.addEntityFactory ?? null,\n\t\t};\n\n\t\t// Self-managing: sync with current state then subscribe for changes\n\t\tthis.syncWithDebugState();\n\t\tthis.debugStateUnsubscribe = subscribe(debugState, () => {\n\t\t\tthis.syncWithDebugState();\n\t\t});\n\t}\n\n\tprivate syncWithDebugState(): void {\n\t\tif (debugState.enabled) {\n\t\t\tthis.activate();\n\t\t} else {\n\t\t\tthis.deactivate();\n\t\t}\n\t}\n\n\t/** Initialize DOM listeners and camera debug delegate when debug is turned on. */\n\tprivate activate(): void {\n\t\tif (!this.domListenersAttached) {\n\t\t\tthis.attachDomListeners();\n\t\t\tthis.domListenersAttached = true;\n\t\t}\n\n\t\tif (this.stage.cameraRef && !this.cameraDebugDelegate) {\n\t\t\tthis.cameraDebugDelegate = new StageCameraDebugDelegate(this.stage);\n\t\t\tthis.stage.cameraRef.setDebugDelegate(this.cameraDebugDelegate);\n\t\t}\n\t}\n\n\t/** Tear down visuals and camera debug delegate when debug is turned off. */\n\tprivate deactivate(): void {\n\t\tthis.disposeDebugVisuals();\n\n\t\tif (this.stage.cameraRef) {\n\t\t\tthis.stage.cameraRef.setDebugDelegate(null);\n\t\t}\n\t\tthis.cameraDebugDelegate = null;\n\t}\n\n\tprivate initDebugVisuals(): void {\n\t\tif (this.debugLines || !this.stage.scene) return;\n\n\t\tthis.debugLines = new LineSegments(\n\t\t\tnew BufferGeometry(),\n\t\t\tnew LineBasicMaterial({ vertexColors: true })\n\t\t);\n\t\tthis.stage.scene.scene.add(this.debugLines);\n\t\tthis.debugLines.visible = true;\n\n\t\tthis.debugCursor = new DebugEntityCursor(this.stage.scene.scene);\n\t}\n\n\tprivate disposeDebugVisuals(): void {\n\t\tif (this.debugLines && this.stage.scene) {\n\t\t\tthis.stage.scene.scene.remove(this.debugLines);\n\t\t\tthis.debugLines.geometry.dispose();\n\t\t\t(this.debugLines.material as LineBasicMaterial).dispose();\n\t\t\tthis.debugLines = null;\n\t\t}\n\t\tthis.debugCursor?.dispose();\n\t\tthis.debugCursor = null;\n\t}\n\n\tupdate(): void {\n\t\tif (!debugState.enabled) {\n\t\t\tif (this.debugLines) {\n\t\t\t\tthis.disposeDebugVisuals();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.stage.scene || !this.stage.world || !this.stage.cameraRef) return;\n\n\t\tif (!this.debugLines) {\n\t\t\tthis.initDebugVisuals();\n\t\t}\n\n\t\tconst { world, cameraRef } = this.stage;\n\n\t\t// Debug rendering and raycasting require the direct Rapier world\n\t\t// instance, which is not available in worker mode.\n\t\tconst hasDirectWorld = world.world != null;\n\n\t\tif (this.debugLines && hasDirectWorld) {\n\t\t\tconst { vertices, colors } = world.world.debugRender();\n\t\t\tthis.debugLines.geometry.setAttribute('position', new BufferAttribute(vertices, 3));\n\t\t\tthis.debugLines.geometry.setAttribute('color', new BufferAttribute(colors, 4));\n\t\t}\n\t\tconst tool = getDebugTool();\n\t\tconst isCursorTool = tool === 'select' || tool === 'delete';\n\n\t\tlet hit: RayColliderToi | null = null;\n\t\tlet origin: Vector3 | null = null;\n\t\tlet direction: Vector3 | null = null;\n\n\t\tif (hasDirectWorld) {\n\t\t\tthis.raycaster.setFromCamera(this.mouseNdc, cameraRef.camera);\n\t\t\torigin = this.raycaster.ray.origin.clone();\n\t\t\tdirection = this.raycaster.ray.direction.clone().normalize();\n\n\t\t\tconst rapierRay = new Ray(\n\t\t\t\t{ x: origin.x, y: origin.y, z: origin.z },\n\t\t\t\t{ x: direction.x, y: direction.y, z: direction.z },\n\t\t\t);\n\t\t\thit = world.world.castRay(rapierRay, this.options.maxRayDistance, true);\n\t\t}\n\n\t\tif (hit && isCursorTool) {\n\t\t\t// @ts-ignore - access compat object's parent userData mapping back to GameEntity\n\t\t\tconst rigidBody = hit.collider?._parent;\n\t\t\tconst hoveredUuid: string | undefined = rigidBody?.userData?.uuid;\n\t\t\tif (hoveredUuid) {\n\t\t\t\tconst entity = this.stage.entityDelegate.debugMap.get(hoveredUuid);\n\t\t\t\tif (entity) setHoveredEntity(entity as any);\n\t\t\t} else {\n\t\t\t\tresetHoveredEntity();\n\t\t\t}\n\n\t\t\tif (this.isMouseDown && origin && direction) {\n\t\t\t\tthis.handleActionOnHit(hoveredUuid ?? null, origin, direction, hit.toi);\n\t\t\t}\n\t\t}\n\t\tthis.isMouseDown = false;\n\n\t\tconst hoveredUuid = getHoveredEntity();\n\t\tif (!hoveredUuid) {\n\t\t\tthis.debugCursor?.hide();\n\t\t\treturn;\n\t\t}\n\t\tconst hoveredEntity: any = this.stage.entityDelegate.debugMap.get(`${hoveredUuid}`);\n\t\tconst targetObject = hoveredEntity?.group ?? hoveredEntity?.mesh ?? null;\n\t\tif (!targetObject) {\n\t\t\tthis.debugCursor?.hide();\n\t\t\treturn;\n\t\t}\n\t\tswitch (tool) {\n\t\t\tcase 'select':\n\t\t\t\tthis.debugCursor?.setColor(SELECT_TOOL_COLOR);\n\t\t\t\tbreak;\n\t\t\tcase 'delete':\n\t\t\t\tthis.debugCursor?.setColor(DELETE_TOOL_COLOR);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.debugCursor?.setColor(0xffffff);\n\t\t\t\tbreak;\n\t\t}\n\t\tthis.debugCursor?.updateFromObject(targetObject);\n\t}\n\n\t/** Full teardown — unsubscribes from debugState and cleans up all resources. */\n\tdispose(): void {\n\t\tthis.debugStateUnsubscribe?.();\n\t\tthis.debugStateUnsubscribe = null;\n\t\tthis.deactivate();\n\t\tthis.domDisposeFns.forEach((fn) => fn());\n\t\tthis.domDisposeFns = [];\n\t\tthis.domListenersAttached = false;\n\t}\n\n\tprivate handleActionOnHit(hoveredUuid: string | null, origin: Vector3, direction: Vector3, toi: number) {\n\t\tconst tool = getDebugTool();\n\t\tswitch (tool) {\n\t\t\tcase 'select': {\n\t\t\t\tif (hoveredUuid) {\n\t\t\t\t\tconst entity = this.stage.entityDelegate.debugMap.get(hoveredUuid);\n\t\t\t\t\tif (entity) setSelectedEntity(entity as any);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'delete': {\n\t\t\t\tif (hoveredUuid) {\n\t\t\t\t\tthis.stage.entityDelegate.removeEntityByUuid(hoveredUuid);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\tif (!this.options.addEntityFactory) break;\n\t\t\t\tconst hitPosition = origin.clone().add(direction.clone().multiplyScalar(toi));\n\t\t\t\tconst newNode = this.options.addEntityFactory({ position: hitPosition });\n\t\t\t\tif (newNode) {\n\t\t\t\t\tPromise.resolve(newNode).then((node) => {\n\t\t\t\t\t\tif (node) this.stage.entityDelegate.spawnEntity(node);\n\t\t\t\t\t}).catch(() => { });\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate attachDomListeners() {\n\t\tconst canvas = this.stage.cameraRef?.renderer.domElement ?? this.stage.scene?.zylemCamera.renderer.domElement;\n\t\tif (!canvas) return;\n\n\t\tconst onMouseMove = (e: MouseEvent) => {\n\t\t\tconst rect = canvas.getBoundingClientRect();\n\t\t\tconst x = ((e.clientX - rect.left) / rect.width) * 2 - 1;\n\t\t\tconst y = -(((e.clientY - rect.top) / rect.height) * 2 - 1);\n\t\t\tthis.mouseNdc.set(x, y);\n\t\t};\n\n\t\tconst onMouseDown = () => {\n\t\t\tthis.isMouseDown = true;\n\t\t};\n\n\t\tcanvas.addEventListener('mousemove', onMouseMove);\n\t\tcanvas.addEventListener('mousedown', onMouseDown);\n\n\t\tthis.domDisposeFns.push(() => canvas.removeEventListener('mousemove', onMouseMove));\n\t\tthis.domDisposeFns.push(() => canvas.removeEventListener('mousedown', onMouseDown));\n\t}\n}\n","export const Perspectives = {\n\tFirstPerson: 'first-person',\n\tThirdPerson: 'third-person',\n\tIsometric: 'isometric',\n\tFlat2D: 'flat-2d',\n\tFixed2D: 'fixed-2d',\n\tTopDown: 'top-down',\n} as const;\n\nexport type PerspectiveType = (typeof Perspectives)[keyof typeof Perspectives];\n","import { Object3D, Vector3, Quaternion, Camera, Scene } from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n\nexport interface CameraDebugState {\n\tenabled: boolean;\n\tselected: string[];\n}\n\nexport interface CameraDebugDelegate {\n\tsubscribe(listener: (state: CameraDebugState) => void): () => void;\n\tresolveTarget(uuid: string): Object3D | null;\n}\n\n/**\n * Manages orbit controls for a camera.\n * Supports two modes:\n * 1. **Debug mode**: orbit controls activated by the debug system, with save/restore of camera state\n * 2. **User mode**: orbit controls enabled by the user via `useOrbitalControls` camera option\n *\n * These modes are independent -- debug mode takes precedence but user mode\n * keeps orbit controls active even outside debug.\n */\nexport class CameraOrbitController {\n\tprivate camera: Camera;\n\tprivate domElement: HTMLElement;\n\tprivate cameraRig: Object3D | null = null;\n\tprivate sceneRef: Scene | null = null;\n\t\n\tprivate orbitControls: OrbitControls | null = null;\n\tprivate orbitTarget: Object3D | null = null;\n\tprivate orbitTargetWorldPos: Vector3 = new Vector3();\n\n\tprivate debugDelegate: CameraDebugDelegate | null = null;\n\tprivate debugUnsubscribe: (() => void) | null = null;\n\tprivate debugStateSnapshot: CameraDebugState = { enabled: false, selected: [] };\n\n\t// Saved camera state for restoration when exiting debug mode\n\tprivate savedCameraPosition: Vector3 | null = null;\n\tprivate savedCameraQuaternion: Quaternion | null = null;\n\tprivate savedCameraZoom: number | null = null;\n\tprivate savedCameraLocalPosition: Vector3 | null = null;\n\n\t// Saved debug camera state for restoration when re-entering debug mode\n\tprivate savedDebugCameraPosition: Vector3 | null = null;\n\tprivate savedDebugCameraQuaternion: Quaternion | null = null;\n\tprivate savedDebugCameraZoom: number | null = null;\n\tprivate savedDebugOrbitTarget: Vector3 | null = null;\n\n\t/** Whether user-configured orbital controls are enabled (independent of debug) */\n\tprivate _userOrbitEnabled = false;\n\n\tconstructor(camera: Camera, domElement: HTMLElement, cameraRig?: Object3D | null) {\n\t\tthis.camera = camera;\n\t\tthis.domElement = domElement;\n\t\tthis.cameraRig = cameraRig ?? null;\n\t}\n\n\t/**\n\t * Set the scene reference for adding/removing camera when detaching from rig.\n\t */\n\tsetScene(scene: Scene | null): void {\n\t\tthis.sceneRef = scene;\n\t}\n\n\t/**\n\t * Check if debug mode is currently active (orbit controls enabled via debug system).\n\t */\n\tget isActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled;\n\t}\n\n\t/**\n\t * Check if any orbit controls are currently active (debug or user).\n\t */\n\tget isOrbitActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled || this._userOrbitEnabled;\n\t}\n\n\t/**\n\t * Update orbit controls each frame.\n\t * Should be called from the camera's update loop.\n\t */\n\tupdate() {\n\t\tif (this.orbitControls && this.orbitTarget) {\n\t\t\tthis.orbitTarget.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t}\n\t\tthis.orbitControls?.update();\n\t}\n\n\t/**\n\t * Enable user-configured orbital controls (not debug mode).\n\t * These orbit controls persist until explicitly disabled.\n\t */\n\tenableUserOrbitControls(): void {\n\t\tthis._userOrbitEnabled = true;\n\t\tif (!this.orbitControls) {\n\t\t\tthis.enableOrbitControls();\n\t\t}\n\t}\n\n\t/**\n\t * Disable user-configured orbital controls.\n\t * Will not disable orbit controls if debug mode is active.\n\t */\n\tdisableUserOrbitControls(): void {\n\t\tthis._userOrbitEnabled = false;\n\t\t// Only disable orbit controls if debug mode isn't also using them\n\t\tif (!this.debugStateSnapshot.enabled) {\n\t\t\tthis.disableOrbitControls();\n\t\t}\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null) {\n\t\tif (this.debugDelegate === delegate) {\n\t\t\treturn;\n\t\t}\n\t\tthis.detachDebugDelegate();\n\t\tthis.debugDelegate = delegate;\n\t\tif (!delegate) {\n\t\t\tthis.applyDebugState({ enabled: false, selected: [] });\n\t\t\treturn;\n\t\t}\n\t\tconst unsubscribe = delegate.subscribe((state) => {\n\t\t\tthis.applyDebugState(state);\n\t\t});\n\t\tthis.debugUnsubscribe = () => {\n\t\t\tunsubscribe?.();\n\t\t};\n\t}\n\n\t/**\n\t * Clean up resources.\n\t */\n\tdispose() {\n\t\tthis.disableOrbitControls();\n\t\tthis.detachDebugDelegate();\n\t}\n\n\t/**\n\t * Get the current debug state snapshot.\n\t */\n\tget debugState(): CameraDebugState {\n\t\treturn this.debugStateSnapshot;\n\t}\n\n\tprivate applyDebugState(state: CameraDebugState) {\n\t\tconst wasEnabled = this.debugStateSnapshot.enabled;\n\t\tthis.debugStateSnapshot = {\n\t\t\tenabled: state.enabled,\n\t\t\tselected: [...state.selected],\n\t\t};\n\t\tif (state.enabled && !wasEnabled) {\n\t\t\t// Entering debug mode: save game camera state, detach from rig, restore debug camera state if available\n\t\t\tthis.saveCameraState();\n\t\t\tthis.detachCameraFromRig();\n\t\t\tthis.enableOrbitControls();\n\t\t\tthis.restoreDebugCameraState();\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t} else if (!state.enabled && wasEnabled) {\n\t\t\t// Exiting debug mode: save debug camera state, then restore game camera state\n\t\t\tthis.saveDebugCameraState();\n\t\t\tthis.orbitTarget = null;\n\t\t\t// Only disable orbit controls if user mode isn't keeping them on\n\t\t\tif (!this._userOrbitEnabled) {\n\t\t\t\tthis.disableOrbitControls();\n\t\t\t}\n\t\t\tthis.reattachCameraToRig();\n\t\t\tthis.restoreCameraState();\n\t\t} else if (state.enabled) {\n\t\t\t// Still in debug mode, just update target\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t}\n\t}\n\n\tprivate enableOrbitControls() {\n\t\tif (this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls = new OrbitControls(this.camera, this.domElement);\n\t\tthis.orbitControls.enableDamping = true;\n\t\tthis.orbitControls.dampingFactor = 0.05;\n\t\tthis.orbitControls.screenSpacePanning = false;\n\t\tthis.orbitControls.minDistance = 1;\n\t\tthis.orbitControls.maxDistance = 500;\n\t\tthis.orbitControls.maxPolarAngle = Math.PI / 2;\n\t\t// Default target to origin\n\t\tthis.orbitControls.target.set(0, 0, 0);\n\t}\n\n\tprivate disableOrbitControls() {\n\t\tif (!this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls.dispose();\n\t\tthis.orbitControls = null;\n\t}\n\n\tprivate updateOrbitTargetFromSelection(selected: string[]) {\n\t\t// Default to origin when no entity is selected\n\t\tif (!this.debugDelegate || selected.length === 0) {\n\t\t\tthis.orbitTarget = null;\n\t\t\tif (this.orbitControls) {\n\t\t\t\tthis.orbitControls.target.set(0, 0, 0);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tfor (let i = selected.length - 1; i >= 0; i -= 1) {\n\t\t\tconst uuid = selected[i];\n\t\t\tconst targetObject = this.debugDelegate.resolveTarget(uuid);\n\t\t\tif (targetObject) {\n\t\t\t\tthis.orbitTarget = targetObject;\n\t\t\t\tif (this.orbitControls) {\n\t\t\t\t\ttargetObject.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.orbitTarget = null;\n\t}\n\n\tprivate detachDebugDelegate() {\n\t\tif (this.debugUnsubscribe) {\n\t\t\ttry {\n\t\t\t\tthis.debugUnsubscribe();\n\t\t\t} catch { /* noop */ }\n\t\t}\n\t\tthis.debugUnsubscribe = null;\n\t\tthis.debugDelegate = null;\n\t}\n\n\t/**\n\t * Save camera position, rotation, and zoom before entering debug mode.\n\t */\n\tprivate saveCameraState() {\n\t\tthis.savedCameraPosition = this.camera.position.clone();\n\t\tthis.savedCameraQuaternion = this.camera.quaternion.clone();\n\t\t// Save zoom for orthographic/perspective cameras\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t}\n\n\t/**\n\t * Restore camera position, rotation, and zoom when exiting debug mode.\n\t */\n\tprivate restoreCameraState() {\n\t\tif (this.savedCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraPosition);\n\t\t\tthis.savedCameraPosition = null;\n\t\t}\n\t\tif (this.savedCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedCameraQuaternion);\n\t\t\tthis.savedCameraQuaternion = null;\n\t\t}\n\t\tif (this.savedCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t\tthis.savedCameraZoom = null;\n\t\t}\n\t}\n\n\t/**\n\t * Save debug camera state when exiting debug mode.\n\t */\n\tprivate saveDebugCameraState() {\n\t\tthis.savedDebugCameraPosition = this.camera.position.clone();\n\t\tthis.savedDebugCameraQuaternion = this.camera.quaternion.clone();\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedDebugCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t\tif (this.orbitControls) {\n\t\t\tthis.savedDebugOrbitTarget = this.orbitControls.target.clone();\n\t\t}\n\t}\n\n\t/**\n\t * Restore debug camera state when re-entering debug mode.\n\t */\n\tprivate restoreDebugCameraState() {\n\t\tif (this.savedDebugCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedDebugCameraPosition);\n\t\t}\n\t\tif (this.savedDebugCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedDebugCameraQuaternion);\n\t\t}\n\t\tif (this.savedDebugCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedDebugCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t}\n\t\tif (this.savedDebugOrbitTarget && this.orbitControls) {\n\t\t\tthis.orbitControls.target.copy(this.savedDebugOrbitTarget);\n\t\t}\n\t}\n\n\t/**\n\t * Detach camera from its rig to allow free orbit movement in debug mode.\n\t * Preserves the camera's world position.\n\t */\n\tprivate detachCameraFromRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent !== this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Save the camera's local position for later restoration\n\t\tthis.savedCameraLocalPosition = this.camera.position.clone();\n\n\t\t// Get camera's world position before detaching\n\t\tconst worldPos = new Vector3();\n\t\tthis.camera.getWorldPosition(worldPos);\n\n\t\t// Remove camera from rig\n\t\tthis.cameraRig.remove(this.camera);\n\n\t\t// Add camera directly to scene if scene ref is available\n\t\tif (this.sceneRef) {\n\t\t\tthis.sceneRef.add(this.camera);\n\t\t}\n\n\t\t// Set camera's position to its previous world position\n\t\tthis.camera.position.copy(worldPos);\n\t}\n\n\t/**\n\t * Reattach camera to its rig when exiting debug mode.\n\t * Restores the camera's local position relative to the rig.\n\t */\n\tprivate reattachCameraToRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent === this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove camera from scene if it's there\n\t\tif (this.sceneRef && this.camera.parent === this.sceneRef) {\n\t\t\tthis.sceneRef.remove(this.camera);\n\t\t}\n\n\t\t// Add camera back to rig\n\t\tthis.cameraRig.add(this.camera);\n\n\t\t// Restore camera's local position\n\t\tif (this.savedCameraLocalPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraLocalPosition);\n\t\t\tthis.savedCameraLocalPosition = null;\n\t\t}\n\t}\n}\n","import { Vector3, Quaternion, MathUtils } from 'three';\nimport type { CameraPose, PoseDelta } from './types';\n\n/**\n * Create a default camera pose at the origin facing forward.\n */\nexport function defaultPose(): CameraPose {\n\treturn {\n\t\tposition: new Vector3(0, 0, 10),\n\t\trotation: new Quaternion(),\n\t\tfov: 75,\n\t\tzoom: 1,\n\t\tnear: 0.1,\n\t\tfar: 1000,\n\t};\n}\n\n/**\n * Deep-clone a CameraPose so mutations don't leak between pipeline stages.\n */\nexport function clonePose(pose: CameraPose): CameraPose {\n\treturn {\n\t\tposition: pose.position.clone(),\n\t\trotation: pose.rotation.clone(),\n\t\tfov: pose.fov,\n\t\tzoom: pose.zoom,\n\t\tnear: pose.near,\n\t\tfar: pose.far,\n\t\tlookAt: pose.lookAt?.clone(),\n\t};\n}\n\n/**\n * Apply an additive PoseDelta on top of a CameraPose.\n * - Position: vector addition\n * - Rotation: quaternion multiplication (compose)\n * - FOV/Zoom: scalar addition\n *\n * Returns a new CameraPose (does not mutate the input).\n */\nexport function applyDelta(pose: CameraPose, delta: PoseDelta): CameraPose {\n\tconst result = clonePose(pose);\n\n\tif (delta.position) {\n\t\tresult.position.add(delta.position);\n\t}\n\tif (delta.rotation) {\n\t\tresult.rotation.multiply(delta.rotation);\n\t}\n\tif (delta.fov != null && result.fov != null) {\n\t\tresult.fov += delta.fov;\n\t}\n\tif (delta.zoom != null && result.zoom != null) {\n\t\tresult.zoom += delta.zoom;\n\t}\n\n\treturn result;\n}\n\n/**\n * Interpolate from `current` pose toward `target` pose using frame-rate-independent damping.\n *\n * @param current The current (smoothed) pose from the previous frame.\n * @param target The desired pose for this frame.\n * @param damping Smoothing factor in 0-1 range. 1 = instant snap, 0 = no movement.\n * @param dt Frame delta time in seconds.\n * @returns A new CameraPose interpolated between current and target.\n */\nexport function smoothPose(current: CameraPose, target: CameraPose, damping: number, dt: number): CameraPose {\n\tconst t = 1 - Math.pow(1 - MathUtils.clamp(damping, 0, 1), dt * 60);\n\n\tconst result = clonePose(current);\n\n\tresult.position.lerp(target.position, t);\n\tresult.rotation.slerp(target.rotation, t);\n\n\tif (target.fov != null && result.fov != null) {\n\t\tresult.fov = MathUtils.lerp(result.fov, target.fov, t);\n\t}\n\tif (target.zoom != null && result.zoom != null) {\n\t\tresult.zoom = MathUtils.lerp(result.zoom, target.zoom, t);\n\t}\n\tif (target.near != null) {\n\t\tresult.near = target.near;\n\t}\n\tif (target.far != null) {\n\t\tresult.far = target.far;\n\t}\n\n\t// Preserve lookAt from target (smoothing is on position/rotation, not lookAt)\n\tresult.lookAt = target.lookAt?.clone();\n\n\treturn result;\n}\n","import type {\n\tCameraPerspective,\n\tCameraBehavior,\n\tCameraAction,\n\tCameraContext,\n\tCameraPose,\n\tCameraPipelineState,\n} from './types';\nimport { defaultPose, clonePose, applyDelta, smoothPose } from './smoothing';\n\n/**\n * CameraPipeline runs a deterministic per-frame update:\n *\n * Perspective -> Behaviors (priority) -> Actions (deltas) -> Smoothing -> finalPose\n *\n * It separates \"desired pose\" from \"final pose\". Everything writes to desired;\n * only smoothing converts desired into the final committed pose.\n */\nexport class CameraPipeline {\n\t/** Active perspective (exactly one at a time). */\n\tperspective: CameraPerspective | null = null;\n\n\t/** Keyed behaviors, sorted by priority each frame. */\n\tprivate behaviors: Map<string, CameraBehavior> = new Map();\n\n\t/** Active transient actions. Expired actions are auto-removed. */\n\tprivate actions: CameraAction[] = [];\n\n\t/** The desired pose after perspective + behaviors + actions. */\n\tprivate _desiredPose: CameraPose = defaultPose();\n\n\t/** The smoothed final pose committed to the Three.js camera. */\n\tprivate _finalPose: CameraPose = defaultPose();\n\n\t/** Whether the pipeline has run at least once (prevents lerp from origin on first frame). */\n\tprivate _initialized = false;\n\n\t/** Smoothing factor: 0 = no movement, 1 = instant snap. */\n\tdamping = 0.15;\n\n\tconstructor(perspective?: CameraPerspective) {\n\t\tif (perspective) {\n\t\t\tthis.perspective = perspective;\n\t\t\tif (perspective.defaults?.damping != null) {\n\t\t\t\tthis.damping = perspective.defaults.damping;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Run the full pipeline for one frame.\n\t * Returns the final pose that should be committed to the Three.js camera.\n\t */\n\trun(ctx: CameraContext): CameraPose {\n\t\t// 1. Base pose from perspective\n\t\tlet pose: CameraPose = this.perspective\n\t\t\t? this.perspective.getBasePose(ctx)\n\t\t\t: defaultPose();\n\n\t\t// 2. Behaviors in priority order (low -> high)\n\t\tconst sorted = this.getSortedBehaviors();\n\t\tfor (const behavior of sorted) {\n\t\t\tif (behavior.enabled === false) continue;\n\t\t\tpose = behavior.update(ctx, pose);\n\t\t}\n\n\t\t// Store desired pose (before actions and smoothing)\n\t\tthis._desiredPose = clonePose(pose);\n\n\t\t// 3. Actions apply additive deltas; expired ones are removed\n\t\tfor (let i = this.actions.length - 1; i >= 0; i--) {\n\t\t\tconst action = this.actions[i];\n\t\t\tconst delta = action.update(ctx);\n\t\t\tpose = applyDelta(pose, delta);\n\t\t\tif (action.isDone(ctx)) {\n\t\t\t\tthis.actions.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\t// 4. Smoothing: interpolate from previous final pose toward computed pose\n\t\tif (!this._initialized) {\n\t\t\tthis._finalPose = clonePose(pose);\n\t\t\tthis._initialized = true;\n\t\t} else {\n\t\t\tthis._finalPose = smoothPose(this._finalPose, pose, this.damping, ctx.dt);\n\t\t}\n\n\t\treturn this._finalPose;\n\t}\n\n\t// ─── Behavior management ───────────────────────────────────────────────\n\n\t/**\n\t * Add or replace a behavior by key (idempotent).\n\t * Calls onDetach on the old behavior and onAttach on the new one.\n\t */\n\taddBehavior(key: string, behavior: CameraBehavior, ctx?: CameraContext): void {\n\t\tconst existing = this.behaviors.get(key);\n\t\tif (existing?.onDetach && ctx) {\n\t\t\texisting.onDetach(ctx);\n\t\t}\n\t\tthis.behaviors.set(key, behavior);\n\t\tif (behavior.onAttach && ctx) {\n\t\t\tbehavior.onAttach(ctx);\n\t\t}\n\t}\n\n\t/**\n\t * Remove a behavior by key. Calls onDetach if a context is provided.\n\t */\n\tremoveBehavior(key: string, ctx?: CameraContext): boolean {\n\t\tconst existing = this.behaviors.get(key);\n\t\tif (!existing) return false;\n\t\tif (existing.onDetach && ctx) {\n\t\t\texisting.onDetach(ctx);\n\t\t}\n\t\treturn this.behaviors.delete(key);\n\t}\n\n\t/**\n\t * Check whether a behavior with the given key exists.\n\t */\n\thasBehavior(key: string): boolean {\n\t\treturn this.behaviors.has(key);\n\t}\n\n\t// ─── Action management ─────────────────────────────────────────────────\n\n\t/**\n\t * Add a transient action. Actions self-expire via isDone().\n\t */\n\taddAction(action: CameraAction): void {\n\t\tthis.actions.push(action);\n\t}\n\n\t// ─── State inspection ──────────────────────────────────────────────────\n\n\t/**\n\t * Return a debug snapshot of the pipeline state.\n\t */\n\tgetState(): CameraPipelineState {\n\t\treturn {\n\t\t\tperspectiveId: this.perspective?.id ?? null,\n\t\t\tdesiredPose: this._desiredPose ? clonePose(this._desiredPose) : null,\n\t\t\tfinalPose: this._finalPose ? clonePose(this._finalPose) : null,\n\t\t\tactiveBehaviors: Array.from(this.behaviors.keys()),\n\t\t\tactiveActionCount: this.actions.length,\n\t\t};\n\t}\n\n\t/**\n\t * Set a new perspective. Resets the pipeline initialization flag so the\n\t * first frame with the new perspective snaps instead of lerping from the old pose.\n\t */\n\tsetPerspective(perspective: CameraPerspective): void {\n\t\tthis.perspective = perspective;\n\t\tthis._initialized = false;\n\t\tif (perspective.defaults?.damping != null) {\n\t\t\tthis.damping = perspective.defaults.damping;\n\t\t}\n\t}\n\n\t// ─── Internal helpers ──────────────────────────────────────────────────\n\n\tprivate getSortedBehaviors(): CameraBehavior[] {\n\t\treturn Array.from(this.behaviors.values()).sort(\n\t\t\t(a, b) => (a.priority ?? 0) - (b.priority ?? 0)\n\t\t);\n\t}\n}\n","import { Vector3, Quaternion } from 'three';\nimport type { CameraPerspective, CameraContext, CameraPose } from '../types';\n\n/**\n * Configuration for the third-person perspective.\n */\nexport interface ThirdPersonOptions {\n\t/** Distance behind the target. Default 8. */\n\tdistance?: number;\n\t/** Height above the target. Default 5. */\n\theight?: number;\n\t/** Lateral offset from the target (shoulder cam). Default 0. */\n\tshoulderOffset?: number;\n\t/** Key in CameraContext.targets to follow. Default 'primary'. */\n\ttargetKey?: string;\n\t/** Perspective field of view. Default 75. */\n\tfov?: number;\n\t/** Padding multiplier when framing multiple targets. Default 1.5. */\n\tpaddingFactor?: number;\n\t/** Minimum camera distance when multi-framing. Default 5. */\n\tminDistance?: number;\n\t/** Fallback camera position when no targets exist (e.g. the user-specified initial position). */\n\tinitialPosition?: Vector3;\n\t/** Fallback lookAt point when no targets exist. */\n\tinitialLookAt?: Vector3;\n}\n\ninterface ThirdPersonBaseDefaults {\n\tdistance: number;\n\theight: number;\n\tshoulderOffset: number;\n\ttargetKey: string;\n\tfov: number;\n\tpaddingFactor: number;\n\tminDistance: number;\n}\n\nconst DEFAULTS: ThirdPersonBaseDefaults = {\n\tdistance: 8,\n\theight: 5,\n\tshoulderOffset: 0,\n\ttargetKey: 'primary',\n\tfov: 75,\n\tpaddingFactor: 1.5,\n\tminDistance: 5,\n};\n\n/**\n * Third-person 3D perspective.\n *\n * - 0 targets: returns a static pose behind the origin.\n * - 1 target: camera positioned behind and above the target, looking at it.\n * - 2+ targets: weighted-centroid framing with dynamic distance.\n */\nexport class ThirdPersonPerspective implements CameraPerspective {\n\treadonly id = 'third-person';\n\treadonly defaults = { damping: 0.15 };\n\n\tprivate opts: ThirdPersonBaseDefaults;\n\tprivate initialPosition?: Vector3;\n\tprivate initialLookAt?: Vector3;\n\n\tconstructor(options?: ThirdPersonOptions) {\n\t\tconst { initialPosition, initialLookAt, ...rest } = options ?? {};\n\t\tthis.opts = { ...DEFAULTS, ...rest };\n\t\tthis.initialPosition = initialPosition;\n\t\tthis.initialLookAt = initialLookAt;\n\t}\n\n\tgetBasePose(ctx: CameraContext): CameraPose {\n\t\tconst targetKeys = Object.keys(ctx.targets);\n\t\tconst primary = ctx.targets[this.opts.targetKey];\n\n\t\tif (targetKeys.length === 0 || !primary) {\n\t\t\treturn this.staticPose();\n\t\t}\n\n\t\tif (targetKeys.length === 1) {\n\t\t\treturn this.singleTargetPose(primary.position);\n\t\t}\n\n\t\treturn this.multiTargetPose(ctx);\n\t}\n\n\t/**\n\t * No targets: use the user-specified initial position if available,\n\t * otherwise fall back to a default pose behind the origin.\n\t */\n\tprivate staticPose(): CameraPose {\n\t\tif (this.initialPosition) {\n\t\t\treturn {\n\t\t\t\tposition: this.initialPosition.clone(),\n\t\t\t\trotation: new Quaternion(),\n\t\t\t\tfov: this.opts.fov,\n\t\t\t\tzoom: 1,\n\t\t\t\tnear: 0.1,\n\t\t\t\tfar: 1000,\n\t\t\t\tlookAt: this.initialLookAt?.clone() ?? new Vector3(0, 0, 0),\n\t\t\t};\n\t\t}\n\n\t\tconst position = new Vector3(\n\t\t\tthis.opts.shoulderOffset,\n\t\t\tthis.opts.height,\n\t\t\tthis.opts.distance\n\t\t);\n\t\treturn {\n\t\t\tposition,\n\t\t\trotation: new Quaternion(),\n\t\t\tfov: this.opts.fov,\n\t\t\tzoom: 1,\n\t\t\tnear: 0.1,\n\t\t\tfar: 1000,\n\t\t\tlookAt: new Vector3(0, 0, 0),\n\t\t};\n\t}\n\n\t/**\n\t * Single target: position = target + offset, lookAt = target.\n\t */\n\tprivate singleTargetPose(targetPos: Vector3): CameraPose {\n\t\tconst position = new Vector3(\n\t\t\ttargetPos.x + this.opts.shoulderOffset,\n\t\t\ttargetPos.y + this.opts.height,\n\t\t\ttargetPos.z + this.opts.distance\n\t\t);\n\t\treturn {\n\t\t\tposition,\n\t\t\trotation: new Quaternion(),\n\t\t\tfov: this.opts.fov,\n\t\t\tzoom: 1,\n\t\t\tnear: 0.1,\n\t\t\tfar: 1000,\n\t\t\tlookAt: targetPos.clone(),\n\t\t};\n\t}\n\n\t/**\n\t * Multi-target: compute centroid and adjust distance to frame all targets.\n\t */\n\tprivate multiTargetPose(ctx: CameraContext): CameraPose {\n\t\tconst targets = Object.values(ctx.targets);\n\n\t\t// Centroid\n\t\tconst centroid = new Vector3();\n\t\tfor (const t of targets) {\n\t\t\tcentroid.add(t.position);\n\t\t}\n\t\tcentroid.divideScalar(targets.length);\n\n\t\t// Max distance from centroid to any target\n\t\tlet maxDist = 0;\n\t\tfor (const t of targets) {\n\t\t\tconst d = centroid.distanceTo(t.position);\n\t\t\tif (d > maxDist) maxDist = d;\n\t\t}\n\n\t\tconst dynamicDistance = Math.max(\n\t\t\tmaxDist * this.opts.paddingFactor,\n\t\t\tthis.opts.minDistance\n\t\t);\n\n\t\t// Offset direction from the base offset\n\t\tconst baseOffset = new Vector3(\n\t\t\tthis.opts.shoulderOffset,\n\t\t\tthis.opts.height,\n\t\t\tthis.opts.distance\n\t\t);\n\t\tconst baseLen = baseOffset.length();\n\t\tconst dir = baseLen > 0 ? baseOffset.clone().normalize() : new Vector3(0, 0.5, 1).normalize();\n\n\t\tconst position = centroid.clone().add(dir.multiplyScalar(dynamicDistance));\n\n\t\t// Preserve vertical ratio\n\t\tif (baseLen > 0) {\n\t\t\tconst heightRatio = this.opts.height / baseLen;\n\t\t\tposition.y = centroid.y + dynamicDistance * heightRatio;\n\t\t}\n\n\t\treturn {\n\t\t\tposition,\n\t\t\trotation: new Quaternion(),\n\t\t\tfov: this.opts.fov,\n\t\t\tzoom: 1,\n\t\t\tnear: 0.1,\n\t\t\tfar: 1000,\n\t\t\tlookAt: centroid.clone(),\n\t\t};\n\t}\n}\n","import { Vector3, Quaternion } from 'three';\nimport type { CameraPerspective, CameraContext, CameraPose } from '../types';\n\n/**\n * Configuration for the fixed 2D perspective.\n */\nexport interface Fixed2DOptions {\n\t/** Fixed camera position. Default (0, 0, 10). */\n\tposition?: { x: number; y: number; z: number };\n\t/** Orthographic zoom (frustum size). Default 10. */\n\tzoom?: number;\n}\n\nconst DEFAULTS: Required<Fixed2DOptions> = {\n\tposition: { x: 0, y: 0, z: 10 },\n\tzoom: 10,\n};\n\n/**\n * Fixed 2D perspective.\n *\n * Returns a static orthographic pose looking down the Z-axis.\n * No target following -- the camera stays at the configured position.\n */\nexport class Fixed2DPerspective implements CameraPerspective {\n\treadonly id = 'fixed-2d';\n\treadonly defaults = { damping: 1 };\n\n\tprivate opts: Required<Fixed2DOptions>;\n\n\tconstructor(options?: Fixed2DOptions) {\n\t\tthis.opts = { ...DEFAULTS, ...options };\n\t}\n\n\tgetBasePose(_ctx: CameraContext): CameraPose {\n\t\treturn {\n\t\t\tposition: new Vector3(\n\t\t\t\tthis.opts.position.x,\n\t\t\t\tthis.opts.position.y,\n\t\t\t\tthis.opts.position.z\n\t\t\t),\n\t\t\trotation: new Quaternion(),\n\t\t\tzoom: this.opts.zoom,\n\t\t\tnear: 1,\n\t\t\tfar: 1000,\n\t\t\tlookAt: new Vector3(this.opts.position.x, this.opts.position.y, 0),\n\t\t};\n\t}\n}\n","import { Vector3, Quaternion, Euler, MathUtils } from 'three';\nimport type { CameraPerspective, CameraContext, CameraPose } from '../types';\n\n/**\n * Configuration for the first-person perspective.\n */\nexport interface FirstPersonOptions {\n\t/** Vertical offset above the target entity's position (eye height). @default 1.7 */\n\teyeHeight?: number;\n\t/** Default field of view in degrees. @default 75 */\n\tdefaultFov?: number;\n\t/** Maximum pitch angle in radians. @default Math.PI/2 - 0.01 */\n\tpitchLimit?: number;\n\t/** Lerp speed for smooth look-at transitions. @default 5 */\n\tlookAtLerpSpeed?: number;\n\t/** Lerp speed for FOV zoom transitions. @default 8 */\n\tfovLerpSpeed?: number;\n\t/** Key in CameraContext.targets to follow. @default 'primary' */\n\ttargetKey?: string;\n\t/** Fallback position when no target entity is attached. */\n\tinitialPosition?: Vector3;\n\t/** Fallback look-at point used to derive initial yaw/pitch when no target. */\n\tinitialLookAt?: Vector3;\n}\n\ninterface Defaults {\n\teyeHeight: number;\n\tdefaultFov: number;\n\tpitchLimit: number;\n\tlookAtLerpSpeed: number;\n\tfovLerpSpeed: number;\n\ttargetKey: string;\n}\n\nconst DEFAULTS: Defaults = {\n\teyeHeight: 1.7,\n\tdefaultFov: 75,\n\tpitchLimit: Math.PI / 2 - 0.01,\n\tlookAtLerpSpeed: 5,\n\tfovLerpSpeed: 8,\n\ttargetKey: 'primary',\n};\n\n/**\n * First-person camera perspective.\n *\n * Position is derived from the attached target entity (+ eye height).\n * Rotation is driven via `look()` / `setLook()` methods called by game code\n * or a future FPS behavior. Supports smooth FOV zoom and lerp'd look-at.\n */\nexport class FirstPersonPerspective implements CameraPerspective {\n\treadonly id = 'first-person';\n\treadonly defaults = { damping: 1 };\n\n\tprivate opts: Defaults;\n\t/** Fallback position when no target entity is attached. Mutate directly for manual movement. */\n\tinitialPosition?: Vector3;\n\tprivate initialLookAt?: Vector3;\n\n\t// --- Look state ---\n\tprivate _yaw = 0;\n\tprivate _pitch = 0;\n\n\t// --- FOV zoom state ---\n\tprivate _currentFov: number;\n\tprivate _targetFov: number;\n\n\t// --- Look-at target state ---\n\tprivate _lookAtTarget: Vector3 | null = null;\n\tprivate _lookAtLerpSpeed: number;\n\tprivate _currentRotation = new Quaternion();\n\tprivate _rotationInitialized = false;\n\n\tconstructor(options?: FirstPersonOptions) {\n\t\tconst { initialPosition, initialLookAt, ...rest } = options ?? {};\n\t\tthis.opts = { ...DEFAULTS, ...rest };\n\t\tthis.initialPosition = initialPosition;\n\t\tthis.initialLookAt = initialLookAt;\n\n\t\tthis._currentFov = this.opts.defaultFov;\n\t\tthis._targetFov = this.opts.defaultFov;\n\t\tthis._lookAtLerpSpeed = this.opts.lookAtLerpSpeed;\n\n\t\tif (initialPosition && initialLookAt) {\n\t\t\tthis.deriveYawPitchFromLookAt(initialPosition, initialLookAt);\n\t\t}\n\t}\n\n\t// --- Public API (called by game code / FPS behavior) ---\n\n\t/** Accumulate yaw and pitch deltas. Pitch is clamped to the configured limit. */\n\tlook(deltaYaw: number, deltaPitch: number): void {\n\t\tthis._yaw += deltaYaw;\n\t\tthis._pitch = MathUtils.clamp(\n\t\t\tthis._pitch + deltaPitch,\n\t\t\t-this.opts.pitchLimit,\n\t\t\tthis.opts.pitchLimit,\n\t\t);\n\t}\n\n\t/** Set absolute yaw and pitch. Pitch is clamped to the configured limit. */\n\tsetLook(yaw: number, pitch: number): void {\n\t\tthis._yaw = yaw;\n\t\tthis._pitch = MathUtils.clamp(pitch, -this.opts.pitchLimit, this.opts.pitchLimit);\n\t}\n\n\t/** Current yaw in radians. */\n\tget yaw(): number { return this._yaw; }\n\n\t/** Current pitch in radians. */\n\tget pitch(): number { return this._pitch; }\n\n\t/** Set the target FOV for a smooth zoom transition (e.g. sniper scope). */\n\tzoom(fov: number): void {\n\t\tthis._targetFov = fov;\n\t}\n\n\t/** Return to the default FOV. */\n\tresetZoom(): void {\n\t\tthis._targetFov = this.opts.defaultFov;\n\t}\n\n\t/** Current field of view. */\n\tget currentFov(): number { return this._currentFov; }\n\n\t/**\n\t * Enable smooth look-at toward a world position.\n\t * The camera will slerp from the current rotation toward the look-at direction.\n\t */\n\tlookAt(target: Vector3, lerpSpeed?: number): void {\n\t\tthis._lookAtTarget = target;\n\t\tif (lerpSpeed != null) {\n\t\t\tthis._lookAtLerpSpeed = lerpSpeed;\n\t\t}\n\t}\n\n\t/** Disable look-at and return to manual yaw/pitch control. */\n\tclearLookAt(): void {\n\t\tif (this._lookAtTarget) {\n\t\t\tthis.deriveYawPitchFromQuaternion(this._currentRotation);\n\t\t}\n\t\tthis._lookAtTarget = null;\n\t}\n\n\t// --- CameraPerspective interface ---\n\n\tgetBasePose(ctx: CameraContext): CameraPose {\n\t\tconst position = this.computePosition(ctx);\n\t\tconst rotation = this.computeRotation(position, ctx.dt);\n\t\tthis._currentFov = this.lerpFov(ctx.dt);\n\n\t\treturn {\n\t\t\tposition,\n\t\t\trotation,\n\t\t\tfov: this._currentFov,\n\t\t\tnear: 0.1,\n\t\t\tfar: 1000,\n\t\t};\n\t}\n\n\t// --- Private helpers ---\n\n\tprivate computePosition(ctx: CameraContext): Vector3 {\n\t\tconst target = ctx.targets[this.opts.targetKey];\n\t\tif (target) {\n\t\t\treturn new Vector3(\n\t\t\t\ttarget.position.x,\n\t\t\t\ttarget.position.y + this.opts.eyeHeight,\n\t\t\t\ttarget.position.z,\n\t\t\t);\n\t\t}\n\t\tif (this.initialPosition) {\n\t\t\treturn this.initialPosition.clone();\n\t\t}\n\t\treturn new Vector3(0, this.opts.eyeHeight, 0);\n\t}\n\n\tprivate computeRotation(eyePosition: Vector3, dt: number): Quaternion {\n\t\tconst yawPitchQuat = new Quaternion().setFromEuler(\n\t\t\tnew Euler(this._pitch, this._yaw, 0, 'YXZ'),\n\t\t);\n\n\t\tif (!this._rotationInitialized) {\n\t\t\tthis._currentRotation.copy(yawPitchQuat);\n\t\t\tthis._rotationInitialized = true;\n\t\t}\n\n\t\tif (this._lookAtTarget) {\n\t\t\tconst dir = _vec3.copy(this._lookAtTarget).sub(eyePosition);\n\t\t\tif (dir.lengthSq() > 0.0001) {\n\t\t\t\tdir.normalize();\n\t\t\t\tconst desiredYaw = Math.atan2(-dir.x, -dir.z);\n\t\t\t\tconst desiredPitch = Math.asin(MathUtils.clamp(dir.y, -1, 1));\n\t\t\t\tconst desiredQuat = _quat.setFromEuler(\n\t\t\t\t\t_euler.set(desiredPitch, desiredYaw, 0, 'YXZ'),\n\t\t\t\t);\n\n\t\t\t\tconst t = 1 - Math.pow(1 - Math.min(this._lookAtLerpSpeed * dt, 1), 1);\n\t\t\t\tthis._currentRotation.slerp(desiredQuat, MathUtils.clamp(t, 0, 1));\n\t\t\t\treturn this._currentRotation.clone();\n\t\t\t}\n\t\t}\n\n\t\tthis._currentRotation.copy(yawPitchQuat);\n\t\treturn yawPitchQuat;\n\t}\n\n\tprivate lerpFov(dt: number): number {\n\t\tif (Math.abs(this._currentFov - this._targetFov) < 0.01) {\n\t\t\treturn this._targetFov;\n\t\t}\n\t\tconst t = 1 - Math.pow(1 - Math.min(this.opts.fovLerpSpeed * dt, 1), 1);\n\t\treturn MathUtils.lerp(this._currentFov, this._targetFov, MathUtils.clamp(t, 0, 1));\n\t}\n\n\tprivate deriveYawPitchFromLookAt(from: Vector3, to: Vector3): void {\n\t\tconst dir = _vec3.copy(to).sub(from).normalize();\n\t\tthis._yaw = Math.atan2(-dir.x, -dir.z);\n\t\tthis._pitch = Math.asin(MathUtils.clamp(dir.y, -1, 1));\n\t}\n\n\tprivate deriveYawPitchFromQuaternion(q: Quaternion): void {\n\t\tconst euler = _euler.setFromQuaternion(q, 'YXZ');\n\t\tthis._yaw = euler.y;\n\t\tthis._pitch = MathUtils.clamp(euler.x, -this.opts.pitchLimit, this.opts.pitchLimit);\n\t}\n}\n\n// Reusable temporaries (avoid per-frame allocations)\nconst _vec3 = new Vector3();\nconst _quat = new Quaternion();\nconst _euler = new Euler();\n","import type { PerspectiveType } from '../perspective';\nimport type { CameraPerspective } from '../types';\nimport { ThirdPersonPerspective } from './third-person-perspective';\nimport type { ThirdPersonOptions } from './third-person-perspective';\nimport { Fixed2DPerspective } from './fixed-2d-perspective';\nimport type { Fixed2DOptions } from './fixed-2d-perspective';\nimport { FirstPersonPerspective } from './first-person-perspective';\nimport type { FirstPersonOptions } from './first-person-perspective';\n\nexport { ThirdPersonPerspective } from './third-person-perspective';\nexport type { ThirdPersonOptions } from './third-person-perspective';\nexport { Fixed2DPerspective } from './fixed-2d-perspective';\nexport type { Fixed2DOptions } from './fixed-2d-perspective';\nexport { FirstPersonPerspective } from './first-person-perspective';\nexport type { FirstPersonOptions } from './first-person-perspective';\n\n/**\n * Perspective-specific options union.\n * Extend as new perspective types are added.\n */\nexport type PerspectiveOptions = ThirdPersonOptions | Fixed2DOptions | FirstPersonOptions;\n\n/**\n * Factory: create a CameraPerspective from a PerspectiveType string.\n * Unrecognized types default to ThirdPersonPerspective.\n */\nexport function createPerspective(\n\ttype: PerspectiveType,\n\toptions?: PerspectiveOptions\n): CameraPerspective {\n\tswitch (type) {\n\t\tcase 'third-person':\n\t\t\treturn new ThirdPersonPerspective(options as ThirdPersonOptions);\n\t\tcase 'first-person':\n\t\t\treturn new FirstPersonPerspective(options as FirstPersonOptions);\n\t\tcase 'isometric':\n\t\t\t// Isometric placeholder -- fixed angle third-person\n\t\t\treturn new ThirdPersonPerspective({\n\t\t\t\tdistance: 10,\n\t\t\t\theight: 10,\n\t\t\t\t...(options as ThirdPersonOptions),\n\t\t\t});\n\t\tcase 'flat-2d':\n\t\t\treturn new Fixed2DPerspective(options as Fixed2DOptions);\n\t\tcase 'fixed-2d':\n\t\t\treturn new Fixed2DPerspective(options as Fixed2DOptions);\n\t\tdefault:\n\t\t\treturn new ThirdPersonPerspective(options as ThirdPersonOptions);\n\t}\n}\n","import { Vector2, Camera, PerspectiveCamera, Vector3, Object3D, OrthographicCamera, Scene, WebGLRenderTarget, Texture, LinearFilter } from 'three';\nimport { PerspectiveType, Perspectives } from './perspective';\nimport { StageEntity } from '../interfaces/entity';\nimport { CameraOrbitController, CameraDebugDelegate } from './camera-debug-delegate';\nimport { RendererManager, DEFAULT_VIEWPORT } from './renderer-manager';\nimport type { ZylemRenderer, RendererType, Viewport } from './renderer-manager';\nimport { CameraPipeline } from './camera-pipeline';\nimport { createPerspective } from './perspectives';\nimport type { CameraContext, TransformLike, CameraPose } from './types';\n\n// Re-export for backwards compatibility\nexport type { CameraDebugState, CameraDebugDelegate } from './camera-debug-delegate';\nexport type { RendererType, ZylemRenderer } from './renderer-manager';\nexport { isWebGPUSupported } from './renderer-manager';\n\n/**\n * ZylemCamera is a lightweight camera wrapper that manages the Three.js camera,\n * the camera pose pipeline, and viewport configuration. Rendering is handled\n * by RendererManager.\n *\n * The pipeline runs: Perspective -> Behaviors -> Actions -> Smoothing -> Commit.\n * When orbit/debug controls are active, the pipeline is bypassed.\n */\nexport class ZylemCamera {\n\t/**\n\t * @deprecated No longer used. Kept as null for backward compatibility\n\t * with code that checks `camera.cameraRig` (e.g. scene graph insertion).\n\t */\n\tcameraRig: Object3D | null = null;\n\n\tcamera: Camera;\n\tscreenResolution: Vector2;\n\t_perspective: PerspectiveType;\n\tfrustumSize = 10;\n\trendererType: RendererType;\n\tsceneRef: Scene | null = null;\n\n\t/** Name for camera manager lookup. */\n\tname: string = '';\n\n\t/**\n\t * Viewport in normalized coordinates (0-1).\n\t * Default is fullscreen: { x: 0, y: 0, width: 1, height: 1 }\n\t */\n\tviewport: Viewport = { ...DEFAULT_VIEWPORT };\n\n\t/**\n\t * Multiple targets for the camera to follow/frame.\n\t */\n\ttargets: StageEntity[] = [];\n\n\t/**\n\t * The camera pose pipeline.\n\t * Exposed so CameraWrapper can delegate addBehavior/addAction/getState.\n\t */\n\tpipeline: CameraPipeline;\n\n\t/**\n\t * Offscreen render target for render-to-texture (RTT) cameras.\n\t * When set, the camera renders to this target instead of the screen viewport.\n\t * Created via createRenderTarget() or automatically by setCameraFeed().\n\t */\n\trenderTarget: WebGLRenderTarget | null = null;\n\n\t/**\n\t * @deprecated Use `targets` array instead. Kept for backward compatibility.\n\t */\n\tget target(): StageEntity | null {\n\t\treturn this.targets.length > 0 ? this.targets[0] : null;\n\t}\n\n\tset target(entity: StageEntity | null) {\n\t\tif (entity) {\n\t\t\tif (this.targets.length === 0) {\n\t\t\t\tthis.targets.push(entity);\n\t\t\t} else {\n\t\t\t\tthis.targets[0] = entity;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.targets = [];\n\t\t}\n\t}\n\n\t// Orbit controls\n\tprivate orbitController: CameraOrbitController | null = null;\n\tprivate _useOrbitalControls = false;\n\n\t/** When true, debug-mode orbital controls are not attached to this camera. */\n\t_skipDebugOrbit = false;\n\n\t/** Reference to the shared renderer manager (set during setup). */\n\tprivate _rendererManager: RendererManager | null = null;\n\n\t/** Elapsed time tracker for CameraContext. */\n\tprivate _elapsedTime = 0;\n\n\tconstructor(perspective: PerspectiveType, screenResolution: Vector2, frustumSize: number = 10, rendererType: RendererType = 'webgl') {\n\t\tthis._perspective = perspective;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.frustumSize = frustumSize;\n\t\tthis.rendererType = rendererType;\n\n\t\t// Create Three.js camera based on perspective\n\t\tconst aspectRatio = screenResolution.x / screenResolution.y;\n\t\tthis.camera = this.createCameraForPerspective(aspectRatio);\n\n\t\t// Position camera directly (no rig)\n\t\tthis.camera.position.set(0, 0, 10);\n\t\tthis.camera.lookAt(new Vector3(0, 0, 0));\n\n\t\t// Create pipeline with the appropriate perspective implementation\n\t\tconst perspectiveImpl = createPerspective(perspective);\n\t\tthis.pipeline = new CameraPipeline(perspectiveImpl);\n\t}\n\n\t/**\n\t * Setup the camera with a scene and renderer manager.\n\t */\n\tasync setup(scene: Scene, rendererManager?: RendererManager): Promise<void> {\n\t\tthis.sceneRef = scene;\n\n\t\tif (rendererManager) {\n\t\t\tthis._rendererManager = rendererManager;\n\t\t}\n\n\t\t// Ensure renderer manager is initialized\n\t\tif (this._rendererManager && !this._rendererManager.initialized) {\n\t\t\tawait this._rendererManager.initRenderer();\n\t\t}\n\n\t\t// Initialize orbit controller if renderer is available\n\t\tif (this._rendererManager) {\n\t\t\tthis.orbitController = new CameraOrbitController(\n\t\t\t\tthis.camera,\n\t\t\t\tthis._rendererManager.renderer.domElement,\n\t\t\t\tnull // no camera rig\n\t\t\t);\n\t\t\tthis.orbitController.setScene(scene);\n\n\t\t\t// If orbital controls were requested, enable them\n\t\t\tif (this._useOrbitalControls) {\n\t\t\t\tthis.orbitController.enableUserOrbitControls();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Legacy setup method for backward compatibility.\n\t * Creates a temporary RendererManager internally.\n\t * @deprecated Use setup(scene, rendererManager) instead.\n\t */\n\tasync setupLegacy(scene: Scene): Promise<void> {\n\t\tif (!this._rendererManager) {\n\t\t\tthis._rendererManager = new RendererManager(this.screenResolution, this.rendererType);\n\t\t\tawait this._rendererManager.initRenderer();\n\n\t\t\t// Setup render pass for WebGL\n\t\t\tthis._rendererManager.setupRenderPass(scene, this.camera);\n\n\t\t\t// Start render loop\n\t\t\tthis._rendererManager.startRenderLoop((delta) => {\n\t\t\t\tthis.update(delta);\n\t\t\t\tif (this._rendererManager && this.sceneRef) {\n\t\t\t\t\tthis._rendererManager.render(this.sceneRef, this.camera);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tawait this.setup(scene, this._rendererManager);\n\t}\n\n\t/**\n\t * Update the camera each frame.\n\t *\n\t * When orbit/debug controls are active, the pipeline is skipped and\n\t * orbit controls manage the camera directly. Otherwise, the pipeline\n\t * runs: Perspective -> Behaviors -> Actions -> Smoothing -> Commit.\n\t */\n\tupdate(delta: number): void {\n\t\t// Update orbit controls (if debug mode or user orbital controls enabled)\n\t\tthis.orbitController?.update();\n\n\t\t// Skip pipeline when orbit controls are active\n\t\tif (this.isDebugModeActive() || this._useOrbitalControls) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Accumulate elapsed time\n\t\tthis._elapsedTime += delta;\n\n\t\t// Build context from current state\n\t\tconst ctx = this.buildContext(delta);\n\n\t\t// Run the pipeline\n\t\tconst finalPose = this.pipeline.run(ctx);\n\n\t\t// Commit the result to the Three.js camera\n\t\tthis.commitPose(finalPose);\n\t}\n\n\t/**\n\t * Check if debug mode is active (orbit controls taking over camera).\n\t */\n\tisDebugModeActive(): boolean {\n\t\treturn this.orbitController?.isActive ?? false;\n\t}\n\n\t/**\n\t * Enable user-configured orbital controls (not debug mode).\n\t */\n\tenableOrbitalControls(): void {\n\t\tthis._useOrbitalControls = true;\n\t\tthis.orbitController?.enableUserOrbitControls();\n\t}\n\n\t/**\n\t * Disable user-configured orbital controls.\n\t */\n\tdisableOrbitalControls(): void {\n\t\tthis._useOrbitalControls = false;\n\t\tthis.orbitController?.disableUserOrbitControls();\n\t}\n\n\t/**\n\t * Whether user orbital controls are enabled.\n\t */\n\tget useOrbitalControls(): boolean {\n\t\treturn this._useOrbitalControls;\n\t}\n\n\t// ─── Target management ──────────────────────────────────────────────────\n\n\t/**\n\t * Add a target entity for the camera to follow/frame.\n\t */\n\taddTarget(entity: StageEntity): void {\n\t\tif (!this.targets.includes(entity)) {\n\t\t\tthis.targets.push(entity);\n\t\t}\n\t}\n\n\t/**\n\t * Remove a target entity.\n\t */\n\tremoveTarget(entity: StageEntity): void {\n\t\tconst index = this.targets.indexOf(entity);\n\t\tif (index !== -1) {\n\t\t\tthis.targets.splice(index, 1);\n\t\t}\n\t}\n\n\t/**\n\t * Clear all targets.\n\t */\n\tclearTargets(): void {\n\t\tthis.targets = [];\n\t}\n\n\t// ─── Viewport & resize ──────────────────────────────────────────────────\n\n\t/**\n\t * Set the viewport for this camera (normalized 0-1 coordinates).\n\t */\n\tsetViewport(x: number, y: number, width: number, height: number): void {\n\t\tthis.viewport = { x, y, width, height };\n\t}\n\n\t/**\n\t * Resize camera projection.\n\t */\n\tresize(width: number, height: number): void {\n\t\tthis.screenResolution.set(width, height);\n\n\t\tif (this.camera instanceof PerspectiveCamera) {\n\t\t\tthis.camera.aspect = width / height;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\n\t\tif (this.camera instanceof OrthographicCamera) {\n\t\t\tconst aspect = width / height;\n\t\t\tthis.camera.left = this.frustumSize * aspect / -2;\n\t\t\tthis.camera.right = this.frustumSize * aspect / 2;\n\t\t\tthis.camera.top = this.frustumSize / 2;\n\t\t\tthis.camera.bottom = this.frustumSize / -2;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\t}\n\n\t// ─── Render-to-texture ─────────────────────────────────────────────────\n\n\t/**\n\t * Create an offscreen render target for this camera.\n\t * When a render target is present, CameraManager renders this camera\n\t * to the target instead of the screen viewport.\n\t *\n\t * @param width Texture width in pixels (default 512)\n\t * @param height Texture height in pixels (default 512)\n\t */\n\tcreateRenderTarget(width: number = 512, height: number = 512): WebGLRenderTarget {\n\t\tif (this.renderTarget) {\n\t\t\tthis.renderTarget.dispose();\n\t\t}\n\t\tthis.renderTarget = new WebGLRenderTarget(width, height, {\n\t\t\tminFilter: LinearFilter,\n\t\t\tmagFilter: LinearFilter,\n\t\t});\n\t\treturn this.renderTarget;\n\t}\n\n\t/**\n\t * Get the texture from the render target (for applying to a mesh material).\n\t * Returns null if no render target has been created.\n\t */\n\tgetRenderTexture(): Texture | null {\n\t\treturn this.renderTarget?.texture ?? null;\n\t}\n\n\t// ─── Lifecycle ──────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispose camera resources.\n\t */\n\tdestroy(): void {\n\t\ttry {\n\t\t\tthis.orbitController?.dispose();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.renderTarget?.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis.renderTarget = null;\n\t\tthis.sceneRef = null;\n\t\tthis.targets = [];\n\t\tthis._rendererManager = null;\n\t}\n\n\t// ─── Debug delegate ─────────────────────────────────────────────────────\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t * Skipped when _skipDebugOrbit is true so the pipeline always runs.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null): void {\n\t\tif (this._skipDebugOrbit) return;\n\t\tthis.orbitController?.setDebugDelegate(delegate);\n\t}\n\n\t// ─── Movement helpers (backward compat) ─────────────────────────────────\n\n\t/**\n\t * Directly set the camera position.\n\t */\n\tmove(position: Vector3): void {\n\t\tif (this._perspective === Perspectives.Flat2D || this._perspective === Perspectives.Fixed2D) {\n\t\t\tthis.frustumSize = position.z;\n\t\t}\n\t\tthis.camera.position.set(position.x, position.y, position.z);\n\t}\n\n\t/**\n\t * Apply incremental rotation to the camera.\n\t */\n\trotate(pitch: number, yaw: number, roll: number): void {\n\t\t(this.camera as Object3D).rotateX(pitch);\n\t\t(this.camera as Object3D).rotateY(yaw);\n\t\t(this.camera as Object3D).rotateZ(roll);\n\t}\n\n\t// ─── Renderer manager access ────────────────────────────────────────────\n\n\t/**\n\t * Get the DOM element for the renderer.\n\t * @deprecated Access via RendererManager instead.\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\tif (this._rendererManager) {\n\t\t\treturn this._rendererManager.getDomElement();\n\t\t}\n\t\tthrow new Error('ZylemCamera: No renderer manager available. Call setup() first.');\n\t}\n\n\t/**\n\t * Get the renderer manager reference.\n\t */\n\tgetRendererManager(): RendererManager | null {\n\t\treturn this._rendererManager;\n\t}\n\n\t/**\n\t * Set the renderer manager reference (used by CameraManager during setup).\n\t */\n\tsetRendererManager(manager: RendererManager): void {\n\t\tthis._rendererManager = manager;\n\t}\n\n\t// ─── Legacy compatibility methods ────────────────────────────────────────\n\n\t/** @deprecated Renderer is now owned by RendererManager */\n\tget renderer(): any {\n\t\treturn this._rendererManager?.renderer;\n\t}\n\n\t/** @deprecated Composer is now owned by RendererManager */\n\tget composer(): any {\n\t\treturn this._rendererManager?.composer;\n\t}\n\n\t/** @deprecated Use RendererManager.setPixelRatio() instead */\n\tsetPixelRatio(dpr: number): void {\n\t\tthis._rendererManager?.setPixelRatio(dpr);\n\t}\n\n\t// ─── Private helpers ────────────────────────────────────────────────────\n\n\t/**\n\t * Build a CameraContext from current ZylemCamera state.\n\t * Converts StageEntity[] targets into Record<string, TransformLike>.\n\t */\n\tprivate buildContext(delta: number): CameraContext {\n\t\tconst targets: Record<string, TransformLike> = {};\n\n\t\tfor (let i = 0; i < this.targets.length; i++) {\n\t\t\tconst entity = this.targets[i];\n\t\t\tconst key = i === 0 ? 'primary' : `target_${i}`;\n\t\t\tif (entity.group) {\n\t\t\t\ttargets[key] = {\n\t\t\t\t\tposition: entity.group.position,\n\t\t\t\t\trotation: entity.group.quaternion,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdt: delta,\n\t\t\ttime: this._elapsedTime,\n\t\t\tviewport: {\n\t\t\t\twidth: this.screenResolution.x,\n\t\t\t\theight: this.screenResolution.y,\n\t\t\t\taspect: this.screenResolution.x / this.screenResolution.y,\n\t\t\t},\n\t\t\ttargets,\n\t\t};\n\t}\n\n\t/**\n\t * Apply the final pipeline pose to the Three.js camera.\n\t */\n\tprivate commitPose(pose: CameraPose): void {\n\t\tthis.camera.position.copy(pose.position);\n\n\t\tif (pose.lookAt) {\n\t\t\tthis.camera.lookAt(pose.lookAt);\n\t\t} else {\n\t\t\tthis.camera.quaternion.copy(pose.rotation);\n\t\t}\n\n\t\tif (this.camera instanceof PerspectiveCamera) {\n\t\t\tif (pose.fov != null) this.camera.fov = pose.fov;\n\t\t\tif (pose.near != null) this.camera.near = pose.near;\n\t\t\tif (pose.far != null) this.camera.far = pose.far;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\n\t\tif (this.camera instanceof OrthographicCamera) {\n\t\t\tif (pose.zoom != null) {\n\t\t\t\tconst aspect = this.screenResolution.x / this.screenResolution.y;\n\t\t\t\tconst size = pose.zoom;\n\t\t\t\tthis.camera.left = -size * aspect / 2;\n\t\t\t\tthis.camera.right = size * aspect / 2;\n\t\t\t\tthis.camera.top = size / 2;\n\t\t\t\tthis.camera.bottom = -size / 2;\n\t\t\t}\n\t\t\tif (pose.near != null) this.camera.near = pose.near;\n\t\t\tif (pose.far != null) this.camera.far = pose.far;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\t}\n\n\t/**\n\t * Create a Three.js camera based on perspective type.\n\t */\n\tprivate createCameraForPerspective(aspectRatio: number): Camera {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t\t\tcase Perspectives.FirstPerson:\n\t\t\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t\t\tcase Perspectives.Isometric:\n\t\t\t\treturn new OrthographicCamera(\n\t\t\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\t\t\tthis.frustumSize / 2,\n\t\t\t\t\tthis.frustumSize / -2,\n\t\t\t\t\t1, 1000\n\t\t\t\t);\n\t\t\tcase Perspectives.Flat2D:\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\treturn new OrthographicCamera(\n\t\t\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\t\t\tthis.frustumSize / 2,\n\t\t\t\t\tthis.frustumSize / -2,\n\t\t\t\t\t1, 1000\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t\t}\n\t}\n}\n","import { Vector2, Scene } from 'three';\nimport { ZylemCamera } from './zylem-camera';\nimport { RendererManager } from './renderer-manager';\nimport { Perspectives } from './perspective';\nimport { nanoid } from 'nanoid';\n\n/**\n * CameraManager orchestrates multiple cameras per stage.\n *\n * Responsibilities:\n * - Named camera registry (add/remove/get by name or reference)\n * - Active camera list management (determines which cameras render)\n * - Always-available debug camera with orbit controls\n * - Per-frame update of all active cameras' perspective controllers\n * - Coordinating rendering via RendererManager for all active viewports\n */\nexport class CameraManager {\n\t/** Named camera registry */\n\tprivate cameras: Map<string, ZylemCamera> = new Map();\n\n\t/** Currently active cameras, ordered by render layer (first = bottom) */\n\tprivate _activeCameras: ZylemCamera[] = [];\n\n\t/** Auto-created debug camera with orbit controls */\n\tprivate _debugCamera: ZylemCamera | null = null;\n\n\t/** Reference to the shared renderer manager */\n\tprivate _rendererManager: RendererManager | null = null;\n\n\t/** Scene reference */\n\tprivate _sceneRef: Scene | null = null;\n\n\t/** Counter for auto-generated camera names */\n\tprivate _autoNameCounter = 0;\n\n\tconstructor() {\n\t\t// Debug camera is created lazily during setup when we have screen resolution\n\t}\n\n\t/**\n\t * Get the list of currently active cameras.\n\t */\n\tget activeCameras(): ReadonlyArray<ZylemCamera> {\n\t\treturn this._activeCameras;\n\t}\n\n\t/**\n\t * Get the primary active camera (first in the active list).\n\t */\n\tget primaryCamera(): ZylemCamera | null {\n\t\treturn this._activeCameras.length > 0 ? this._activeCameras[0] : null;\n\t}\n\n\t/**\n\t * Get the debug camera.\n\t */\n\tget debugCamera(): ZylemCamera | null {\n\t\treturn this._debugCamera;\n\t}\n\n\t/**\n\t * Get all registered cameras.\n\t */\n\tget allCameras(): ReadonlyArray<ZylemCamera> {\n\t\treturn Array.from(this.cameras.values());\n\t}\n\n\t/**\n\t * Add a camera to the manager.\n\t * If no name is provided, one is auto-generated.\n\t * The first camera added becomes the active camera.\n\t *\n\t * @param camera The ZylemCamera instance to add\n\t * @param name Optional name for lookup\n\t * @returns The assigned name\n\t */\n\taddCamera(camera: ZylemCamera, name?: string): string {\n\t\tconst resolvedName = name || camera.name || `camera_${this._autoNameCounter++}`;\n\t\tcamera.name = resolvedName;\n\t\tthis.cameras.set(resolvedName, camera);\n\n\t\t// First camera added automatically becomes active\n\t\tif (this._activeCameras.length === 0) {\n\t\t\tthis._activeCameras.push(camera);\n\t\t}\n\n\t\treturn resolvedName;\n\t}\n\n\t/**\n\t * Remove a camera by name or reference.\n\t * Cannot remove the debug camera via this method.\n\t */\n\tremoveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tlet name: string | undefined;\n\n\t\tif (typeof nameOrRef === 'string') {\n\t\t\tname = nameOrRef;\n\t\t} else {\n\t\t\t// Find by reference\n\t\t\tfor (const [key, cam] of this.cameras.entries()) {\n\t\t\t\tif (cam === nameOrRef) {\n\t\t\t\t\tname = key;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!name) return false;\n\n\t\tconst camera = this.cameras.get(name);\n\t\tif (!camera) return false;\n\n\t\t// Prevent removing the debug camera\n\t\tif (camera === this._debugCamera) {\n\t\t\tconsole.warn('CameraManager: Cannot remove the debug camera');\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.cameras.delete(name);\n\n\t\t// Remove from active cameras\n\t\tconst activeIndex = this._activeCameras.indexOf(camera);\n\t\tif (activeIndex !== -1) {\n\t\t\tthis._activeCameras.splice(activeIndex, 1);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Set a camera as the primary active camera (replaces all active cameras\n\t * except additional viewport cameras).\n\t *\n\t * @param nameOrRef Camera name or reference to activate\n\t */\n\tsetActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) {\n\t\t\tconsole.warn(`CameraManager: Camera not found: ${nameOrRef}`);\n\t\t\treturn false;\n\t\t}\n\n\t\t// Set as the sole active camera (keeping PiP cameras if any)\n\t\tconst pipCameras = this._activeCameras.filter(c => {\n\t\t\treturn c !== this._activeCameras[0] && c.viewport.width < 1;\n\t\t});\n\n\t\tthis._activeCameras = [camera, ...pipCameras];\n\t\treturn true;\n\t}\n\n\t/**\n\t * Add a camera as an additional active camera (for split-screen or PiP).\n\t */\n\taddActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) return false;\n\n\t\tif (!this._activeCameras.includes(camera)) {\n\t\t\tthis._activeCameras.push(camera);\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Remove a camera from the active render list (does not remove from registry).\n\t */\n\tdeactivateCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) return false;\n\n\t\tconst index = this._activeCameras.indexOf(camera);\n\t\tif (index !== -1) {\n\t\t\tthis._activeCameras.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get a camera by name.\n\t */\n\tgetCamera(name: string): ZylemCamera | null {\n\t\treturn this.cameras.get(name) ?? null;\n\t}\n\n\t/**\n\t * Setup all cameras with the given scene and renderer manager.\n\t * Also creates the debug camera.\n\t */\n\tasync setup(scene: Scene, rendererManager: RendererManager): Promise<void> {\n\t\tthis._sceneRef = scene;\n\t\tthis._rendererManager = rendererManager;\n\n\t\t// Create the debug camera\n\t\tthis.createDebugCamera(rendererManager.screenResolution);\n\n\t\t// Setup all registered cameras\n\t\tfor (const camera of this.cameras.values()) {\n\t\t\tcamera.setRendererManager(rendererManager);\n\t\t\tawait camera.setup(scene, rendererManager);\n\t\t}\n\n\t\t// Setup the debug camera\n\t\tif (this._debugCamera) {\n\t\t\tthis._debugCamera.setRendererManager(rendererManager);\n\t\t\tawait this._debugCamera.setup(scene, rendererManager);\n\t\t}\n\t}\n\n\t/**\n\t * Update all active cameras' controllers.\n\t */\n\tupdate(delta: number): void {\n\t\tfor (const camera of this._activeCameras) {\n\t\t\tcamera.update(delta);\n\t\t}\n\t}\n\n\t/**\n\t * Render all active cameras through the renderer manager.\n\t * RTT cameras (those with a renderTarget) are rendered first to their\n\t * offscreen textures, then viewport cameras are rendered to the screen.\n\t */\n\trender(scene: Scene): void {\n\t\tif (!this._rendererManager || this._activeCameras.length === 0) return;\n\n\t\tconst rttCameras: ZylemCamera[] = [];\n\t\tconst viewportCameras: ZylemCamera[] = [];\n\n\t\tfor (const cam of this._activeCameras) {\n\t\t\tif (cam.renderTarget) {\n\t\t\t\trttCameras.push(cam);\n\t\t\t} else {\n\t\t\t\tviewportCameras.push(cam);\n\t\t\t}\n\t\t}\n\n\t\t// RTT pass first so textures are ready for the viewport pass\n\t\tfor (const cam of rttCameras) {\n\t\t\tthis._rendererManager.renderCameraToTarget(scene, cam);\n\t\t}\n\n\t\t// Viewport pass renders to the screen canvas\n\t\tif (viewportCameras.length > 0) {\n\t\t\tthis._rendererManager.renderCameras(scene, viewportCameras);\n\t\t}\n\t}\n\n\t/**\n\t * Create a default third-person camera if no cameras have been added.\n\t */\n\tensureDefaultCamera(): ZylemCamera {\n\t\tif (this.cameras.size === 0 || this._activeCameras.length === 0) {\n\t\t\tconst screenRes = this._rendererManager?.screenResolution\n\t\t\t\t|| new Vector2(window.innerWidth, window.innerHeight);\n\t\t\tconst defaultCam = new ZylemCamera(Perspectives.ThirdPerson, screenRes);\n\t\t\tthis.addCamera(defaultCam, 'default');\n\t\t\treturn defaultCam;\n\t\t}\n\t\treturn this._activeCameras[0];\n\t}\n\n\t/**\n\t * Dispose all cameras and cleanup.\n\t */\n\tdispose(): void {\n\t\tfor (const camera of this.cameras.values()) {\n\t\t\tcamera.destroy();\n\t\t}\n\t\tthis._debugCamera?.destroy();\n\t\tthis.cameras.clear();\n\t\tthis._activeCameras = [];\n\t\tthis._debugCamera = null;\n\t\tthis._rendererManager = null;\n\t\tthis._sceneRef = null;\n\t}\n\n\t/**\n\t * Create the always-available debug camera with orbit controls.\n\t */\n\tprivate createDebugCamera(screenResolution: Vector2): void {\n\t\tthis._debugCamera = new ZylemCamera(Perspectives.ThirdPerson, screenResolution);\n\t\tthis._debugCamera.name = '__debug__';\n\t\tthis._debugCamera.enableOrbitalControls();\n\t\t// Debug camera is NOT added to the active cameras by default;\n\t\t// it's activated via the debug system\n\t}\n\n\t/**\n\t * Resolve a camera from a name or reference.\n\t */\n\tprivate resolveCamera(nameOrRef: string | ZylemCamera): ZylemCamera | null {\n\t\tif (typeof nameOrRef === 'string') {\n\t\t\treturn this.cameras.get(nameOrRef) ?? null;\n\t\t}\n\t\t// Check if the reference exists in our registry\n\t\tfor (const cam of this.cameras.values()) {\n\t\t\tif (cam === nameOrRef) return cam;\n\t\t}\n\t\treturn null;\n\t}\n}\n","import { Vector2 } from 'three';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { Perspectives } from '../camera/perspective';\nimport { CameraWrapper } from '../camera/camera';\nimport { CameraManager } from '../camera/camera-manager';\nimport type { ZylemStage } from './zylem-stage';\n\n/**\n * Delegate for camera creation and management within a stage.\n * Accepts an injected stage reference for context.\n */\nexport class StageCameraDelegate {\n\tprivate stage: ZylemStage;\n\n\tconstructor(stage: ZylemStage) {\n\t\tthis.stage = stage;\n\t}\n\n\t/**\n\t * Create a default third-person camera based on window size.\n\t */\n\tcreateDefaultCamera(): ZylemCamera {\n\t\tconst width = window.innerWidth;\n\t\tconst height = window.innerHeight;\n\t\tconst screenResolution = new Vector2(width, height);\n\t\treturn new ZylemCamera(Perspectives.ThirdPerson, screenResolution);\n\t}\n\n\t/**\n\t * Resolve the camera to use for the stage.\n\t * Uses the provided camera, stage camera wrapper, or creates a default.\n\t * \n\t * @param cameraOverride Optional camera override\n\t * @param cameraWrapper Optional camera wrapper from stage options\n\t * @returns The resolved ZylemCamera instance\n\t */\n\tresolveCamera(cameraOverride?: ZylemCamera | null, cameraWrapper?: CameraWrapper): ZylemCamera {\n\t\tif (cameraOverride) {\n\t\t\treturn cameraOverride;\n\t\t}\n\t\tif (cameraWrapper) {\n\t\t\treturn cameraWrapper.cameraRef;\n\t\t}\n\t\treturn this.createDefaultCamera();\n\t}\n\n\t/**\n\t * Build a CameraManager from stage options.\n\t * Supports single camera (backward compatible) and multiple cameras.\n\t * \n\t * @param cameraOverride Optional camera override from game-level config\n\t * @param cameraWrappers Camera wrappers from stage options (can be single or array)\n\t * @returns A CameraManager populated with the resolved cameras\n\t */\n\tbuildCameraManager(\n\t\tcameraOverride?: ZylemCamera | null,\n\t\t...cameraWrappers: (CameraWrapper | undefined)[]\n\t): CameraManager {\n\t\tconst manager = new CameraManager();\n\n\t\t// If there's a camera override, use it as the primary\n\t\tif (cameraOverride) {\n\t\t\tmanager.addCamera(cameraOverride, cameraOverride.name || 'main');\n\t\t\treturn manager;\n\t\t}\n\n\t\t// Add cameras from wrappers\n\t\tconst validWrappers = cameraWrappers.filter((w): w is CameraWrapper => w !== undefined);\n\n\t\tif (validWrappers.length > 0) {\n\t\t\tfor (const wrapper of validWrappers) {\n\t\t\t\tconst cam = wrapper.cameraRef;\n\t\t\t\tmanager.addCamera(cam, cam.name || undefined);\n\t\t\t}\n\t\t\t// Activate all cameras beyond the first (addCamera auto-activates only the first).\n\t\t\t// All cameras explicitly passed to createStage should render.\n\t\t\tfor (let i = 1; i < validWrappers.length; i++) {\n\t\t\t\tmanager.addActiveCamera(validWrappers[i].cameraRef);\n\t\t\t}\n\t\t} else {\n\t\t\t// No cameras provided: create a default\n\t\t\tconst defaultCam = this.createDefaultCamera();\n\t\t\tmanager.addCamera(defaultCam, 'default');\n\t\t}\n\n\t\treturn manager;\n\t}\n}\n","import { LoadingEvent } from '../core/interfaces';\nimport { gameEventBus, StageLoadingPayload } from '../game/game-event-bus';\n\n/**\n * Event name for stage loading events.\n * Dispatched via window for cross-application communication.\n */\nexport const STAGE_LOADING_EVENT = 'STAGE_LOADING_EVENT';\n\n/**\n * Delegate for managing loading events and progress within a stage.\n * Handles subscription to loading events and broadcasting progress.\n * Emits to game event bus for game-level observation.\n */\nexport class StageLoadingDelegate {\n\tprivate loadingHandlers: Array<(event: LoadingEvent) => void> = [];\n\tprivate stageName?: string;\n\tprivate stageIndex?: number;\n\n\t/**\n\t * Set stage context for event bus emissions.\n\t */\n\tsetStageContext(stageName: string, stageIndex: number): void {\n\t\tthis.stageName = stageName;\n\t\tthis.stageIndex = stageIndex;\n\t}\n\n\t/**\n\t * Subscribe to loading events.\n\t * \n\t * @param callback Invoked for each loading event (start, progress, complete)\n\t * @returns Unsubscribe function\n\t */\n\tonLoading(callback: (event: LoadingEvent) => void): () => void {\n\t\tthis.loadingHandlers.push(callback);\n\t\treturn () => {\n\t\t\tthis.loadingHandlers = this.loadingHandlers.filter((h) => h !== callback);\n\t\t};\n\t}\n\n\t/**\n\t * Emit a loading event to all subscribers and to the game event bus.\n\t * \n\t * @param event The loading event to broadcast\n\t */\n\temit(event: LoadingEvent): void {\n\t\t// Dispatch to direct subscribers\n\t\tfor (const handler of this.loadingHandlers) {\n\t\t\ttry {\n\t\t\t\thandler(event);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Loading handler failed', e);\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Emit to game event bus for game-level observation\n\t\tconst payload: StageLoadingPayload = {\n\t\t\t...event,\n\t\t\tstageName: this.stageName,\n\t\t\tstageIndex: this.stageIndex,\n\t\t};\n\t\t\n\t\tif (event.type === 'start') {\n\t\t\tgameEventBus.emit('stage:loading:start', payload);\n\t\t} else if (event.type === 'progress') {\n\t\t\tgameEventBus.emit('stage:loading:progress', payload);\n\t\t} else if (event.type === 'complete') {\n\t\t\tgameEventBus.emit('stage:loading:complete', payload);\n\t\t}\n\t}\n\n\t/**\n\t * Emit a start loading event.\n\t */\n\temitStart(message: string = 'Loading stage...'): void {\n\t\tthis.emit({ type: 'start', message, progress: 0 });\n\t}\n\n\t/**\n\t * Emit a progress loading event.\n\t */\n\temitProgress(message: string, current: number, total: number): void {\n\t\tconst progress = total > 0 ? current / total : 0;\n\t\tthis.emit({ type: 'progress', message, progress, current, total });\n\t}\n\n\t/**\n\t * Emit a complete loading event.\n\t */\n\temitComplete(message: string = 'Stage loaded'): void {\n\t\tthis.emit({ type: 'complete', message, progress: 1 });\n\t}\n\n\t/**\n\t * Clear all loading handlers.\n\t */\n\tdispose(): void {\n\t\tthis.loadingHandlers = [];\n\t}\n}\n","import { zylemEventBus } from '../events';\nimport { ZylemScene } from '../graphics/zylem-scene';\nimport { GameEntity } from '../entities/entity';\n\n/**\n * Delegate for handling deferred model loading in entities.\n * Subscribes to model:loaded events and adds entity groups to the scene\n * when they become available after async loading completes.\n */\nexport class StageEntityModelDelegate {\n\tprivate scene: ZylemScene | null = null;\n\tprivate onEntityReady: ((entity: GameEntity<any>) => void) | null = null;\n\tprivate pendingEntities: Map<string, GameEntity<any>> = new Map();\n\tprivate modelLoadedHandler: ((payload: { entityId: string; success: boolean }) => void) | null = null;\n\n\t/**\n\t * Initialize the delegate with the scene reference and start listening.\n\t */\n\tattach(scene: ZylemScene, onEntityReady?: (entity: GameEntity<any>) => void): void {\n\t\tthis.scene = scene;\n\t\tthis.onEntityReady = onEntityReady ?? null;\n\t\tthis.modelLoadedHandler = (payload) => {\n\t\t\tthis.handleModelLoaded(payload.entityId, payload.success);\n\t\t};\n\t\tzylemEventBus.on('entity:model:loaded', this.modelLoadedHandler);\n\t}\n\n\t/**\n\t * Register an entity for observation.\n\t * When its model loads, the group will be added to the scene.\n\t */\n\tobserve(entity: GameEntity<any>): void {\n\t\tif (entity.group || entity.mesh) {\n\t\t\treturn;\n\t\t}\n\t\tthis.pendingEntities.set(entity.uuid, entity);\n\t}\n\n\t/**\n\t * Unregister an entity (e.g., when removed before model loads).\n\t */\n\tunobserve(entityId: string): void {\n\t\tthis.pendingEntities.delete(entityId);\n\t}\n\n\t/**\n\t * Handle model loaded event - add group to scene if entity is pending.\n\t */\n\tprivate handleModelLoaded(entityId: string, success: boolean): void {\n\t\tconst entity = this.pendingEntities.get(entityId);\n\t\tif (!entity || !success) {\n\t\t\tthis.pendingEntities.delete(entityId);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.scene?.addEntityGroup(entity);\n\t\tthis.onEntityReady?.(entity);\n\t\tthis.pendingEntities.delete(entityId);\n\t}\n\n\t/**\n\t * Cleanup all subscriptions and pending entities.\n\t */\n\tdispose(): void {\n\t\tif (this.modelLoadedHandler) {\n\t\t\tzylemEventBus.off('entity:model:loaded', this.modelLoadedHandler);\n\t\t\tthis.modelLoadedHandler = null;\n\t\t}\n\t\tthis.pendingEntities.clear();\n\t\tthis.onEntityReady = null;\n\t\tthis.scene = null;\n\t}\n}\n","import { Color, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { CameraWrapper } from '../camera/camera';\nimport { isBaseNode, isCameraWrapper, isConfigObject, isEntityInput } from '../core/utility/options-parser';\nimport { ZylemBlueColor } from '../core/utility/vector';\nimport type { ZylemShader } from '../graphics/material';\n\n/**\n * Stage configuration type for user-facing options.\n */\nexport type StageConfigLike = Partial<{\n\tinputs: Record<string, string[]>;\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader: ZylemShader;\n\tgravity: Vector3;\n\tvariables: Record<string, any>;\n\t/** Physics update rate in Hz (default 60). */\n\tphysicsRate: number;\n\t/** Run physics in a Web Worker (default false). */\n\tusePhysicsWorker: boolean;\n\t/**\n\t * URL to the physics worker script. Required when `usePhysicsWorker` is true.\n\t * In a Vite app, use:\n\t * ```ts\n\t * physicsWorkerUrl: new URL('@zylem/game-lib/dist/physics-worker.js', import.meta.url)\n\t * ```\n\t */\n\tphysicsWorkerUrl: URL | string;\n}>;\n\n/**\n * Internal stage configuration class.\n */\nexport class StageConfig {\n\tconstructor(\n\t\tpublic inputs: Record<string, string[]>,\n\t\tpublic backgroundColor: Color | string,\n\t\tpublic backgroundImage: string | null,\n\t\tpublic backgroundShader: ZylemShader | null,\n\t\tpublic gravity: Vector3,\n\t\tpublic variables: Record<string, any>,\n\t\t/** Physics update rate in Hz (default 60). */\n\t\tpublic physicsRate: number = 60,\n\t\t/** Run physics in a Web Worker (default false). */\n\t\tpublic usePhysicsWorker: boolean = false,\n\t\t/** URL to the physics worker script. Required when usePhysicsWorker is true. */\n\t\tpublic physicsWorkerUrl: URL | string | undefined = undefined,\n\t) { }\n}\n\n/**\n * Create default stage configuration.\n */\nexport function createDefaultStageConfig(): StageConfig {\n\treturn new StageConfig(\n\t\t{\n\t\t\tp1: ['gamepad-1', 'keyboard-1'],\n\t\t\tp2: ['gamepad-2', 'keyboard-2'],\n\t\t},\n\t\tZylemBlueColor,\n\t\tnull,\n\t\tnull,\n\t\tnew Vector3(0, 0, 0),\n\t\t{},\n\t\t60,\n\t\tfalse,\n\t\tundefined,\n\t);\n}\n\n/**\n * Result of parsing stage options.\n */\nexport interface ParsedStageOptions {\n\tconfig: StageConfig;\n\tentities: BaseNode[];\n\tasyncEntities: Array<BaseNode | Promise<any> | (() => BaseNode | Promise<any>)>;\n\t/** @deprecated Use `cameras` array instead for multi-camera support */\n\tcamera?: CameraWrapper;\n\t/** All camera wrappers found in stage options */\n\tcameras: CameraWrapper[];\n}\n\n/**\n * Parse stage options array and resolve configuration.\n * Separates config objects, camera wrappers, and entity inputs.\n * \n * @param options Stage options array\n * @returns Parsed stage options with resolved config, entities, and camera\n */\nexport function parseStageOptions(options: any[] = []): ParsedStageOptions {\n\tconst defaults = createDefaultStageConfig();\n\tlet config: Partial<StageConfig> = {};\n\tconst entities: BaseNode[] = [];\n\tconst asyncEntities: Array<BaseNode | Promise<any> | (() => BaseNode | Promise<any>)> = [];\n\tconst cameras: CameraWrapper[] = [];\n\n\tfor (const item of options) {\n\t\tif (isCameraWrapper(item)) {\n\t\t\tcameras.push(item);\n\t\t} else if (isBaseNode(item)) {\n\t\t\tentities.push(item);\n\t\t} else if (isEntityInput(item) && !isBaseNode(item)) {\n\t\t\tasyncEntities.push(item);\n\t\t} else if (isConfigObject(item)) {\n\t\t\tconfig = { ...config, ...item };\n\t\t}\n\t}\n\n\t// Merge user config with defaults\n\tconst resolvedConfig = new StageConfig(\n\t\tconfig.inputs ?? defaults.inputs,\n\t\tconfig.backgroundColor ?? defaults.backgroundColor,\n\t\tconfig.backgroundImage ?? defaults.backgroundImage,\n\t\tconfig.backgroundShader ?? defaults.backgroundShader,\n\t\tconfig.gravity ?? defaults.gravity,\n\t\tconfig.variables ?? defaults.variables,\n\t\tconfig.physicsRate ?? defaults.physicsRate,\n\t\tconfig.usePhysicsWorker ?? defaults.usePhysicsWorker,\n\t\t(config as any).physicsWorkerUrl ?? defaults.physicsWorkerUrl,\n\t);\n\n\t// Backward compat: first camera is the legacy `camera` field\n\tconst camera = cameras.length > 0 ? cameras[0] : undefined;\n\n\treturn { config: resolvedConfig, entities, asyncEntities, camera, cameras };\n}\n\n/**\n * Factory for authoring stage configuration objects in user code.\n * Returns a plain object that can be passed to `createStage(...)`.\n */\nexport function stageConfig(config: StageConfigLike): StageConfigLike {\n\treturn { ...config };\n}\n","import { RigidBody } from '@dimforge/rapier3d-compat';\nimport { TransformState } from './transform-store';\n\ninterface ComposedAxis {\n\tvalue: number;\n\ttouched: boolean;\n}\n\ninterface ComposedVelocity {\n\tx: ComposedAxis;\n\ty: ComposedAxis;\n\tz: ComposedAxis;\n}\n\ninterface ResolvedIntent {\n\tsourceId: string;\n\tmode: 'replace' | 'add';\n\tpriority: number;\n\tx?: number;\n\ty?: number;\n\tz?: number;\n}\n\nfunction sortIntents(a: ResolvedIntent, b: ResolvedIntent): number {\n\tif (a.priority !== b.priority) return a.priority - b.priority;\n\treturn a.sourceId.localeCompare(b.sourceId);\n}\n\nfunction composeAxis(\n\tcurrent: number,\n\tintents: ResolvedIntent[],\n\taxis: 'x' | 'y' | 'z',\n): ComposedAxis {\n\tlet touched = false;\n\tlet addSum = 0;\n\tlet hasReplace = false;\n\tlet replaceValue = current;\n\tlet replacePriority = Number.NEGATIVE_INFINITY;\n\n\tfor (const intent of intents) {\n\t\tconst axisValue = intent[axis];\n\t\tif (axisValue == null) continue;\n\t\ttouched = true;\n\n\t\tif (intent.mode === 'add') {\n\t\t\taddSum += axisValue;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!hasReplace || intent.priority >= replacePriority) {\n\t\t\thasReplace = true;\n\t\t\treplacePriority = intent.priority;\n\t\t\treplaceValue = axisValue;\n\t\t}\n\t}\n\n\treturn {\n\t\ttouched,\n\t\tvalue: (hasReplace ? replaceValue : 0) + addSum,\n\t};\n}\n\nfunction composeVelocity(current: { x: number; y: number; z: number }, intents: ResolvedIntent[]): ComposedVelocity {\n\treturn {\n\t\tx: composeAxis(current.x, intents, 'x'),\n\t\ty: composeAxis(current.y, intents, 'y'),\n\t\tz: composeAxis(current.z, intents, 'z'),\n\t};\n}\n\nfunction clearVelocityChannels(store: TransformState): void {\n\tfor (const sourceId in store.velocityChannels) {\n\t\tdelete store.velocityChannels[sourceId];\n\t}\n\tstore.dirty.velocityChannels = false;\n}\n\n/**\n * Entity that can have transformations applied from a store\n */\nexport interface TransformableEntity {\n\tbody: RigidBody | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Apply accumulated transformations from the store to the physics body.\n * \n * This is called automatically after onUpdate() callbacks complete,\n * flushing all pending transformations to the physics engine in a single batch.\n * \n * Flow:\n * 1. Check dirty flags to see what changed\n * 2. Apply changes to RigidBody\n * 3. Reset store for next frame\n * \n * @param entity Entity with physics body and transform store\n * @param store Transform store containing pending changes\n */\nexport function applyTransformChanges(\n\tentity: TransformableEntity,\n\tstore: TransformState\n): void {\n\tif (!entity.body) return;\n\n\tconst hasPosition = store.dirty.position;\n\tconst hasRotation = store.dirty.rotation;\n\tconst hasAngularVelocity = store.dirty.angularVelocity;\n\tconst hasPerAxis = store.dirty.velocityX || store.dirty.velocityY || store.dirty.velocityZ;\n\tconst hasLegacyVelocity = store.dirty.velocity;\n\tconst hasChannels = store.dirty.velocityChannels;\n\n\tif (!hasPosition && !hasRotation && !hasAngularVelocity && !hasPerAxis && !hasLegacyVelocity && !hasChannels) {\n\t\treturn;\n\t}\n\n\tconst intents: ResolvedIntent[] = [];\n\tif (hasChannels) {\n\t\tfor (const sourceId in store.velocityChannels) {\n\t\t\tconst intent = store.velocityChannels[sourceId];\n\t\t\tintents.push({\n\t\t\t\tsourceId,\n\t\t\t\tmode: intent.mode ?? 'replace',\n\t\t\t\tpriority: intent.priority ?? 0,\n\t\t\t\tx: intent.x,\n\t\t\t\ty: intent.y,\n\t\t\t\tz: intent.z,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Legacy fallback mapped into the same composition pipeline.\n\tif (hasLegacyVelocity) {\n\t\tintents.push({\n\t\t\tsourceId: '__legacy_velocity__',\n\t\t\tmode: 'replace',\n\t\t\tpriority: -100,\n\t\t\tx: store.velocity.x,\n\t\t\ty: store.velocity.y,\n\t\t\tz: store.velocity.z,\n\t\t});\n\t} else if (hasPerAxis) {\n\t\tintents.push({\n\t\t\tsourceId: '__legacy_per_axis__',\n\t\t\tmode: 'replace',\n\t\t\tpriority: -100,\n\t\t\tx: store.dirty.velocityX ? store.velocity.x : undefined,\n\t\t\ty: store.dirty.velocityY ? store.velocity.y : undefined,\n\t\t\tz: store.dirty.velocityZ ? store.velocity.z : undefined,\n\t\t});\n\t}\n\n\tif (intents.length > 0) {\n\t\tconst current = entity.body.linvel();\n\t\tif (intents.length > 1) {\n\t\t\tintents.sort(sortIntents);\n\t\t}\n\t\tconst composed = composeVelocity(current, intents);\n\n\t\tentity.body.setLinvel(\n\t\t\t{\n\t\t\t\tx: composed.x.touched ? composed.x.value : current.x,\n\t\t\t\ty: composed.y.touched ? composed.y.value : current.y,\n\t\t\t\tz: composed.z.touched ? composed.z.value : current.z,\n\t\t\t},\n\t\t\ttrue,\n\t\t);\n\t}\n\n\tif (hasRotation) {\n\t\tentity.body.setRotation(store.rotation, true);\n\t}\n\n\tif (hasAngularVelocity) {\n\t\tentity.body.setAngvel(store.angularVelocity, true);\n\t}\n\n\tif (hasPosition) {\n\t\tconst current = entity.body.translation();\n\t\tentity.body.setTranslation(\n\t\t\t{\n\t\t\t\tx: current.x + store.position.x,\n\t\t\t\ty: current.y + store.position.y,\n\t\t\t\tz: current.z + store.position.z,\n\t\t\t},\n\t\t\ttrue,\n\t\t);\n\t}\n\n\t// Reset dirty flags for next frame\n\tstore.dirty.position = false;\n\tstore.dirty.rotation = false;\n\tstore.dirty.velocity = false;\n\tstore.dirty.velocityX = false;\n\tstore.dirty.velocityY = false;\n\tstore.dirty.velocityZ = false;\n\tclearVelocityChannels(store);\n\tstore.dirty.angularVelocity = false;\n}\n","import { BaseNode } from './base-node';\nimport {\n\tSetupContext,\n\tUpdateContext,\n\tDestroyContext,\n\tLoadedContext,\n\tCleanupContext,\n} from './base-node-life-cycle';\nimport type { NodeInterface } from './node-interface';\n\nconst VESSEL_TYPE = Symbol('vessel');\n\n/**\n * A Vessel is an empty container entity that holds child entities.\n * It has no geometry, physics, or rendering of its own, but propagates\n * lifecycle events to its children and provides a logical grouping mechanism.\n *\n * Child entities added to a Vessel will be individually spawned into the\n * stage's physics world and render scene when the Vessel is spawned.\n */\nexport class Vessel extends BaseNode<{}, Vessel> {\n\tstatic type = VESSEL_TYPE;\n\n\tprotected _setup(_params: SetupContext<this>): void { }\n\n\tprotected async _loaded(_params: LoadedContext<this>): Promise<void> { }\n\n\tprotected _update(_params: UpdateContext<this>): void { }\n\n\tprotected _destroy(_params: DestroyContext<this>): void { }\n\n\tprotected _cleanup(_params: CleanupContext<this>): void { }\n\n\tpublic create(): this {\n\t\treturn this;\n\t}\n\n\tpublic clone(): this {\n\t\tconst cloned = vessel() as this;\n\t\tthis.replayUserLifecycleRegistrationsTo(cloned);\n\t\tthis.cloneChildrenInto(cloned);\n\t\treturn cloned;\n\t}\n\n\t/**\n\t * Add one or more child entities to this vessel.\n\t * Overrides parent to support multiple arguments.\n\t * @returns this for chaining\n\t */\n\tpublic add(...nodes: NodeInterface[]): this {\n\t\tfor (const node of nodes) {\n\t\t\tsuper.add(node);\n\t\t}\n\t\treturn this;\n\t}\n}\n\n/**\n * Create a vessel containing the given child entities.\n * @param args Child BaseNode entities to add\n * @returns A new Vessel with the children added\n */\nexport function vessel(...args: Array<BaseNode>): Vessel {\n\tconst instance = new Vessel();\n\targs.forEach(arg => instance.add(arg));\n\tinstance.enableUserLifecycleTracking();\n\treturn instance;\n}\n","import { addEntity, removeEntity } from 'bitecs';\n\nimport { ZylemWorld } from '../collision/world';\nimport { ZylemScene } from '../graphics/zylem-scene';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { InstanceManager } from '../graphics/instance-manager';\nimport { clearVariables } from './stage-state';\nimport { debugState } from '../debug/debug-state';\nimport { getGlobals } from '../game/game-state';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntity } from '../entities/entity';\nimport { ZylemActor } from '../entities/actor';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { StageLoadingDelegate } from './stage-loading-delegate';\nimport { StageEntityModelDelegate } from './stage-entity-model-delegate';\nimport { isBaseNode, isThenable } from '../core/utility/options-parser';\nimport type {\n\tBehaviorEntityLink,\n\tBehaviorSystem,\n\tBehaviorSystemFactory,\n} from '../behaviors/behavior-system';\nimport { Vessel } from '../core/vessel';\n\ntype NodeLike = { create: Function };\nexport type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);\n\n/**\n * Runtime context provided by ZylemStage after scene and world are initialized.\n */\nexport interface EntityDelegateContext {\n\tscene: ZylemScene;\n\tworld: ZylemWorld;\n\tecs: ReturnType<typeof import('bitecs').createWorld>;\n\tinstanceManager: InstanceManager | null;\n\t/** Resolved camera for entity setup contexts. */\n\tcamera: ZylemCamera;\n}\n\n/**\n * Delegate responsible for entity spawning, tracking, queuing, removal, and lookup.\n *\n * Owns all entity-related state and exposes it to ZylemStage for orchestration\n * and to external consumers (debug delegate, transform system) via public getters.\n */\nexport class StageEntityDelegate {\n\tprivate static readonly EMPTY_BEHAVIOR_LINKS: readonly BehaviorEntityLink[] = [];\n\n\t/** Entities queued before load completes. */\n\tchildren: BaseNode[] = [];\n\n\t/** EID → BaseNode map of all live entities. */\n\treadonly childrenMap: Map<number, BaseNode> = new Map();\n\n\t/** UUID → BaseNode map populated when debug mode is active. */\n\treadonly debugMap: Map<string, BaseNode> = new Map();\n\n\t/** UUID → EID reverse lookup for O(1) removal. */\n\tprivate readonly uuidToEid: Map<string, number> = new Map();\n\n\tprivate pendingEntities: StageEntityInput[] = [];\n\tprivate pendingPromises: Promise<BaseNode>[] = [];\n\tprivate _isLoaded = false;\n\n\tprivate entityAddedHandlers: Array<(entity: BaseNode) => void> = [];\n\n\t/** ECS behavior systems auto-registered from entity refs or manually added. */\n\treadonly behaviorSystems: BehaviorSystem[] = [];\n\treadonly registeredSystemKeys: Set<symbol> = new Set();\n\treadonly behaviorEntityIndex: Map<symbol, Set<BehaviorEntityLink>> = new Map();\n\tprivate readonly behaviorLinksByUuid: Map<string, BehaviorEntityLink[]> = new Map();\n\n\t// Runtime context — set via attach() during stage load\n\tprivate scene: ZylemScene | null = null;\n\tprivate world: ZylemWorld | null = null;\n\tprivate ecs: ReturnType<typeof import('bitecs').createWorld> | null = null;\n\tprivate instanceManager: InstanceManager | null = null;\n\tprivate camera: ZylemCamera | null = null;\n\n\tprivate loadingDelegate: StageLoadingDelegate;\n\tprivate entityModelDelegate: StageEntityModelDelegate;\n\n\tconstructor(\n\t\tloadingDelegate: StageLoadingDelegate,\n\t\tentityModelDelegate: StageEntityModelDelegate,\n\t) {\n\t\tthis.loadingDelegate = loadingDelegate;\n\t\tthis.entityModelDelegate = entityModelDelegate;\n\t}\n\n\tget isLoaded(): boolean {\n\t\treturn this._isLoaded;\n\t}\n\n\tset isLoaded(value: boolean) {\n\t\tthis._isLoaded = value;\n\t}\n\n\t/**\n\t * Bind runtime context after scene and world are initialized.\n\t * Must be called before any spawn/enqueue operations.\n\t */\n\tattach(context: EntityDelegateContext): void {\n\t\tthis.scene = context.scene;\n\t\tthis.world = context.world;\n\t\tthis.ecs = context.ecs;\n\t\tthis.instanceManager = context.instanceManager;\n\t\tthis.camera = context.camera;\n\t}\n\n\t// ─── Spawning ────────────────────────────────────────────────────────────\n\n\t/**\n\t * Create, register, and add an entity to the scene/world.\n\t * Safe to call only after `attach` when scene/world exist.\n\t */\n\tasync spawnEntity(child: BaseNode): Promise<void> {\n\t\tif (!this.scene || !this.world || !this.ecs) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (child instanceof Vessel) {\n\t\t\tchild.create();\n\t\t\tfor (const childEntity of child.getChildren()) {\n\t\t\t\tif (childEntity instanceof BaseNode) {\n\t\t\t\t\tawait this.spawnEntity(childEntity);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst vesselEid = addEntity(this.ecs);\n\t\t\tchild.eid = vesselEid;\n\n\t\t\tchild.nodeSetup({\n\t\t\t\tme: child,\n\t\t\t\tglobals: getGlobals(),\n\t\t\t\tcamera: this.camera!,\n\t\t\t});\n\n\t\t\tthis.addEntityToStage(child);\n\t\t\treturn;\n\t\t}\n\n\t\tconst entity = child.create();\n\t\tconst eid = addEntity(this.ecs);\n\t\tentity.eid = eid;\n\n\t\t// Register behavior links and auto-register behavior systems once per key.\n\t\tthis.registerBehaviorLinks(entity);\n\n\t\tthis.maybeAttachEntityPhysics(entity);\n\n\t\tfor (const childNode of child.getChildren()) {\n\t\t\tif (childNode instanceof BaseNode) {\n\t\t\t\tawait this.spawnEntity(childNode);\n\t\t\t}\n\t\t}\n\n\t\tchild.nodeSetup({\n\t\t\tme: child,\n\t\t\tglobals: getGlobals(),\n\t\t\tcamera: this.camera!,\n\t\t});\n\n\t\tthis.scene.addEntityGroup(entity);\n\t\tthis.tryRegisterInstance(entity);\n\t\tthis.addEntityToStage(entity);\n\t\tthis.entityModelDelegate.observe(entity);\n\t}\n\n\thandleLateModelReady(entity: GameEntity<any>): void {\n\t\tif (!this.world || !this.scene || !this.uuidToEid.has(entity.uuid)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.maybeAttachEntityPhysics(entity);\n\t\tthis.tryRegisterInstance(entity);\n\t}\n\n\t// ─── Instance batching ───────────────────────────────────────────────────\n\n\t/**\n\t * Register an entity for instanced rendering if opted in with `batched: true`.\n\t */\n\tprivate tryRegisterInstance(entity: GameEntity<any>): void {\n\t\tif (!this.instanceManager) return;\n\t\tif (entity.isInstanced) return;\n\n\t\tconst options = entity.options as any;\n\t\tif (options?.batched !== true) return;\n\t\tif (!entity.mesh?.geometry || !entity.materials?.length) return;\n\n\t\tconst geometry = entity.mesh.geometry;\n\t\tconst material = entity.materials[0];\n\n\t\tconst entityType = (entity.constructor as any).type?.description || 'unknown';\n\t\tconst size = options.size || { x: 1, y: 1, z: 1 };\n\t\tconst matOptions = options.material || {};\n\n\t\tconst batchKey = InstanceManager.generateBatchKey({\n\t\t\tgeometryType: entityType,\n\t\t\tdimensions: { x: size.x, y: size.y, z: size.z },\n\t\t\tmaterialPath: matOptions.path || null,\n\t\t\tshaderType: matOptions.shader ? 'custom' : 'standard',\n\t\t\tcolorHex: matOptions.color?.getHex?.() || 0xffffff,\n\t\t});\n\n\t\tconst instanceId = this.instanceManager.register(entity, geometry, material, batchKey);\n\n\t\tif (instanceId >= 0) {\n\t\t\tentity.batchKey = batchKey;\n\t\t\tentity.instanceId = instanceId;\n\t\t\tentity.isInstanced = true;\n\n\t\t\tif (entity.mesh) {\n\t\t\t\tentity.mesh.visible = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate maybeAttachEntityPhysics(entity: GameEntity<any>): void {\n\t\tif (!this.world || entity.physicsAttached || !entity.colliderDesc) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (entity instanceof ZylemActor) {\n\t\t\tif (entity.needsDeferredModelCollision()) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tentity.synchronizeRuntimeCollider();\n\t\t}\n\n\t\tthis.world.addEntity(entity);\n\t}\n\n\t// ─── Stage registration ──────────────────────────────────────────────────\n\n\t/** Add the entity to internal maps and notify listeners. */\n\taddEntityToStage(entity: BaseNode): void {\n\t\tthis.childrenMap.set(entity.eid, entity);\n\t\tthis.uuidToEid.set(entity.uuid, entity.eid);\n\t\tif (debugState.enabled) {\n\t\t\tthis.debugMap.set(entity.uuid, entity);\n\t\t}\n\t\tfor (const handler of this.entityAddedHandlers) {\n\t\t\ttry {\n\t\t\t\thandler(entity);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('onEntityAdded handler failed', e);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ─── Removal ─────────────────────────────────────────────────────────────\n\n\t/**\n\t * Remove an entity and its resources by its UUID.\n\t * Uses a uuid→eid reverse map for O(1) lookup.\n\t * @returns true if removed, false if not found or stage not ready\n\t */\n\tremoveEntityByUuid(uuid: string): boolean {\n\t\tif (!this.scene || !this.world || !this.ecs) return false;\n\n\t\t// @ts-ignore - collisionMap is public Map<string, GameEntity<any>>\n\t\tconst mapEntity = this.world.collisionMap.get(uuid) as any | undefined;\n\t\tconst entity: any = mapEntity ?? this.debugMap.get(uuid);\n\t\tif (!entity) return false;\n\t\tthis.unregisterBehaviorLinks(entity);\n\n\t\tthis.entityModelDelegate.unobserve(uuid);\n\n\t\tif (entity.isInstanced && this.instanceManager) {\n\t\t\tthis.instanceManager.unregister(entity);\n\t\t}\n\n\t\tthis.world.destroyEntity(entity);\n\n\t\tif (entity.group) {\n\t\t\tthis.scene.scene.remove(entity.group);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.scene.scene.remove(entity.mesh);\n\t\t}\n\n\t\tremoveEntity(this.ecs, entity.eid);\n\n\t\t// O(1) removal via reverse map\n\t\tconst eid = this.uuidToEid.get(uuid);\n\t\tif (eid !== undefined) {\n\t\t\tthis.childrenMap.delete(eid);\n\t\t\tthis.uuidToEid.delete(uuid);\n\t\t}\n\t\tthis.debugMap.delete(uuid);\n\t\treturn true;\n\t}\n\n\t// ─── Lookup ──────────────────────────────────────────────────────────────\n\n\t/** Get an entity by its name; returns null if not found. */\n\tgetEntityByName(name: string): BaseNode | null {\n\t\tfor (const child of this.childrenMap.values()) {\n\t\t\tif (child.name === name) return child;\n\t\t}\n\t\tconsole.warn(`Entity ${name} not found`);\n\t\treturn null;\n\t}\n\n\t/** Build a serializable state snapshot for an entity. */\n\tbuildEntityState(child: BaseNode): Partial<BaseEntityInterface> {\n\t\tif (child instanceof GameEntity) {\n\t\t\treturn { ...child.buildInfo() } as Partial<BaseEntityInterface>;\n\t\t}\n\t\treturn {\n\t\t\tuuid: child.uuid,\n\t\t\tname: child.name,\n\t\t\teid: child.eid,\n\t\t} as Partial<BaseEntityInterface>;\n\t}\n\n\t// ─── Subscriptions ───────────────────────────────────────────────────────\n\n\t/**\n\t * Subscribe to entity-added events.\n\t * @param callback Invoked for each entity when added\n\t * @param options.replayExisting If true and stage already loaded, replays existing entities\n\t * @returns Unsubscribe function\n\t */\n\tonEntityAdded(\n\t\tcallback: (entity: BaseNode) => void,\n\t\toptions?: { replayExisting?: boolean },\n\t): () => void {\n\t\tthis.entityAddedHandlers.push(callback);\n\t\tif (options?.replayExisting && this._isLoaded) {\n\t\t\tthis.childrenMap.forEach((entity) => {\n\t\t\t\ttry {\n\t\t\t\t\tcallback(entity);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.error('onEntityAdded replay failed', e);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn () => {\n\t\t\tthis.entityAddedHandlers = this.entityAddedHandlers.filter((h) => h !== callback);\n\t\t};\n\t}\n\n\t// ─── Queuing ─────────────────────────────────────────────────────────────\n\n\t/**\n\t * Enqueue items to be spawned. Items can be:\n\t * - BaseNode instances (immediate or deferred until load)\n\t * - Factory functions returning BaseNode or Promise<BaseNode>\n\t * - Promises resolving to BaseNode\n\t */\n\tenqueue(...items: StageEntityInput[]): void {\n\t\tfor (const item of items) {\n\t\t\tif (!item) continue;\n\t\t\tif (isBaseNode(item)) {\n\t\t\t\tthis.handleEntityImmediatelyOrQueue(item);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (typeof item === 'function') {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = (item as (() => BaseNode | Promise<any>))();\n\t\t\t\t\tif (isBaseNode(result)) {\n\t\t\t\t\t\tthis.handleEntityImmediatelyOrQueue(result);\n\t\t\t\t\t} else if (isThenable(result)) {\n\t\t\t\t\t\tthis.handlePromiseWithSpawnOnResolve(result as Promise<any>);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('Error executing entity factory', error);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isThenable(item)) {\n\t\t\t\tthis.handlePromiseWithSpawnOnResolve(item as Promise<any>);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleEntityImmediatelyOrQueue(entity: BaseNode): void {\n\t\tif (this._isLoaded) {\n\t\t\tthis.spawnEntity(entity);\n\t\t} else {\n\t\t\tthis.children.push(entity);\n\t\t}\n\t}\n\n\tprivate handlePromiseWithSpawnOnResolve(promise: Promise<any>): void {\n\t\tif (this._isLoaded) {\n\t\t\tpromise\n\t\t\t\t.then((entity) => this.spawnEntity(entity))\n\t\t\t\t.catch((e) => console.error('Failed to build async entity', e));\n\t\t} else {\n\t\t\tthis.pendingPromises.push(promise as Promise<BaseNode>);\n\t\t}\n\t}\n\n\t// ─── Loading generator ───────────────────────────────────────────────────\n\n\t/**\n\t * Generator that yields between entity loads for real-time progress updates.\n\t */\n\tprivate *entityLoadGenerator(): Generator<{ current: number; total: number; name: string }> {\n\t\tconst total = this.children.length + this.pendingEntities.length + this.pendingPromises.length;\n\t\tlet current = 0;\n\n\t\tfor (const child of this.children) {\n\t\t\tthis.spawnEntity(child);\n\t\t\tcurrent++;\n\t\t\tyield { current, total, name: child.name || 'unknown' };\n\t\t}\n\n\t\tif (this.pendingEntities.length) {\n\t\t\tthis.enqueue(...this.pendingEntities);\n\t\t\tcurrent += this.pendingEntities.length;\n\t\t\tthis.pendingEntities = [];\n\t\t\tyield { current, total, name: 'pending entities' };\n\t\t}\n\n\t\tif (this.pendingPromises.length) {\n\t\t\tfor (const promise of this.pendingPromises) {\n\t\t\t\tpromise.then((entity) => {\n\t\t\t\t\tthis.spawnEntity(entity);\n\t\t\t\t}).catch((e) => console.error('Failed to resolve pending stage entity', e));\n\t\t\t}\n\t\t\tcurrent += this.pendingPromises.length;\n\t\t\tthis.pendingPromises = [];\n\t\t\tyield { current, total, name: 'async entities' };\n\t\t}\n\t}\n\n\t/** Yields to the event loop via MessageChannel (~0.1ms vs ~4ms for setTimeout). */\n\tprivate yieldToEventLoop(): Promise<void> {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst ch = new MessageChannel();\n\t\t\tch.port1.onmessage = () => resolve();\n\t\t\tch.port2.postMessage(undefined);\n\t\t});\n\t}\n\n\t/**\n\t * Runs the entity load generator, yielding to the event loop in batches.\n\t * Emits progress events through the loading delegate.\n\t */\n\tasync runEntityLoadGenerator(): Promise<void> {\n\t\tconst gen = this.entityLoadGenerator();\n\t\tlet i = 0;\n\t\tconst BATCH_SIZE = 5;\n\t\tfor (const progress of gen) {\n\t\t\tthis.loadingDelegate.emitProgress(`Loaded ${progress.name}`, progress.current, progress.total);\n\t\t\tif (++i % BATCH_SIZE === 0) {\n\t\t\t\tawait this.yieldToEventLoop();\n\t\t\t}\n\t\t}\n\t\tif (i % BATCH_SIZE !== 0) {\n\t\t\tawait this.yieldToEventLoop();\n\t\t}\n\t}\n\n\t// ─── Behavior systems ────────────────────────────────────────────────────\n\n\t/**\n\t * Register an ECS behavior system to run each frame.\n\t * @param systemOrFactory A BehaviorSystem instance or factory function\n\t */\n\tregisterSystem(systemOrFactory: BehaviorSystem | BehaviorSystemFactory): void {\n\t\tif (!this.world || !this.ecs || !this.scene) return;\n\t\tlet system: BehaviorSystem;\n\t\tif (typeof systemOrFactory === 'function') {\n\t\t\tsystem = systemOrFactory({\n\t\t\t\tworld: this.world,\n\t\t\t\tecs: this.ecs,\n\t\t\t\tscene: this.scene,\n\t\t\t\tgetBehaviorLinks: (key: symbol) =>\n\t\t\t\t\tthis.behaviorEntityIndex.get(key)\n\t\t\t\t\t?? StageEntityDelegate.EMPTY_BEHAVIOR_LINKS,\n\t\t\t});\n\t\t} else {\n\t\t\tsystem = systemOrFactory;\n\t\t}\n\t\tthis.behaviorSystems.push(system);\n\t}\n\n\t// ─── Cleanup ─────────────────────────────────────────────────────────────\n\n\t/**\n\t * Destroy all entities and clear internal state.\n\t * Called by ZylemStage._destroy().\n\t */\n\tdestroyAll(): void {\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.destroy?.(this.ecs!);\n\t\t}\n\t\tthis.behaviorSystems.length = 0;\n\t\tthis.registeredSystemKeys.clear();\n\t\tthis.behaviorEntityIndex.clear();\n\t\tthis.behaviorLinksByUuid.clear();\n\n\t\tthis.childrenMap.forEach((child) => {\n\t\t\ttry {\n\t\t\t\tchild.nodeDestroy({ me: child, globals: getGlobals() });\n\t\t\t} catch { /* noop */ }\n\t\t\tclearVariables(child);\n\t\t});\n\t\tthis.childrenMap.clear();\n\t\tthis.debugMap.clear();\n\t\tthis.uuidToEid.clear();\n\t\tthis.entityAddedHandlers = [];\n\n\t\tthis._isLoaded = false;\n\t\tthis.scene = null;\n\t\tthis.world = null;\n\t\tthis.ecs = null;\n\t\tthis.instanceManager = null;\n\t\tthis.camera = null;\n\t}\n\n\tprivate registerBehaviorLinks(entity: any): void {\n\t\tif (!this.world || !this.ecs || !this.scene) return;\n\t\tif (typeof entity?.getBehaviorRefs !== 'function') return;\n\n\t\tconst refs = entity.getBehaviorRefs();\n\t\tif (!Array.isArray(refs) || refs.length === 0) return;\n\n\t\tconst links: BehaviorEntityLink[] = [];\n\n\t\tfor (const ref of refs) {\n\t\t\tconst key = ref.descriptor.key;\n\t\t\tconst link: BehaviorEntityLink = { entity, ref };\n\t\t\tlinks.push(link);\n\n\t\t\tlet indexed = this.behaviorEntityIndex.get(key);\n\t\t\tif (!indexed) {\n\t\t\t\tindexed = new Set();\n\t\t\t\tthis.behaviorEntityIndex.set(key, indexed);\n\t\t\t}\n\t\t\tindexed.add(link);\n\n\t\t\tif (!this.registeredSystemKeys.has(key)) {\n\t\t\t\tconst system = ref.descriptor.systemFactory({\n\t\t\t\t\tworld: this.world,\n\t\t\t\t\tecs: this.ecs,\n\t\t\t\t\tscene: this.scene,\n\t\t\t\t\tgetBehaviorLinks: (behaviorKey: symbol) =>\n\t\t\t\t\t\tthis.behaviorEntityIndex.get(behaviorKey)\n\t\t\t\t\t\t?? StageEntityDelegate.EMPTY_BEHAVIOR_LINKS,\n\t\t\t\t});\n\t\t\t\tthis.behaviorSystems.push(system);\n\t\t\t\tthis.registeredSystemKeys.add(key);\n\t\t\t}\n\t\t}\n\n\t\tthis.behaviorLinksByUuid.set(entity.uuid, links);\n\t}\n\n\tprivate unregisterBehaviorLinks(entity: any): void {\n\t\tconst links = this.behaviorLinksByUuid.get(entity?.uuid);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst key = link.ref?.descriptor?.key as symbol | undefined;\n\t\t\tif (!key) continue;\n\t\t\tconst indexed = this.behaviorEntityIndex.get(key);\n\t\t\tif (!indexed) continue;\n\n\t\t\tindexed.delete(link);\n\t\t\tif (indexed.size === 0) {\n\t\t\t\tthis.behaviorEntityIndex.delete(key);\n\t\t\t}\n\t\t}\n\n\t\tthis.behaviorLinksByUuid.delete(entity.uuid);\n\t}\n}\n","import { createWorld as createECS } from 'bitecs';\nimport { Color, Vector3 } from 'three';\n\nimport { ZylemWorld } from '../collision/world';\nimport { ZylemScene } from '../graphics/zylem-scene';\nimport { InstanceManager } from '../graphics/instance-manager';\nimport { resetStageVariables, setStageBackgroundColor, setStageBackgroundImage, setStageVariables, clearVariables, initialStageState } from './stage-state';\n\nimport { GameEntityInterface } from '../types/entity-types';\nimport { debugState } from '../debug/debug-state';\n\nimport { SetupContext, UpdateContext, DestroyContext } from '../core/base-node-life-cycle';\nimport { LifeCycleBase } from '../core/lifecycle-base';\nimport createTransformSystem, { StageSystem } from '../systems/transformable.system';\nimport { BaseNode } from '../core/base-node';\nimport { nanoid } from 'nanoid';\nimport { Stage } from './stage';\nimport { CameraWrapper } from '../camera/camera';\nimport { CameraManager } from '../camera/camera-manager';\nimport { RendererManager } from '../camera/renderer-manager';\nimport { StageDebugDelegate } from './stage-debug-delegate';\nimport { StageCameraDelegate } from './stage-camera-delegate';\nimport { StageLoadingDelegate } from './stage-loading-delegate';\nimport { StageEntityModelDelegate } from './stage-entity-model-delegate';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { LoadingEvent } from '../core/interfaces';\nimport { parseStageOptions } from './stage-config';\nimport type { BehaviorSystem, BehaviorSystemFactory } from '../behaviors/behavior-system';\nimport { applyTransformChanges, TransformableEntity } from '../actions/capabilities/apply-transform';\nimport { StageEntityDelegate, StageEntityInput } from './stage-entity-delegate';\nexport type { LoadingEvent };\n\nexport interface ZylemStageConfig {\n\tinputs: Record<string, string[]>;\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader: any | null;\n\tgravity: Vector3;\n\tvariables: Record<string, any>;\n\t/** Physics update rate in Hz (default 60). */\n\tphysicsRate: number;\n\t/** Run physics in a Web Worker for true parallelism (default false). */\n\tusePhysicsWorker: boolean;\n\t/** URL to the physics worker script (required when usePhysicsWorker is true). */\n\tphysicsWorkerUrl?: URL | string;\n\tstageRef?: Stage;\n}\n\nexport type StageOptionItem = Partial<ZylemStageConfig> | CameraWrapper | StageEntityInput;\nexport type StageOptions = [] | [Partial<ZylemStageConfig>, ...StageOptionItem[]];\n\nexport type StageState = ZylemStageConfig & { entities: GameEntityInterface[] };\n\nconst STAGE_TYPE = 'Stage';\n\n/**\n * ZylemStage orchestrates scene, physics world, entities, and lifecycle.\n *\n * Responsibilities:\n * - Manage stage configuration (background, inputs, gravity, variables)\n * - Initialize and own `ZylemScene` and `ZylemWorld`\n * - Coordinate delegates for entities, camera, loading, debug, and models\n * - Drive per-frame updates and transform system\n */\nexport class ZylemStage extends LifeCycleBase<ZylemStage> {\n\tpublic type = STAGE_TYPE;\n\n\tstate: StageState = { ...initialStageState };\n\tgravity: Vector3;\n\n\tworld: ZylemWorld | null;\n\tscene: ZylemScene | null;\n\tinstanceManager: InstanceManager | null = null;\n\n\tecs = createECS();\n\ttransformSystem: ReturnType<typeof createTransformSystem> | null = null;\n\tdebugDelegate: StageDebugDelegate | null = null;\n\n\tuuid: string;\n\twrapperRef: Stage | null = null;\n\tcamera?: CameraWrapper;\n\tcameras: CameraWrapper[] = [];\n\tcameraRef?: ZylemCamera | null = null;\n\t/** Camera manager for multi-camera support */\n\tcameraManagerRef: CameraManager | null = null;\n\t/** Shared renderer manager (injected by the game) */\n\trendererManager: RendererManager | null = null;\n\n\t// Delegates\n\tprivate cameraDelegate: StageCameraDelegate;\n\tprivate loadingDelegate: StageLoadingDelegate;\n\tprivate entityModelDelegate: StageEntityModelDelegate;\n\tprivate readonly childUpdateParams = {} as UpdateContext<any>;\n\n\t/** Entity management delegate — public for external consumers (debug, transform system). */\n\treadonly entityDelegate: StageEntityDelegate;\n\n\t/**\n\t * Create a new stage.\n\t * @param options Stage options: partial config, camera, and initial entities or factories\n\t */\n\tconstructor(options: StageOptions = []) {\n\t\tsuper();\n\t\tthis.world = null;\n\t\tthis.scene = null;\n\t\tthis.uuid = nanoid();\n\n\t\t// Initialize delegates\n\t\tthis.cameraDelegate = new StageCameraDelegate(this);\n\t\tthis.loadingDelegate = new StageLoadingDelegate();\n\t\tthis.entityModelDelegate = new StageEntityModelDelegate();\n\t\tthis.entityDelegate = new StageEntityDelegate(this.loadingDelegate, this.entityModelDelegate);\n\n\t\t// Parse the options array using the stage-config module\n\t\tconst parsed = parseStageOptions(options);\n\t\tthis.camera = parsed.camera;\n\t\tthis.cameras = parsed.cameras;\n\t\tthis.entityDelegate.children = parsed.entities;\n\n\t\t// Async entities are queued via enqueue which handles deferred loading\n\t\tif (parsed.asyncEntities.length) {\n\t\t\tthis.entityDelegate.enqueue(...parsed.asyncEntities);\n\t\t}\n\n\t\t// Update state with resolved config\n\t\tthis.state = {\n\t\t\t...this.state,\n\t\t\tinputs: parsed.config.inputs,\n\t\t\tbackgroundColor: parsed.config.backgroundColor,\n\t\t\tbackgroundImage: parsed.config.backgroundImage,\n\t\t\tbackgroundShader: parsed.config.backgroundShader,\n\t\t\tgravity: parsed.config.gravity,\n\t\t\tvariables: parsed.config.variables,\n\t\t\tphysicsRate: parsed.config.physicsRate,\n\t\t\tusePhysicsWorker: parsed.config.usePhysicsWorker,\n\t\t\tphysicsWorkerUrl: parsed.config.physicsWorkerUrl,\n\t\t\tentities: [],\n\t\t};\n\n\t\tthis.gravity = parsed.config.gravity ?? new Vector3(0, 0, 0);\n\t}\n\n\tprivate setState() {\n\t\tconst { backgroundColor, backgroundImage } = this.state;\n\t\tconst color = backgroundColor instanceof Color ? backgroundColor : new Color(backgroundColor);\n\t\tsetStageBackgroundColor(color);\n\t\tsetStageBackgroundImage(backgroundImage);\n\t\tsetStageVariables(this.state.variables ?? {});\n\t}\n\n\t/**\n\t * Load and initialize the stage's scene and world.\n\t * Uses generator pattern to yield control to event loop for real-time progress.\n\t * @param id DOM element id for the renderer container\n\t * @param camera Optional camera override\n\t */\n\tasync load(id: string, camera?: ZylemCamera | null, rendererManager?: RendererManager | null) {\n\t\tthis.setState();\n\n\t\tif (rendererManager) {\n\t\t\tthis.rendererManager = rendererManager;\n\t\t}\n\n\t\t// Build camera manager first so we can use its primary camera as the\n\t\t// canonical camera reference.\n\t\tif (this.rendererManager) {\n\t\t\tthis.cameraManagerRef = this.cameraDelegate.buildCameraManager(\n\t\t\t\tcamera,\n\t\t\t\t...this.cameras\n\t\t\t);\n\t\t}\n\n\t\t// Derive the resolved camera from the camera manager's primary camera\n\t\t// (when available), otherwise fall back to the legacy single-camera path.\n\t\tconst zylemCamera = this.cameraManagerRef?.primaryCamera\n\t\t\t?? this.cameraDelegate.resolveCamera(camera, this.camera);\n\t\tthis.cameraRef = zylemCamera;\n\t\tthis.scene = new ZylemScene(id, zylemCamera, this.state);\n\n\t\tconst gravity = this.gravity ?? new Vector3(0, 0, 0);\n\t\tif (this.state.usePhysicsWorker) {\n\t\t\tconst workerUrl = this.state.physicsWorkerUrl\n\t\t\t\t? new URL(this.state.physicsWorkerUrl, typeof location !== 'undefined' ? location.href : undefined)\n\t\t\t\t: undefined;\n\t\t\tthis.world = await ZylemWorld.loadPhysicsWorker(gravity, this.state.physicsRate, workerUrl);\n\t\t} else {\n\t\t\tconst physicsWorld = await ZylemWorld.loadPhysics(gravity);\n\t\t\tthis.world = new ZylemWorld(physicsWorld, this.state.physicsRate);\n\t\t}\n\n\t\tthis.scene.setup();\n\n\t\t// Setup cameras: prefer camera manager, fall back to legacy single camera\n\t\tif (this.cameraManagerRef && this.rendererManager) {\n\t\t\tawait this.scene.setupCameraManager(this.scene.scene, this.cameraManagerRef, this.rendererManager);\n\t\t\tconst primaryCam = this.cameraManagerRef.primaryCamera;\n\t\t\tif (primaryCam) {\n\t\t\t\tthis.rendererManager.setupRenderPass(this.scene.scene, primaryCam.camera);\n\t\t\t}\n\t\t\tthis.rendererManager.startRenderLoop((delta) => {\n\t\t\t\tthis.cameraManagerRef?.update(delta);\n\t\t\t\tthis.cameraManagerRef?.render(this.scene!.scene);\n\t\t\t});\n\t\t} else {\n\t\t\tthis.scene.setupCamera(this.scene.scene, zylemCamera);\n\t\t}\n\n\t\tthis.entityModelDelegate.attach(\n\t\t\tthis.scene,\n\t\t\t(entity) => this.entityDelegate.handleLateModelReady(entity),\n\t\t);\n\n\t\t// Initialize instance manager for mesh batching\n\t\tthis.instanceManager = new InstanceManager();\n\t\tthis.instanceManager.setScene(this.scene.scene);\n\n\t\t// Attach entity delegate context now that scene/world are ready\n\t\tthis.entityDelegate.attach({\n\t\t\tscene: this.scene,\n\t\t\tworld: this.world,\n\t\t\tecs: this.ecs,\n\t\t\tinstanceManager: this.instanceManager,\n\t\t\tcamera: zylemCamera,\n\t\t});\n\n\t\tthis.loadingDelegate.emitStart();\n\t\tawait this.entityDelegate.runEntityLoadGenerator();\n\n\t\tthis.transformSystem = createTransformSystem({\n\t\t\t_childrenMap: this.entityDelegate.childrenMap,\n\t\t\t_world: this.world,\n\t\t} as unknown as StageSystem);\n\t\tthis.entityDelegate.isLoaded = true;\n\t\tthis.loadingDelegate.emitComplete();\n\t}\n\n\tprotected _setup(params: SetupContext<ZylemStage>): void {\n\t\tif (!this.scene || !this.world) {\n\t\t\tthis.logMissingEntities();\n\t\t\treturn;\n\t\t}\n\t\t// Debug delegate is self-managing — it subscribes to debugState internally\n\t\t// and activates/deactivates visuals and camera debug automatically.\n\t\tthis.debugDelegate = new StageDebugDelegate(this);\n\t}\n\n\tprotected _update(params: UpdateContext<ZylemStage>): void {\n\t\tconst { delta } = params;\n\t\tif (!this.scene || !this.world) {\n\t\t\tthis.logMissingEntities();\n\t\t\treturn;\n\t\t}\n\t\tthis.world.update(params);\n\n\t\t// Run registered ECS behavior systems\n\t\tfor (const system of this.entityDelegate.behaviorSystems) {\n\t\t\tsystem.update(this.ecs, delta);\n\t\t}\n\n\t\tfor (const child of this.entityDelegate.childrenMap.values()) {\n\t\t\tconst childParams = this.childUpdateParams;\n\t\t\tchildParams.delta = params.delta;\n\t\t\tchildParams.inputs = params.inputs;\n\t\t\tchildParams.globals = params.globals;\n\t\t\tchildParams.camera = params.camera;\n\t\t\tchildParams.stage = params.stage;\n\t\t\tchildParams.game = params.game;\n\t\t\tchildParams.me = child;\n\t\t\tchild.nodeUpdate(childParams);\n\n\t\t\t// Apply pending transformations after update callbacks\n\t\t\tconst transformable = child as unknown as TransformableEntity;\n\t\t\tif (transformable.transformStore) {\n\t\t\t\tapplyTransformChanges(transformable, transformable.transformStore);\n\t\t\t}\n\n\t\t\tif (child.markedForRemoval) {\n\t\t\t\tthis.entityDelegate.removeEntityByUuid(child.uuid);\n\t\t\t}\n\t\t}\n\n\t\t// Sync physics to rendering AFTER transforms are applied\n\t\tthis.transformSystem?.system(this.ecs);\n\n\t\t// Sync instanced mesh transforms\n\t\tthis.instanceManager?.update();\n\t\tthis.scene.update({ delta });\n\t\tthis.scene.updateSkybox(delta);\n\t}\n\n\tpublic outOfLoop() {\n\t\tthis.debugUpdate();\n\t}\n\n\t/** Update debug overlays and helpers if enabled. */\n\tpublic debugUpdate() {\n\t\tif (debugState.enabled) {\n\t\t\tthis.debugDelegate?.update();\n\t\t}\n\t}\n\n\t/** Cleanup owned resources when the stage is destroyed. */\n\tprotected _destroy(params: DestroyContext<ZylemStage>): void {\n\t\t// Delegate handles entity + behavior system cleanup\n\t\tthis.entityDelegate.destroyAll();\n\n\t\tthis.world?.destroy();\n\t\tthis.scene?.destroy();\n\n\t\t// Debug delegate handles its own unsubscription and cleanup\n\t\tthis.debugDelegate?.dispose();\n\t\tthis.debugDelegate = null;\n\n\t\tthis.entityModelDelegate.dispose();\n\n\t\t// Dispose instance manager\n\t\tthis.instanceManager?.dispose();\n\t\tthis.instanceManager = null;\n\n\t\t// Stop renderer render loop if using renderer manager\n\t\tif (this.rendererManager) {\n\t\t\tthis.rendererManager.stopRenderLoop();\n\t\t}\n\n\t\tthis.world = null as any;\n\t\tthis.scene = null as any;\n\t\tthis.cameraRef = null;\n\t\tthis.cameraManagerRef = null;\n\n\t\t// Cleanup transform system\n\t\tthis.transformSystem?.destroy(this.ecs);\n\t\tthis.transformSystem = null;\n\n\t\t// Clear reactive stage variables on unload\n\t\tresetStageVariables();\n\t\tclearVariables(this);\n\t}\n\n\t// ─── Forwarding API ──────────────────────────────────────────────────────\n\n\t/** Forward to entity delegate. */\n\tasync spawnEntity(child: BaseNode) {\n\t\treturn this.entityDelegate.spawnEntity(child);\n\t}\n\n\t/** Forward to entity delegate. */\n\tbuildEntityState(child: BaseNode): Partial<BaseEntityInterface> {\n\t\treturn this.entityDelegate.buildEntityState(child);\n\t}\n\n\t/** Forward to entity delegate. */\n\tonEntityAdded(callback: (entity: BaseNode) => void, options?: { replayExisting?: boolean }) {\n\t\treturn this.entityDelegate.onEntityAdded(callback, options);\n\t}\n\n\tonLoading(callback: (event: LoadingEvent) => void) {\n\t\treturn this.loadingDelegate.onLoading(callback);\n\t}\n\n\t/**\n\t * Register an ECS behavior system to run each frame.\n\t * @param systemOrFactory A BehaviorSystem instance or factory function\n\t * @returns this for chaining\n\t */\n\tregisterSystem(systemOrFactory: BehaviorSystem | BehaviorSystemFactory): this {\n\t\tthis.entityDelegate.registerSystem(systemOrFactory);\n\t\treturn this;\n\t}\n\n\t/** Forward to entity delegate. */\n\tremoveEntityByUuid(uuid: string): boolean {\n\t\treturn this.entityDelegate.removeEntityByUuid(uuid);\n\t}\n\n\t/** Forward to entity delegate. */\n\tgetEntityByName(name: string) {\n\t\treturn this.entityDelegate.getEntityByName(name);\n\t}\n\n\t/** Forward to entity delegate. */\n\tenqueue(...items: StageEntityInput[]) {\n\t\tthis.entityDelegate.enqueue(...items);\n\t}\n\n\tlogMissingEntities() {\n\t\tconsole.warn('Zylem world or scene is null');\n\t}\n\n\t// ─── Camera management forwarding ─────────────────────────────────────\n\n\t/** Add a camera to this stage's camera manager. */\n\taddCamera(camera: ZylemCamera, name?: string): string | null {\n\t\tif (!this.cameraManagerRef) {\n\t\t\tconsole.warn('ZylemStage: CameraManager not available. Ensure stage is loaded with a RendererManager.');\n\t\t\treturn null;\n\t\t}\n\t\treturn this.cameraManagerRef.addCamera(camera, name);\n\t}\n\n\t/** Remove a camera from this stage's camera manager. */\n\tremoveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\treturn this.cameraManagerRef?.removeCamera(nameOrRef) ?? false;\n\t}\n\n\t/** Set the active camera by name or reference. */\n\tsetActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\treturn this.cameraManagerRef?.setActiveCamera(nameOrRef) ?? false;\n\t}\n\n\t/** Get a camera by name from the camera manager. */\n\tgetCamera(name: string): ZylemCamera | null {\n\t\treturn this.cameraManagerRef?.getCamera(name) ?? null;\n\t}\n\n\t/** Resize renderer viewport. */\n\tresize(width: number, height: number) {\n\t\tif (this.scene) {\n\t\t\tthis.scene.updateRenderer(width, height);\n\t\t}\n\t}\n}\n","import { Vector2, Vector3, Texture } from \"three\";\nimport { PerspectiveType } from \"./perspective\";\nimport { ZylemCamera } from \"./zylem-camera\";\nimport { RendererType, Viewport, DEFAULT_VIEWPORT } from \"./renderer-manager\";\nimport { StageEntity } from \"../interfaces/entity\";\nimport type { CameraBehavior, CameraAction, CameraPerspective, CameraPipelineState } from \"./types\";\nimport { createPerspective } from \"./perspectives\";\nimport type { PerspectiveOptions } from \"./perspectives\";\n\nexport interface CameraOptions {\n\tperspective?: PerspectiveType;\n\tposition?: Vector3 | { x: number; y: number; z: number };\n\ttarget?: Vector3 | { x: number; y: number; z: number } | any;\n\tzoom?: number;\n\tscreenResolution?: Vector2;\n\t/**\n\t * Renderer type: 'auto' | 'webgpu' | 'webgl'\n\t * Use 'webgpu' for TSL shaders\n\t * @default 'webgl'\n\t */\n\trendererType?: RendererType;\n\t/**\n\t * Enable orbital controls for this camera.\n\t * Can be toggled at runtime via enableOrbitalControls() / disableOrbitalControls().\n\t * @default false\n\t */\n\tuseOrbitalControls?: boolean;\n\t/**\n\t * Viewport in normalized coordinates (0-1).\n\t * Defines where this camera renders on the canvas.\n\t * @default { x: 0, y: 0, width: 1, height: 1 } (fullscreen)\n\t */\n\tviewport?: Viewport;\n\t/**\n\t * Optional name for camera manager lookup.\n\t */\n\tname?: string;\n\t/**\n\t * Initial behaviors to attach to the camera pipeline.\n\t * Keys are used for idempotent add/remove.\n\t */\n\tbehaviors?: Record<string, CameraBehavior>;\n\t/**\n\t * Pipeline smoothing factor (0-1).\n\t * 1 = instant snap, 0 = no movement.\n\t * @default 0.15\n\t */\n\tdamping?: number;\n\t/**\n\t * When set, the camera renders to an offscreen texture instead of a\n\t * screen viewport. Use with setCameraFeed() to display the feed on\n\t * an in-scene mesh (jumbotron, security monitor, portal, etc.).\n\t *\n\t * @default undefined (renders to screen)\n\t */\n\trenderToTexture?: {\n\t\t/** Texture width in pixels. @default 512 */\n\t\twidth?: number;\n\t\t/** Texture height in pixels. @default 512 */\n\t\theight?: number;\n\t};\n\t/**\n\t * When true, this camera will not activate orbital controls in debug mode.\n\t * The pipeline (and its behaviors) will always run for this camera.\n\t * Use for cameras with custom behaviors (e.g. FPS mouse-look) that must\n\t * control the camera through the pipeline rather than debug orbit controls.\n\t * @default false\n\t */\n\tskipDebugOrbit?: boolean;\n}\n\n/**\n * CameraWrapper is the user-facing camera handle returned by createCamera().\n * It provides convenience methods for target management, orbital controls,\n * viewport configuration, and the camera pose pipeline.\n */\nexport class CameraWrapper {\n\tcameraRef: ZylemCamera;\n\n\tconstructor(camera: ZylemCamera) {\n\t\tthis.cameraRef = camera;\n\t}\n\n\t// ─── Target management ──────────────────────────────────────────────────\n\n\t/**\n\t * Add a target entity for the camera to follow/frame.\n\t * With multiple targets, the camera auto-frames to include all of them.\n\t */\n\taddTarget(entity: StageEntity): void {\n\t\tthis.cameraRef.addTarget(entity);\n\t}\n\n\t/**\n\t * Remove a target entity from the camera.\n\t */\n\tremoveTarget(entity: StageEntity): void {\n\t\tthis.cameraRef.removeTarget(entity);\n\t}\n\n\t/**\n\t * Clear all targets. Camera will look at world origin.\n\t */\n\tclearTargets(): void {\n\t\tthis.cameraRef.clearTargets();\n\t}\n\n\t// ─── Orbital controls ───────────────────────────────────────────────────\n\n\t/**\n\t * Enable orbital controls for this camera.\n\t * Allows the user to orbit, pan, and zoom the camera.\n\t */\n\tenableOrbitalControls(): void {\n\t\tthis.cameraRef.enableOrbitalControls();\n\t}\n\n\t/**\n\t * Disable orbital controls for this camera.\n\t */\n\tdisableOrbitalControls(): void {\n\t\tthis.cameraRef.disableOrbitalControls();\n\t}\n\n\t// ─── Viewport ───────────────────────────────────────────────────────────\n\n\t/**\n\t * Set the viewport for this camera (normalized 0-1 coordinates).\n\t * @param x Left edge (0 = left of canvas)\n\t * @param y Bottom edge (0 = bottom of canvas)\n\t * @param width Width as fraction of canvas\n\t * @param height Height as fraction of canvas\n\t */\n\tsetViewport(x: number, y: number, width: number, height: number): void {\n\t\tthis.cameraRef.setViewport(x, y, width, height);\n\t}\n\n\t// ─── Pipeline: Behaviors ────────────────────────────────────────────────\n\n\t/**\n\t * Add or replace a behavior by key (idempotent).\n\t * Behaviors modify the desired camera pose each frame.\n\t *\n\t * @param key Unique key for this behavior (used for replacement/removal).\n\t * @param behavior The CameraBehavior implementation.\n\t */\n\taddBehavior(key: string, behavior: CameraBehavior): void {\n\t\tthis.cameraRef.pipeline.addBehavior(key, behavior);\n\t}\n\n\t/**\n\t * Remove a behavior by key.\n\t */\n\tremoveBehavior(key: string): boolean {\n\t\treturn this.cameraRef.pipeline.removeBehavior(key);\n\t}\n\n\t// ─── Pipeline: Actions ──────────────────────────────────────────────────\n\n\t/**\n\t * Add a transient action (screenshake, recoil, etc.).\n\t * Actions apply additive deltas and self-expire when isDone() returns true.\n\t */\n\taddAction(action: CameraAction): void {\n\t\tthis.cameraRef.pipeline.addAction(action);\n\t}\n\n\t// ─── Pipeline: Perspective ──────────────────────────────────────────────\n\n\t/**\n\t * Switch the camera's active perspective at runtime.\n\t * The first frame after switching snaps to the new pose (no lerp).\n\t *\n\t * @param type Perspective type string (e.g. Perspectives.ThirdPerson).\n\t * @param options Perspective-specific options (distance, height, zoom, etc.).\n\t */\n\tsetPerspective(type: PerspectiveType, options?: PerspectiveOptions): void {\n\t\tthis.cameraRef.pipeline.setPerspective(createPerspective(type, options));\n\t}\n\n\t/**\n\t * Retrieve the active perspective instance, cast to the desired type.\n\t * Useful for calling perspective-specific methods (e.g. FirstPersonPerspective.look()).\n\t *\n\t * @example\n\t * const fps = camera.getPerspective<FirstPersonPerspective>();\n\t * fps.look(dx, dy);\n\t */\n\tgetPerspective<T extends CameraPerspective = CameraPerspective>(): T {\n\t\treturn this.cameraRef.pipeline.perspective as T;\n\t}\n\n\t// ─── Pipeline: Debug state ──────────────────────────────────────────────\n\n\t/**\n\t * Return a debug snapshot of the camera pipeline state.\n\t * Includes: active perspective, desired/final pose, behavior keys, action count.\n\t */\n\tgetState(): CameraPipelineState {\n\t\treturn this.cameraRef.pipeline.getState();\n\t}\n\n\t// ─── Render-to-texture ─────────────────────────────────────────────────\n\n\t/**\n\t * Get the offscreen render texture for this camera.\n\t * Returns null if the camera was not created with renderToTexture.\n\t * Use with setCameraFeed() or apply directly to a mesh material.\n\t */\n\tgetRenderTexture(): Texture | null {\n\t\treturn this.cameraRef.getRenderTexture();\n\t}\n}\n\n/**\n * Create a camera with the given options.\n * Returns a CameraWrapper for convenient access to camera features.\n */\nexport function createCamera(options: CameraOptions): CameraWrapper {\n\tconst screenResolution = options.screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\tlet frustumSize = 10;\n\tif (options.perspective === 'fixed-2d') {\n\t\tfrustumSize = options.zoom || 10;\n\t}\n\tconst zylemCamera = new ZylemCamera(\n\t\toptions.perspective || 'third-person',\n\t\tscreenResolution,\n\t\tfrustumSize,\n\t\toptions.rendererType || 'webgl'\n\t);\n\n\t// Set camera name if provided\n\tif (options.name) {\n\t\tzylemCamera.name = options.name;\n\t}\n\n\t// Set initial position and target\n\tconst position = options.position \n\t\t? (options.position instanceof Vector3 ? options.position : new Vector3(options.position.x, options.position.y, options.position.z))\n\t\t: new Vector3(0, 0, 0);\n\t\n\tconst target = options.target\n\t\t? (options.target instanceof Vector3 ? options.target : new Vector3(options.target.x, options.target.y, options.target.z))\n\t\t: new Vector3(0, 0, 0);\n\t\n\tzylemCamera.move(position);\n\tzylemCamera.camera.lookAt(target);\n\n\t// Reconfigure the perspective with user-specified options (position, zoom, etc.)\n\t// so the pipeline produces the correct base pose from the first frame.\n\tconst perspType = options.perspective || 'third-person';\n\tif (perspType === 'fixed-2d' || perspType === 'flat-2d') {\n\t\tzylemCamera.pipeline.setPerspective(\n\t\t\tcreatePerspective(perspType, { zoom: frustumSize })\n\t\t);\n\t} else {\n\t\tzylemCamera.pipeline.setPerspective(\n\t\t\tcreatePerspective(perspType, {\n\t\t\t\tinitialPosition: position.clone(),\n\t\t\t\tinitialLookAt: target.clone(),\n\t\t\t})\n\t\t);\n\t}\n\n\t// Set viewport if provided\n\tif (options.viewport) {\n\t\tzylemCamera.viewport = { ...options.viewport };\n\t}\n\n\t// Configure orbital controls\n\tif (options.useOrbitalControls) {\n\t\t(zylemCamera as any)._useOrbitalControls = true;\n\t}\n\n\t// Opt out of debug-mode orbital controls\n\tif (options.skipDebugOrbit) {\n\t\tzylemCamera._skipDebugOrbit = true;\n\t}\n\n\t// Configure pipeline damping\n\tif (options.damping != null) {\n\t\tzylemCamera.pipeline.damping = options.damping;\n\t}\n\n\t// Attach initial behaviors\n\tif (options.behaviors) {\n\t\tfor (const [key, behavior] of Object.entries(options.behaviors)) {\n\t\t\tzylemCamera.pipeline.addBehavior(key, behavior);\n\t\t}\n\t}\n\n\t// Create render target for RTT cameras\n\tif (options.renderToTexture) {\n\t\tconst { width = 512, height = 512 } = options.renderToTexture;\n\t\tzylemCamera.createRenderTarget(width, height);\n\t}\n\n\treturn new CameraWrapper(zylemCamera);\n}\n","import { proxy } from 'valtio/vanilla';\nimport { Vector3 } from 'three';\nimport type { StageOptions, ZylemStageConfig } from './zylem-stage';\nimport { ZylemBlueColor } from '../core/utility/vector';\n\n/**\n * Reactive defaults for building `Stage` instances. These values are applied\n * automatically by the `stage()` builder and can be changed at runtime to\n * influence future stage creations.\n */\nconst initialDefaults: Partial<ZylemStageConfig> = {\n\tbackgroundColor: ZylemBlueColor,\n\tbackgroundImage: null,\n\tinputs: {\n\t\tp1: ['gamepad-1', 'keyboard'],\n\t\tp2: ['gamepad-2', 'keyboard'],\n\t},\n\tgravity: new Vector3(0, 0, 0),\n\tvariables: {},\n};\n\nconst stageDefaultsState = proxy<Partial<ZylemStageConfig>>({\n\t...initialDefaults,\n});\n\n/** Replace multiple defaults at once (shallow merge). */\nfunction setStageDefaults(partial: Partial<ZylemStageConfig>): void {\n\tObject.assign(stageDefaultsState, partial);\n}\n\n/** Reset defaults back to library defaults. */\nfunction resetStageDefaults(): void {\n\tObject.assign(stageDefaultsState, initialDefaults);\n}\n\nexport function getStageOptions(options: StageOptions): StageOptions {\n\tconst defaults = getStageDefaultConfig();\n\tlet originalConfig = {};\n\tif (typeof options[0] === 'object') {\n\t\toriginalConfig = options.shift() ?? {};\n\t}\n\tconst combinedConfig = { ...defaults, ...originalConfig };\n\treturn [combinedConfig, ...options] as StageOptions;\n}\n\n/** Get a plain object copy of the current defaults. */\nfunction getStageDefaultConfig(): Partial<ZylemStageConfig> {\n\treturn {\n\t\tbackgroundColor: stageDefaultsState.backgroundColor,\n\t\tbackgroundImage: stageDefaultsState.backgroundImage ?? null,\n\t\tinputs: stageDefaultsState.inputs ? { ...stageDefaultsState.inputs } : undefined,\n\t\tgravity: stageDefaultsState.gravity,\n\t\tvariables: stageDefaultsState.variables ? { ...stageDefaultsState.variables } : undefined,\n\t};\n}\n\n\n","import { BaseNode } from '../core/base-node';\nimport { DestroyFunction, SetupContext, SetupFunction, UpdateFunction } from '../core/base-node-life-cycle';\nimport { LoadingEvent, StageOptionItem, StageOptions, ZylemStage } from './zylem-stage';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { CameraWrapper } from '../camera/camera';\nimport { RendererManager } from '../camera/renderer-manager';\nimport { stageState } from './stage-state';\nimport { getStageOptions } from './stage-default';\nimport { EntityTypeMap } from '../types/entity-type-map';\nimport { EventEmitterDelegate, zylemEventBus, type StageEvents } from '../events';\nimport { GameInputConfig } from '../game/game-interfaces';\nimport { mergeInputConfigs } from '../input/input-presets';\n\ntype NodeLike = { create: Function };\ntype AnyNode = NodeLike | Promise<NodeLike>;\ntype EntityInput = AnyNode | (() => AnyNode) | (() => Promise<any>);\n\nexport class Stage {\n\twrappedStage: ZylemStage | null;\n\toptions: StageOptionItem[] = [];\n\t// Entities added after construction, consumed on each load\n\tprivate _pendingEntities: BaseNode[] = [];\n\n\t// Lifecycle callback arrays\n\tprivate setupCallbacks: Array<SetupFunction<ZylemStage>> = [];\n\tprivate updateCallbacks: Array<UpdateFunction<ZylemStage>> = [];\n\tprivate destroyCallbacks: Array<DestroyFunction<ZylemStage>> = [];\n\tprivate pendingLoadingCallbacks: Array<(event: LoadingEvent) => void> = [];\n\n\t// Event delegate for dispatch/listen API\n\tprivate eventDelegate = new EventEmitterDelegate<StageEvents>();\n\n\t/** Per-stage input configuration overrides. Merged with game-level defaults on stage load. */\n\tinputConfig: GameInputConfig | null = null;\n\n\t/**\n\t * Callback set by the game to trigger input reconfiguration\n\t * when this stage's input config changes at runtime.\n\t * @internal\n\t */\n\tonInputConfigChanged: (() => void) | null = null;\n\n\tconstructor(options: StageOptions) {\n\t\tthis.options = options;\n\t\tthis.wrappedStage = null;\n\t}\n\n\t/**\n\t * Set composable input configuration for this stage.\n\t * Multiple configs are deep-merged (later configs win on key conflicts).\n\t * If this stage is currently active, the change takes effect immediately.\n\t * @example stage.setInputConfiguration(useArrowsForAxes('p1'), useWASDForDirections('p2'));\n\t */\n\tsetInputConfiguration(...configs: GameInputConfig[]): this {\n\t\tthis.inputConfig = mergeInputConfigs(...configs);\n\t\tif (this.onInputConfigChanged) {\n\t\t\tthis.onInputConfigChanged();\n\t\t}\n\t\treturn this;\n\t}\n\n\tasync load(id: string, camera?: ZylemCamera | CameraWrapper | null, rendererManager?: RendererManager | null) {\n\t\tstageState.entities = [];\n\t\t// Combine original options with pending entities, then clear pending\n\t\tconst loadOptions = [...this.options, ...this._pendingEntities] as StageOptions;\n\t\tthis._pendingEntities = [];\n\t\t\n\t\tthis.wrappedStage = new ZylemStage(loadOptions);\n\t\tthis.wrappedStage.wrapperRef = this;\n\n\t\t// Flush pending loading callbacks BEFORE load so we catch start/progress events\n\t\tthis.pendingLoadingCallbacks.forEach(cb => {\n\t\t\tthis.wrappedStage!.onLoading(cb);\n\t\t});\n\t\tthis.pendingLoadingCallbacks = [];\n\n\t\tconst zylemCamera = camera instanceof CameraWrapper ? camera.cameraRef : camera;\n\t\tawait this.wrappedStage!.load(id, zylemCamera, rendererManager);\n\n\t\tthis.wrappedStage!.onEntityAdded((child) => {\n\t\t\tconst next = this.wrappedStage!.buildEntityState(child);\n\t\t\tstageState.entities = [...stageState.entities, next];\n\t\t}, { replayExisting: true });\n\n\t\t// Apply lifecycle callbacks to wrapped stage\n\t\tthis.applyLifecycleCallbacks();\n\n\t}\n\n\tprivate applyLifecycleCallbacks() {\n\t\tif (!this.wrappedStage) return;\n\n\t\t// Compose setup callbacks into a single function\n\t\tif (this.setupCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.setup = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.setupCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\n\t\t// Compose update callbacks\n\t\tif (this.updateCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.update = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.updateCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\n\t\t// Compose destroy callbacks\n\t\tif (this.destroyCallbacks.length > 0) {\n\t\t\tthis.wrappedStage.destroy = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.destroyCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t}\n\n\tasync addEntities(entities: BaseNode[]) {\n\t\t// Store in pending, don't mutate options\n\t\tthis._pendingEntities.push(...entities);\n\t\tif (!this.wrappedStage) { return; }\n\t\tthis.wrappedStage!.enqueue(...entities);\n\t}\n\n\tadd(...inputs: Array<EntityInput>) {\n\t\tthis.addToBlueprints(...inputs);\n\t\tthis.addToStage(...inputs);\n\t}\n\n\tprivate addToBlueprints(...inputs: Array<EntityInput>) {\n\t\tif (this.wrappedStage) { return; }\n\t\t// Add to options (persistent) so they're available on reload\n\t\tthis.options.push(...(inputs as unknown as StageOptionItem[]));\n\t}\n\n\tprivate addToStage(...inputs: Array<EntityInput>) {\n\t\tif (!this.wrappedStage) { return; }\n\t\tthis.wrappedStage!.enqueue(...(inputs as any));\n\t}\n\n\tstart(params: SetupContext<ZylemStage>) {\n\t\tthis.wrappedStage?.nodeSetup(params);\n\t}\n\n\t// Fluent API for adding lifecycle callbacks\n\tonUpdate(...callbacks: UpdateFunction<ZylemStage>[]): this {\n\t\tthis.updateCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the update callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.update = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.updateCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonSetup(...callbacks: SetupFunction<ZylemStage>[]): this {\n\t\tthis.setupCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the setup callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.setup = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.setupCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonDestroy(...callbacks: DestroyFunction<ZylemStage>[]): this {\n\t\tthis.destroyCallbacks.push(...callbacks);\n\t\t// If already loaded, recompose the destroy callback\n\t\tif (this.wrappedStage) {\n\t\t\tthis.wrappedStage.destroy = (params) => {\n\t\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\t\tthis.destroyCallbacks.forEach(cb => cb(extended));\n\t\t\t};\n\t\t}\n\t\treturn this;\n\t}\n\n\tonLoading(callback: (event: LoadingEvent) => void) {\n\t\tif (!this.wrappedStage) { \n\t\t\tthis.pendingLoadingCallbacks.push(callback);\n\t\t\treturn () => {\n\t\t\t\tthis.pendingLoadingCallbacks = this.pendingLoadingCallbacks.filter(c => c !== callback);\n\t\t\t};\n\t\t}\n\t\treturn this.wrappedStage.onLoading(callback);\n\t}\n\n\t/**\n\t * Find an entity by name on the current stage.\n\t * @param name The name of the entity to find\n\t * @param type Optional type symbol for type inference (e.g., TEXT_TYPE, SPRITE_TYPE)\n\t * @returns The entity if found, or undefined\n\t * @example stage.getEntityByName('scoreText', TEXT_TYPE)\n\t */\n\tgetEntityByName<T extends symbol | void = void>(\n\t\tname: string,\n\t\ttype?: T\n\t): T extends keyof EntityTypeMap ? EntityTypeMap[T] | undefined : BaseNode | undefined {\n\t\tconst entity = this.wrappedStage?.getEntityByName(name);\n\t\treturn entity as any;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Camera management\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add a camera to this stage.\n\t * @param camera The ZylemCamera or CameraWrapper to add\n\t * @param name Optional name for lookup\n\t */\n\taddCamera(camera: ZylemCamera | CameraWrapper, name?: string): string | null {\n\t\tconst zylemCam = camera instanceof CameraWrapper ? camera.cameraRef : camera;\n\t\treturn this.wrappedStage?.addCamera(zylemCam, name) ?? null;\n\t}\n\n\t/**\n\t * Remove a camera from this stage by name or reference.\n\t */\n\tremoveCamera(nameOrRef: string | ZylemCamera | CameraWrapper): boolean {\n\t\tif (nameOrRef instanceof CameraWrapper) {\n\t\t\treturn this.wrappedStage?.removeCamera(nameOrRef.cameraRef) ?? false;\n\t\t}\n\t\treturn this.wrappedStage?.removeCamera(nameOrRef) ?? false;\n\t}\n\n\t/**\n\t * Set the active camera by name or reference.\n\t */\n\tsetActiveCamera(nameOrRef: string | ZylemCamera | CameraWrapper): boolean {\n\t\tif (nameOrRef instanceof CameraWrapper) {\n\t\t\treturn this.wrappedStage?.setActiveCamera(nameOrRef.cameraRef) ?? false;\n\t\t}\n\t\treturn this.wrappedStage?.setActiveCamera(nameOrRef) ?? false;\n\t}\n\n\t/**\n\t * Get a camera by name from the camera manager.\n\t */\n\tgetCamera(name: string): ZylemCamera | null {\n\t\treturn this.wrappedStage?.getCamera(name) ?? null;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Events API\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispatch an event from the stage.\n\t * Events are emitted both locally and to the global event bus.\n\t */\n\tdispatch<K extends keyof StageEvents>(event: K, payload: StageEvents[K]): void {\n\t\tthis.eventDelegate.dispatch(event, payload);\n\t\t(zylemEventBus as any).emit(event, payload);\n\t}\n\n\t/**\n\t * Listen for events on this stage instance.\n\t * @returns Unsubscribe function\n\t */\n\tlisten<K extends keyof StageEvents>(event: K, handler: (payload: StageEvents[K]) => void): () => void {\n\t\treturn this.eventDelegate.listen(event, handler);\n\t}\n\n\t/**\n\t * Clean up stage resources including event subscriptions.\n\t */\n\tdispose(): void {\n\t\tthis.eventDelegate.dispose();\n\t}\n}\n\n/**\n * Create a stage with optional camera\n */\nexport function createStage(...options: StageOptions): Stage {\n\tconst _options = getStageOptions(options);\n\treturn new Stage([..._options] as StageOptions);\n}","import { proxy } from 'valtio/vanilla';\nimport { createStage, Stage } from '../stage/stage';\nimport type { BasicTypes, BaseGlobals, ZylemGameConfig, GameInputConfig } from './game-interfaces';\n\ntype InitialDefaults = Partial<ZylemGameConfig<Stage, any, BaseGlobals>>;\n/**\n * Reactive defaults for building `Game` instances. These values are applied\n * automatically by the `game()` builder via `convertNodes` and can be changed\n * at runtime to influence future game creations.\n */\nconst initialDefaults: () => InitialDefaults = (): InitialDefaults => {\n\treturn {\n\t\tid: 'zylem',\n\t\tglobals: {} as BaseGlobals,\n\t\tstages: [createStage()],\n\t\tdebug: false,\n\t\ttime: 0,\n\t\tinput: undefined,\n\t};\n}\n\nconst gameDefaultsState = proxy<Partial<ZylemGameConfig<Stage, any, BaseGlobals>>>(\n\t{ ...initialDefaults() }\n);\n\n/**\n * Get a plain object copy of the current defaults.\n */\nexport function getGameDefaultConfig<TGlobals extends Record<string, BasicTypes> = BaseGlobals>(): {\n\tid: string;\n\tglobals: TGlobals;\n\tstages: Stage[];\n\tdebug?: boolean;\n\ttime?: number;\n\tinput?: GameInputConfig;\n} {\n\treturn {\n\t\tid: (gameDefaultsState.id as string) ?? 'zylem',\n\t\tglobals: (gameDefaultsState.globals as TGlobals) ?? ({} as unknown as TGlobals),\n\t\tstages: (gameDefaultsState.stages as Stage[]) ?? [createStage()],\n\t\tdebug: gameDefaultsState.debug,\n\t\ttime: gameDefaultsState.time,\n\t\tinput: gameDefaultsState.input,\n\t};\n}\n\n\n","import { state, setGlobal, getGlobals, initGlobals, resetGlobals } from './game-state';\n\nimport { debugState, isPaused, setDebugFlag } from '../debug/debug-state';\n\nimport { Game } from './game';\nimport { UpdateContext, SetupContext, DestroyContext } from '../core/base-node-life-cycle';\nimport { InputManager } from '../input/input-manager';\nimport { mergeInputConfigs } from '../input/input-presets';\nimport { Timer } from '../core/three-addons/Timer';\nimport { ZylemCamera } from '~/lib/camera/zylem-camera';\nimport { RendererManager, RendererType } from '../camera/renderer-manager';\nimport { CameraWrapper } from '../camera/camera';\nimport { isCameraWrapper } from '../core/utility/options-parser';\nimport { Stage } from '../stage/stage';\nimport { BaseGlobals, GameInputConfig, ZylemGameConfig } from './game-interfaces';\nimport {\n\tGameConfig,\n\tresolveGameConfig,\n\ttype ResolveGameConfigRuntime,\n} from './game-config';\nimport { AspectRatioDelegate } from '../device/aspect-ratio';\nimport { GameCanvas } from './game-canvas';\nimport { GameDebugDelegate } from './game-debug-delegate';\nimport { GameLoadingDelegate, GameLoadingEvent } from './game-loading-delegate';\nimport { gameEventBus, GameStateUpdatedPayload } from './game-event-bus';\nimport { zylemEventBus, type StateDispatchPayload, type StageConfigPayload, type EntityConfigPayload } from '../events';\nimport { GameRendererObserver } from './game-renderer-observer';\nimport { ZylemStage } from '../core';\n\nexport type { GameLoadingEvent };\n\ntype ZylemGameOptions<TGlobals extends BaseGlobals> = ZylemGameConfig<Stage, ZylemGame<TGlobals>, TGlobals> & Partial<GameConfig>\n\n// TODO: need to split this up into delegate classes\nexport class ZylemGame<TGlobals extends BaseGlobals> {\n\tid: string;\n\tinitialGlobals = {} as TGlobals;\n\n\t// TODO: these should be unecessary given a delegate or inherited from base node\n\tcustomSetup: ((params: SetupContext<ZylemGame<TGlobals>, TGlobals>) => void) | null = null;\n\tcustomUpdate: ((params: UpdateContext<ZylemGame<TGlobals>, TGlobals>) => void) | null = null;\n\tcustomDestroy: ((params: DestroyContext<ZylemGame<TGlobals>, TGlobals>) => void) | null = null;\n\n\tstages: Stage[] = [];\n\tstageMap: Map<string, Stage> = new Map();\n\tcurrentStageId = '';\n\n\tpreviousTimeStamp: number = 0;\n\ttotalTime = 0;\n\n\ttimer: Timer;\n\tinputManager: InputManager;\n\n\twrapperRef: Game<TGlobals>;\n\tglobalInputConfig: GameInputConfig | undefined;\n\tdefaultCamera: ZylemCamera | null = null;\n\t/** Shared renderer manager for all stages */\n\trendererManager: RendererManager | null = null;\n\tcontainer: HTMLElement | null = null;\n\tcanvas: HTMLCanvasElement | null = null;\n\taspectRatioDelegate: AspectRatioDelegate | null = null;\n\tresolvedConfig: GameConfig | null = null;\n\tgameCanvas: GameCanvas | null = null;\n\tprivate animationFrameId: number | null = null;\n\tprivate isDisposed = false;\n\tprivate debugDelegate: GameDebugDelegate | null = null;\n\tprivate loadingDelegate: GameLoadingDelegate = new GameLoadingDelegate();\n\tprivate rendererObserver: GameRendererObserver = new GameRendererObserver();\n\tprivate eventBusUnsubscribes: (() => void)[] = [];\n\tprivate readonly gameUpdateParams = {} as UpdateContext<\n\t\tZylemGame<TGlobals>,\n\t\tTGlobals\n\t>;\n\tprivate readonly stageSetupParams = {} as SetupContext<ZylemStage, TGlobals>;\n\tprivate readonly stageUpdateParams = {} as UpdateContext<ZylemStage, TGlobals>;\n\tprivate readonly frameCallback = (timestamp: number) => this.loop(timestamp);\n\tprivate readonly sourceOptions: ZylemGameOptions<TGlobals>;\n\tprivate displayRuntime: ResolveGameConfigRuntime;\n\n\tstatic FRAME_LIMIT = 120;\n\tstatic FRAME_DURATION = 1000 / ZylemGame.FRAME_LIMIT;\n\tstatic MAX_DELTA_SECONDS = 1 / 30;\n\n\tconstructor(\n\t\toptions: ZylemGameOptions<TGlobals>,\n\t\twrapperRef: Game<TGlobals>,\n\t\tdisplayRuntime: ResolveGameConfigRuntime = {},\n\t) {\n\t\tthis.wrapperRef = wrapperRef;\n\t\tthis.timer = new Timer();\n\t\tthis.timer.connect(document);\n\t\tthis.sourceOptions = { ...options };\n\t\tthis.displayRuntime = { ...displayRuntime };\n\n\t\tconst config = resolveGameConfig(options as any, this.displayRuntime);\n\n\t\tthis.globalInputConfig = config.input;\n\t\tthis.inputManager = new InputManager(config.input);\n\n\t\tthis.id = config.id;\n\t\tthis.stages = (config.stages as any) || [];\n\t\tthis.container = config.container;\n\t\tthis.canvas = config.canvas ?? null;\n\t\tthis.resolvedConfig = config;\n\t\tthis.loadGameCanvas(config);\n\t\tthis.loadDebugOptions(options);\n\t\tthis.setGlobals(options);\n\t}\n\n\tsetDisplayRuntime(runtime: ResolveGameConfigRuntime): void {\n\t\tthis.displayRuntime = { ...runtime };\n\t\tconst nextConfig = resolveGameConfig(this.sourceOptions as any, this.displayRuntime);\n\t\tthis.resolvedConfig = nextConfig;\n\t\tthis.rendererObserver.setConfig(nextConfig);\n\t\tthis.gameCanvas?.setAspectRatio(nextConfig.aspectRatio);\n\t\tthis.emitStateDispatch('@game:display-config');\n\t}\n\n\tloadGameCanvas(config: GameConfig) {\n\t\tthis.gameCanvas = new GameCanvas({\n\t\t\tid: config.id,\n\t\t\tcontainer: config.container,\n\t\t\tcontainerId: config.containerId,\n\t\t\tcanvas: this.canvas ?? undefined,\n\t\t\tbodyBackground: config.bodyBackground,\n\t\t\tfullscreen: config.fullscreen,\n\t\t\taspectRatio: config.aspectRatio,\n\t\t});\n\t\tthis.gameCanvas.applyBodyBackground();\n\t\tthis.gameCanvas.mountCanvas();\n\t\tthis.gameCanvas.centerIfFullscreen();\n\t\t\n\t\t// Setup renderer observer\n\t\tthis.rendererObserver.setGameCanvas(this.gameCanvas);\n\t\tif (this.resolvedConfig) {\n\t\t\tthis.rendererObserver.setConfig(this.resolvedConfig);\n\t\t}\n\t\tif (this.container) {\n\t\t\tthis.rendererObserver.setContainer(this.container);\n\t\t}\n\t\t\n\t\t// Subscribe to event bus for stage loading events\n\t\tthis.subscribeToEventBus();\n\t}\n\n\tloadDebugOptions(options: ZylemGameOptions<TGlobals>) {\n\t\tif (options.debug !== undefined) {\n\t\t\tdebugState.enabled = Boolean(options.debug);\n\t\t}\n\t\tthis.debugDelegate = new GameDebugDelegate();\n\t}\n\n\tasync loadStage(stage: Stage, stageIndex: number = 0): Promise<void> {\n\t\tthis.unloadCurrentStage();\n\t\tconst config = stage.options[0] as any;\n\t\t\n\t\t// Subscribe to stage loading events via delegate\n\t\tthis.loadingDelegate.wireStageLoading(stage, stageIndex);\n\n\t\t// Lazily create the shared renderer manager.\n\t\t// Inspect the stage's camera options to determine the renderer type\n\t\t// (e.g. 'webgpu' vs 'webgl') before initializing the renderer.\n\t\tif (!this.rendererManager) {\n\t\t\tconst rendererType = this.resolveRendererType(stage);\n\t\t\tthis.rendererManager = new RendererManager(undefined, rendererType);\n\t\t\tawait this.rendererManager.initRenderer();\n\t\t}\n\n\t\t// Start stage loading with shared renderer manager\n\t\tawait stage.load(this.id, config?.camera as ZylemCamera | null, this.rendererManager);\n\n\t\tthis.stageMap.set(stage.wrappedStage!.uuid, stage);\n\t\tthis.currentStageId = stage.wrappedStage!.uuid;\n\t\tthis.defaultCamera = stage.wrappedStage!.cameraRef!;\n\t\t\n\t\t// Trigger renderer observer with renderer manager\n\t\tthis.rendererObserver.setStage(stage.wrappedStage ?? null);\n\t\tif (this.rendererManager) {\n\t\t\tthis.rendererObserver.setRendererManager(this.rendererManager);\n\t\t}\n\n\t\t// Apply merged input configuration (global + stage overrides)\n\t\tthis.applyInputConfig(stage);\n\n\t\t// Wire callback so runtime changes to stage input config take effect immediately\n\t\tstage.onInputConfigChanged = () => this.applyInputConfig(stage);\n\n\t\t// Emit state dispatch after stage is loaded so editor receives initial config\n\t\tthis.emitStateDispatch('@stage:loaded');\n\t}\n\n\t/**\n\t * Merges game-level global input config with the stage's per-stage overrides\n\t * and reconfigures the InputManager.\n\t */\n\tapplyInputConfig(stage: Stage): void {\n\t\tconst merged = mergeInputConfigs(\n\t\t\tthis.globalInputConfig ?? {},\n\t\t\tstage.inputConfig ?? {},\n\t\t);\n\t\tthis.inputManager.configure(merged);\n\t}\n\n\t/**\n\t * Update the game-level global input config and re-apply to the current stage.\n\t */\n\tsetGlobalInputConfig(config: GameInputConfig): void {\n\t\tthis.globalInputConfig = config;\n\t\tconst stage = this.currentStage();\n\t\tif (stage) {\n\t\t\tthis.applyInputConfig(stage);\n\t\t}\n\t}\n\n\tunloadCurrentStage() {\n\t\tif (!this.currentStageId) return;\n\t\tconst current = this.getStage(this.currentStageId);\n\t\tif (!current) return;\n\n\t\t// Disconnect input config callback from outgoing stage\n\t\tcurrent.onInputConfigChanged = null;\n\n\t\tif (current?.wrappedStage) {\n\t\t\ttry {\n\t\t\t\tcurrent.wrappedStage.nodeDestroy({\n\t\t\t\t\tme: current.wrappedStage,\n\t\t\t\t\tglobals: state.globals as unknown as TGlobals,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Failed to destroy previous stage', e);\n\t\t\t}\n\t\t\t// Clear the Stage wrapper's reference to the destroyed stage\n\t\t\tcurrent.wrappedStage = null;\n\t\t}\n\n\t\t// Dispose Stage wrapper event delegate to prevent listener accumulation\n\t\tcurrent.dispose();\n\t\t\n\t\t// Remove from stage map\n\t\tthis.stageMap.delete(this.currentStageId);\n\t\t\n\t\t// Reset game state\n\t\tthis.currentStageId = '';\n\t\tthis.defaultCamera = null;\n\t\t\n\t\t// Reset renderer observer for stage transitions\n\t\tthis.rendererObserver.reset();\n\t}\n\n\tsetGlobals(options: ZylemGameConfig<Stage, ZylemGame<TGlobals>, TGlobals>) {\n\t\tthis.initialGlobals = { ...(options.globals as TGlobals) };\n\t\tfor (const variable in this.initialGlobals) {\n\t\t\tconst value = this.initialGlobals[variable];\n\t\t\tif (value === undefined) {\n\t\t\t\tconsole.error(`global ${variable} is undefined`);\n\t\t\t}\n\t\t\tsetGlobal(variable, value);\n\t\t}\n\t}\n\n\tparams(): UpdateContext<ZylemGame<TGlobals>, TGlobals> {\n\t\tconst stage = this.currentStage();\n\t\tconst delta = this.timer.getDelta();\n\t\tconst inputs = this.inputManager.getInputs(delta);\n\t\tconst camera = stage?.wrappedStage?.cameraRef || this.defaultCamera;\n\n\t\tconst params = this.gameUpdateParams;\n\t\tparams.delta = delta;\n\t\tparams.inputs = inputs;\n\t\tparams.globals = getGlobals<TGlobals>();\n\t\tparams.me = this;\n\t\tparams.camera = camera!;\n\t\tparams.stage = stage as any;\n\t\tparams.game = this.wrapperRef;\n\t\treturn params;\n\t}\n\n\tstart() {\n\t\tconst stage = this.currentStage();\n\t\tconst params = this.params();\n\t\tconst setupParams = this.stageSetupParams;\n\t\tsetupParams.inputs = params.inputs;\n\t\tsetupParams.globals = params.globals;\n\t\tsetupParams.camera = params.camera;\n\t\tsetupParams.stage = params.stage;\n\t\tsetupParams.game = params.game;\n\t\tsetupParams.me = stage!.wrappedStage as ZylemStage;\n\t\tstage!.start(setupParams);\n\t\tif (this.customSetup) {\n\t\t\tthis.customSetup(params);\n\t\t}\n\t\tthis.loop(0);\n\t}\n\n\t/**\n\t * Execute a single frame update.\n\t * This method can be called directly for testing or from the game loop.\n\t * @param deltaTime Optional delta time in seconds. If not provided, uses timer delta.\n\t */\n\tstep(deltaTime?: number): void {\n\t\tconst stage = this.currentStage();\n\t\tif (!stage || !stage.wrappedStage) return;\n\n\t\tconst params = this.params();\n\t\tconst delta = deltaTime !== undefined ? deltaTime : params.delta;\n\t\tconst clampedDelta = Math.min(Math.max(delta, 0), ZylemGame.MAX_DELTA_SECONDS);\n\t\tparams.delta = clampedDelta;\n\n\t\tif (this.customUpdate) {\n\t\t\tthis.customUpdate(params);\n\t\t}\n\n\t\tconst stageParams = this.stageUpdateParams;\n\t\tstageParams.delta = params.delta;\n\t\tstageParams.inputs = params.inputs;\n\t\tstageParams.globals = params.globals;\n\t\tstageParams.camera = params.camera;\n\t\tstageParams.stage = params.stage;\n\t\tstageParams.game = params.game;\n\t\tstageParams.me = stage.wrappedStage as ZylemStage;\n\t\tstage.wrappedStage?.nodeUpdate(stageParams);\n\n\t\tthis.totalTime += clampedDelta;\n\t\tstate.time = this.totalTime;\n\t}\n\n\tloop(timestamp: number) {\n\t\tthis.debugDelegate?.begin();\n\t\tif (!isPaused()) {\n\t\t\tthis.timer.update(timestamp);\n\t\t\tthis.step();\n\t\t\tthis.previousTimeStamp = timestamp;\n\t\t}\n\t\tthis.debugDelegate?.end();\n\t\tthis.outOfLoop();\n\t\tif (!this.isDisposed) {\n\t\t\tthis.animationFrameId = requestAnimationFrame(this.frameCallback);\n\t\t}\n\t}\n\n\tdispose() {\n\t\tthis.isDisposed = true;\n\t\tif (this.animationFrameId !== null) {\n\t\t\tcancelAnimationFrame(this.animationFrameId);\n\t\t\tthis.animationFrameId = null;\n\t\t}\n\n\t\tthis.unloadCurrentStage();\n\n\t\tif (this.debugDelegate) {\n\t\t\tthis.debugDelegate.dispose();\n\t\t\tthis.debugDelegate = null;\n\t\t}\n\n\t\tthis.eventBusUnsubscribes.forEach(unsub => unsub());\n\t\tthis.eventBusUnsubscribes = [];\n\n\t\tthis.rendererObserver.dispose();\n\n\t\t// Dispose the shared renderer manager\n\t\tif (this.rendererManager) {\n\t\t\tthis.rendererManager.dispose();\n\t\t\tthis.rendererManager = null;\n\t\t}\n\n\t\tthis.timer.dispose();\n\n\t\tif (this.customDestroy) {\n\t\t\tthis.customDestroy({\n\t\t\t\tme: this,\n\t\t\t\tglobals: state.globals as unknown as TGlobals\n\t\t\t});\n\t\t}\n\t\tresetGlobals();\n\t}\n\n\toutOfLoop() {\n\t\tconst currentStage = this.currentStage();\n\t\tif (!currentStage) return;\n\t\tcurrentStage.wrappedStage!.outOfLoop();\n\t}\n\n\tgetStage(id: string) {\n\t\treturn this.stageMap.get(id);\n\t}\n\n\tcurrentStage() {\n\t\treturn this.getStage(this.currentStageId);\n\t}\n\n\t/**\n\t * Subscribe to loading events from the game.\n\t * Events include stage context (stageName, stageIndex).\n\t * @param callback Invoked for each loading event\n\t * @returns Unsubscribe function\n\t */\n\tonLoading(callback: (event: GameLoadingEvent) => void): () => void {\n\t\treturn this.loadingDelegate.onLoading(callback);\n\t}\n\n\t/**\n\t * Build the stage config payload for the current stage.\n\t */\n\tprivate buildStageConfigPayload(): StageConfigPayload | null {\n\t\tconst stage = this.currentStage();\n\t\tif (!stage?.wrappedStage) return null;\n\n\t\tconst state = stage.wrappedStage.state;\n\t\tconst bgColor = state.backgroundColor;\n\t\tconst colorStr = typeof bgColor === 'string' ? bgColor : `#${bgColor.getHexString()}`;\n\n\t\treturn {\n\t\t\tid: stage.wrappedStage.uuid,\n\t\t\tbackgroundColor: colorStr,\n\t\t\tbackgroundImage: state.backgroundImage,\n\t\t\tgravity: {\n\t\t\t\tx: state.gravity.x,\n\t\t\t\ty: state.gravity.y,\n\t\t\t\tz: state.gravity.z,\n\t\t\t},\n\t\t\tinputs: state.inputs,\n\t\t\tvariables: state.variables,\n\t\t};\n\t}\n\n\t/**\n\t * Build the entities payload for the current stage.\n\t */\n\tprivate buildEntitiesPayload(): EntityConfigPayload[] | null {\n\t\tconst stage = this.currentStage();\n\t\tif (!stage?.wrappedStage) return null;\n\n\t\tconst entities: EntityConfigPayload[] = [];\n\t\tstage.wrappedStage.entityDelegate.childrenMap.forEach((child) => {\n\t\t\t// Get type string from the entity's constructor\n\t\t\tconst entityType = (child.constructor as any).type;\n\t\t\tconst typeStr = entityType ? String(entityType).replace('Symbol(', '').replace(')', '') : 'Unknown';\n\n\t\t\t// Get transform data\n\t\t\tconst position = (child as any).position ?? { x: 0, y: 0, z: 0 };\n\t\t\tconst rotation = (child as any).rotation ?? { x: 0, y: 0, z: 0 };\n\t\t\tconst scale = (child as any).scale ?? { x: 1, y: 1, z: 1 };\n\n\t\t\tentities.push({\n\t\t\t\tuuid: child.uuid,\n\t\t\t\tname: child.name || 'Unnamed',\n\t\t\t\ttype: typeStr,\n\t\t\t\tposition: { x: position.x ?? 0, y: position.y ?? 0, z: position.z ?? 0 },\n\t\t\t\trotation: { x: rotation.x ?? 0, y: rotation.y ?? 0, z: rotation.z ?? 0 },\n\t\t\t\tscale: { x: scale.x ?? 1, y: scale.y ?? 1, z: scale.z ?? 1 },\n\t\t\t});\n\t\t});\n\n\t\treturn entities;\n\t}\n\n\t/**\n\t * Emit a state:dispatch event to the zylemEventBus.\n\t * Called after stage load and on global state changes.\n\t */\n\tprivate emitStateDispatch(path: string, value?: unknown, previousValue?: unknown): void {\n\t\tconst statePayload: StateDispatchPayload = {\n\t\t\tscope: 'game',\n\t\t\tpath,\n\t\t\tvalue,\n\t\t\tpreviousValue,\n\t\t\tconfig: this.resolvedConfig ? {\n\t\t\t\tid: this.resolvedConfig.id,\n\t\t\t\taspectRatio: this.resolvedConfig.aspectRatio,\n\t\t\t\tfullscreen: this.resolvedConfig.fullscreen,\n\t\t\t\tbodyBackground: this.resolvedConfig.bodyBackground,\n\t\t\t\tinternalResolution: this.resolvedConfig.internalResolution,\n\t\t\t\tdebug: this.resolvedConfig.debug,\n\t\t\t} : null,\n\t\t\tstageConfig: this.buildStageConfigPayload(),\n\t\t\tentities: this.buildEntitiesPayload(),\n\t\t};\n\t\tzylemEventBus.emit('state:dispatch', statePayload);\n\t}\n\n\t/**\n\t * Inspect a stage's options to determine the renderer type.\n\t * Looks for CameraWrapper instances in the stage options and uses\n\t * the first camera's rendererType. Falls back to 'webgl'.\n\t */\n\tprivate resolveRendererType(stage: Stage): RendererType {\n\t\tfor (const opt of stage.options) {\n\t\t\tif (isCameraWrapper(opt)) {\n\t\t\t\tconst rt = (opt as CameraWrapper).cameraRef.rendererType;\n\t\t\t\tif (rt && rt !== 'webgl') {\n\t\t\t\t\treturn rt;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn 'webgl';\n\t}\n\n\t/**\n\t * Subscribe to the game event bus for stage loading and state events.\n\t * Emits events to zylemEventBus for cross-package communication.\n\t */\n\tprivate subscribeToEventBus(): void {\n\t\tthis.eventBusUnsubscribes.push(\n\t\t\tgameEventBus.on('game:state:updated', (payload: GameStateUpdatedPayload) => {\n\t\t\t\tthis.emitStateDispatch(payload.path, payload.value, payload.previousValue);\n\t\t\t}),\n\t\t);\n\t}\n}\n","import { InputGamepad, ButtonState, AnalogState, InputPlayerNumber } from './input';\n\n/**\n * Represents a direct property path for efficient state updates.\n * Avoids string parsing on every frame.\n */\nexport interface PropertyPath {\n\tcategory: 'buttons' | 'directions' | 'shoulders' | 'axes';\n\tproperty: string;\n\t/** Axis contribution direction: -1 or 1. Only present for axes paths. */\n\taxisDirection?: -1 | 1;\n}\n\n/**\n * Pre-computed mapping from keyboard key to input properties.\n * Built once at initialization to avoid per-frame string parsing.\n */\ntype CompiledMapping = Map<string, PropertyPath[]>;\n\n/**\n * Creates a default ButtonState\n */\nfunction createButtonState(): ButtonState {\n\treturn { pressed: false, released: false, held: 0 };\n}\n\n/**\n * Creates a default AnalogState\n */\nfunction createAnalogState(): AnalogState {\n\treturn { value: 0, held: 0 };\n}\n\n/**\n * Creates a fresh InputGamepad state object\n */\nexport function createInputGamepadState(playerNumber: InputPlayerNumber): InputGamepad {\n\treturn {\n\t\tplayerNumber,\n\t\tbuttons: {\n\t\t\tA: createButtonState(),\n\t\t\tB: createButtonState(),\n\t\t\tX: createButtonState(),\n\t\t\tY: createButtonState(),\n\t\t\tStart: createButtonState(),\n\t\t\tSelect: createButtonState(),\n\t\t\tL: createButtonState(),\n\t\t\tR: createButtonState(),\n\t\t},\n\t\tdirections: {\n\t\t\tUp: createButtonState(),\n\t\t\tDown: createButtonState(),\n\t\t\tLeft: createButtonState(),\n\t\t\tRight: createButtonState(),\n\t\t},\n\t\tshoulders: {\n\t\t\tLTrigger: createButtonState(),\n\t\t\tRTrigger: createButtonState(),\n\t\t},\n\t\taxes: {\n\t\t\tHorizontal: createAnalogState(),\n\t\t\tVertical: createAnalogState(),\n\t\t\tSecondaryHorizontal: createAnalogState(),\n\t\t\tSecondaryVertical: createAnalogState(),\n\t\t},\n\t};\n}\n\n/**\n * Compiles a keyboard mapping into efficient property paths.\n * This is done once at initialization instead of every frame.\n * \n * @param mapping - Raw mapping from config (e.g., { 'w': ['directions.Up'] })\n * @returns Compiled mapping for O(1) lookups\n */\nexport function compileMapping(mapping: Record<string, string[]> | null): CompiledMapping {\n\tconst compiled = new Map<string, PropertyPath[]>();\n\t\n\tif (!mapping) return compiled;\n\n\tfor (const [key, targets] of Object.entries(mapping)) {\n\t\tif (!targets || targets.length === 0) continue;\n\t\t\n\t\tconst paths: PropertyPath[] = [];\n\t\t\n\t\tfor (const target of targets) {\n\t\t\tconst [rawCategory, rawName] = (target || '').split('.');\n\t\t\tif (!rawCategory || !rawName) continue;\n\t\t\t\n\t\t\tconst category = rawCategory.toLowerCase();\n\t\t\tconst nameKey = rawName.toLowerCase();\n\t\t\t\n\t\t\t// Map category and property name\n\t\t\tif (category === 'buttons') {\n\t\t\t\tconst propertyMap: Record<string, string> = {\n\t\t\t\t\t'a': 'A', 'b': 'B', 'x': 'X', 'y': 'Y',\n\t\t\t\t\t'start': 'Start', 'select': 'Select',\n\t\t\t\t\t'l': 'L', 'r': 'R',\n\t\t\t\t};\n\t\t\t\tconst prop = propertyMap[nameKey];\n\t\t\t\tif (prop) {\n\t\t\t\t\tpaths.push({ category: 'buttons', property: prop });\n\t\t\t\t}\n\t\t\t} else if (category === 'directions') {\n\t\t\t\tconst propertyMap: Record<string, string> = {\n\t\t\t\t\t'up': 'Up', 'down': 'Down', 'left': 'Left', 'right': 'Right',\n\t\t\t\t};\n\t\t\t\tconst prop = propertyMap[nameKey];\n\t\t\t\tif (prop) {\n\t\t\t\t\tpaths.push({ category: 'directions', property: prop });\n\t\t\t\t}\n\t\t\t} else if (category === 'shoulders') {\n\t\t\t\tconst propertyMap: Record<string, string> = {\n\t\t\t\t\t'ltrigger': 'LTrigger', 'rtrigger': 'RTrigger',\n\t\t\t\t};\n\t\t\t\tconst prop = propertyMap[nameKey];\n\t\t\t\tif (prop) {\n\t\t\t\t\tpaths.push({ category: 'shoulders', property: prop });\n\t\t\t\t}\n\t\t\t} else if (category === 'axes') {\n\t\t\t\t// Axis targets use directional names: axes.Left, axes.Right, axes.Up, axes.Down\n\t\t\t\t// Right stick: axes.RightLeft, axes.RightRight, axes.RightUp, axes.RightDown\n\t\t\t\tconst axisMap: Record<string, { property: string; direction: -1 | 1 }> = {\n\t\t\t\t\t'left': { property: 'Horizontal', direction: -1 },\n\t\t\t\t\t'right': { property: 'Horizontal', direction: 1 },\n\t\t\t\t\t'up': { property: 'Vertical', direction: -1 },\n\t\t\t\t\t'down': { property: 'Vertical', direction: 1 },\n\t\t\t\t\t'secondaryleft': { property: 'SecondaryHorizontal', direction: -1 },\n\t\t\t\t\t'secondaryright': { property: 'SecondaryHorizontal', direction: 1 },\n\t\t\t\t\t'secondaryup': { property: 'SecondaryVertical', direction: -1 },\n\t\t\t\t\t'secondarydown': { property: 'SecondaryVertical', direction: 1 },\n\t\t\t\t};\n\t\t\t\tconst axis = axisMap[nameKey];\n\t\t\t\tif (axis) {\n\t\t\t\t\tpaths.push({ category: 'axes', property: axis.property, axisDirection: axis.direction });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (paths.length > 0) {\n\t\t\tcompiled.set(key, paths);\n\t\t}\n\t}\n\t\n\treturn compiled;\n}\n\n/**\n * Merges two ButtonStates efficiently\n */\nexport function mergeButtonState(a: ButtonState | undefined, b: ButtonState | undefined): ButtonState {\n\tif (!a && !b) return createButtonState();\n\tif (!a) return { ...b! };\n\tif (!b) return { ...a };\n\t\n\treturn {\n\t\tpressed: a.pressed || b.pressed,\n\t\treleased: a.released || b.released,\n\t\theld: a.held + b.held,\n\t};\n}\n\n/**\n * Merges two AnalogStates efficiently\n */\nexport function mergeAnalogState(a: AnalogState | undefined, b: AnalogState | undefined): AnalogState {\n\tif (!a && !b) return createAnalogState();\n\tif (!a) return { ...b! };\n\tif (!b) return { ...a };\n\t\n\treturn {\n\t\tvalue: a.value + b.value,\n\t\theld: a.held + b.held,\n\t};\n}\n\n/**\n * Merges two InputGamepad objects efficiently.\n * Reuses the target object structure to minimize allocations.\n */\nexport function mergeInputGamepads(target: InputGamepad, source: Partial<InputGamepad>): void {\n\t// Merge buttons\n\tif (source.buttons) {\n\t\ttarget.buttons.A = mergeButtonState(target.buttons.A, source.buttons.A);\n\t\ttarget.buttons.B = mergeButtonState(target.buttons.B, source.buttons.B);\n\t\ttarget.buttons.X = mergeButtonState(target.buttons.X, source.buttons.X);\n\t\ttarget.buttons.Y = mergeButtonState(target.buttons.Y, source.buttons.Y);\n\t\ttarget.buttons.Start = mergeButtonState(target.buttons.Start, source.buttons.Start);\n\t\ttarget.buttons.Select = mergeButtonState(target.buttons.Select, source.buttons.Select);\n\t\ttarget.buttons.L = mergeButtonState(target.buttons.L, source.buttons.L);\n\t\ttarget.buttons.R = mergeButtonState(target.buttons.R, source.buttons.R);\n\t}\n\t\n\t// Merge directions\n\tif (source.directions) {\n\t\ttarget.directions.Up = mergeButtonState(target.directions.Up, source.directions.Up);\n\t\ttarget.directions.Down = mergeButtonState(target.directions.Down, source.directions.Down);\n\t\ttarget.directions.Left = mergeButtonState(target.directions.Left, source.directions.Left);\n\t\ttarget.directions.Right = mergeButtonState(target.directions.Right, source.directions.Right);\n\t}\n\t\n\t// Merge shoulders\n\tif (source.shoulders) {\n\t\ttarget.shoulders.LTrigger = mergeButtonState(target.shoulders.LTrigger, source.shoulders.LTrigger);\n\t\ttarget.shoulders.RTrigger = mergeButtonState(target.shoulders.RTrigger, source.shoulders.RTrigger);\n\t}\n\t\n\t// Merge axes\n\tif (source.axes) {\n\t\ttarget.axes.Horizontal = mergeAnalogState(target.axes.Horizontal, source.axes.Horizontal);\n\t\ttarget.axes.Vertical = mergeAnalogState(target.axes.Vertical, source.axes.Vertical);\n\t\ttarget.axes.SecondaryHorizontal = mergeAnalogState(target.axes.SecondaryHorizontal, source.axes.SecondaryHorizontal);\n\t\ttarget.axes.SecondaryVertical = mergeAnalogState(target.axes.SecondaryVertical, source.axes.SecondaryVertical);\n\t}\n\n\t// Pointer: last-write-wins (not additive)\n\tif (source.pointer) {\n\t\ttarget.pointer = source.pointer;\n\t}\n}\n","import { InputProvider, AnalogState, ButtonState, InputGamepad } from './input';\nimport { compileMapping, mergeAnalogState, mergeButtonState, PropertyPath } from './input-state';\n\nexport class KeyboardProvider implements InputProvider {\n\tprivate keyStates = new Map<string, boolean>();\n\tprivate keyButtonStates = new Map<string, ButtonState>();\n\tprivate analogStates = new Map<string, AnalogState>();\n\tprivate compiledMapping: Map<string, PropertyPath[]>;\n\tprivate includeDefaultBase: boolean = true;\n\n\tprivate onKeyDown = ({ key }: KeyboardEvent) => this.keyStates.set(key, true);\n\tprivate onKeyUp = ({ key }: KeyboardEvent) => this.keyStates.set(key, false);\n\n\tconstructor(mapping?: Record<string, string[]>, options?: { includeDefaultBase?: boolean }) {\n\t\tthis.includeDefaultBase = options?.includeDefaultBase ?? true;\n\t\tthis.compiledMapping = compileMapping(mapping ?? null);\n\n\t\twindow.addEventListener('keydown', this.onKeyDown);\n\t\twindow.addEventListener('keyup', this.onKeyUp);\n\t}\n\n\t/** Removes event listeners and cleans up state. */\n\tdispose(): void {\n\t\twindow.removeEventListener('keydown', this.onKeyDown);\n\t\twindow.removeEventListener('keyup', this.onKeyUp);\n\t\tthis.keyStates.clear();\n\t\tthis.keyButtonStates.clear();\n\t\tthis.analogStates.clear();\n\t}\n\n\tprivate isKeyPressed(key: string): boolean {\n\t\treturn this.keyStates.get(key) || false;\n\t}\n\n\tprivate handleButtonState(key: string, delta: number): ButtonState {\n\t\tlet state = this.keyButtonStates.get(key);\n\t\tif (!state) {\n\t\t\tstate = { pressed: false, released: false, held: 0 };\n\t\t\tthis.keyButtonStates.set(key, state);\n\t\t}\n\n\t\tconst isPressed = this.isKeyPressed(key);\n\t\tstate.pressed = isPressed && state.held === 0;\n\t\tstate.released = !isPressed && state.held > 0;\n\t\tstate.held = isPressed ? state.held + delta : 0;\n\n\t\treturn state;\n\t}\n\n\tprivate handleAnalogState(negativeKey: string, positiveKey: string, delta: number): AnalogState {\n\t\tconst stateKey = `${negativeKey}:${positiveKey}`;\n\t\tlet state = this.analogStates.get(stateKey);\n\t\tif (!state) {\n\t\t\tstate = { value: 0, held: 0 };\n\t\t\tthis.analogStates.set(stateKey, state);\n\t\t}\n\n\t\tstate.value = this.getAxisValue(negativeKey, positiveKey);\n\t\tstate.held = state.value !== 0 ? state.held + delta : 0;\n\n\t\treturn state;\n\t}\n\n\t/**\n\t * Applies custom key mappings using pre-computed paths.\n\t * Handles buttons/directions/shoulders via ButtonState merging,\n\t * and axes via accumulated axis contributions with held tracking.\n\t */\n\tprivate applyCustomMapping(input: Partial<InputGamepad>, delta: number): Partial<InputGamepad> {\n\t\tif (this.compiledMapping.size === 0) return input;\n\n\t\t// Collect axis contributions across all keys (initialized to 0)\n\t\tconst axisValues = new Map<string, number>();\n\n\t\tfor (const [key, paths] of this.compiledMapping.entries()) {\n\t\t\tlet buttonState: ButtonState | null = null;\n\n\t\t\tfor (const path of paths) {\n\t\t\t\tif (path.category === 'axes') {\n\t\t\t\t\tif (!axisValues.has(path.property)) {\n\t\t\t\t\t\taxisValues.set(path.property, 0);\n\t\t\t\t\t}\n\t\t\t\t\tif (this.isKeyPressed(key)) {\n\t\t\t\t\t\taxisValues.set(path.property, axisValues.get(path.property)! + path.axisDirection!);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Lazy-compute button state only when needed\n\t\t\t\t\tif (!buttonState) {\n\t\t\t\t\t\tbuttonState = this.handleButtonState(key, delta);\n\t\t\t\t\t}\n\t\t\t\t\tconst group = ((input as any)[path.category] ??= {});\n\t\t\t\t\tgroup[path.property] = mergeButtonState(group[path.property], buttonState);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Apply accumulated axis values with held-time tracking\n\t\tif (axisValues.size > 0) {\n\t\t\tif (!input.axes) input.axes = {} as any;\n\t\t\tfor (const [axisName, value] of axisValues.entries()) {\n\t\t\t\tconst stateKey = `custom:${axisName}`;\n\t\t\t\tlet state = this.analogStates.get(stateKey);\n\t\t\t\tif (!state) {\n\t\t\t\t\tstate = { value: 0, held: 0 };\n\t\t\t\t\tthis.analogStates.set(stateKey, state);\n\t\t\t\t}\n\t\t\t\tstate.value = value;\n\t\t\t\tstate.held = value !== 0 ? state.held + delta : 0;\n\t\t\t\t(input.axes as any)[axisName] = mergeAnalogState((input.axes as any)[axisName], state);\n\t\t\t}\n\t\t}\n\n\t\treturn input;\n\t}\n\n\tgetInput(delta: number): Partial<InputGamepad> {\n\t\tconst base: Partial<InputGamepad> = {};\n\t\tif (this.includeDefaultBase) {\n\t\t\tbase.buttons = {\n\t\t\t\tA: this.handleButtonState('z', delta),\n\t\t\t\tB: this.handleButtonState('x', delta),\n\t\t\t\tX: this.handleButtonState('a', delta),\n\t\t\t\tY: this.handleButtonState('s', delta),\n\t\t\t\tStart: this.handleButtonState(' ', delta),\n\t\t\t\tSelect: this.handleButtonState('Enter', delta),\n\t\t\t\tL: this.handleButtonState('q', delta),\n\t\t\t\tR: this.handleButtonState('e', delta),\n\t\t\t};\n\t\t\tbase.directions = {\n\t\t\t\tUp: this.handleButtonState('ArrowUp', delta),\n\t\t\t\tDown: this.handleButtonState('ArrowDown', delta),\n\t\t\t\tLeft: this.handleButtonState('ArrowLeft', delta),\n\t\t\t\tRight: this.handleButtonState('ArrowRight', delta),\n\t\t\t};\n\t\t\tbase.shoulders = {\n\t\t\t\tLTrigger: this.handleButtonState('Q', delta),\n\t\t\t\tRTrigger: this.handleButtonState('E', delta),\n\t\t\t};\n\t\t}\n\n\t\treturn this.applyCustomMapping(base, delta);\n\t}\n\n\tgetName(): string {\n\t\treturn 'keyboard';\n\t}\n\n\tprivate getAxisValue(negativeKey: string, positiveKey: string): number {\n\t\treturn (this.isKeyPressed(positiveKey) ? 1 : 0) - (this.isKeyPressed(negativeKey) ? 1 : 0);\n\t}\n\n\tisConnected(): boolean {\n\t\treturn true;\n\t}\n}\n","import { InputProvider, AnalogState, ButtonState, InputGamepad } from './input';\n\nexport class GamepadProvider implements InputProvider {\n\tprivate gamepadIndex: number;\n\tprivate connected: boolean = false;\n\n\tprivate buttonStates: Record<number, ButtonState> = {};\n\tprivate analogStates: Record<number, AnalogState> = {};\n\n\tprivate onConnected = (e: GamepadEvent) => {\n\t\tif (e.gamepad.index === this.gamepadIndex) {\n\t\t\tthis.connected = true;\n\t\t}\n\t};\n\tprivate onDisconnected = (e: GamepadEvent) => {\n\t\tif (e.gamepad.index === this.gamepadIndex) {\n\t\t\tthis.connected = false;\n\t\t}\n\t};\n\n\tconstructor(gamepadIndex: number) {\n\t\tthis.gamepadIndex = gamepadIndex;\n\t\twindow.addEventListener('gamepadconnected', this.onConnected);\n\t\twindow.addEventListener('gamepaddisconnected', this.onDisconnected);\n\t}\n\n\t/** Removes event listeners and cleans up state. */\n\tdispose(): void {\n\t\twindow.removeEventListener('gamepadconnected', this.onConnected);\n\t\twindow.removeEventListener('gamepaddisconnected', this.onDisconnected);\n\t\tthis.buttonStates = {};\n\t\tthis.analogStates = {};\n\t}\n\n\tprivate handleButtonState(index: number, gamepad: Gamepad, delta: number): ButtonState {\n\t\tlet state = this.buttonStates[index];\n\t\tif (!state) {\n\t\t\tstate = { pressed: false, released: false, held: 0 };\n\t\t\tthis.buttonStates[index] = state;\n\t\t}\n\n\t\tconst isPressed = gamepad.buttons[index].pressed;\n\t\tstate.pressed = isPressed && state.held === 0;\n\t\tstate.released = !isPressed && state.held > 0;\n\t\tstate.held = isPressed ? state.held + delta : 0;\n\n\t\treturn state;\n\t}\n\n\tprivate handleAnalogState(index: number, gamepad: Gamepad, delta: number): AnalogState {\n\t\tlet state = this.analogStates[index];\n\t\tif (!state) {\n\t\t\tstate = { value: 0, held: 0 };\n\t\t\tthis.analogStates[index] = state;\n\t\t}\n\n\t\tstate.value = gamepad.axes[index];\n\t\tstate.held = state.value !== 0 ? state.held + delta : 0;\n\n\t\treturn state;\n\t}\n\n\tgetInput(delta: number): Partial<InputGamepad> {\n\t\tconst gamepad = navigator.getGamepads()[this.gamepadIndex];\n\t\tif (!gamepad) return {};\n\n\t\treturn {\n\t\t\tbuttons: {\n\t\t\t\tA: this.handleButtonState(0, gamepad, delta),\n\t\t\t\tB: this.handleButtonState(1, gamepad, delta),\n\t\t\t\tX: this.handleButtonState(2, gamepad, delta),\n\t\t\t\tY: this.handleButtonState(3, gamepad, delta),\n\t\t\t\tStart: this.handleButtonState(9, gamepad, delta),\n\t\t\t\tSelect: this.handleButtonState(8, gamepad, delta),\n\t\t\t\tL: this.handleButtonState(4, gamepad, delta),\n\t\t\t\tR: this.handleButtonState(5, gamepad, delta),\n\t\t\t},\n\t\t\tdirections: {\n\t\t\t\tUp: this.handleButtonState(12, gamepad, delta),\n\t\t\t\tDown: this.handleButtonState(13, gamepad, delta),\n\t\t\t\tLeft: this.handleButtonState(14, gamepad, delta),\n\t\t\t\tRight: this.handleButtonState(15, gamepad, delta),\n\t\t\t},\n\t\taxes: {\n\t\t\tHorizontal: this.handleAnalogState(0, gamepad, delta),\n\t\t\tVertical: this.handleAnalogState(1, gamepad, delta),\n\t\t\tSecondaryHorizontal: this.handleAnalogState(2, gamepad, delta),\n\t\t\tSecondaryVertical: this.handleAnalogState(3, gamepad, delta),\n\t\t},\n\t\t\tshoulders: {\n\t\t\t\tLTrigger: this.handleButtonState(6, gamepad, delta),\n\t\t\t\tRTrigger: this.handleButtonState(7, gamepad, delta),\n\t\t\t}\n\t\t};\n\t}\n\n\tgetName(): string {\n\t\treturn `gamepad-${this.gamepadIndex + 1}`;\n\t}\n\n\tisConnected(): boolean {\n\t\treturn this.connected;\n\t}\n} ","import { InputProvider, AnalogState, ButtonState, InputGamepad } from './input';\nimport { compileMapping, mergeAnalogState, mergeButtonState, PropertyPath } from './input-state';\nimport { MouseConfig } from '../game/game-interfaces';\n\nconst DEFAULT_SENSITIVITY = 0.002;\n\n/**\n * Maps mouse movement and button input to the InputGamepad interface.\n *\n * Default mapping:\n * - Mouse movement X/Y -> axes.SecondaryHorizontal / axes.SecondaryVertical\n * - Left click -> shoulders.LTrigger\n * - Right click -> shoulders.RTrigger\n *\n * Supports optional pointer lock for FPS-style camera control.\n */\nexport class MouseProvider implements InputProvider {\n\tprivate buttonStates = new Map<number, ButtonState>();\n\tprivate analogStates = new Map<string, AnalogState>();\n\tprivate compiledMapping: Map<string, PropertyPath[]>;\n\n\tprivate movementX = 0;\n\tprivate movementY = 0;\n\n\tprivate pointerX = 0;\n\tprivate pointerY = 0;\n\n\tprivate mouseButtonDown = new Set<number>();\n\n\tprivate sensitivity: number;\n\tprivate usePointerLock: boolean;\n\tprivate isLocked = false;\n\n\tprivate targetElement: HTMLElement;\n\n\t// --- bound event handlers ---\n\n\tprivate onMouseMove = (e: MouseEvent) => {\n\t\tthis.movementX += e.movementX;\n\t\tthis.movementY += e.movementY;\n\t\tthis.pointerX = e.clientX / window.innerWidth;\n\t\tthis.pointerY = e.clientY / window.innerHeight;\n\t};\n\n\tprivate onMouseDown = (e: MouseEvent) => {\n\t\tconst target = e.target as Element | null;\n\t\tconst isGameCanvas = target instanceof HTMLCanvasElement\n\t\t\t&& this.targetElement.contains(target);\n\n\t\tif (!isGameCanvas) return;\n\n\t\tthis.mouseButtonDown.add(e.button);\n\t\tif (this.usePointerLock && !this.isLocked) {\n\t\t\tthis.targetElement.requestPointerLock();\n\t\t}\n\t};\n\n\tprivate onMouseUp = (e: MouseEvent) => {\n\t\tthis.mouseButtonDown.delete(e.button);\n\t};\n\n\tprivate onContextMenu = (e: MouseEvent) => {\n\t\te.preventDefault();\n\t};\n\n\tprivate onPointerLockChange = () => {\n\t\tthis.isLocked = document.pointerLockElement === this.targetElement;\n\t};\n\n\tconstructor(config?: MouseConfig, targetElement?: HTMLElement) {\n\t\tthis.sensitivity = config?.sensitivity ?? DEFAULT_SENSITIVITY;\n\t\tthis.usePointerLock = config?.pointerLock ?? false;\n\t\tthis.compiledMapping = compileMapping(config?.mapping ?? null);\n\n\t\tthis.targetElement = targetElement ?? document.body;\n\n\t\tthis.targetElement.addEventListener('mousemove', this.onMouseMove);\n\t\tthis.targetElement.addEventListener('mousedown', this.onMouseDown);\n\t\tthis.targetElement.addEventListener('mouseup', this.onMouseUp);\n\t\tthis.targetElement.addEventListener('contextmenu', this.onContextMenu);\n\n\t\tif (this.usePointerLock) {\n\t\t\tdocument.addEventListener('pointerlockchange', this.onPointerLockChange);\n\t\t}\n\t}\n\n\t/** Removes all event listeners and cleans up state. */\n\tdispose(): void {\n\t\tthis.targetElement.removeEventListener('mousemove', this.onMouseMove);\n\t\tthis.targetElement.removeEventListener('mousedown', this.onMouseDown);\n\t\tthis.targetElement.removeEventListener('mouseup', this.onMouseUp);\n\t\tthis.targetElement.removeEventListener('contextmenu', this.onContextMenu);\n\t\tdocument.removeEventListener('pointerlockchange', this.onPointerLockChange);\n\n\t\tif (this.isLocked) {\n\t\t\tdocument.exitPointerLock();\n\t\t}\n\n\t\tthis.buttonStates.clear();\n\t\tthis.analogStates.clear();\n\t\tthis.mouseButtonDown.clear();\n\t\tthis.movementX = 0;\n\t\tthis.movementY = 0;\n\t}\n\n\t// --- state helpers ---\n\n\tprivate handleMouseButton(button: number, delta: number): ButtonState {\n\t\tlet state = this.buttonStates.get(button);\n\t\tif (!state) {\n\t\t\tstate = { pressed: false, released: false, held: 0 };\n\t\t\tthis.buttonStates.set(button, state);\n\t\t}\n\n\t\tconst isPressed = this.mouseButtonDown.has(button);\n\t\tstate.pressed = isPressed && state.held === 0;\n\t\tstate.released = !isPressed && state.held > 0;\n\t\tstate.held = isPressed ? state.held + delta : 0;\n\n\t\treturn state;\n\t}\n\n\tprivate handleMovementAxis(axis: 'x' | 'y', delta: number): AnalogState {\n\t\tlet state = this.analogStates.get(axis);\n\t\tif (!state) {\n\t\t\tstate = { value: 0, held: 0 };\n\t\t\tthis.analogStates.set(axis, state);\n\t\t}\n\n\t\tconst raw = axis === 'x' ? this.movementX : this.movementY;\n\t\tstate.value = Math.max(-1, Math.min(1, raw * this.sensitivity));\n\t\tstate.held = state.value !== 0 ? state.held + delta : 0;\n\n\t\treturn state;\n\t}\n\n\t// --- custom mapping ---\n\n\t/**\n\t * Applies custom MouseMapping on top of the base input.\n\t * Mouse action keys: 'leftButton', 'rightButton', 'middleButton', 'moveX', 'moveY'.\n\t */\n\tprivate applyCustomMapping(input: Partial<InputGamepad>, delta: number): Partial<InputGamepad> {\n\t\tif (this.compiledMapping.size === 0) return input;\n\n\t\tconst axisValues = new Map<string, number>();\n\n\t\tconst mouseActions: Record<string, () => ButtonState | null> = {\n\t\t\t'leftbutton': () => this.handleMouseButton(0, delta),\n\t\t\t'rightbutton': () => this.handleMouseButton(2, delta),\n\t\t\t'middlebutton': () => this.handleMouseButton(1, delta),\n\t\t};\n\n\t\tfor (const [key, paths] of this.compiledMapping.entries()) {\n\t\t\tconst lowerKey = key.toLowerCase();\n\n\t\t\tfor (const path of paths) {\n\t\t\t\tif (path.category === 'axes') {\n\t\t\t\t\tif (!axisValues.has(path.property)) {\n\t\t\t\t\t\taxisValues.set(path.property, 0);\n\t\t\t\t\t}\n\t\t\t\t\tif (lowerKey === 'movex') {\n\t\t\t\t\t\taxisValues.set(\n\t\t\t\t\t\t\tpath.property,\n\t\t\t\t\t\t\taxisValues.get(path.property)! + Math.max(-1, Math.min(1, this.movementX * this.sensitivity)) * path.axisDirection!\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (lowerKey === 'movey') {\n\t\t\t\t\t\taxisValues.set(\n\t\t\t\t\t\t\tpath.property,\n\t\t\t\t\t\t\taxisValues.get(path.property)! + Math.max(-1, Math.min(1, this.movementY * this.sensitivity)) * path.axisDirection!\n\t\t\t\t\t\t);\n\t\t\t\t} else if (lowerKey in mouseActions && this.mouseButtonDown.has(this.buttonIndexForAction(lowerKey))) {\n\t\t\t\t\taxisValues.set(path.property, axisValues.get(path.property)! + path.axisDirection!);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst buttonAction = mouseActions[lowerKey];\n\t\t\t\t\tif (buttonAction) {\n\t\t\t\t\t\tconst buttonState = buttonAction();\n\t\t\t\t\t\tif (buttonState) {\n\t\t\t\t\t\t\tconst group = ((input as any)[path.category] ??= {});\n\t\t\t\t\t\t\tgroup[path.property] = mergeButtonState(group[path.property], buttonState);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (axisValues.size > 0) {\n\t\t\tif (!input.axes) input.axes = {} as any;\n\t\t\tfor (const [axisName, value] of axisValues.entries()) {\n\t\t\t\tconst stateKey = `custom:${axisName}`;\n\t\t\t\tlet state = this.analogStates.get(stateKey);\n\t\t\t\tif (!state) {\n\t\t\t\t\tstate = { value: 0, held: 0 };\n\t\t\t\t\tthis.analogStates.set(stateKey, state);\n\t\t\t\t}\n\t\t\t\tstate.value = Math.max(-1, Math.min(1, value));\n\t\t\t\tstate.held = value !== 0 ? state.held + delta : 0;\n\t\t\t\t(input.axes as any)[axisName] = mergeAnalogState((input.axes as any)[axisName], state);\n\t\t\t}\n\t\t}\n\n\t\treturn input;\n\t}\n\n\tprivate buttonIndexForAction(action: string): number {\n\t\tswitch (action) {\n\t\t\tcase 'leftbutton': return 0;\n\t\t\tcase 'middlebutton': return 1;\n\t\t\tcase 'rightbutton': return 2;\n\t\t\tdefault: return -1;\n\t\t}\n\t}\n\n\t// --- InputProvider interface ---\n\n\tgetInput(delta: number): Partial<InputGamepad> {\n\t\tconst input: Partial<InputGamepad> = {\n\t\t\taxes: {\n\t\t\t\tHorizontal: { value: 0, held: 0 },\n\t\t\t\tVertical: { value: 0, held: 0 },\n\t\t\t\tSecondaryHorizontal: this.handleMovementAxis('x', delta),\n\t\t\t\tSecondaryVertical: this.handleMovementAxis('y', delta),\n\t\t\t},\n\t\t\tshoulders: {\n\t\t\t\tLTrigger: this.handleMouseButton(0, delta),\n\t\t\t\tRTrigger: this.handleMouseButton(2, delta),\n\t\t\t},\n\t\t\tpointer: {\n\t\t\t\tx: this.pointerX,\n\t\t\t\ty: this.pointerY,\n\t\t\t},\n\t\t};\n\n\t\t// Reset accumulated movement for this frame\n\t\tthis.movementX = 0;\n\t\tthis.movementY = 0;\n\n\t\treturn this.applyCustomMapping(input, delta);\n\t}\n\n\tgetName(): string {\n\t\treturn 'mouse';\n\t}\n\n\tisConnected(): boolean {\n\t\treturn true;\n\t}\n}\n","import { InputProvider, InputGamepad, InputPlayerNumber, Inputs } from './input';\nimport { KeyboardProvider } from './keyboard-provider';\nimport { GamepadProvider } from './gamepad-provider';\nimport { MouseProvider } from './mouse-provider';\nimport { GameInputConfig, GameInputPlayerConfig } from '../game/game-interfaces';\nimport { mergeButtonState, mergeAnalogState } from './input-state';\n\ninterface PlayerEntry {\n\tplayer: InputPlayerNumber;\n\tconfig?: GameInputPlayerConfig;\n\tgamepadIndex: number;\n\tisP1: boolean;\n}\n\nexport class InputManager {\n\tprivate inputMap: Map<InputPlayerNumber, InputProvider[]> = new Map();\n\tprivate currentInputs: Inputs = {} as Inputs;\n\tprivate previousInputs: Inputs = {} as Inputs;\n\n\tconstructor(config?: GameInputConfig) {\n\t\tconst players = this.buildPlayerEntries(config);\n\n\t\tfor (const { player, config: playerConfig, gamepadIndex, isP1 } of players) {\n\t\t\tif (playerConfig?.key) {\n\t\t\t\tconst includeDefaultBase = playerConfig.includeDefaults ?? isP1;\n\t\t\t\tthis.addInputProvider(player, new KeyboardProvider(playerConfig.key, { includeDefaultBase }));\n\t\t\t} else if (isP1) {\n\t\t\t\tthis.addInputProvider(player, new KeyboardProvider());\n\t\t\t}\n\t\t\tif (playerConfig?.mouse) {\n\t\t\t\tthis.addInputProvider(player, new MouseProvider(playerConfig.mouse));\n\t\t\t}\n\t\t\tthis.addInputProvider(player, new GamepadProvider(gamepadIndex));\n\t\t}\n\t}\n\n\t/**\n\t * Reconfigure keyboard and mouse providers at runtime without affecting gamepad providers.\n\t * Disposes existing keyboard/mouse providers and creates new ones from the given config.\n\t */\n\tconfigure(config: GameInputConfig): void {\n\t\tconst players = this.buildPlayerEntries(config);\n\n\t\tfor (const { player, config: playerConfig, isP1 } of players) {\n\t\t\tconst providers = this.inputMap.get(player) ?? [];\n\n\t\t\t// Dispose and remove keyboard + mouse providers\n\t\t\tconst remaining = providers.filter(p => {\n\t\t\t\tif (p instanceof KeyboardProvider || p instanceof MouseProvider) {\n\t\t\t\t\tp.dispose();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t});\n\n\t\t\t// Create new keyboard provider and prepend before gamepad providers\n\t\t\tif (playerConfig?.key) {\n\t\t\t\tconst includeDefaultBase = playerConfig.includeDefaults ?? isP1;\n\t\t\t\tremaining.unshift(new KeyboardProvider(playerConfig.key, { includeDefaultBase }));\n\t\t\t} else if (isP1) {\n\t\t\t\tremaining.unshift(new KeyboardProvider());\n\t\t\t}\n\n\t\t\t// Create new mouse provider\n\t\t\tif (playerConfig?.mouse) {\n\t\t\t\tremaining.unshift(new MouseProvider(playerConfig.mouse));\n\t\t\t}\n\n\t\t\tthis.inputMap.set(player, remaining);\n\t\t}\n\t}\n\n\taddInputProvider(playerNumber: InputPlayerNumber, provider: InputProvider) {\n\t\tif (!this.inputMap.has(playerNumber)) {\n\t\t\tthis.inputMap.set(playerNumber, []);\n\t\t}\n\t\tthis.inputMap.get(playerNumber)?.push(provider);\n\t}\n\n\tgetInputs(delta: number): Inputs {\n\t\tconst inputs = {} as Inputs;\n\t\tthis.inputMap.forEach((providers, playerNumber) => {\n\t\t\tconst playerKey = `p${playerNumber}` as const;\n\n\t\t\tconst mergedInput = providers.reduce((acc, provider) => {\n\t\t\t\tconst input = provider.getInput(delta);\n\t\t\t\treturn this.mergeInputs(acc, input);\n\t\t\t}, {} as Partial<InputGamepad>);\n\n\t\t\tinputs[playerKey] = {\n\t\t\t\tplayerNumber: playerNumber as InputPlayerNumber,\n\t\t\t\t...mergedInput\n\t\t\t} as InputGamepad;\n\t\t});\n\t\treturn inputs;\n\t}\n\n\tprivate buildPlayerEntries(config?: GameInputConfig): PlayerEntry[] {\n\t\treturn [\n\t\t\t{ player: 1, config: config?.p1, gamepadIndex: 0, isP1: true },\n\t\t\t{ player: 2, config: config?.p2, gamepadIndex: 1, isP1: false },\n\t\t\t{ player: 3, config: config?.p3, gamepadIndex: 2, isP1: false },\n\t\t\t{ player: 4, config: config?.p4, gamepadIndex: 3, isP1: false },\n\t\t\t{ player: 5, config: config?.p5, gamepadIndex: 4, isP1: false },\n\t\t\t{ player: 6, config: config?.p6, gamepadIndex: 5, isP1: false },\n\t\t\t{ player: 7, config: config?.p7, gamepadIndex: 6, isP1: false },\n\t\t\t{ player: 8, config: config?.p8, gamepadIndex: 7, isP1: false },\n\t\t];\n\t}\n\n\tprivate mergeInputs(a: Partial<InputGamepad>, b: Partial<InputGamepad>): Partial<InputGamepad> {\n\t\treturn {\n\t\t\tbuttons: {\n\t\t\t\tA: mergeButtonState(a.buttons?.A, b.buttons?.A),\n\t\t\t\tB: mergeButtonState(a.buttons?.B, b.buttons?.B),\n\t\t\t\tX: mergeButtonState(a.buttons?.X, b.buttons?.X),\n\t\t\t\tY: mergeButtonState(a.buttons?.Y, b.buttons?.Y),\n\t\t\t\tStart: mergeButtonState(a.buttons?.Start, b.buttons?.Start),\n\t\t\t\tSelect: mergeButtonState(a.buttons?.Select, b.buttons?.Select),\n\t\t\t\tL: mergeButtonState(a.buttons?.L, b.buttons?.L),\n\t\t\t\tR: mergeButtonState(a.buttons?.R, b.buttons?.R),\n\t\t\t},\n\t\t\tdirections: {\n\t\t\t\tUp: mergeButtonState(a.directions?.Up, b.directions?.Up),\n\t\t\t\tDown: mergeButtonState(a.directions?.Down, b.directions?.Down),\n\t\t\t\tLeft: mergeButtonState(a.directions?.Left, b.directions?.Left),\n\t\t\t\tRight: mergeButtonState(a.directions?.Right, b.directions?.Right),\n\t\t\t},\n\t\t\taxes: {\n\t\t\t\tHorizontal: mergeAnalogState(a.axes?.Horizontal, b.axes?.Horizontal),\n\t\t\t\tVertical: mergeAnalogState(a.axes?.Vertical, b.axes?.Vertical),\n\t\t\t\tSecondaryHorizontal: mergeAnalogState(a.axes?.SecondaryHorizontal, b.axes?.SecondaryHorizontal),\n\t\t\t\tSecondaryVertical: mergeAnalogState(a.axes?.SecondaryVertical, b.axes?.SecondaryVertical),\n\t\t\t},\n\t\t\tshoulders: {\n\t\t\t\tLTrigger: mergeButtonState(a.shoulders?.LTrigger, b.shoulders?.LTrigger),\n\t\t\t\tRTrigger: mergeButtonState(a.shoulders?.RTrigger, b.shoulders?.RTrigger),\n\t\t\t},\n\t\t\tpointer: b.pointer ?? a.pointer,\n\t\t};\n\t}\n}\n","/**\n * This class is an alternative to {@link Clock} with a different API design and behavior.\n * The goal is to avoid the conceptual flaws that became apparent in `Clock` over time.\n *\n * - `Timer` has an `update()` method that updates its internal state. That makes it possible to\n * call `getDelta()` and `getElapsed()` multiple times per simulation step without getting different values.\n * - The class can make use of the Page Visibility API to avoid large time delta values when the app\n * is inactive (e.g. tab switched or browser hidden).\n *\n * ```js\n * const timer = new Timer();\n * timer.connect( document ); // use Page Visibility API\n * ```\n *\n * @three_import import { Timer } from 'three/addons/misc/Timer.js';\n */\nclass Timer {\n\tprotected _previousTime: number;\n\tprotected _currentTime: number;\n\tprotected _startTime: number;\n\tprotected _delta: number;\n\tprotected _elapsed: number;\n\tprotected _timescale: number;\n\tprotected _document: Document | null;\n\tprotected _pageVisibilityHandler: (() => void) | null;\n\n\t/**\n\t * Constructs a new timer.\n\t */\n\tconstructor() {\n\n\t\tthis._previousTime = 0;\n\t\tthis._currentTime = 0;\n\t\tthis._startTime = now();\n\n\t\tthis._delta = 0;\n\t\tthis._elapsed = 0;\n\n\t\tthis._timescale = 1;\n\n\t\tthis._document = null;\n\t\tthis._pageVisibilityHandler = null;\n\n\t}\n\n\t/**\n\t * Connect the timer to the given document.Calling this method is not mandatory to\n\t * use the timer but enables the usage of the Page Visibility API to avoid large time\n\t * delta values.\n\t *\n\t * @param {Document} document - The document.\n\t */\n\tconnect(document: Document): void {\n\n\t\tthis._document = document;\n\n\t\t// use Page Visibility API to avoid large time delta values\n\n\t\tif (document.hidden !== undefined) {\n\n\t\t\tthis._pageVisibilityHandler = handleVisibilityChange.bind(this);\n\n\t\t\tdocument.addEventListener('visibilitychange', this._pageVisibilityHandler, false);\n\n\t\t}\n\n\t}\n\n\t/**\n\t * Disconnects the timer from the DOM and also disables the usage of the Page Visibility API.\n\t */\n\tdisconnect(): void {\n\n\t\tif (this._pageVisibilityHandler !== null) {\n\n\t\t\tthis._document!.removeEventListener('visibilitychange', this._pageVisibilityHandler);\n\t\t\tthis._pageVisibilityHandler = null;\n\n\t\t}\n\n\t\tthis._document = null;\n\n\t}\n\n\t/**\n\t * Returns the time delta in seconds.\n\t *\n\t * @return {number} The time delta in second.\n\t */\n\tgetDelta(): number {\n\n\t\treturn this._delta / 1000;\n\n\t}\n\n\t/**\n\t * Returns the elapsed time in seconds.\n\t *\n\t * @return {number} The elapsed time in second.\n\t */\n\tgetElapsed(): number {\n\n\t\treturn this._elapsed / 1000;\n\n\t}\n\n\t/**\n\t * Returns the timescale.\n\t *\n\t * @return {number} The timescale.\n\t */\n\tgetTimescale(): number {\n\n\t\treturn this._timescale;\n\n\t}\n\n\t/**\n\t * Sets the given timescale which scale the time delta computation\n\t * in `update()`.\n\t *\n\t * @param {number} timescale - The timescale to set.\n\t * @return {Timer} A reference to this timer.\n\t */\n\tsetTimescale(timescale: number): Timer {\n\n\t\tthis._timescale = timescale;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Resets the time computation for the current simulation step.\n\t *\n\t * @return {Timer} A reference to this timer.\n\t */\n\treset(): Timer {\n\n\t\tthis._currentTime = now() - this._startTime;\n\n\t\treturn this;\n\n\t}\n\n\t/**\n\t * Can be used to free all internal resources. Usually called when\n\t * the timer instance isn't required anymore.\n\t */\n\tdispose(): void {\n\n\t\tthis.disconnect();\n\n\t}\n\n\t/**\n\t * Updates the internal state of the timer. This method should be called\n\t * once per simulation step and before you perform queries against the timer\n\t * (e.g. via `getDelta()`).\n\t *\n\t * @param {number} timestamp - The current time in milliseconds. Can be obtained\n\t * from the `requestAnimationFrame` callback argument. If not provided, the current\n\t * time will be determined with `performance.now`.\n\t * @return {Timer} A reference to this timer.\n\t */\n\tupdate(timestamp?: number): Timer {\n\n\t\tif (this._pageVisibilityHandler !== null && this._document!.hidden === true) {\n\n\t\t\tthis._delta = 0;\n\n\t\t} else {\n\n\t\t\tthis._previousTime = this._currentTime;\n\t\t\tthis._currentTime = (timestamp !== undefined ? timestamp : now()) - this._startTime;\n\n\t\t\tthis._delta = (this._currentTime - this._previousTime) * this._timescale;\n\t\t\tthis._elapsed += this._delta; // _elapsed is the accumulation of all previous deltas\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\n/**\n * A special version of a timer with a fixed time delta value.\n * Can be useful for testing and debugging purposes.\n *\n * @augments Timer\n */\nclass FixedTimer extends Timer {\n\n\t/**\n\t * Constructs a new timer.\n\t *\n\t * @param {number} [fps=60] - The fixed FPS of this timer.\n\t */\n\tconstructor(fps: number = 60) {\n\n\t\tsuper();\n\t\tthis._delta = (1 / fps) * 1000;\n\n\t}\n\n\tupdate(): FixedTimer {\n\n\t\tthis._elapsed += (this._delta * this._timescale); // _elapsed is the accumulation of all previous deltas\n\n\t\treturn this;\n\n\t}\n\n}\n\nfunction now(): number {\n\n\treturn performance.now();\n\n}\n\nfunction handleVisibilityChange(this: Timer): void {\n\n\tif (this._document!.hidden === false) this.reset();\n\n}\n\nexport { Timer, };","export const AspectRatio = {\n\tFourByThree: 4 / 3,\n\tSixteenByNine: 16 / 9,\n\tNineBySixteen: 9 / 16,\n\tTwentyOneByNine: 21 / 9,\n\tOneByOne: 1 / 1,\n} as const;\n\nexport type AspectRatioValue = (typeof AspectRatio)[keyof typeof AspectRatio] | number;\n\n/**\n * AspectRatioDelegate manages sizing a canvas to fit within a container\n * while preserving a target aspect ratio. It notifies a consumer via\n * onResize when the final width/height are applied so renderers/cameras\n * can update their viewports.\n */\nexport class AspectRatioDelegate {\n\tcontainer: HTMLElement;\n\tcanvas: HTMLCanvasElement;\n\taspectRatio: number;\n\tonResize?: (width: number, height: number) => void;\n\tprivate handleResizeBound: () => void;\n\tprivate resizeObserver: ResizeObserver | null = null;\n\n\tconstructor(params: {\n\t\tcontainer: HTMLElement;\n\t\tcanvas: HTMLCanvasElement;\n\t\taspectRatio: AspectRatioValue;\n\t\tonResize?: (width: number, height: number) => void;\n\t}) {\n\t\tthis.container = params.container;\n\t\tthis.canvas = params.canvas;\n\t\tthis.aspectRatio = typeof params.aspectRatio === 'number' ? params.aspectRatio : params.aspectRatio;\n\t\tthis.onResize = params.onResize;\n\t\tthis.handleResizeBound = this.apply.bind(this);\n\t}\n\n\t/** Attach window resize listener and apply once. */\n\tattach() {\n\t\twindow.addEventListener('resize', this.handleResizeBound);\n\t\tif (typeof ResizeObserver !== 'undefined') {\n\t\t\tthis.resizeObserver = new ResizeObserver(this.handleResizeBound);\n\t\t\tthis.resizeObserver.observe(this.container);\n\t\t}\n\t\tthis.apply();\n\t}\n\n\t/** Detach window resize listener. */\n\tdetach() {\n\t\twindow.removeEventListener('resize', this.handleResizeBound);\n\t\tthis.resizeObserver?.disconnect();\n\t\tthis.resizeObserver = null;\n\t}\n\n\t/** Compute the largest size that fits container while preserving aspect. */\n\tmeasure(): { width: number; height: number } {\n\t\tconst rect = this.container.getBoundingClientRect();\n\t\tconst measuredWidth = Math.round(rect.width || this.container.clientWidth || 0);\n\t\tconst measuredHeight = Math.round(rect.height || this.container.clientHeight || 0);\n\n\t\tif (measuredWidth > 0 && measuredHeight > 0) {\n\t\t\tconst containerRatio = measuredWidth / measuredHeight;\n\t\t\tif (containerRatio > this.aspectRatio) {\n\t\t\t\t// container is wider than target; limit by height\n\t\t\t\tconst height = measuredHeight;\n\t\t\t\tconst width = Math.round(height * this.aspectRatio);\n\t\t\t\treturn { width, height };\n\t\t\t}\n\n\t\t\t// container is taller/narrower; limit by width\n\t\t\tconst width = measuredWidth;\n\t\t\tconst height = Math.round(width / this.aspectRatio);\n\t\t\treturn { width, height };\n\t\t}\n\n\t\tif (measuredWidth > 0) {\n\t\t\tconst width = measuredWidth;\n\t\t\tconst height = Math.round(width / this.aspectRatio);\n\t\t\treturn { width, height };\n\t\t}\n\n\t\tif (measuredHeight > 0) {\n\t\t\tconst height = measuredHeight;\n\t\t\tconst width = Math.round(height * this.aspectRatio);\n\t\t\treturn { width, height };\n\t\t}\n\n\t\tconst width = window.innerWidth;\n\t\tconst height = Math.round(width / this.aspectRatio);\n\t\treturn { width, height };\n\t}\n\n\t/** Apply measured size to canvas and notify. */\n\tapply() {\n\t\tconst { width, height } = this.measure();\n\t\t// Apply CSS size; renderer will update internal size via onResize callback\n\t\tthis.canvas.style.width = `${width}px`;\n\t\tthis.canvas.style.height = `${height}px`;\n\t\tthis.onResize?.(width, height);\n\t}\n}\n","export interface ViewportSize {\n\twidth: number;\n\theight: number;\n}\n\nexport interface MobileDetectionOptions {\n\tviewportSize?: ViewportSize;\n\tallowViewportOnly?: boolean;\n}\n\nexport function isMobile(options: MobileDetectionOptions = {}) {\n\tif (typeof window === 'undefined' || typeof navigator === 'undefined') {\n\t\treturn false;\n\t}\n\n\tconst userAgent = navigator.userAgent;\n\tconst isMobileAgent = /android/i.test(userAgent) || /iPad|iPhone|iPod/.test(userAgent);\n\tconst isTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0;\n\tconst isCoarsePointer = typeof window.matchMedia === 'function'\n\t\t? window.matchMedia('(pointer: coarse)').matches\n\t\t: false;\n\tconst viewportWidth = options.viewportSize?.width ?? window.innerWidth ?? 0;\n\tconst viewportHeight = options.viewportSize?.height ?? window.innerHeight ?? 0;\n\tconst largestViewportEdge = Math.max(viewportWidth, viewportHeight);\n\tconst isSmallViewport = largestViewportEdge === 0 || largestViewportEdge <= 1024;\n\n\tif (options.allowViewportOnly && options.viewportSize) {\n\t\treturn isSmallViewport;\n\t}\n\n\treturn isMobileAgent || ((isTouch || isCoarsePointer) && isSmallViewport);\n}\n","export type RetroResolution = { key: string; width: number; height: number; notes?: string };\n\nexport type RetroPreset = {\n\tdisplayAspect: number;\n\tresolutions: RetroResolution[];\n};\n\n/**\n * Retro, console, and device display presets.\n * displayAspect represents the intended display aspect (letterboxing target),\n * not necessarily the raw pixel aspect of internal buffers.\n */\nconst RetroPresets: Record<string, RetroPreset> = {\n\tNES: {\n\t\tdisplayAspect: 4 / 3,\n\t\tresolutions: [\n\t\t\t{ key: '256x240', width: 256, height: 240, notes: 'Standard NTSC; effective 240p.' },\n\t\t],\n\t},\n\tSNES: {\n\t\tdisplayAspect: 4 / 3,\n\t\tresolutions: [\n\t\t\t{ key: '256x224', width: 256, height: 224, notes: 'Common 240p-equivalent mode.' },\n\t\t\t{ key: '512x448', width: 512, height: 448, notes: 'Hi-res interlaced (480i).' },\n\t\t],\n\t},\n\tN64: {\n\t\tdisplayAspect: 4 / 3,\n\t\tresolutions: [\n\t\t\t{ key: '320x240', width: 320, height: 240, notes: 'Common 240p mode.' },\n\t\t\t{ key: '640x480', width: 640, height: 480, notes: 'Higher resolution (480i).' },\n\t\t],\n\t},\n\tPS1: {\n\t\tdisplayAspect: 4 / 3,\n\t\tresolutions: [\n\t\t\t{ key: '320x240', width: 320, height: 240, notes: 'Progressive 240p common.' },\n\t\t\t{ key: '640x480', width: 640, height: 480, notes: 'Interlaced 480i for higher detail.' },\n\t\t],\n\t},\n\tPS2: {\n\t\tdisplayAspect: 4 / 3,\n\t\tresolutions: [\n\t\t\t{ key: '640x480', width: 640, height: 480, notes: '480i/480p baseline.' },\n\t\t\t{ key: '720x480', width: 720, height: 480, notes: '480p (widescreen capable in some titles).' },\n\t\t\t{ key: '1280x720', width: 1280, height: 720, notes: '720p (select titles).' },\n\t\t],\n\t},\n\tPS5: {\n\t\tdisplayAspect: 16 / 9,\n\t\tresolutions: [\n\t\t\t{ key: '720x480', width: 720, height: 480, notes: 'Legacy compatibility.' },\n\t\t\t{ key: '1280x720', width: 1280, height: 720, notes: '720p.' },\n\t\t\t{ key: '1920x1080', width: 1920, height: 1080, notes: '1080p.' },\n\t\t\t{ key: '2560x1440', width: 2560, height: 1440, notes: '1440p.' },\n\t\t\t{ key: '3840x2160', width: 3840, height: 2160, notes: '4K (up to 120Hz).' },\n\t\t\t{ key: '7680x4320', width: 7680, height: 4320, notes: '8K (limited).' },\n\t\t],\n\t},\n\tXboxOne: {\n\t\tdisplayAspect: 16 / 9,\n\t\tresolutions: [\n\t\t\t{ key: '1280x720', width: 1280, height: 720, notes: '720p (original).' },\n\t\t\t{ key: '1920x1080', width: 1920, height: 1080, notes: '1080p (original).' },\n\t\t\t{ key: '3840x2160', width: 3840, height: 2160, notes: '4K UHD (S/X models).' },\n\t\t],\n\t},\n\tMobilePortrait: {\n\t\tdisplayAspect: 9 / 16,\n\t\tresolutions: [\n\t\t\t{ key: '360x640', width: 360, height: 640, notes: 'Low-density phone portrait baseline.' },\n\t\t\t{ key: '720x1280', width: 720, height: 1280, notes: 'HD phone portrait.' },\n\t\t\t{ key: '1080x1920', width: 1080, height: 1920, notes: 'Full HD phone portrait.' },\n\t\t],\n\t},\n};\n\nexport type RetroPresetKey = keyof typeof RetroPresets;\n\nexport function getDisplayAspect(preset: RetroPresetKey): number {\n\treturn RetroPresets[preset].displayAspect;\n}\n\nexport function getPresetResolution(preset: RetroPresetKey, key?: string): RetroResolution | undefined {\n\tconst list = RetroPresets[preset]?.resolutions || [];\n\tif (!key) return list[0];\n\tconst normalized = key.toLowerCase().replace(/\\s+/g, '').replace('×', 'x');\n\treturn list.find(r => r.key.toLowerCase() === normalized);\n}\n\nexport function parseResolution(text: string): { width: number; height: number } | null {\n\tif (!text) return null;\n\tconst normalized = String(text).toLowerCase().trim().replace(/\\s+/g, '').replace('×', 'x');\n\tconst match = normalized.match(/^(\\d+)x(\\d+)$/);\n\tif (!match) return null;\n\tconst width = parseInt(match[1], 10);\n\tconst height = parseInt(match[2], 10);\n\tif (!Number.isFinite(width) || !Number.isFinite(height)) return null;\n\treturn { width, height };\n}\n\n","import { StageInterface } from \"../types\";\nimport { GameInputConfig } from \"./game-interfaces\";\nimport { AspectRatio, AspectRatioValue } from \"../device/aspect-ratio\";\nimport { isMobile, type ViewportSize } from \"../device/mobile\";\nimport { getDisplayAspect, getPresetResolution, parseResolution, RetroPresetKey } from \"./game-retro-resolutions\";\n\nexport type ResolutionInput = string | { width: number; height: number };\nexport type DeviceProfile = 'auto' | 'desktop' | 'mobile';\n\nexport interface ResolveGameConfigRuntime {\n\tdeviceProfile?: DeviceProfile;\n\tviewportSize?: ViewportSize;\n}\n\nexport type GameDeviceConfig = Partial<{\n\t/** numeric value or key in AspectRatio */\n\taspectRatio: AspectRatioValue | keyof typeof AspectRatio;\n\t/** console/display preset to derive aspect ratio */\n\tpreset: RetroPresetKey;\n\t/** lock internal render buffer for this device profile */\n\tresolution: ResolutionInput;\n}>;\n\nexport type GameConfigLike = Partial<{\n\tid: string;\n\tglobals: Record<string, any>;\n\tstages: StageInterface[];\n\tdebug: boolean;\n\ttime: number;\n\tinput: GameInputConfig;\n\t/** numeric value or key in AspectRatio */\n\taspectRatio: AspectRatioValue | keyof typeof AspectRatio;\n\t/** console/display preset to derive aspect ratio */\n\tpreset: RetroPresetKey;\n\t/** lock internal render buffer to this desktop/default resolution */\n\tresolution: ResolutionInput;\n\t/** mobile-specific aspect/preset/resolution overrides */\n\tmobile: GameDeviceConfig;\n\tfullscreen: boolean;\n\t/** CSS background value for document body */\n\tbodyBackground: string;\n\t/** existing container by reference */\n\tcontainer: HTMLElement;\n\t/** create/find container by id */\n\tcontainerId: string;\n\t/** optional canvas if caller wants to manage it */\n\tcanvas: HTMLCanvasElement;\n}>;\n\nexport class GameConfig {\n\tconstructor(\n\t\tpublic id: string,\n\t\tpublic globals: Record<string, any>,\n\t\tpublic stages: StageInterface[],\n\t\tpublic debug: boolean,\n\t\tpublic time: number,\n\t\tpublic input: GameInputConfig | undefined,\n\t\tpublic aspectRatio: number,\n\t\tpublic internalResolution: { width: number; height: number } | undefined,\n\t\tpublic fullscreen: boolean,\n\t\tpublic bodyBackground: string | undefined,\n\t\tpublic container: HTMLElement,\n\t\tpublic containerId?: string,\n\t\tpublic canvas?: HTMLCanvasElement,\n\t) { }\n}\n\nfunction usesMobileProfile(runtime: ResolveGameConfigRuntime = {}): boolean {\n\tif (runtime.deviceProfile === 'mobile') {\n\t\treturn true;\n\t}\n\n\tif (runtime.deviceProfile === 'desktop') {\n\t\treturn false;\n\t}\n\n\tif (runtime.viewportSize) {\n\t\treturn isMobile({\n\t\t\tviewportSize: runtime.viewportSize,\n\t\t\tallowViewportOnly: true,\n\t\t});\n\t}\n\n\treturn isMobile();\n}\n\nfunction ensureContainer(containerId?: string, existing?: HTMLElement | null): HTMLElement {\n\tif (existing) return existing;\n\tif (containerId) {\n\t\tconst found = document.getElementById(containerId);\n\t\tif (found) return found;\n\t}\n\tconst id = containerId || 'zylem-root';\n\tconst el = document.createElement('main');\n\tel.setAttribute('id', id);\n\tel.style.position = 'relative';\n\tel.style.width = '100%';\n\tel.style.height = '100%';\n\tdocument.body.appendChild(el);\n\treturn el;\n}\n\nfunction createDefaultGameConfig(base?: Partial<Pick<GameConfig, 'id' | 'debug' | 'time' | 'input'>> & { stages?: StageInterface[]; globals?: Record<string, any> }): GameConfig {\n\tconst id = base?.id ?? 'zylem';\n\tconst container = ensureContainer(id);\n\treturn new GameConfig(\n\t\tid,\n\t\t(base?.globals ?? {}) as Record<string, any>,\n\t\t(base?.stages ?? []) as StageInterface[],\n\t\tBoolean(base?.debug),\n\t\tbase?.time ?? 0,\n\t\tbase?.input,\n\t\tAspectRatio.SixteenByNine,\n\t\tundefined,\n\t\ttrue,\n\t\t'#000000',\n\t\tcontainer,\n\t\tid,\n\t\tundefined,\n\t);\n}\n\nconst DEFAULT_MOBILE_BASE_EDGE = 360;\n\nfunction normalizeResolutionInput(\n\tinput?: ResolutionInput,\n\tpreset?: RetroPresetKey,\n): { width: number; height: number } | undefined {\n\tif (!input) return undefined;\n\n\tif (typeof input === 'string') {\n\t\tconst parsed = parseResolution(input);\n\t\tif (parsed) return parsed;\n\n\t\tif (preset) {\n\t\t\tconst res = getPresetResolution(preset, input);\n\t\t\tif (res) {\n\t\t\t\treturn { width: res.width, height: res.height };\n\t\t\t}\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tconst width = (input as any).width;\n\tconst height = (input as any).height;\n\tif (Number.isFinite(width) && Number.isFinite(height)) {\n\t\treturn { width, height };\n\t}\n\n\treturn undefined;\n}\n\nfunction resolveAspectRatioValue(\n\taspectInput: GameDeviceConfig['aspectRatio'],\n\tpreset: RetroPresetKey | undefined,\n\tfallbackAspect: number,\n\tfallbackResolution?: { width: number; height: number },\n): number {\n\tif (typeof aspectInput === 'number') {\n\t\treturn aspectInput;\n\t}\n\n\tif (typeof aspectInput === 'string') {\n\t\treturn (AspectRatio as any)[aspectInput] ?? fallbackAspect;\n\t}\n\n\tif (preset) {\n\t\ttry {\n\t\t\treturn getDisplayAspect(preset) || fallbackAspect;\n\t\t} catch {\n\t\t\treturn fallbackAspect;\n\t\t}\n\t}\n\n\tif (fallbackResolution) {\n\t\treturn fallbackResolution.width / fallbackResolution.height;\n\t}\n\n\treturn fallbackAspect;\n}\n\nfunction createDefaultMobileResolution(aspectRatio: number): { width: number; height: number } {\n\tconst safeAspect = Number.isFinite(aspectRatio) && aspectRatio > 0\n\t\t? aspectRatio\n\t\t: AspectRatio.SixteenByNine;\n\n\tif (safeAspect >= 1) {\n\t\tconst height = DEFAULT_MOBILE_BASE_EDGE;\n\t\tconst width = Math.round(height * safeAspect);\n\t\treturn { width, height };\n\t}\n\n\tconst width = DEFAULT_MOBILE_BASE_EDGE;\n\tconst height = Math.round(width / safeAspect);\n\treturn { width, height };\n}\n\nexport function resolveGameConfig(\n\tuser?: GameConfigLike,\n\truntime: ResolveGameConfigRuntime = {},\n): GameConfig {\n\tconst defaults = createDefaultGameConfig({\n\t\tid: user?.id ?? 'zylem',\n\t\tdebug: Boolean(user?.debug),\n\t\ttime: (user?.time as number) ?? 0,\n\t\tinput: user?.input,\n\t\tstages: (user?.stages as StageInterface[]) ?? [],\n\t\tglobals: (user?.globals as Record<string, any>) ?? {},\n\t});\n\n\t// Resolve container\n\tconst containerId = (user?.containerId as string) ?? defaults.containerId;\n\tconst container = ensureContainer(containerId, user?.container ?? null);\n\tconst mobileConfig = user?.mobile;\n\tconst useMobileProfile = usesMobileProfile(runtime);\n\tconst activePreset = useMobileProfile\n\t\t? mobileConfig?.preset ?? user?.preset\n\t\t: user?.preset;\n\tconst desktopResolution = normalizeResolutionInput(user?.resolution, user?.preset);\n\tconst mobileResolution = normalizeResolutionInput(\n\t\tmobileConfig?.resolution,\n\t\tmobileConfig?.preset ?? user?.preset,\n\t);\n\tconst aspectFallbackResolution = useMobileProfile\n\t\t? mobileResolution ?? desktopResolution\n\t\t: desktopResolution;\n\tconst activeAspectInput = useMobileProfile\n\t\t? mobileConfig?.aspectRatio ?? user?.aspectRatio\n\t\t: user?.aspectRatio;\n\tconst aspectRatio = resolveAspectRatioValue(\n\t\tactiveAspectInput,\n\t\tactivePreset,\n\t\tdefaults.aspectRatio,\n\t\taspectFallbackResolution,\n\t);\n\tconst internalResolution = useMobileProfile\n\t\t? mobileResolution ?? createDefaultMobileResolution(aspectRatio)\n\t\t: desktopResolution;\n\n\tconst fullscreen = (user?.fullscreen as boolean) ?? defaults.fullscreen;\n\tconst bodyBackground = (user?.bodyBackground as string) ?? defaults.bodyBackground;\n\n\t// Prefer provided canvas if any\n\tconst canvas = user?.canvas ?? undefined;\n\n\treturn new GameConfig(\n\t\t(user?.id as string) ?? defaults.id,\n\t\t(user?.globals as Record<string, any>) ?? defaults.globals,\n\t\t(user?.stages as StageInterface[]) ?? defaults.stages,\n\t\tBoolean(user?.debug ?? defaults.debug),\n\t\t(user?.time as number) ?? defaults.time,\n\t\tuser?.input ?? defaults.input,\n\t\taspectRatio,\n\t\tinternalResolution,\n\t\tfullscreen,\n\t\tbodyBackground,\n\t\tcontainer,\n\t\tcontainerId,\n\t\tcanvas,\n\t);\n}\n\n/**\n * Factory for authoring configuration objects in user code.\n * Returns a plain object that can be passed to `game(...)`.\n */\nexport function gameConfig(config: GameConfigLike): GameConfigLike {\n\treturn { ...config };\n}\n","import { AspectRatioDelegate, AspectRatioValue } from '../device/aspect-ratio';\n\nexport interface GameCanvasOptions {\n\tid: string;\n\tcontainer?: HTMLElement;\n\tcontainerId?: string;\n\tcanvas?: HTMLCanvasElement;\n\tbodyBackground?: string;\n\tfullscreen?: boolean;\n\taspectRatio: AspectRatioValue | number;\n}\n\n/**\n * GameCanvas is a DOM delegate that owns:\n * - container lookup/creation and styling (including fullscreen centering)\n * - body background application\n * - canvas mounting into container\n * - aspect ratio sizing via AspectRatioDelegate\n */\nexport class GameCanvas {\n\tid: string;\n\tcontainer!: HTMLElement;\n\tcanvas!: HTMLCanvasElement;\n\tbodyBackground?: string;\n\tfullscreen: boolean;\n\taspectRatio: number;\n\tprivate ratioDelegate: AspectRatioDelegate | null = null;\n\n\tconstructor(options: GameCanvasOptions) {\n\t\tthis.id = options.id;\n\t\tthis.container = this.ensureContainer(options.containerId ?? options.id, options.container);\n\t\tthis.canvas = options.canvas ?? document.createElement('canvas');\n\t\tthis.bodyBackground = options.bodyBackground;\n\t\tthis.fullscreen = Boolean(options.fullscreen);\n\t\tthis.aspectRatio = typeof options.aspectRatio === 'number' ? options.aspectRatio : options.aspectRatio;\n\t}\n\n\tapplyBodyBackground() {\n\t\tif (this.bodyBackground) {\n\t\t\tdocument.body.style.background = this.bodyBackground;\n\t\t}\n\t}\n\n\tmountCanvas() {\n\t\twhile (this.container.firstChild) {\n\t\t\tthis.container.removeChild(this.container.firstChild);\n\t\t}\n\t\tthis.container.appendChild(this.canvas);\n\t}\n\n\tmountRenderer(rendererDom: HTMLCanvasElement, onResize: (width: number, height: number) => void) {\n\t\twhile (this.container.firstChild) {\n\t\t\tthis.container.removeChild(this.container.firstChild);\n\t\t}\n\t\tthis.container.appendChild(rendererDom);\n\t\tthis.canvas = rendererDom;\n\t\tthis.attachAspectRatio(onResize);\n\t}\n\n\tcenterIfFullscreen() {\n\t\tif (!this.fullscreen) return;\n\t\tconst style = this.container.style;\n\t\tstyle.display = 'flex';\n\t\tstyle.alignItems = 'center';\n\t\tstyle.justifyContent = 'center';\n\t\tstyle.position = 'relative';\n\t\tstyle.inset = '0';\n\t}\n\n\tattachAspectRatio(onResize: (width: number, height: number) => void) {\n\t\tif (!this.ratioDelegate) {\n\t\t\tthis.ratioDelegate = new AspectRatioDelegate({\n\t\t\t\tcontainer: this.container,\n\t\t\t\tcanvas: this.canvas,\n\t\t\t\taspectRatio: this.aspectRatio,\n\t\t\t\tonResize\n\t\t\t});\n\t\t\tthis.ratioDelegate.attach();\n\t\t} else {\n\t\t\tthis.ratioDelegate.canvas = this.canvas;\n\t\t\tthis.ratioDelegate.onResize = onResize;\n\t\t\tthis.ratioDelegate.aspectRatio = this.aspectRatio;\n\t\t\tthis.ratioDelegate.apply();\n\t\t}\n\t}\n\n\tsetAspectRatio(aspectRatio: number): void {\n\t\tthis.aspectRatio = aspectRatio;\n\t\tif (this.ratioDelegate) {\n\t\t\tthis.ratioDelegate.aspectRatio = aspectRatio;\n\t\t\tthis.ratioDelegate.apply();\n\t\t}\n\t}\n\n\treapplyLayout(): void {\n\t\tthis.ratioDelegate?.apply();\n\t}\n\n\tdestroy() {\n\t\tthis.ratioDelegate?.detach();\n\t\tthis.ratioDelegate = null;\n\t}\n\n\tprivate ensureContainer(containerId?: string, existing?: HTMLElement | null): HTMLElement {\n\t\tif (existing) return existing;\n\t\tif (containerId) {\n\t\t\tconst found = document.getElementById(containerId);\n\t\t\tif (found) return found;\n\t\t}\n\t\tconst id = containerId || this.id || 'zylem-root';\n\t\tconst el = document.createElement('main');\n\t\tel.setAttribute('id', id);\n\t\tel.style.position = 'relative';\n\t\tel.style.width = '100%';\n\t\tel.style.height = '100%';\n\t\tdocument.body.appendChild(el);\n\t\treturn el;\n\t}\n}\n","import Stats from 'stats.js';\nimport { subscribe } from 'valtio/vanilla';\nimport { debugState } from '../debug/debug-state';\n\n/**\n * GameDebugDelegate handles debug UI for the game (Stats panel).\n * Subscribes to debugState changes for runtime toggle.\n */\nexport class GameDebugDelegate {\n private statsRef: Stats | null = null;\n private unsubscribe: (() => void) | null = null;\n\n constructor() {\n this.updateDebugUI();\n this.unsubscribe = subscribe(debugState, () => {\n this.updateDebugUI();\n });\n }\n\n /**\n * Called every frame - wraps stats.begin()\n */\n begin(): void {\n this.statsRef?.begin();\n }\n\n /**\n * Called every frame - wraps stats.end()\n */\n end(): void {\n this.statsRef?.end();\n }\n\n private updateDebugUI(): void {\n if (debugState.enabled && !this.statsRef) {\n // Enable debug UI\n this.statsRef = new Stats();\n this.statsRef.showPanel(0);\n this.statsRef.dom.style.position = 'absolute';\n this.statsRef.dom.style.bottom = '0';\n this.statsRef.dom.style.right = '0';\n this.statsRef.dom.style.top = 'auto';\n this.statsRef.dom.style.left = 'auto';\n document.body.appendChild(this.statsRef.dom);\n } else if (!debugState.enabled && this.statsRef) {\n // Disable debug UI\n if (this.statsRef.dom.parentNode) {\n this.statsRef.dom.parentNode.removeChild(this.statsRef.dom);\n }\n this.statsRef = null;\n }\n }\n\n dispose(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n if (this.statsRef?.dom?.parentNode) {\n this.statsRef.dom.parentNode.removeChild(this.statsRef.dom);\n }\n this.statsRef = null;\n }\n}\n","import { LoadingEvent } from '../core/interfaces';\nimport { zylemEventBus, type GameLoadingPayload } from '../events';\n\n/**\n * Game-level loading event that includes stage context.\n */\nexport interface GameLoadingEvent {\n\ttype: 'start' | 'progress' | 'complete';\n\tstageName?: string;\n\tstageIndex?: number;\n\tmessage: string;\n\tprogress: number;\n\tcurrent?: number;\n\ttotal?: number;\n}\n\n/**\n * Delegate for managing game-level loading events.\n * Aggregates loading events from stages and includes stage context.\n * Emits to zylemEventBus for cross-application communication.\n */\nexport class GameLoadingDelegate {\n\tprivate loadingHandlers: Array<(event: GameLoadingEvent) => void> = [];\n\tprivate stageLoadingUnsubscribes: (() => void)[] = [];\n\n\t/**\n\t * Subscribe to loading events from the game.\n\t * Events include stage context (stageName, stageIndex).\n\t * \n\t * @param callback Invoked for each loading event\n\t * @returns Unsubscribe function\n\t */\n\tonLoading(callback: (event: GameLoadingEvent) => void): () => void {\n\t\tthis.loadingHandlers.push(callback);\n\t\treturn () => {\n\t\t\tthis.loadingHandlers = this.loadingHandlers.filter((h) => h !== callback);\n\t\t};\n\t}\n\n\t/**\n\t * Emit a loading event to all subscribers and to zylemEventBus.\n\t */\n\temit(event: GameLoadingEvent): void {\n\t\t// Dispatch to direct subscribers\n\t\tfor (const handler of this.loadingHandlers) {\n\t\t\ttry {\n\t\t\t\thandler(event);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('Game loading handler failed', e);\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Emit to zylemEventBus for cross-package communication\n\t\tconst eventName = `loading:${event.type}` as 'loading:start' | 'loading:progress' | 'loading:complete';\n\t\t(zylemEventBus as any).emit(eventName, event as GameLoadingPayload);\n\t}\n\n\t/**\n\t * Wire up a stage's loading events to this delegate.\n\t * \n\t * @param stage The stage to wire up\n\t * @param stageIndex The index of the stage\n\t */\n\twireStageLoading(stage: { uuid?: string; onLoading: (cb: (event: LoadingEvent) => void) => () => void | void }, stageIndex: number): void {\n const unsub = stage.onLoading((event: LoadingEvent) => {\n\t\t\tthis.emit({\n\t\t\t\ttype: event.type,\n\t\t\t\tmessage: event.message ?? '',\n\t\t\t\tprogress: event.progress ?? 0,\n\t\t\t\tcurrent: event.current,\n\t\t\t\ttotal: event.total,\n\t\t\t\tstageName: stage.uuid ?? `Stage ${stageIndex}`,\n\t\t\t\tstageIndex,\n\t\t\t});\n\t\t});\n\t\tif (typeof unsub === 'function') {\n\t\t\tthis.stageLoadingUnsubscribes.push(unsub);\n\t\t}\n\t}\n\n\t/**\n\t * Unsubscribe from all stage loading events.\n\t */\n\tunwireAllStages(): void {\n\t\tfor (const unsub of this.stageLoadingUnsubscribes) {\n\t\t\ttry {\n\t\t\t\tunsub();\n\t\t\t} catch { /* noop */ }\n\t\t}\n\t\tthis.stageLoadingUnsubscribes = [];\n\t}\n\n\t/**\n\t * Clean up all handlers.\n\t */\n\tdispose(): void {\n\t\tthis.unwireAllStages();\n\t\tthis.loadingHandlers = [];\n\t}\n}\n","import { ZylemCamera } from '../camera/zylem-camera';\nimport { RendererManager } from '../camera/renderer-manager';\nimport { GameCanvas } from './game-canvas';\nimport { GameConfig } from './game-config';\nimport type { ZylemStage } from '../stage/zylem-stage';\n\n/**\n * Observer that triggers renderer mounting when container and camera/renderer are both available.\n * Decouples renderer mounting from stage loading.\n * Supports both legacy ZylemCamera mode and new RendererManager mode.\n */\nexport class GameRendererObserver {\n\tprivate container: HTMLElement | null = null;\n\tprivate camera: ZylemCamera | null = null;\n\tprivate rendererManager: RendererManager | null = null;\n\tprivate gameCanvas: GameCanvas | null = null;\n\tprivate config: GameConfig | null = null;\n\tprivate stage: ZylemStage | null = null;\n\tprivate mounted = false;\n\n\tsetGameCanvas(canvas: GameCanvas): void {\n\t\tthis.gameCanvas = canvas;\n\t\tthis.tryMount();\n\t}\n\n\tsetConfig(config: GameConfig): void {\n\t\tthis.config = config;\n\t\tthis.tryMount();\n\t}\n\n\tsetContainer(container: HTMLElement): void {\n\t\tthis.container = container;\n\t\tthis.tryMount();\n\t}\n\n\tsetStage(stage: ZylemStage | null): void {\n\t\tthis.stage = stage;\n\t\tif (this.mounted) {\n\t\t\tthis.gameCanvas?.reapplyLayout();\n\t\t}\n\t}\n\n\t/**\n\t * @deprecated Use setRendererManager instead for the new multi-camera path.\n\t */\n\tsetCamera(camera: ZylemCamera): void {\n\t\tthis.camera = camera;\n\t\tthis.tryMount();\n\t}\n\n\t/**\n\t * Set the shared renderer manager (new path for multi-camera support).\n\t */\n\tsetRendererManager(manager: RendererManager): void {\n\t\tthis.rendererManager = manager;\n\t\tthis.tryMount();\n\t}\n\n\t/**\n\t * Attempt to mount renderer if all dependencies are available.\n\t */\n\tprivate tryMount(): void {\n\t\tif (this.mounted) return;\n\t\tif (!this.container || !this.gameCanvas) return;\n\n\t\t// Prefer RendererManager (new path), fall back to legacy ZylemCamera\n\t\tif (this.rendererManager) {\n\t\t\tthis.mountWithRendererManager();\n\t\t} else if (this.camera) {\n\t\t\tthis.mountWithCamera();\n\t\t}\n\t}\n\n\t/**\n\t * Mount using the shared RendererManager.\n\t */\n\tprivate mountWithRendererManager(): void {\n\t\tif (!this.rendererManager || !this.gameCanvas) return;\n\n\t\tconst dom = this.rendererManager.getDomElement();\n\n\t\tthis.gameCanvas.mountRenderer(dom, (cssW, cssH) => {\n\t\t\tif (!this.rendererManager) return;\n\t\t\tconst internal = this.config?.internalResolution;\n\t\t\tif (internal) {\n\t\t\t\tthis.rendererManager.setPixelRatio(1);\n\t\t\t\tthis.rendererManager.resize(internal.width, internal.height);\n\t\t\t\tthis.stage?.resize(internal.width, internal.height);\n\t\t\t} else {\n\t\t\t\tconst dpr = window.devicePixelRatio || 1;\n\t\t\t\tthis.rendererManager.setPixelRatio(dpr);\n\t\t\t\tthis.rendererManager.resize(cssW, cssH);\n\t\t\t\tthis.stage?.resize(cssW, cssH);\n\t\t\t}\n\t\t});\n\n\t\tthis.mounted = true;\n\t}\n\n\t/**\n\t * Mount using a legacy ZylemCamera (backward compatible).\n\t */\n\tprivate mountWithCamera(): void {\n\t\tif (!this.camera || !this.gameCanvas) return;\n\n\t\tconst dom = this.camera.getDomElement();\n\t\t\n\t\tthis.gameCanvas.mountRenderer(dom, (cssW, cssH) => {\n\t\t\tif (!this.camera) return;\n\t\t\tconst internal = this.config?.internalResolution;\n\t\t\tif (internal) {\n\t\t\t\tthis.camera.setPixelRatio(1);\n\t\t\t\tthis.camera.resize(internal.width, internal.height);\n\t\t\t} else {\n\t\t\t\tconst dpr = window.devicePixelRatio || 1;\n\t\t\t\tthis.camera.setPixelRatio(dpr);\n\t\t\t\tthis.camera.resize(cssW, cssH);\n\t\t\t}\n\t\t});\n\t\t\n\t\tthis.mounted = true;\n\t}\n\n\t/**\n\t * Reset state for stage transitions.\n\t */\n\treset(): void {\n\t\tthis.camera = null;\n\t\tthis.stage = null;\n\t\tthis.mounted = false;\n\t\t// Keep rendererManager -- it persists across stages\n\t}\n\n\tdispose(): void {\n\t\tthis.container = null;\n\t\tthis.camera = null;\n\t\tthis.rendererManager = null;\n\t\tthis.gameCanvas = null;\n\t\tthis.config = null;\n\t\tthis.stage = null;\n\t\tthis.mounted = false;\n\t}\n}\n","import { ZylemGame, GameLoadingEvent } from './zylem-game';\nimport { DestroyFunction, SetupFunction, UpdateFunction } from '../core/base-node-life-cycle';\nimport { IGame } from '../core/interfaces';\nimport { setPaused } from '../debug/debug-state';\nimport { BaseGlobals, GameInputConfig } from './game-interfaces';\nimport { convertNodes, GameOptions, hasStages, extractGlobalsFromOptions } from '../core/utility/nodes';\nimport {\n\tresolveGameConfig,\n\ttype DeviceProfile,\n\ttype ResolveGameConfigRuntime,\n} from './game-config';\nimport { mergeInputConfigs } from '../input/input-presets';\nimport { createStage, Stage } from '../stage/stage';\nimport { StageManager, stageState } from '../stage/stage-manager';\nimport { StageFactory } from '../stage/stage-factory';\nimport { initGlobals, clearGlobalSubscriptions, resetGlobals, onGlobalChange as onGlobalChangeInternal, onGlobalChanges as onGlobalChangesInternal } from './game-state';\nimport { EventEmitterDelegate, zylemEventBus, type GameEvents } from '../events';\n\nexport class Game<TGlobals extends BaseGlobals> implements IGame<TGlobals> {\n\tprivate wrappedGame: ZylemGame<TGlobals> | null = null;\n\n\toptions: GameOptions<TGlobals>;\n\n\t// Lifecycle callback arrays\n\tprivate setupCallbacks: Array<SetupFunction<ZylemGame<TGlobals>, TGlobals>> = [];\n\tprivate updateCallbacks: Array<UpdateFunction<ZylemGame<TGlobals>, TGlobals>> = [];\n\tprivate destroyCallbacks: Array<DestroyFunction<ZylemGame<TGlobals>, TGlobals>> = [];\n\tprivate pendingLoadingCallbacks: Array<(event: GameLoadingEvent) => void> = [];\n\n\t// Game-scoped global change subscriptions\n\tprivate globalChangeCallbacks: Array<{ path: string; callback: (value: unknown, stage: Stage | null) => void }> = [];\n\tprivate globalChangesCallbacks: Array<{ paths: string[]; callback: (values: unknown[], stage: Stage | null) => void }> = [];\n\tprivate activeGlobalSubscriptions: Array<() => void> = [];\n\n\t// Event delegate for dispatch/listen API\n\tprivate eventDelegate = new EventEmitterDelegate<GameEvents>();\n\n\t/** Pending global input config set before the game starts. */\n\tprivate pendingInputConfig: GameInputConfig | null = null;\n\tprivate displayRuntime: ResolveGameConfigRuntime = {};\n\n\trefErrorMessage = 'lost reference to game';\n\n\tconstructor(options: GameOptions<TGlobals>) {\n\t\tthis.options = options;\n\t\tif (!hasStages(options)) {\n\t\t\tthis.options.push(createStage());\n\t\t}\n\t\t// Initialize globals immediately so onGlobalChange subscriptions work\n\t\tconst globals = extractGlobalsFromOptions(options);\n\t\tif (globals) {\n\t\t\tinitGlobals(globals as Record<string, unknown>);\n\t\t}\n\t}\n\n\t// Fluent API for adding lifecycle callbacks\n\tonSetup(...callbacks: Array<SetupFunction<ZylemGame<TGlobals>, TGlobals>>): this {\n\t\tthis.setupCallbacks.push(...callbacks);\n\t\treturn this;\n\t}\n\n\tonUpdate(...callbacks: Array<UpdateFunction<ZylemGame<TGlobals>, TGlobals>>): this {\n\t\tthis.updateCallbacks.push(...callbacks);\n\t\treturn this;\n\t}\n\n\tonDestroy(...callbacks: Array<DestroyFunction<ZylemGame<TGlobals>, TGlobals>>): this {\n\t\tthis.destroyCallbacks.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set composable input configuration as global defaults for the entire game.\n\t * Multiple configs are deep-merged (later configs win on key conflicts).\n\t * Per-stage overrides (via stage.setInputConfiguration) are merged on top.\n\t * Can be called before or after start().\n\t * @example game.setInputConfiguration(useArrowsForAxes('p1'), useWASDForDirections('p2'));\n\t */\n\tsetInputConfiguration(...configs: GameInputConfig[]): this {\n\t\tconst merged = mergeInputConfigs(...configs);\n\t\tthis.pendingInputConfig = merged;\n\t\tif (this.wrappedGame) {\n\t\t\tthis.wrappedGame.setGlobalInputConfig(merged);\n\t\t}\n\t\treturn this;\n\t}\n\n\tasync start(): Promise<this> {\n\t\t// Re-initialize globals for this game\n\t\tresetGlobals();\n\t\tconst globals = extractGlobalsFromOptions(this.options);\n\t\tif (globals) {\n\t\t\tinitGlobals(globals as Record<string, unknown>);\n\t\t}\n\t\t\n\t\tconst game = await this.load();\n\t\tthis.wrappedGame = game;\n\t\tthis.setOverrides();\n\t\tthis.registerGlobalSubscriptions();\n\t\tgame.start();\n\t\treturn this;\n\t}\n\n\tsetDisplayRuntime(runtime: Partial<ResolveGameConfigRuntime>): this {\n\t\tthis.displayRuntime = {\n\t\t\t...this.displayRuntime,\n\t\t\t...runtime,\n\t\t};\n\t\tif (this.wrappedGame) {\n\t\t\tthis.wrappedGame.setDisplayRuntime(this.displayRuntime);\n\t\t}\n\t\treturn this;\n\t}\n\n\tsetDeviceProfile(profile: DeviceProfile): this {\n\t\treturn this.setDisplayRuntime({ deviceProfile: profile });\n\t}\n\n\tsetViewportSize(width: number, height: number): this {\n\t\treturn this.setDisplayRuntime({\n\t\t\tviewportSize: { width, height },\n\t\t});\n\t}\n\n\tprivate async load(): Promise<ZylemGame<TGlobals>> {\n\t\tconst options = await convertNodes<TGlobals>(this.options);\n\t\tconst resolved = resolveGameConfig(options as any, this.displayRuntime);\n\n\t\t// Merge any pending input configuration set via setInputConfiguration() before start\n\t\tif (this.pendingInputConfig) {\n\t\t\tresolved.input = mergeInputConfigs(resolved.input ?? {}, this.pendingInputConfig);\n\t\t}\n\n\t\tconst game = new ZylemGame<TGlobals>({\n\t\t\t...options as any,\n\t\t\t...resolved as any,\n\t\t} as any, this, this.displayRuntime);\n\t\t\n\t\t// Apply pending loading callbacks BEFORE loadStage so events are captured\n\t\tfor (const callback of this.pendingLoadingCallbacks) {\n\t\t\tgame.onLoading(callback);\n\t\t}\n\t\t\n\t\tawait game.loadStage(options.stages[0]);\n\t\treturn game;\n\t}\n\n\tprivate setOverrides() {\n\t\tif (!this.wrappedGame) {\n\t\t\tconsole.error(this.refErrorMessage);\n\t\t\treturn;\n\t\t}\n\t\t// Pass callback arrays to wrapped game\n\t\tthis.wrappedGame.customSetup = (params) => {\n\t\t\tthis.setupCallbacks.forEach(cb => cb(params));\n\t\t};\n\t\tthis.wrappedGame.customUpdate = (params) => {\n\t\t\tthis.updateCallbacks.forEach(cb => cb(params));\n\t\t};\n\t\tthis.wrappedGame.customDestroy = (params) => {\n\t\t\tthis.destroyCallbacks.forEach(cb => cb(params));\n\t\t};\n\t}\n\n\t/**\n\t * Subscribe to changes on a global value. Subscriptions are registered\n\t * when the game starts and cleaned up when disposed.\n\t * The callback receives the value and the current stage.\n\t * @example game.onGlobalChange('score', (val, stage) => console.log(val));\n\t */\n\tonGlobalChange<T = unknown>(path: string, callback: (value: T, stage: Stage | null) => void): this {\n\t\tthis.globalChangeCallbacks.push({ path, callback: callback as (value: unknown, stage: Stage | null) => void });\n\t\treturn this;\n\t}\n\n\t/**\n\t * Subscribe to changes on multiple global paths. Subscriptions are registered\n\t * when the game starts and cleaned up when disposed.\n\t * The callback receives the values and the current stage.\n\t * @example game.onGlobalChanges(['score', 'lives'], ([score, lives], stage) => console.log(score, lives));\n\t */\n\tonGlobalChanges<T extends unknown[] = unknown[]>(paths: string[], callback: (values: T, stage: Stage | null) => void): this {\n\t\tthis.globalChangesCallbacks.push({ paths, callback: callback as (values: unknown[], stage: Stage | null) => void });\n\t\treturn this;\n\t}\n\n\t/**\n\t * Register all stored global change callbacks.\n\t * Called internally during start().\n\t */\n\tprivate registerGlobalSubscriptions() {\n\t\tfor (const { path, callback } of this.globalChangeCallbacks) {\n\t\t\tconst unsub = onGlobalChangeInternal(path, (value) => {\n\t\t\t\tcallback(value, this.getCurrentStage());\n\t\t\t});\n\t\t\tthis.activeGlobalSubscriptions.push(unsub);\n\t\t}\n\t\tfor (const { paths, callback } of this.globalChangesCallbacks) {\n\t\t\tconst unsub = onGlobalChangesInternal(paths, (values) => {\n\t\t\t\tcallback(values, this.getCurrentStage());\n\t\t\t});\n\t\t\tthis.activeGlobalSubscriptions.push(unsub);\n\t\t}\n\t}\n\n\t/**\n\t * Get the current stage wrapper.\n\t */\n\tgetCurrentStage(): Stage | null {\n\t\treturn this.wrappedGame?.currentStage() ?? null;\n\t}\n\n\tasync pause() {\n\t\tsetPaused(true);\n\t}\n\n\tasync resume() {\n\t\tsetPaused(false);\n\t\tif (this.wrappedGame) {\n\t\t\tthis.wrappedGame.previousTimeStamp = 0;\n\t\t\tthis.wrappedGame.timer.reset();\n\t\t}\n\t}\n\n\t/**\n\t * Execute a single frame update.\n\t * Useful for testing or manual frame stepping.\n\t * @param deltaTime Optional delta time in seconds (defaults to 1/60)\n\t */\n\tstep(deltaTime: number = 1/60): void {\n\t\tif (!this.wrappedGame) {\n\t\t\tconsole.error(this.refErrorMessage);\n\t\t\treturn;\n\t\t}\n\t\tthis.wrappedGame.step(deltaTime);\n\t}\n\n\tasync reset() {\n\t\tif (!this.wrappedGame) {\n\t\t\tconsole.error(this.refErrorMessage);\n\t\t\treturn;\n\t\t}\n\t\tawait this.wrappedGame.loadStage(this.wrappedGame.stages[0]);\n\t}\n\n\tpreviousStage() {\n\t\tif (!this.wrappedGame) {\n\t\t\tconsole.error(this.refErrorMessage);\n\t\t\treturn;\n\t\t}\n\t\tconst currentStageId = this.wrappedGame.currentStageId;\n\t\tconst currentIndex = this.wrappedGame.stages.findIndex((s) => s.wrappedStage?.uuid === currentStageId);\n\t\tconst previousStage = this.wrappedGame.stages[currentIndex - 1];\n\t\tif (!previousStage) {\n\t\t\tconsole.error('previous stage called on first stage');\n\t\t\treturn;\n\t\t}\n\t\tthis.wrappedGame.loadStage(previousStage);\n\t}\n\n\tasync loadStageFromId(stageId: string) {\n\t\tif (!this.wrappedGame) {\n\t\t\tconsole.error(this.refErrorMessage);\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst blueprint = await StageManager.loadStageData(stageId);\n\t\t\tconst stage = await StageFactory.createFromBlueprint(blueprint);\n\t\t\tawait this.wrappedGame.loadStage(stage);\n\t\t\t\n\t\t\t// Update StageManager state\n\t\t\tstageState.current = blueprint;\n\t\t} catch (e) {\n\t\t\tconsole.error(`Failed to load stage ${stageId}`, e);\n\t\t}\n\t}\n\n\tnextStage() {\n\t\tif (!this.wrappedGame) {\n\t\t\tconsole.error(this.refErrorMessage);\n\t\t\treturn;\n\t\t}\n\t\t\n\t\t// Try to use StageManager first if we have a next stage in state\n\t\tif (stageState.next) {\n\t\t\tconsole.log('next stage called');\n\t\t\tconst nextId = stageState.next.id;\n\t\t\tStageManager.transitionForward(nextId);\n\t\t\t// After transition, current is the new stage\n\t\t\tif (stageState.current) {\n\t\t\t\tStageFactory.createFromBlueprint(stageState.current).then((stage) => {\n\t\t\t\t\tthis.wrappedGame?.loadStage(stage);\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Fallback to legacy array-based navigation\n\t\tconst currentStageId = this.wrappedGame.currentStageId;\n\t\tconst currentIndex = this.wrappedGame.stages.findIndex((s) => s.wrappedStage?.uuid === currentStageId);\n\t\tconst nextStage = this.wrappedGame.stages[currentIndex + 1];\n\t\tif (!nextStage) {\n\t\t\tconsole.error('next stage called on last stage');\n\t\t\treturn;\n\t\t}\n\t\tthis.wrappedGame.loadStage(nextStage);\n\t}\n\n\tasync goToStage() { }\n\n\tasync end() { }\n\n\tdispose() {\n\t\t// Clear event delegate subscriptions\n\t\tthis.eventDelegate.dispose();\n\n\t\t// Clear game-specific subscriptions\n\t\tfor (const unsub of this.activeGlobalSubscriptions) {\n\t\t\tunsub();\n\t\t}\n\t\tthis.activeGlobalSubscriptions = [];\n\t\t\n\t\tif (this.wrappedGame) {\n\t\t\tthis.wrappedGame.dispose();\n\t\t\tthis.wrappedGame = null;\n\t\t}\n\t\t// Clear all remaining global subscriptions and reset globals\n\t\tclearGlobalSubscriptions();\n\t\tresetGlobals();\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Events API\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispatch an event from the game.\n\t * Events are emitted both locally and to the global event bus.\n\t */\n\tdispatch<K extends keyof GameEvents>(event: K, payload: GameEvents[K]): void {\n\t\tthis.eventDelegate.dispatch(event, payload);\n\t\t// Emit to global bus for cross-package communication\n\t\t(zylemEventBus as any).emit(event, payload);\n\t}\n\n\t/**\n\t * Listen for events on this game instance.\n\t * @returns Unsubscribe function\n\t */\n\tlisten<K extends keyof GameEvents>(event: K, handler: (payload: GameEvents[K]) => void): () => void {\n\t\treturn this.eventDelegate.listen(event, handler);\n\t}\n\n\t/**\n\t * Subscribe to loading events from the game.\n\t * Events include stage context (stageName, stageIndex).\n\t * @param callback Invoked for each loading event\n\t * @returns Unsubscribe function\n\t */\n\tonLoading(callback: (event: GameLoadingEvent) => void): () => void {\n\t\tif (this.wrappedGame) {\n\t\t\treturn this.wrappedGame.onLoading(callback);\n\t\t}\n\t\t// Store callback to be applied when game is created\n\t\tthis.pendingLoadingCallbacks.push(callback);\n\t\treturn () => {\n\t\t\tthis.pendingLoadingCallbacks = this.pendingLoadingCallbacks.filter(c => c !== callback);\n\t\t\tif (this.wrappedGame) {\n\t\t\t\t// If already started, also unsubscribe from wrapped game\n\t\t\t\t// Note: this won't perfectly track existing subscriptions, but prevents future calls\n\t\t\t}\n\t\t};\n\t}\n}\n\n/**\n * create a new game\n * @param options GameOptions - Array of IGameOptions, Stage, GameEntity, or BaseNode objects\n * @param options.id Game name string (when using IGameOptions)\n * @param options.globals Game globals object (when using IGameOptions)\n * @param options.stages Array of stage objects (when using IGameOptions)\n * @returns Game\n */\nexport function createGame<TGlobals extends BaseGlobals>(...options: GameOptions<TGlobals>): Game<TGlobals> {\n\treturn new Game<TGlobals>(options);\n}\n","import { BaseNode } from '../base-node';\nimport { Stage } from '../../stage/stage';\nimport { GameEntity, GameEntityLifeCycle } from '../../entities/entity';\nimport { BaseGlobals, ZylemGameConfig, GameInputConfig } from '../../game/game-interfaces';\nimport { GameConfigLike } from '~/lib/game/game-config';\n\n// export function isStageContext(value: unknown): value is StageContext {\n// \treturn !!value && typeof value === 'object' && 'instance' in (value as any) && 'stageBlueprint' in (value as any);\n// }\n\nexport type GameOptions<TGlobals extends BaseGlobals> = Array<\n\tZylemGameConfig<Stage, any, TGlobals> |\n\tGameConfigLike |\n\tStage |\n\tGameEntityLifeCycle |\n\tBaseNode\n>;\n\n/** \n * TODO: need to revisit the way configurations are handled\n * \n * - default config is applied first\n * - then only one config should be allowed. \n * - if multiple configs are provided, the last one is used\n * - then any nodes provided are applied\n * \n **/\n\nexport async function convertNodes<TGlobals extends BaseGlobals>(\n\t_options: GameOptions<TGlobals>\n): Promise<{ id: string, globals: TGlobals, stages: Stage[], input?: GameInputConfig }> {\n\tconst { getGameDefaultConfig } = await import('../../game/game-default');\n\tlet convertedDefault = { ...getGameDefaultConfig<TGlobals>() } as { id: string, globals: TGlobals, stages: Stage[], input?: GameInputConfig };\n\tconst configurations: ZylemGameConfig<Stage, any, TGlobals>[] = [];\n\tconst stages: Stage[] = [];\n\tconst entities: (BaseNode | GameEntity<any>)[] = [];\n\n\tObject.values(_options).forEach((node) => {\n\t\tif (node instanceof Stage) {\n\t\t\tstages.push(node);\n\t\t} else if (node instanceof GameEntity) {\n\t\t\tentities.push(node);\n\t\t} else if (node instanceof BaseNode) {\n\t\t\tentities.push(node);\n\t\t} else if ((node as any)?.constructor?.name === 'Object' && typeof node === 'object') {\n\t\t\tconst configuration = Object.assign({ ...getGameDefaultConfig<TGlobals>() }, { ...node });\n\t\t\tconfigurations.push(configuration as ZylemGameConfig<Stage, any, TGlobals>);\n\t\t}\n\t});\n\n\tconfigurations.forEach((configuration) => {\n\t\tconvertedDefault = Object.assign(convertedDefault, { ...configuration });\n\t});\n\n\tconst converted = convertedDefault;\n\tconverted.input = configurations[0].input;\n\t\n\tstages.forEach((stageInstance) => {\n\t\tstageInstance.addEntities(entities as BaseNode[]);\n\t});\n\tif (stages.length) {\n\t\tconverted.stages = stages;\n\t} else {\n\t\tconverted.stages[0].addEntities(entities as BaseNode[]);\n\t}\n\treturn converted as unknown as { id: string, globals: TGlobals, stages: Stage[], input?: GameInputConfig };\n}\n\nexport function hasStages<TGlobals extends BaseGlobals>(_options: GameOptions<TGlobals>): Boolean {\n\tconst stage = _options.find(option => option instanceof Stage);\n\treturn Boolean(stage);\n}\n\n/**\n * Extract globals object from game options array.\n * Used to initialize globals before game starts.\n */\nexport function extractGlobalsFromOptions<TGlobals extends BaseGlobals>(\n\t_options: GameOptions<TGlobals>\n): TGlobals | undefined {\n\tfor (const option of _options) {\n\t\tif (option && typeof option === 'object' && !(option instanceof Stage) && !(option instanceof BaseNode) && !(option instanceof GameEntity)) {\n\t\t\tconst config = option as ZylemGameConfig<Stage, any, TGlobals>;\n\t\t\tif (config.globals) {\n\t\t\t\treturn config.globals;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}","import { proxy } from 'valtio/vanilla';\nimport { get, set } from 'idb-keyval';\nimport { pack, unpack } from 'msgpackr';\nimport { StageBlueprint } from '../core/blueprints';\n\n// The State\nexport const stageState = proxy({\n previous: null as StageBlueprint | null,\n current: null as StageBlueprint | null,\n next: null as StageBlueprint | null,\n isLoading: false,\n});\n\n// The Logic\nexport const StageManager = {\n staticRegistry: new Map<string, StageBlueprint>(),\n\n registerStaticStage(id: string, blueprint: StageBlueprint) {\n this.staticRegistry.set(id, blueprint);\n },\n\n async loadStageData(stageId: string): Promise<StageBlueprint> {\n // 1. Check Local Storage (User Save)\n try {\n const saved = await get(stageId);\n if (saved) {\n // msgpackr returns a buffer, we need to unpack it\n return unpack(saved);\n }\n } catch (e) {\n console.warn(`Failed to load stage ${stageId} from storage`, e);\n }\n\n // 2. Fallback to Static File (Initial Load)\n if (this.staticRegistry.has(stageId)) {\n return this.staticRegistry.get(stageId)!;\n }\n\n // Note: This assumes a convention where stages are importable.\n // You might need a registry or a specific path structure.\n // For now, we'll assume a dynamic import from a known location or a registry.\n // Since dynamic imports with variables can be tricky in bundlers, \n // we might need a map of stage IDs to import functions if the path isn't static enough.\n \n // TODO: Implement a robust way to resolve stage paths.\n // For now, throwing an error if not found in storage, as the static loading strategy \n // depends on project structure.\n throw new Error(`Stage ${stageId} not found in storage and static loading not fully implemented.`);\n },\n\n async transitionForward(nextStageId: string, loadStaticStage?: (id: string) => Promise<StageBlueprint>) {\n if (stageState.isLoading) return;\n \n stageState.isLoading = true;\n\n try {\n // Save current state to disk before unloading\n if (stageState.current) {\n await set(stageState.current.id, pack(stageState.current));\n }\n\n // Shift Window\n stageState.previous = stageState.current;\n stageState.current = stageState.next;\n \n // If we don't have a next stage preloaded (or if we just shifted it to current),\n // we might need to load the *new* next stage. \n // But the architecture doc says \"Fetch new Next\".\n // Let's assume we want to load the requested nextStageId as the *new Current* \n // if it wasn't already in 'next'. \n // Actually, the sliding window usually implies we move towards 'next'.\n // If 'next' was already populated with nextStageId, we just move it to 'current'.\n \n if (stageState.current?.id !== nextStageId) {\n // If the shift didn't result in the desired stage (e.g. we jumped), load it directly.\n // Or if 'next' was null.\n if (loadStaticStage) {\n stageState.current = await loadStaticStage(nextStageId);\n } else {\n stageState.current = await this.loadStageData(nextStageId);\n }\n }\n\n // Ideally we would pre-fetch the stage *after* this one into 'next'.\n // But we don't know what comes after 'nextStageId' without a map.\n // For now, we leave 'next' null or let the game logic trigger a preload.\n stageState.next = null; \n \n } catch (error) {\n console.error(\"Failed to transition stage:\", error);\n } finally {\n stageState.isLoading = false;\n }\n },\n \n /**\n * Manually set the next stage to pre-load it.\n */\n async preloadNext(stageId: string, loadStaticStage?: (id: string) => Promise<StageBlueprint>) {\n if (loadStaticStage) {\n stageState.next = await loadStaticStage(stageId);\n } else {\n stageState.next = await this.loadStageData(stageId);\n }\n }\n};\n","import { StageBlueprint } from '../core/blueprints';\nimport { createStage, Stage } from './stage';\nimport { EntityFactory } from '../entities/entity-factory';\n\nexport const StageFactory = {\n async createFromBlueprint(blueprint: StageBlueprint): Promise<Stage> {\n // Create a new Stage instance\n // We might need to pass options from blueprint if StageSchema has them\n const stage = createStage({\n // Map blueprint properties to stage options if needed\n // e.g. name: blueprint.name\n });\n \n // Assign ID if possible, though Stage might generate its own UUID.\n // If we want to track it by blueprint ID, we might need to store it on the stage.\n // stage.id = blueprint.id; // Stage doesn't have public ID setter easily maybe?\n\n if (blueprint.entities) {\n for (const entityBlueprint of blueprint.entities) {\n try {\n const entity = await EntityFactory.createFromBlueprint(entityBlueprint);\n stage.add(entity);\n } catch (e) {\n console.error(`Failed to create entity ${entityBlueprint.id} for stage ${blueprint.id}`, e);\n }\n }\n }\n\n return stage;\n }\n};\n","import { Color, Group, Sprite as ThreeSprite, SpriteMaterial, CanvasTexture, LinearFilter, Vector2, PerspectiveCamera, OrthographicCamera, ClampToEdgeWrapping } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { createEntity } from './create';\nimport { UpdateContext, SetupContext } from '../core/base-node-life-cycle';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { DebugDelegate } from './delegates/debug';\n\ntype ZylemTextOptions = GameEntityOptions & {\n\ttext?: string;\n\tfontFamily?: string;\n\tfontSize?: number;\n\tfontColor?: Color | string;\n\tbackgroundColor?: Color | string | null;\n\tpadding?: number;\n\tstickToViewport?: boolean;\n\tscreenPosition?: Vector2;\n\tzDistance?: number;\n};\n\nconst textDefaults: ZylemTextOptions = {\n\tposition: undefined,\n\ttext: '',\n\tfontFamily: 'Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n\tfontSize: 18,\n\tfontColor: '#FFFFFF',\n\tbackgroundColor: null,\n\tpadding: 4,\n\tstickToViewport: true,\n\tscreenPosition: new Vector2(24, 24),\n\tzDistance: 1,\n};\n\nexport class TextBuilder extends EntityBuilder<ZylemText, ZylemTextOptions> {\n\tprotected createEntity(options: Partial<ZylemTextOptions>): ZylemText {\n\t\treturn new ZylemText(options);\n\t}\n}\n\nexport const TEXT_TYPE = Symbol('Text');\n\nexport class ZylemText extends GameEntity<ZylemTextOptions> {\n\tstatic type = TEXT_TYPE;\n\n\tprivate _sprite: ThreeSprite | null = null;\n\tprivate _texture: CanvasTexture | null = null;\n\tprivate _canvas: HTMLCanvasElement | null = null;\n\tprivate _ctx: CanvasRenderingContext2D | null = null;\n\tprivate _cameraRef: ZylemCamera | null = null;\n\tprivate _lastCanvasW: number = 0;\n\tprivate _lastCanvasH: number = 0;\n\n\tconstructor(options?: ZylemTextOptions) {\n\t\tsuper();\n\t\tthis.options = { ...textDefaults, ...options } as ZylemTextOptions;\n\t\t// Add text-specific lifecycle callbacks (only registered once)\n\t\tthis.prependSetup(this.textSetup.bind(this) as any);\n\t\tthis.prependUpdate(this.textUpdate.bind(this) as any);\n\t\tthis.onCleanup(this.textDestroy.bind(this) as any);\n\t}\n\n\tpublic create(): this {\n\t\t// Clear previous state to prevent issues on reload\n\t\tthis._sprite = null;\n\t\tthis._texture = null;\n\t\tthis._canvas = null;\n\t\tthis._ctx = null;\n\t\tthis._lastCanvasW = 0;\n\t\tthis._lastCanvasH = 0;\n\t\tthis.group = new Group();\n\t\t\n\t\t// Recreate the sprite\n\t\tthis.createSprite();\n\t\t\n\t\t// Call parent create\n\t\treturn super.create();\n\t}\n\n\tprivate createSprite() {\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._ctx = this._canvas.getContext('2d');\n\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\tthis._texture.minFilter = LinearFilter;\n\t\tthis._texture.magFilter = LinearFilter;\n\t\tconst material = new SpriteMaterial({\n\t\t\tmap: this._texture,\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\talphaTest: 0.5,\n\t\t});\n\t\tthis._sprite = new ThreeSprite(material);\n\t\tthis.group?.add(this._sprite);\n\t\tthis.redrawText(this.options.text ?? '');\n\t}\n\n\tprivate measureAndResizeCanvas(text: string, fontSize: number, fontFamily: string, padding: number) {\n\t\tif (!this._canvas || !this._ctx) return { sizeChanged: false };\n\t\tthis._ctx.font = `${fontSize}px ${fontFamily}`;\n\t\tconst metrics = this._ctx.measureText(text);\n\t\tconst textWidth = Math.ceil(metrics.width);\n\t\tconst textHeight = Math.ceil(fontSize * 1.4);\n\t\tconst nextW = Math.max(2, textWidth + padding * 2);\n\t\tconst nextH = Math.max(2, textHeight + padding * 2);\n\t\tconst sizeChanged = nextW !== this._lastCanvasW || nextH !== this._lastCanvasH;\n\t\tthis._canvas.width = nextW;\n\t\tthis._canvas.height = nextH;\n\t\tthis._lastCanvasW = nextW;\n\t\tthis._lastCanvasH = nextH;\n\t\treturn { sizeChanged };\n\t}\n\n\tprivate drawCenteredText(text: string, fontSize: number, fontFamily: string) {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tthis._ctx.font = `${fontSize}px ${fontFamily}`;\n\t\tthis._ctx.textAlign = 'center';\n\t\tthis._ctx.textBaseline = 'middle';\n\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\t\tif (this.options.backgroundColor) {\n\t\t\tthis._ctx.fillStyle = this.toCssColor(this.options.backgroundColor);\n\t\t\tthis._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t}\n\t\tthis._ctx.fillStyle = this.toCssColor(this.options.fontColor ?? '#FFFFFF');\n\t\tthis._ctx.fillText(text, this._canvas.width / 2, this._canvas.height / 2);\n\t}\n\n\tprivate updateTexture(sizeChanged: boolean) {\n\t\tif (!this._texture || !this._canvas) return;\n\t\tif (sizeChanged) {\n\t\t\tthis._texture.dispose();\n\t\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\t\tthis._texture.minFilter = LinearFilter;\n\t\t\tthis._texture.magFilter = LinearFilter;\n\t\t\tthis._texture.wrapS = ClampToEdgeWrapping;\n\t\t\tthis._texture.wrapT = ClampToEdgeWrapping;\n\t\t}\n\t\tthis._texture.image = this._canvas;\n\t\tthis._texture.needsUpdate = true;\n\t\tif (this._sprite && this._sprite.material) {\n\t\t\t(this._sprite.material as any).map = this._texture;\n\t\t\tthis._sprite.material.needsUpdate = true;\n\t\t}\n\t}\n\n\tprivate redrawText(_text: string) {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tconst fontSize = this.options.fontSize ?? 18;\n\t\tconst fontFamily = this.options.fontFamily ?? (textDefaults.fontFamily as string);\n\t\tconst padding = this.options.padding ?? 4;\n\n\t\tconst { sizeChanged } = this.measureAndResizeCanvas(_text, fontSize, fontFamily, padding);\n\t\tthis.drawCenteredText(_text, fontSize, fontFamily);\n\t\tthis.updateTexture(Boolean(sizeChanged));\n\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate toCssColor(color: Color | string): string {\n\t\tif (typeof color === 'string') return color;\n\t\tconst c = color instanceof Color ? color : new Color(color as any);\n\t\treturn `#${c.getHexString()}`;\n\t}\n\n\tprivate textSetup(params: SetupContext<ZylemTextOptions>) {\n\t\tthis._cameraRef = (params.camera as unknown) as ZylemCamera | null;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\t(this._cameraRef.camera as any).add(this.group);\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate textUpdate(params: UpdateContext<ZylemTextOptions>) {\n\t\tif (!this._sprite) return;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate getResolution() {\n\t\treturn {\n\t\t\twidth: this._cameraRef?.screenResolution.x ?? 1,\n\t\t\theight: this._cameraRef?.screenResolution.y ?? 1,\n\t\t};\n\t}\n\n\tprivate getScreenPixels(sp: Vector2, width: number, height: number) {\n\t\tconst isPercentX = sp.x >= 0 && sp.x <= 1;\n\t\tconst isPercentY = sp.y >= 0 && sp.y <= 1;\n\t\treturn {\n\t\t\tpx: isPercentX ? sp.x * width : sp.x,\n\t\t\tpy: isPercentY ? sp.y * height : sp.y,\n\t\t};\n\t}\n\n\tprivate computeWorldExtents(camera: PerspectiveCamera | OrthographicCamera, zDist: number) {\n\t\tlet worldHalfW = 1;\n\t\tlet worldHalfH = 1;\n\t\tif ((camera as PerspectiveCamera).isPerspectiveCamera) {\n\t\t\tconst pc = camera as PerspectiveCamera;\n\t\t\tconst halfH = Math.tan((pc.fov * Math.PI) / 180 / 2) * zDist;\n\t\t\tconst halfW = halfH * pc.aspect;\n\t\t\tworldHalfW = halfW;\n\t\t\tworldHalfH = halfH;\n\t\t} else if ((camera as OrthographicCamera).isOrthographicCamera) {\n\t\t\tconst oc = camera as OrthographicCamera;\n\t\t\tworldHalfW = (oc.right - oc.left) / 2;\n\t\t\tworldHalfH = (oc.top - oc.bottom) / 2;\n\t\t}\n\t\treturn { worldHalfW, worldHalfH };\n\t}\n\n\tprivate updateSpriteScale(worldHalfH: number, viewportHeight: number) {\n\t\tif (!this._canvas || !this._sprite) return;\n\t\tconst planeH = worldHalfH * 2;\n\t\tconst unitsPerPixel = planeH / viewportHeight;\n\t\tconst pixelH = this._canvas.height;\n\t\tconst scaleY = Math.max(0.0001, pixelH * unitsPerPixel);\n\t\tconst aspect = this._canvas.width / this._canvas.height;\n\t\tconst scaleX = scaleY * aspect;\n\t\tthis._sprite.scale.set(scaleX, scaleY, 1);\n\t}\n\n\tprivate updateStickyTransform() {\n\t\tif (!this._sprite || !this._cameraRef) return;\n\t\tconst camera = this._cameraRef.camera as PerspectiveCamera | OrthographicCamera;\n\t\tconst { width, height } = this.getResolution();\n\t\tconst sp = this.options.screenPosition ?? new Vector2(24, 24);\n\t\tconst { px, py } = this.getScreenPixels(sp, width, height);\n\t\tconst zDist = Math.max(0.001, this.options.zDistance ?? 1);\n\t\tconst { worldHalfW, worldHalfH } = this.computeWorldExtents(camera, zDist);\n\n\t\tconst ndcX = (px / width) * 2 - 1;\n\t\tconst ndcY = 1 - (py / height) * 2;\n\t\tconst localX = ndcX * worldHalfW;\n\t\tconst localY = ndcY * worldHalfH;\n\t\tthis.group?.position.set(localX, localY, -zDist);\n\t\tthis.updateSpriteScale(worldHalfH, height);\n\t}\n\n\tupdateText(_text: string) {\n\t\tthis.options.text = _text;\n\t\tthis.redrawText(_text);\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemText.type),\n\t\t\ttext: this.options.text ?? '',\n\t\t\tsticky: this.options.stickToViewport,\n\t\t};\n\t}\n\n\t/**\n\t * Dispose of Three.js resources when the entity is destroyed.\n\t */\n\tprivate textDestroy(): void {\n\t\t// Dispose texture\n\t\tthis._texture?.dispose();\n\t\t\n\t\t// Dispose sprite material\n\t\tif (this._sprite?.material) {\n\t\t\t(this._sprite.material as SpriteMaterial).dispose();\n\t\t}\n\t\t\n\t\t// Remove sprite from group\n\t\tif (this._sprite) {\n\t\t\tthis._sprite.removeFromParent();\n\t\t}\n\t\t\n\t\t// Remove group from parent (camera or scene)\n\t\tthis.group?.removeFromParent();\n\t\t\n\t\t// Clear references\n\t\tthis._sprite = null;\n\t\tthis._texture = null;\n\t\tthis._canvas = null;\n\t\tthis._ctx = null;\n\t\tthis._cameraRef = null;\n\t}\n}\n\ntype TextOptions = BaseNode | Partial<ZylemTextOptions>;\n\nexport function createText(...args: Array<TextOptions>): ZylemText {\n\treturn createEntity<ZylemText, ZylemTextOptions>({\n\t\targs,\n\t\tdefaultConfig: { ...textDefaults },\n\t\tEntityClass: ZylemText,\n\t\tBuilderClass: TextBuilder,\n\t\tentityType: ZylemText.type,\n\t\tcloneFactory: (options) => createText(options ?? {}),\n\t});\n}\n\n","import { GameEntity, GameEntityOptions } from '../entity';\nimport { MeshStandardMaterial, MeshBasicMaterial, MeshPhongMaterial } from 'three';\n\n/**\n * Interface for entities that provide custom debug information\n */\nexport interface DebugInfoProvider {\n\tgetDebugInfo(): Record<string, any>;\n}\n\n/**\n * Helper to check if an object implements DebugInfoProvider\n */\nfunction hasDebugInfo(obj: any): obj is DebugInfoProvider {\n\treturn obj && typeof obj.getDebugInfo === 'function';\n}\n\n/**\n * Debug delegate that provides debug information for entities\n */\nexport class DebugDelegate {\n\tprivate entity: GameEntity<any>;\n\n\tconstructor(entity: GameEntity<any>) {\n\t\tthis.entity = entity;\n\t}\n\n\t/**\n\t * Get formatted position string\n\t */\n\tprivate getPositionString(): string {\n\t\tif (this.entity.mesh) {\n\t\t\tconst { x, y, z } = this.entity.mesh.position;\n\t\t\treturn `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`;\n\t\t}\n\t\tconst { x, y, z } = this.entity.options.position || { x: 0, y: 0, z: 0 };\n\t\treturn `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`;\n\t}\n\n\t/**\n\t * Get formatted rotation string (in degrees)\n\t */\n\tprivate getRotationString(): string {\n\t\tif (this.entity.mesh) {\n\t\t\tconst { x, y, z } = this.entity.mesh.rotation;\n\t\t\tconst toDeg = (rad: number) => (rad * 180 / Math.PI).toFixed(1);\n\t\t\treturn `${toDeg(x)}°, ${toDeg(y)}°, ${toDeg(z)}°`;\n\t\t}\n\t\tconst { x, y, z } = this.entity.options.rotation || { x: 0, y: 0, z: 0 };\n\t\tconst toDeg = (rad: number) => (rad * 180 / Math.PI).toFixed(1);\n\t\treturn `${toDeg(x)}°, ${toDeg(y)}°, ${toDeg(z)}°`;\n\t}\n\n\t/**\n\t * Get material information\n\t */\n\tprivate getMaterialInfo(): Record<string, any> {\n\t\tif (!this.entity.mesh || !this.entity.mesh.material) {\n\t\t\treturn { type: 'none' };\n\t\t}\n\n\t\tconst material = Array.isArray(this.entity.mesh.material)\n\t\t\t? this.entity.mesh.material[0]\n\t\t\t: this.entity.mesh.material;\n\n\t\tconst info: Record<string, any> = {\n\t\t\ttype: material.type\n\t\t};\n\n\t\tif (material instanceof MeshStandardMaterial ||\n\t\t\tmaterial instanceof MeshBasicMaterial ||\n\t\t\tmaterial instanceof MeshPhongMaterial) {\n\t\t\tinfo.color = `#${material.color.getHexString()}`;\n\t\t\tinfo.opacity = material.opacity;\n\t\t\tinfo.transparent = material.transparent;\n\t\t}\n\n\t\tif ('roughness' in material) {\n\t\t\tinfo.roughness = material.roughness;\n\t\t}\n\n\t\tif ('metalness' in material) {\n\t\t\tinfo.metalness = material.metalness;\n\t\t}\n\n\t\treturn info;\n\t}\n\n\tprivate getPhysicsInfo(): Record<string, any> | null {\n\t\tif (!this.entity.body) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst info: Record<string, any> = {\n\t\t\ttype: this.entity.body.bodyType(),\n\t\t\tmass: this.entity.body.mass(),\n\t\t\tisEnabled: this.entity.body.isEnabled(),\n\t\t\tisSleeping: this.entity.body.isSleeping()\n\t\t};\n\n\t\tconst velocity = this.entity.body.linvel();\n\t\tinfo.velocity = `${velocity.x.toFixed(2)}, ${velocity.y.toFixed(2)}, ${velocity.z.toFixed(2)}`;\n\n\t\treturn info;\n\t}\n\n\tpublic buildDebugInfo(): Record<string, any> {\n\t\tconst defaultInfo: Record<string, any> = {\n\t\t\tname: this.entity.name || this.entity.uuid,\n\t\t\tuuid: this.entity.uuid,\n\t\t\tposition: this.getPositionString(),\n\t\t\trotation: this.getRotationString(),\n\t\t\tmaterial: this.getMaterialInfo()\n\t\t};\n\n\t\tconst physicsInfo = this.getPhysicsInfo();\n\t\tif (physicsInfo) {\n\t\t\tdefaultInfo.physics = physicsInfo;\n\t\t}\n\n\t\tif (this.entity.behaviors.length > 0) {\n\t\t\tdefaultInfo.behaviors = this.entity.behaviors.map(b => b.constructor.name);\n\t\t}\n\n\t\tif (hasDebugInfo(this.entity)) {\n\t\t\tconst customInfo = this.entity.getDebugInfo();\n\t\t\treturn { ...defaultInfo, ...customInfo };\n\t\t}\n\n\t\treturn defaultInfo;\n\t}\n}\n\nclass EnhancedDebugInfoBuilder {\n\tprivate customBuilder?: (options: GameEntityOptions) => Record<string, any>;\n\n\tconstructor(customBuilder?: (options: GameEntityOptions) => Record<string, any>) {\n\t\tthis.customBuilder = customBuilder;\n\t}\n\n\tbuildInfo(options: GameEntityOptions, entity?: GameEntity<any>): Record<string, any> {\n\t\tif (this.customBuilder) {\n\t\t\treturn this.customBuilder(options);\n\t\t}\n\n\t\tif (entity) {\n\t\t\tconst delegate = new DebugDelegate(entity);\n\t\t\treturn delegate.buildDebugInfo();\n\t\t}\n\n\t\tconst { x, y, z } = options.position || { x: 0, y: 0, z: 0 };\n\t\treturn {\n\t\t\tname: (options as any).name || 'unnamed',\n\t\t\tposition: `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`\n\t\t};\n\t}\n}\n","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { Color, Euler, Group, Quaternion, Vector3 } from 'three';\nimport {\n\tTextureLoader,\n\tSpriteMaterial,\n\tSprite as ThreeSprite,\n} from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { createEntity } from './create';\nimport {\n\tDestroyContext,\n\tSetupContext,\n\tUpdateContext,\n} from '../core/base-node-life-cycle';\nimport { DebugDelegate } from './delegates/debug';\nimport { standardShader } from '../graphics/shaders/standard.shader';\n\nexport type SpriteImage = { name: string; file: string };\nexport type SpriteAnimation = {\n\tname: string;\n\tframes: string[];\n\tspeed: number | number[];\n\tloop: boolean;\n};\n\ntype ZylemSpriteOptions = GameEntityOptions & {\n\timages?: SpriteImage[];\n\tanimations?: SpriteAnimation[];\n\tsize?: Vector3;\n\tcollisionSize?: Vector3;\n};\n\nimport { commonDefaults } from './common';\n\nconst spriteDefaults: ZylemSpriteOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n\timages: [],\n\tanimations: [],\n};\n\nexport class SpriteCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemSpriteOptions): ColliderDesc {\n\t\tconst size = options.collisionSize || options.size || new Vector3(1, 1, 1);\n\t\tconst half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };\n\t\tlet colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class SpriteBuilder extends EntityBuilder<ZylemSprite, ZylemSpriteOptions> {\n\tprotected createEntity(options: Partial<ZylemSpriteOptions>): ZylemSprite {\n\t\treturn new ZylemSprite(options);\n\t}\n}\n\nexport const SPRITE_TYPE = Symbol('Sprite');\n\nexport class ZylemSprite extends GameEntity<ZylemSpriteOptions> {\n\tstatic type = SPRITE_TYPE;\n\n\tprotected sprites: ThreeSprite[] = [];\n\tprotected spriteMap: Map<string, number> = new Map();\n\tprotected currentSpriteIndex: number = 0;\n\tprotected animations: Map<string, any> = new Map();\n\tprotected currentAnimation: any = null;\n\tprotected currentAnimationFrame: string = '';\n\tprotected currentAnimationIndex: number = 0;\n\tprotected currentAnimationTime: number = 0;\n\n\tconstructor(options?: ZylemSpriteOptions) {\n\t\tsuper();\n\t\tthis.options = { ...spriteDefaults, ...options };\n\t\t// Add sprite-specific lifecycle callbacks (only registered once)\n\t\tthis.prependSetup(this.spriteSetup.bind(this) as any);\n\t\tthis.prependUpdate(this.spriteUpdate.bind(this) as any);\n\t\tthis.onCleanup(this.spriteDestroy.bind(this) as any);\n\t}\n\n\tpublic create(): this {\n\t\t// Clear previous state to prevent accumulation on reload\n\t\tthis.sprites = [];\n\t\tthis.spriteMap.clear();\n\t\tthis.animations.clear();\n\t\tthis.currentAnimation = null;\n\t\tthis.currentAnimationFrame = '';\n\t\tthis.currentAnimationIndex = 0;\n\t\tthis.currentAnimationTime = 0;\n\t\tthis.group = undefined;\n\t\t\n\t\t// Recreate sprites and animations\n\t\tthis.createSpritesFromImages(this.options?.images || []);\n\t\tthis.createAnimations(this.options?.animations || []);\n\t\t\n\t\t// Call parent create\n\t\treturn super.create();\n\t}\n\n\tprotected createSpritesFromImages(images: SpriteImage[]) {\n\t\t// Use synchronous load() which returns a texture that updates when ready\n\t\t// This maintains compatibility with the synchronous create() method\n\t\tconst textureLoader = new TextureLoader();\n\t\tconst size = this.options.size ?? new Vector3(1, 1, 1);\n\t\timages.forEach((image, index) => {\n\t\t\tconst spriteMap = textureLoader.load(image.file);\n\t\t\tconst material = new SpriteMaterial({\n\t\t\t\tmap: spriteMap,\n\t\t\t\ttransparent: true,\n\t\t\t});\n\t\t\tconst _sprite = new ThreeSprite(material);\n\t\t\t_sprite.position.normalize();\n\t\t\t_sprite.scale.set(size.x, size.y, size.z);\n\t\t\t_sprite.visible = index === 0;\n\t\t\tthis.sprites.push(_sprite);\n\t\t\tthis.spriteMap.set(image.name, index);\n\t\t});\n\t\tthis.group = new Group();\n\t\tthis.group.add(...this.sprites);\n\t}\n\n\tprotected createAnimations(animations: SpriteAnimation[]) {\n\t\tanimations.forEach(animation => {\n\t\t\tconst { name, frames, loop = false, speed = 1 } = animation;\n\t\t\tconst internalAnimation = {\n\t\t\t\tframes: frames.map((frame, index) => ({\n\t\t\t\t\tkey: frame,\n\t\t\t\t\tindex,\n\t\t\t\t\ttime: (typeof speed === 'number' ? speed : speed[index]) * (index + 1),\n\t\t\t\t\tduration: typeof speed === 'number' ? speed : speed[index]\n\t\t\t\t})),\n\t\t\t\tloop,\n\t\t\t};\n\t\t\tthis.animations.set(name, internalAnimation);\n\t\t});\n\t}\n\n\tsetSprite(key: string) {\n\t\tconst spriteIndex = this.spriteMap.get(key);\n\t\tconst useIndex = spriteIndex ?? 0;\n\t\tthis.currentSpriteIndex = useIndex;\n\t\tthis.sprites.forEach((_sprite, i) => {\n\t\t\t_sprite.visible = this.currentSpriteIndex === i;\n\t\t});\n\t}\n\n\tsetAnimation(name: string, delta: number) {\n\t\tconst animation = this.animations.get(name);\n\t\tif (!animation) return;\n\n\t\tconst { loop, frames } = animation;\n\t\tconst frame = frames[this.currentAnimationIndex];\n\n\t\tif (name === this.currentAnimation) {\n\t\t\tthis.currentAnimationFrame = frame.key;\n\t\t\tthis.currentAnimationTime += delta;\n\t\t\tthis.setSprite(this.currentAnimationFrame);\n\t\t} else {\n\t\t\tthis.currentAnimation = name;\n\t\t}\n\n\t\tif (this.currentAnimationTime > frame.time) {\n\t\t\tthis.currentAnimationIndex++;\n\t\t}\n\n\t\tif (this.currentAnimationIndex >= frames.length) {\n\t\t\tif (loop) {\n\t\t\t\tthis.currentAnimationIndex = 0;\n\t\t\t\tthis.currentAnimationTime = 0;\n\t\t\t} else {\n\t\t\t\tthis.currentAnimationTime = frames[this.currentAnimationIndex].time;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getCurrentRotationQuaternion():\n\t\t| { x: number; y: number; z: number; w: number }\n\t\t| null {\n\t\tif (this.transformStore?.dirty.rotation) {\n\t\t\treturn this.transformStore.rotation;\n\t\t}\n\n\t\treturn this.body?.rotation?.() ?? null;\n\t}\n\n\tprivate syncSpriteMaterials(): void {\n\t\tconst q = this.getCurrentRotationQuaternion();\n\n\t\tthis.sprites.forEach(_sprite => {\n\t\t\tif (_sprite.material && q) {\n\t\t\t\tconst quat = new Quaternion(q.x, q.y, q.z, q.w);\n\t\t\t\tconst euler = new Euler().setFromQuaternion(quat, 'XYZ');\n\t\t\t\t_sprite.material.rotation = euler.z;\n\t\t\t}\n\t\t\t_sprite.scale.set(this.options.size?.x ?? 1, this.options.size?.y ?? 1, this.options.size?.z ?? 1);\n\t\t});\n\t}\n\n\tspriteSetup(_params: SetupContext<ZylemSpriteOptions>): void {\n\t\tthis.syncSpriteMaterials();\n\t}\n\n\tspriteUpdate(params: UpdateContext<ZylemSpriteOptions>): void {\n\t\tthis.syncSpriteMaterials();\n\t}\n\n\tspriteDestroy(params: DestroyContext<ZylemSpriteOptions>): void {\n\t\tthis.sprites.forEach(_sprite => {\n\t\t\t_sprite.removeFromParent();\n\t\t});\n\t\tthis.group?.remove(...this.sprites);\n\t\tthis.group?.removeFromParent();\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemSprite.type),\n\t\t};\n\t}\n}\n\ntype SpriteOptions = BaseNode | Partial<ZylemSpriteOptions>;\n\nexport function createSprite(...args: Array<SpriteOptions>): ZylemSprite {\n\treturn createEntity<ZylemSprite, ZylemSpriteOptions>({\n\t\targs,\n\t\tdefaultConfig: spriteDefaults,\n\t\tEntityClass: ZylemSprite,\n\t\tBuilderClass: SpriteBuilder,\n\t\tCollisionBuilderClass: SpriteCollisionBuilder,\n\t\tentityType: ZylemSprite.type,\n\t\tcloneFactory: (options) => createSprite(options ?? {}),\n\t});\n}\n","import { EntityBlueprint } from '../core/blueprints';\nimport { GameEntity, GameEntityOptions } from './entity';\nimport { createText } from './text';\nimport { createSprite } from './sprite';\n\ntype EntityCreator = (options: any) => GameEntity<any>;\n\nexport const EntityFactory = {\n registry: new Map<string, EntityCreator>(),\n\n register(type: string, creator: EntityCreator) {\n this.registry.set(type, creator);\n },\n\n createFromBlueprint(blueprint: EntityBlueprint): GameEntity<any> {\n const creator = this.registry.get(blueprint.type);\n if (!creator) {\n throw new Error(`Unknown entity type: ${blueprint.type}`);\n }\n\n const options: GameEntityOptions = {\n ...blueprint.data,\n position: blueprint.position ? { x: blueprint.position[0], y: blueprint.position[1], z: 0 } : undefined,\n name: blueprint.id,\n };\n\n const entity = creator(options);\n \n return entity;\n }\n};\n\nEntityFactory.register('text', (opts) => createText(opts) as unknown as GameEntity<any>);\nEntityFactory.register('sprite', (opts) => createSprite(opts) as unknown as GameEntity<any>);\n\n/**\n * Factory interface for generating entity copies\n */\nexport interface TemplateFactory<E extends GameEntity<O>, O extends GameEntityOptions = GameEntityOptions> {\n\t/** The template entity used for cloning */\n\treadonly template: E;\n\t\n\t/**\n\t * Generate multiple copies of the template entity\n\t * @param count Number of copies to generate\n\t * @returns Array of new entity instances\n\t */\n\tgenerate(count: number): E[];\n}\n\n/**\n * Create an entity factory from a template entity.\n * \n * @param template The entity to use as a template for cloning\n * @returns Factory object with generate() method\n * \n * @example\n * ```typescript\n * const asteroidTemplate = createSprite({ images: [{ name: 'asteroid', file: asteroidImg }] });\n * const asteroidFactory = createEntityFactory(asteroidTemplate);\n * const asteroids = asteroidFactory.generate(10);\n * \n * asteroids.forEach((asteroid, i) => {\n * asteroid.setPosition(Math.random() * 20 - 10, Math.random() * 15 - 7.5, 0);\n * stage.add(asteroid);\n * });\n * ```\n */\nexport function createEntityFactory<E extends GameEntity<O>, O extends GameEntityOptions = GameEntityOptions>(\n\ttemplate: E\n): TemplateFactory<E, O> {\n\treturn {\n\t\ttemplate,\n\t\t\n\t\tgenerate(count: number): E[] {\n\t\t\tconst entities: E[] = [];\n\t\t\t\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tentities.push(template.clone());\n\t\t\t}\n\t\t\t\n\t\t\treturn entities;\n\t\t}\n\t};\n}\n","// Core game functionality\nexport { createGame, Game } from '../lib/game/game';\nexport type { ZylemGameConfig } from '../lib/game/game-interfaces';\nexport { gameConfig } from '../lib/game/game-config';\nexport type {\n\tGameConfigLike,\n\tGameDeviceConfig,\n\tResolutionInput,\n\tDeviceProfile,\n\tResolveGameConfigRuntime,\n} from '../lib/game/game-config';\nexport { AspectRatio } from '../lib/device/aspect-ratio';\nexport type { AspectRatioValue } from '../lib/device/aspect-ratio';\nexport { getDisplayAspect, getPresetResolution, parseResolution } from '../lib/game/game-retro-resolutions';\nexport type { RetroPreset, RetroPresetKey, RetroResolution } from '../lib/game/game-retro-resolutions';\n\nexport { createStage } from '../lib/stage/stage';\nexport { entitySpawner } from '../lib/stage/entity-spawner';\nexport type { StageOptions, LoadingEvent } from '../lib/stage/zylem-stage';\nexport type { StageBlueprint } from '../lib/core/blueprints';\nexport { StageManager, stageState } from '../lib/stage/stage-manager';\n\nexport { vessel } from '../lib/core/vessel';\n\n// Camera\nexport { createCamera } from '../lib/camera/camera';\nexport type { CameraOptions } from '../lib/camera/camera';\nexport { CameraWrapper } from '../lib/camera/camera';\nexport type { PerspectiveType } from '../lib/camera/perspective';\nexport { Perspectives } from '../lib/camera/perspective';\nexport type { RendererType, ZylemRenderer, Viewport } from '../lib/camera/renderer-manager';\nexport { isWebGPUSupported } from '../lib/camera/renderer-manager';\nexport { CameraManager } from '../lib/camera/camera-manager';\n\n// Camera pipeline types\nexport type {\n\tCameraPose, PoseDelta, CameraContext, TransformLike,\n\tCameraPerspective, CameraBehavior, CameraAction, CameraPipelineState,\n} from '../lib/camera/types';\nexport { CameraPipeline } from '../lib/camera/camera-pipeline';\n\n// Camera perspectives\nexport { ThirdPersonPerspective, Fixed2DPerspective, FirstPersonPerspective, createPerspective } from '../lib/camera/perspectives';\nexport type { ThirdPersonOptions, Fixed2DOptions, FirstPersonOptions, PerspectiveOptions } from '../lib/camera/perspectives';\n\n// Camera behaviors\nexport { createFollowTarget } from '../lib/camera/behaviors/follow-target';\nexport type { FollowTargetOptions } from '../lib/camera/behaviors/follow-target';\n\n// Camera feed (render-to-texture utilities)\nexport { setCameraFeed } from '../lib/camera/camera-feed';\nexport type { CameraFeedOptions } from '../lib/camera/camera-feed';\n\n// Utility types\nexport type { Vect3 } from '../lib/core/utility/vector';\n\n// Entities\nexport { createBox } from '../lib/entities/box';\nexport { createSphere } from '../lib/entities/sphere';\nexport { createSprite } from '../lib/entities/sprite';\nexport { createPlane } from '../lib/entities/plane';\nexport { createZone } from '../lib/entities/zone';\nexport { createActor } from '../lib/entities/actor';\nexport { createText } from '../lib/entities/text';\nexport { createRect } from '../lib/entities/rect';\nexport { createDisk } from '../lib/entities/disk';\nexport { createCone } from '../lib/entities/cone';\nexport { createPyramid } from '../lib/entities/pyramid';\nexport { createCylinder } from '../lib/entities/cylinder';\nexport { createPill } from '../lib/entities/pill';\nexport { createEntityFactory, type TemplateFactory } from '../lib/entities/entity-factory';\nexport { ZylemBox } from '../lib/entities/box';\nexport { create } from '../lib/entities/entity';\n\n// Component factories for composable entity API\nexport {\n\tboxMesh, sphereMesh, coneMesh, pyramidMesh, cylinderMesh, pillMesh,\n\tboxCollision, sphereCollision, coneCollision, pyramidCollision,\n\tcylinderCollision, pillCollision, planeCollision, zoneCollision,\n\ttype CollisionComponent,\n} from '../lib/entities/parts';\n\n// ECS Components & Behaviors (new thruster system)\nexport * from '../lib/behaviors';\n\n// Standalone action functions (capabilities are auto-applied on all entities)\nexport { rotateInDirection } from '../lib/actions/capabilities/rotatable';\nexport { move, resetVelocity } from '../lib/actions/capabilities/moveable';\n\n// Actions API (Cocos2d-inspired)\nexport { type Action } from '../lib/actions/action';\nexport { moveBy, moveTo, rotateBy, delay, callFunc } from '../lib/actions/interval-actions';\nexport { throttle, onPress, onRelease } from '../lib/actions/persistent-actions';\nexport { sequence, parallel, repeat, repeatForever } from '../lib/actions/composition';\n\n// Cooldown system\nexport {\n\tCooldownBehavior,\n\tregisterCooldown, getCooldown, fireCooldown, resetCooldown,\n\ttype CooldownEntry, type CooldownHandle, type CooldownOptions,\n} from '../lib/behaviors/cooldown';\nexport { createCooldownIcon, type IconSize, type IconSizePreset, type ScreenAnchor } from '../lib/entities/cooldown-icon';\n\n// Destruction utilities\nexport { destroy } from '../lib/entities/destroy';\n\n// Sounds\nexport { ricochetSound, pingPongBeep } from '../lib/sounds';\n\n// External dependencies - these will be in separate vendor chunks\nexport { Howl } from 'howler';\nexport * as THREE from 'three';\nexport * as RAPIER from '@dimforge/rapier3d-compat';\n\n// Update helpers\nexport { globalChange, globalChanges, variableChange, variableChanges } from '../lib/actions/global-change';\n\n// Input presets\nexport {\n\tuseArrowsForAxes,\n\tuseArrowsForSecondaryAxes,\n\tuseArrowsForDirections,\n\tuseWASDForDirections,\n\tuseWASDForAxes,\n\tuseIJKLForAxes,\n\tuseIJKLForDirections,\n\tuseMouseLook,\n\tuseMouse,\n\tmergeInputConfigs,\n} from '../lib/input/input-presets';\n\n// State management - standalone functions\nexport { setGlobal, getGlobal, createGlobal, onGlobalChange, onGlobalChanges, getGlobals, clearGlobalSubscriptions } from '../lib/game/game-state';\nexport { setVariable, getVariable, createVariable, onVariableChange, onVariableChanges } from '../lib/stage/stage-state';\n\n// Debug state - exposed for direct mutation by editor integration\nexport { debugState, setDebugTool, setPaused, type DebugTools } from '../lib/debug/debug-state';\n\n// Web Components\nexport { ZylemGameElement, type ZylemGameState } from '../web-components/zylem-game';\n\n// Lifecycle types\nexport type { SetupContext, UpdateContext } from '../lib/core/base-node-life-cycle';\n\n// Interfaces\nexport type { StageEntity } from '../lib/interfaces/entity';\n\n// Entity type symbols for getEntityByName type inference\nexport {\n\tTEXT_TYPE, SPRITE_TYPE, BOX_TYPE, SPHERE_TYPE,\n\tRECT_TYPE, PLANE_TYPE, ZONE_TYPE, ACTOR_TYPE,\n\tCONE_TYPE, PYRAMID_TYPE, CYLINDER_TYPE, PILL_TYPE,\n} from '../lib/types/entity-type-map';\n\n// Events\nexport {\n\tEventEmitterDelegate,\n\tzylemEventBus,\n\ttype ZylemEvents,\n\ttype GameEvents,\n\ttype StageEvents,\n\ttype EntityEvents,\n\ttype GameLoadingPayload,\n\ttype StateDispatchPayload,\n\ttype StageConfigPayload,\n\ttype EntityConfigPayload,\n} from '../lib/events';\n\n// Shaders\nexport { fireShader } from '../lib/graphics/shaders/fire.shader';\nexport { starShader } from '../lib/graphics/shaders/star.shader';\nexport { standardShader } from '../lib/graphics/shaders/standard.shader';\nexport { debugShader } from '../lib/graphics/shaders/debug.shader';\nexport { objectVertexShader } from '../lib/graphics/shaders/vertex/object.shader';\nexport type { ZylemShaderObject, ZylemTSLShader, ZylemShader } from '../lib/graphics/material';\nexport { isTSLShader, isGLSLShader } from '../lib/graphics/material';\n\n// TSL utilities for shader authoring (WebGPU)\nexport { uniform, uv, time, vec3, vec4, float, Fn } from '../lib/graphics/material';\n","import { Euler, Quaternion, Vector2 } from \"three\";\nimport { GameEntity } from \"../entities\";\nimport { Stage } from \"./stage\";\n\nexport interface EntitySpawner {\n\tspawn: (stage: Stage, x: number, y: number) => Promise<GameEntity<any>>;\n\tspawnRelative: (source: any, stage: Stage, offset?: Vector2) => Promise<any | void>;\n}\n\nexport function entitySpawner(factory: (x: number, y: number) => Promise<any> | GameEntity<any>): EntitySpawner {\n\treturn {\n\t\tspawn: async (stage: Stage, x: number, y: number) => {\n\t\t\tconst instance = await Promise.resolve(factory(x, y));\n\t\t\tstage.add(instance);\n\t\t\treturn instance;\n\t\t},\n\t\tspawnRelative: async (source: any, stage: Stage, offset: Vector2 = new Vector2(0, 1)) => {\n\t\t\tif (!source.body) {\n\t\t\t\tconsole.warn('body missing for entity during spawnRelative');\n\t\t\t\treturn undefined;\n\t\t\t}\n\n\t\t\tconst { x, y, z } = source.body.translation();\n\t\t\tlet rz = (source as any)._rotation2DAngle ?? 0;\n\t\t\ttry {\n\t\t\t\tconst r = source.body.rotation();\n\t\t\t\tconst q = new Quaternion(r.x, r.y, r.z, r.w);\n\t\t\t\tconst e = new Euler().setFromQuaternion(q, 'XYZ');\n\t\t\t\trz = e.z;\n\t\t\t} catch { /* use fallback angle */ }\n\n\t\t\tconst offsetX = Math.sin(-rz) * (offset.x ?? 0);\n\t\t\tconst offsetY = Math.cos(-rz) * (offset.y ?? 0);\n\n\t\t\tconst instance = await Promise.resolve(factory(x + offsetX, y + offsetY));\n\t\t\tstage.add(instance);\n\t\t\treturn instance;\n\t\t}\n\t};\n}","import { Vector3 } from 'three';\nimport type { CameraBehavior, CameraContext, CameraPose } from '../types';\nimport { clonePose } from '../smoothing';\n\n/**\n * Options for the followTarget behavior.\n */\nexport interface FollowTargetOptions {\n\t/** Key in CameraContext.targets to follow. Default 'primary'. */\n\ttargetKey?: string;\n\t/** Position offset from the target. Default (0, 0, 0). */\n\toffset?: Vector3;\n\t/**\n\t * Per-frame interpolation factor (0-1). Controls how quickly the\n\t * pose converges on the target each frame.\n\t * 1 = instant snap, lower = smoother follow.\n\t * Default 0.1.\n\t */\n\tlerpFactor?: number;\n}\n\nconst DEFAULTS: Required<FollowTargetOptions> = {\n\ttargetKey: 'primary',\n\toffset: new Vector3(0, 0, 0),\n\tlerpFactor: 0.1,\n};\n\n/**\n * A simple follow behavior that moves the camera pose toward a target's position + offset.\n *\n * This behavior modifies only the position (and lookAt) of the incoming pose,\n * leaving rotation/fov/zoom to the perspective or other behaviors.\n *\n * @example\n * ```ts\n * camera.addBehavior('follow', createFollowTarget({ targetKey: 'player', offset: new Vector3(0, 3, 8) }));\n * ```\n */\nexport function createFollowTarget(options?: FollowTargetOptions): CameraBehavior {\n\tconst opts = { ...DEFAULTS, ...options };\n\n\t// Internal state for smooth interpolation\n\tlet currentPos: Vector3 | null = null;\n\n\treturn {\n\t\tpriority: 0,\n\t\tenabled: true,\n\n\t\tonAttach() {\n\t\t\tcurrentPos = null;\n\t\t},\n\n\t\tupdate(ctx: CameraContext, pose: CameraPose): CameraPose {\n\t\t\tconst target = ctx.targets[opts.targetKey];\n\t\t\tif (!target) return pose;\n\n\t\t\tconst desiredPos = target.position.clone().add(opts.offset);\n\t\t\tconst result = clonePose(pose);\n\n\t\t\tif (!currentPos) {\n\t\t\t\tcurrentPos = desiredPos.clone();\n\t\t\t} else {\n\t\t\t\tcurrentPos.lerp(desiredPos, opts.lerpFactor);\n\t\t\t}\n\n\t\t\tresult.position.copy(currentPos);\n\t\t\tresult.lookAt = target.position.clone();\n\n\t\t\treturn result;\n\t\t},\n\n\t\tonDetach() {\n\t\t\tcurrentPos = null;\n\t\t},\n\t};\n}\n","import { MeshBasicMaterial } from 'three';\nimport type { StageEntity } from '../interfaces/entity';\nimport type { CameraWrapper } from './camera';\n\n/**\n * Options for setCameraFeed.\n */\nexport interface CameraFeedOptions {\n\t/** Render target width in pixels. Only used when the camera does not\n\t * already have a render target. @default 512 */\n\twidth?: number;\n\t/** Render target height in pixels. Only used when the camera does not\n\t * already have a render target. @default 512 */\n\theight?: number;\n}\n\n/**\n * Display a camera's live feed on an entity's mesh surface.\n *\n * This is the primary user-facing function for \"jumbotron\", security-camera,\n * or broadcast-style effects. It ensures the camera has an offscreen render\n * target and replaces the entity's mesh material with one that shows the\n * camera's rendered output.\n *\n * @param entity The entity whose mesh will display the camera feed.\n * @param camera The camera whose view will be rendered to the texture.\n * @param options Optional dimensions for the render target.\n *\n * @example\n * ```ts\n * const feedCam = createCamera({\n * perspective: Perspectives.ThirdPerson,\n * position: new Vector3(0, 30, 60),\n * target: new Vector3(0, 0, 0),\n * renderToTexture: { width: 1024, height: 576 },\n * });\n *\n * const screen = createBox({ size: { x: 16, y: 9, z: 0.2 } });\n * screen.onSetup(({ me }) => {\n * setCameraFeed(me, feedCam);\n * });\n * ```\n */\nexport function setCameraFeed(\n\tentity: StageEntity,\n\tcamera: CameraWrapper,\n\toptions?: CameraFeedOptions,\n): void {\n\tconst cam = camera.cameraRef;\n\n\t// Ensure the camera has a render target\n\tif (!cam.renderTarget) {\n\t\tconst w = options?.width ?? 512;\n\t\tconst h = options?.height ?? 512;\n\t\tcam.createRenderTarget(w, h);\n\t}\n\n\tconst texture = cam.getRenderTexture();\n\tif (!texture) {\n\t\tconsole.warn('setCameraFeed: Failed to obtain render texture from camera.');\n\t\treturn;\n\t}\n\n\tif (!entity.mesh) {\n\t\tconsole.warn('setCameraFeed: Entity has no mesh to apply the camera feed to.');\n\t\treturn;\n\t}\n\n\t// Replace the mesh material with one that displays the camera feed\n\tconst material = new MeshBasicMaterial({ map: texture });\n\tentity.mesh.material = material;\n}\n","import { Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { finalizeEntityCloneSupport, GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { boxMesh } from './parts/mesh-factories';\nimport { boxCollision } from './parts/collision-factories';\n\ntype ZylemBoxOptions = GameEntityOptions;\n\nconst boxDefaults: ZylemBoxOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n};\n\nexport const BOX_TYPE = Symbol('Box');\n\nexport class ZylemBox extends GameEntity<ZylemBoxOptions> {\n\tstatic type = BOX_TYPE;\n\n\tconstructor(options?: ZylemBoxOptions) {\n\t\tsuper();\n\t\tthis.options = { ...boxDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\tconst { x: sizeX, y: sizeY, z: sizeZ } = this.options.size ?? { x: 1, y: 1, z: 1 };\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemBox.type),\n\t\t\tsize: `${sizeX}, ${sizeY}, ${sizeZ}`,\n\t\t};\n\t}\n}\n\ntype BoxOptions = BaseNode | Partial<ZylemBoxOptions>;\n\nexport function createBox(...args: Array<BoxOptions>): ZylemBox {\n\tconst options = mergeArgs(args, boxDefaults);\n\tconst entity = new ZylemBox(options);\n\tentity.add(\n\t\tboxMesh({ size: options.size, material: options.material, color: options.color }),\n\t\tboxCollision({\n\t\t\tsize: options.size,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn finalizeEntityCloneSupport(\n\t\tentity,\n\t\t(cloneOptions) => createBox(cloneOptions ?? {}),\n\t);\n}\n","import {\n\tBoxGeometry,\n\tCapsuleGeometry,\n\tConeGeometry,\n\tCylinderGeometry,\n\tMesh,\n\tMeshStandardMaterial,\n\tSphereGeometry,\n\ttype Color,\n} from 'three';\nimport { MaterialBuilder, type MaterialOptions } from '../../graphics/material';\nimport type { Vec3 } from '../../core/vector';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Shared options that every mesh factory accepts. */\ninterface BaseMeshOptions {\n\t/** Offset position relative to the entity origin */\n\tposition?: Vec3;\n\t/** Material options (texture, shader, etc.) */\n\tmaterial?: Partial<MaterialOptions>;\n\t/** Convenience color override */\n\tcolor?: Color;\n}\n\n/**\n * Build a material array from options.\n * Returns a fallback MeshStandardMaterial when no material options are provided.\n */\nfunction buildMaterial(\n\topts: BaseMeshOptions,\n\tentityType: symbol = Symbol('mesh'),\n): MeshStandardMaterial[] {\n\tif (opts.material || opts.color) {\n\t\tconst builder = new MaterialBuilder();\n\t\tbuilder.build(\n\t\t\t{ ...opts.material, color: opts.color ?? opts.material?.color },\n\t\t\tentityType,\n\t\t);\n\t\tif (builder.materials.length > 0) {\n\t\t\treturn builder.materials as MeshStandardMaterial[];\n\t\t}\n\t}\n\treturn [new MeshStandardMaterial()];\n}\n\nfunction finalizeMesh(mesh: Mesh, opts: BaseMeshOptions): Mesh {\n\tif (opts.position) {\n\t\tmesh.position.set(opts.position.x, opts.position.y, opts.position.z);\n\t}\n\tmesh.castShadow = true;\n\tmesh.receiveShadow = true;\n\treturn mesh;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Box\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BoxMeshOptions extends BaseMeshOptions {\n\t/** Box dimensions (default: 1x1x1) */\n\tsize?: Vec3;\n}\n\n/**\n * Create a box mesh.\n */\nexport function boxMesh(opts: BoxMeshOptions = {}): Mesh {\n\tconst size = opts.size ?? { x: 1, y: 1, z: 1 };\n\tconst geometry = new BoxGeometry(size.x, size.y, size.z);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Sphere\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SphereMeshOptions extends BaseMeshOptions {\n\t/** Sphere radius (default: 1) */\n\tradius?: number;\n}\n\n/**\n * Create a sphere mesh.\n */\nexport function sphereMesh(opts: SphereMeshOptions = {}): Mesh {\n\tconst geometry = new SphereGeometry(opts.radius ?? 1);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cone\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ConeMeshOptions extends BaseMeshOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n\t/** Radial segments (default: 32) */\n\tradialSegments?: number;\n}\n\n/**\n * Create a cone mesh.\n */\nexport function coneMesh(opts: ConeMeshOptions = {}): Mesh {\n\tconst geometry = new ConeGeometry(\n\t\topts.radius ?? 1,\n\t\topts.height ?? 2,\n\t\topts.radialSegments ?? 32,\n\t);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pyramid (cone geometry with 4 segments)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PyramidMeshOptions extends BaseMeshOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a pyramid mesh (4-sided cone).\n */\nexport function pyramidMesh(opts: PyramidMeshOptions = {}): Mesh {\n\tconst geometry = new ConeGeometry(opts.radius ?? 1, opts.height ?? 2, 4);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cylinder\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface CylinderMeshOptions extends BaseMeshOptions {\n\t/** Top radius (default: 1) */\n\tradiusTop?: number;\n\t/** Bottom radius (default: 1) */\n\tradiusBottom?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n\t/** Radial segments (default: 32) */\n\tradialSegments?: number;\n}\n\n/**\n * Create a cylinder mesh.\n */\nexport function cylinderMesh(opts: CylinderMeshOptions = {}): Mesh {\n\tconst geometry = new CylinderGeometry(\n\t\topts.radiusTop ?? 1,\n\t\topts.radiusBottom ?? 1,\n\t\topts.height ?? 2,\n\t\topts.radialSegments ?? 32,\n\t);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pill (capsule)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PillMeshOptions extends BaseMeshOptions {\n\t/** Capsule hemisphere radius (default: 0.5) */\n\tradius?: number;\n\t/** Cylindrical section length (default: 1) */\n\tlength?: number;\n\t/** Cap segments (default: 10) */\n\tcapSegments?: number;\n\t/** Radial segments (default: 20) */\n\tradialSegments?: number;\n}\n\n/**\n * Create a pill (capsule) mesh.\n */\nexport function pillMesh(opts: PillMeshOptions = {}): Mesh {\n\tconst geometry = new CapsuleGeometry(\n\t\topts.radius ?? 0.5,\n\t\topts.length ?? 1,\n\t\topts.capSegments ?? 10,\n\t\topts.radialSegments ?? 20,\n\t);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n","import { BaseNode } from '../core/base-node';\nimport { finalizeEntityCloneSupport, GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { sphereMesh } from './parts/mesh-factories';\nimport { sphereCollision } from './parts/collision-factories';\n\ntype ZylemSphereOptions = GameEntityOptions & {\n\tradius?: number;\n};\n\nconst sphereDefaults: ZylemSphereOptions = {\n\t...commonDefaults,\n\tradius: 1,\n};\n\nexport const SPHERE_TYPE = Symbol('Sphere');\n\nexport class ZylemSphere extends GameEntity<ZylemSphereOptions> {\n\tstatic type = SPHERE_TYPE;\n\n\tconstructor(options?: ZylemSphereOptions) {\n\t\tsuper();\n\t\tthis.options = { ...sphereDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 1;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemSphere.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t};\n\t}\n}\n\ntype SphereOptions = BaseNode | Partial<ZylemSphereOptions>;\n\nexport function createSphere(...args: Array<SphereOptions>): ZylemSphere {\n\tconst options = mergeArgs(args, sphereDefaults);\n\tconst entity = new ZylemSphere(options);\n\tentity.add(\n\t\tsphereMesh({ radius: options.radius, material: options.material, color: options.color }),\n\t\tsphereCollision({\n\t\t\tradius: options.radius,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn finalizeEntityCloneSupport(\n\t\tentity,\n\t\t(cloneOptions) => createSphere(cloneOptions ?? {}),\n\t);\n}\n","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { PlaneGeometry, Vector2, Vector3 } from 'three';\nimport { TexturePath } from '../graphics/material';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { EntityMeshBuilder } from './builder';\nimport { XZPlaneGeometry } from '../graphics/geometries/XZPlaneGeometry';\nimport { createEntity } from './create';\n\ntype ZylemPlaneOptions = GameEntityOptions & {\n\ttile?: Vector2;\n\trepeat?: Vector2;\n\ttexture?: TexturePath;\n\tsubdivisions?: number;\n\trandomizeHeight?: boolean;\n\theightMap?: number[];\n\theightScale?: number;\n};\n\nconst DEFAULT_SUBDIVISIONS = 4;\n\nimport { commonDefaults } from './common';\n\nconst planeDefaults: ZylemPlaneOptions = {\n\t...commonDefaults,\n\ttile: new Vector2(10, 10),\n\trepeat: new Vector2(1, 1),\n\tcollision: {\n\t\tstatic: true,\n\t},\n\tsubdivisions: DEFAULT_SUBDIVISIONS,\n\trandomizeHeight: false,\n\theightScale: 1,\n};\n\nexport class PlaneCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemPlaneOptions): ColliderDesc {\n\t\tconst tile = options.tile ?? new Vector2(1, 1);\n\t\tconst subdivisions = options.subdivisions ?? DEFAULT_SUBDIVISIONS;\n\t\tconst size = new Vector3(tile.x, 1, tile.y);\n\n\t\tconst heightData = (options._builders?.meshBuilder as unknown as PlaneMeshBuilder)?.heightData;\n\t\tconst scale = new Vector3(size.x, 1, size.z);\n\t\tlet colliderDesc = ColliderDesc.heightfield(\n\t\t\tsubdivisions,\n\t\t\tsubdivisions,\n\t\t\theightData,\n\t\t\tscale\n\t\t);\n\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class PlaneMeshBuilder extends EntityMeshBuilder {\n\theightData: Float32Array = new Float32Array();\n\tcolumnsRows = new Map();\n\tprivate subdivisions: number = DEFAULT_SUBDIVISIONS;\n\n\tbuild(options: ZylemPlaneOptions): XZPlaneGeometry {\n\t\tconst tile = options.tile ?? new Vector2(1, 1);\n\t\tconst subdivisions = options.subdivisions ?? DEFAULT_SUBDIVISIONS;\n\t\tthis.subdivisions = subdivisions;\n\t\tconst size = new Vector3(tile.x, 1, tile.y);\n\t\tconst heightScale = options.heightScale ?? 1;\n\n\t\tconst geometry = new XZPlaneGeometry(size.x, size.z, subdivisions, subdivisions);\n\t\tconst vertexGeometry = new PlaneGeometry(size.x, size.z, subdivisions, subdivisions);\n\t\tconst dx = size.x / subdivisions;\n\t\tconst dy = size.z / subdivisions;\n\t\tconst originalVertices = geometry.attributes.position.array;\n\t\tconst vertices = vertexGeometry.attributes.position.array;\n\t\tconst columsRows = new Map();\n\n\t\t// Get height data source\n\t\tconst heightMapData = options.heightMap;\n\t\tconst useRandomHeight = options.randomizeHeight ?? false;\n\n\t\tfor (let i = 0; i < vertices.length; i += 3) {\n\t\t\tconst vertexIndex = i / 3;\n\t\t\tlet row = Math.floor(Math.abs((vertices as any)[i] + (size.x / 2)) / dx);\n\t\t\tlet column = Math.floor(Math.abs((vertices as any)[i + 1] - (size.z / 2)) / dy);\n\n\t\t\tlet height = 0;\n\t\t\tif (heightMapData && heightMapData.length > 0) {\n\t\t\t\t// Loop the height map data if it doesn't cover all vertices\n\t\t\t\tconst heightIndex = vertexIndex % heightMapData.length;\n\t\t\t\theight = heightMapData[heightIndex] * heightScale;\n\t\t\t} else if (useRandomHeight) {\n\t\t\t\theight = Math.random() * 4 * heightScale;\n\t\t\t}\n\n\t\t\t(vertices as any)[i + 2] = height;\n\t\t\toriginalVertices[i + 1] = height;\n\t\t\tif (!columsRows.get(column)) {\n\t\t\t\tcolumsRows.set(column, new Map());\n\t\t\t}\n\t\t\tcolumsRows.get(column).set(row, height);\n\t\t}\n\t\tthis.columnsRows = columsRows;\n\t\treturn geometry;\n\t}\n\n\tpostBuild(): void {\n\t\tconst heights = [];\n\t\tfor (let i = 0; i <= this.subdivisions; ++i) {\n\t\t\tfor (let j = 0; j <= this.subdivisions; ++j) {\n\t\t\t\tconst row = this.columnsRows.get(j);\n\t\t\t\tif (!row) {\n\t\t\t\t\theights.push(0);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst data = row.get(i);\n\t\t\t\theights.push(data ?? 0);\n\t\t\t}\n\t\t}\n\t\tthis.heightData = new Float32Array(heights as unknown as number[]);\n\t}\n}\n\nexport class PlaneBuilder extends EntityBuilder<ZylemPlane, ZylemPlaneOptions> {\n\tprotected createEntity(options: Partial<ZylemPlaneOptions>): ZylemPlane {\n\t\treturn new ZylemPlane(options);\n\t}\n}\n\nexport const PLANE_TYPE = Symbol('Plane');\n\nexport class ZylemPlane extends GameEntity<ZylemPlaneOptions> {\n\tstatic type = PLANE_TYPE;\n\n\tconstructor(options?: ZylemPlaneOptions) {\n\t\tsuper();\n\t\tthis.options = { ...planeDefaults, ...options };\n\t}\n}\n\ntype PlaneOptions = BaseNode | Partial<ZylemPlaneOptions>;\n\nexport function createPlane(...args: Array<PlaneOptions>): ZylemPlane {\n\treturn createEntity<ZylemPlane, ZylemPlaneOptions>({\n\t\targs,\n\t\tdefaultConfig: planeDefaults,\n\t\tEntityClass: ZylemPlane,\n\t\tBuilderClass: PlaneBuilder,\n\t\tMeshBuilderClass: PlaneMeshBuilder,\n\t\tCollisionBuilderClass: PlaneCollisionBuilder,\n\t\tentityType: ZylemPlane.type,\n\t\tcloneFactory: (options) => createPlane(options ?? {}),\n\t});\n}\n","// @ts-nocheck\nimport { BufferGeometry, Float32BufferAttribute } from 'three';\n\nclass XZPlaneGeometry extends BufferGeometry {\n\n\tconstructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) {\n\n\t\tsuper();\n\n\t\tthis.type = 'XZPlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tconst width_half = width / 2;\n\t\tconst height_half = height / 2;\n\n\t\tconst gridX = Math.floor(widthSegments);\n\t\tconst gridY = Math.floor(heightSegments);\n\n\t\tconst gridX1 = gridX + 1;\n\t\tconst gridY1 = gridY + 1;\n\n\t\tconst segment_width = width / gridX;\n\t\tconst segment_height = height / gridY;\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\tfor (let iy = 0; iy < gridY1; iy++) {\n\n\t\t\tconst z = iy * segment_height - height_half;\n\n\t\t\tfor (let ix = 0; ix < gridX1; ix++) {\n\n\t\t\t\tconst x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push(x, 0, z);\n\n\t\t\t\tnormals.push(0, 1, 0);\n\n\t\t\t\tuvs.push(ix / gridX);\n\t\t\t\tuvs.push(1 - (iy / gridY));\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor (let iy = 0; iy < gridY; iy++) {\n\n\t\t\tfor (let ix = 0; ix < gridX; ix++) {\n\n\t\t\t\tconst a = ix + gridX1 * iy;\n\t\t\t\tconst b = ix + gridX1 * (iy + 1);\n\t\t\t\tconst c = (ix + 1) + gridX1 * (iy + 1);\n\t\t\t\tconst d = (ix + 1) + gridX1 * iy;\n\n\t\t\t\tindices.push(a, b, d);\n\t\t\t\tindices.push(b, c, d);\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex(indices);\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\tthis.setAttribute('normal', new Float32BufferAttribute(normals, 3));\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvs, 2));\n\n\t}\n\n\tcopy(source) {\n\n\t\tsuper.copy(source);\n\n\t\tthis.parameters = Object.assign({}, source.parameters);\n\n\t\treturn this;\n\t}\n\n\tstatic fromJSON(data) {\n\t\treturn new XZPlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments);\n\t}\n\n}\n\nexport { XZPlaneGeometry };","import { Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { finalizeEntityCloneSupport, GameEntityOptions, GameEntity } from './entity';\nimport { CollisionHandlerDelegate } from '../collision/world';\nimport { state } from '../game/game-state';\nimport { commonDefaults, mergeArgs } from './common';\nimport { zoneCollision } from './parts/collision-factories';\n\nexport type OnHeldParams = {\n\tdelta: number;\n\tself: ZylemZone;\n\tvisitor: GameEntity<any>;\n\theldTime: number;\n\tglobals: any;\n}\n\nexport type OnEnterParams = Pick<OnHeldParams, 'self' | 'visitor' | 'globals'>;\nexport type OnExitParams = Pick<OnHeldParams, 'self' | 'visitor' | 'globals'>;\n\ntype ZylemZoneOptions = GameEntityOptions & {\n\tsize?: Vector3;\n\tstatic?: boolean;\n\tonEnter?: (params: OnEnterParams) => void;\n\tonHeld?: (params: OnHeldParams) => void;\n\tonExit?: (params: OnExitParams) => void;\n};\n\nconst zoneDefaults: ZylemZoneOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n\tcollision: {\n\t\tstatic: true,\n\t},\n};\n\nexport const ZONE_TYPE = Symbol('Zone');\n\nexport class ZylemZone extends GameEntity<ZylemZoneOptions> implements CollisionHandlerDelegate {\n\tstatic type = ZONE_TYPE;\n\n\tprivate _enteredZone: Map<string, number> = new Map();\n\tprivate _exitedZone: Map<string, number> = new Map();\n\tprivate _zoneEntities: Map<string, any> = new Map();\n\n\tconstructor(options?: ZylemZoneOptions) {\n\t\tsuper();\n\t\tthis.options = { ...zoneDefaults, ...options };\n\t}\n\n\tpublic handlePostCollision({ delta }: { delta: number }): boolean {\n\t\tthis._enteredZone.forEach((val, key) => {\n\t\t\tthis.exited(delta, key);\n\t\t});\n\t\treturn this._enteredZone.size > 0;\n\t}\n\n\tpublic handleIntersectionEvent({ other, delta }: { other: any, delta: number }) {\n\t\tconst hasEntered = this._enteredZone.get(other.uuid);\n\t\tif (!hasEntered) {\n\t\t\tthis.entered(other);\n\t\t\tthis._zoneEntities.set(other.uuid, other);\n\t\t} else {\n\t\t\tthis.held(delta, other);\n\t\t}\n\t}\n\n\tonEnter(callback: (params: OnEnterParams) => void) {\n\t\tthis.options.onEnter = callback;\n\t\treturn this;\n\t}\n\n\tonHeld(callback: (params: OnHeldParams) => void) {\n\t\tthis.options.onHeld = callback;\n\t\treturn this;\n\t}\n\n\tonExit(callback: (params: OnExitParams) => void) {\n\t\tthis.options.onExit = callback;\n\t\treturn this;\n\t}\n\n\tentered(other: any) {\n\t\tthis._enteredZone.set(other.uuid, 1);\n\t\tif (this.options.onEnter) {\n\t\t\tthis.options.onEnter({\n\t\t\t\tself: this,\n\t\t\t\tvisitor: other,\n\t\t\t\tglobals: state.globals\n\t\t\t});\n\t\t}\n\t}\n\n\texited(delta: number, key: string) {\n\t\tconst hasExited = this._exitedZone.get(key);\n\t\tif (hasExited && hasExited > 1 + delta) {\n\t\t\tthis._exitedZone.delete(key);\n\t\t\tthis._enteredZone.delete(key);\n\t\t\tconst other = this._zoneEntities.get(key);\n\t\t\tif (this.options.onExit) {\n\t\t\t\tthis.options.onExit({\n\t\t\t\t\tself: this,\n\t\t\t\t\tvisitor: other,\n\t\t\t\t\tglobals: state.globals\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._exitedZone.set(key, 1 + delta);\n\t}\n\n\theld(delta: number, other: any) {\n\t\tconst heldTime = this._enteredZone.get(other.uuid) ?? 0;\n\t\tthis._enteredZone.set(other.uuid, heldTime + delta);\n\t\tthis._exitedZone.set(other.uuid, 1);\n\t\tif (this.options.onHeld) {\n\t\t\tthis.options.onHeld({\n\t\t\t\tdelta,\n\t\t\t\tself: this,\n\t\t\t\tvisitor: other,\n\t\t\t\tglobals: state.globals,\n\t\t\t\theldTime\n\t\t\t});\n\t\t}\n\t}\n}\n\ntype ZoneOptions = BaseNode | Partial<ZylemZoneOptions>;\n\nexport function createZone(...args: Array<ZoneOptions>): ZylemZone {\n\tconst options = mergeArgs(args, zoneDefaults);\n\tconst entity = new ZylemZone(options);\n\tentity.add(\n\t\tzoneCollision({\n\t\t\tsize: options.size,\n\t\t\tstatic: options.collision?.static ?? true,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn finalizeEntityCloneSupport(\n\t\tentity,\n\t\t(cloneOptions) => createZone(cloneOptions ?? {}),\n\t);\n}\n","import { Color, Group, Sprite as ThreeSprite, SpriteMaterial, CanvasTexture, LinearFilter, Vector2, PerspectiveCamera, OrthographicCamera, ClampToEdgeWrapping, ShaderMaterial, Mesh, PlaneGeometry, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { createEntity } from './create';\nimport { UpdateContext, SetupContext } from '../core/base-node-life-cycle';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { DebugDelegate } from './delegates/debug';\n\ntype ZylemRectOptions = GameEntityOptions & {\n\twidth?: number;\n\theight?: number;\n\tfillColor?: Color | string | null;\n\tstrokeColor?: Color | string | null;\n\tstrokeWidth?: number;\n\tradius?: number;\n\tpadding?: number;\n\tstickToViewport?: boolean;\n\tscreenPosition?: Vector2;\n\tzDistance?: number;\n\tanchor?: Vector2; // 0-100 per axis, default top-left (0,0)\n\tbounds?: {\n\t\tscreen?: { x: number; y: number; width: number; height: number };\n\t\tworld?: { left: number; right: number; top: number; bottom: number; z?: number };\n\t};\n};\n\nconst rectDefaults: ZylemRectOptions = {\n\tposition: undefined,\n\twidth: 120,\n\theight: 48,\n\tfillColor: '#FFFFFF',\n\tstrokeColor: null,\n\tstrokeWidth: 0,\n\tradius: 0,\n\tpadding: 0,\n\tstickToViewport: true,\n\tscreenPosition: new Vector2(24, 24),\n\tzDistance: 1,\n\tanchor: new Vector2(0, 0),\n};\n\nexport class RectBuilder extends EntityBuilder<ZylemRect, ZylemRectOptions> {\n\tprotected createEntity(options: Partial<ZylemRectOptions>): ZylemRect {\n\t\treturn new ZylemRect(options);\n\t}\n}\n\nexport const RECT_TYPE = Symbol('Rect');\n\nexport class ZylemRect extends GameEntity<ZylemRectOptions> {\n\tstatic type = RECT_TYPE;\n\n\tprivate _sprite: ThreeSprite | null = null;\n\tprivate _mesh: Mesh | null = null;\n\tprivate _texture: CanvasTexture | null = null;\n\tprivate _canvas: HTMLCanvasElement | null = null;\n\tprivate _ctx: CanvasRenderingContext2D | null = null;\n\tprivate _cameraRef: ZylemCamera | null = null;\n\tprivate _lastCanvasW: number = 0;\n\tprivate _lastCanvasH: number = 0;\n\n\tconstructor(options?: ZylemRectOptions) {\n\t\tsuper();\n\t\tthis.options = { ...rectDefaults, ...options } as ZylemRectOptions;\n\t\tthis.group = new Group();\n\t\tthis.createSprite();\n\t\t// Add rect-specific lifecycle callbacks\n\t\tthis.prependSetup(this.rectSetup.bind(this) as any);\n\t\tthis.prependUpdate(this.rectUpdate.bind(this) as any);\n\t}\n\n\tprivate createSprite() {\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._ctx = this._canvas.getContext('2d');\n\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\tthis._texture.minFilter = LinearFilter;\n\t\tthis._texture.magFilter = LinearFilter;\n\t\tconst material = new SpriteMaterial({\n\t\t\tmap: this._texture,\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\talphaTest: 0.5,\n\t\t});\n\t\tthis._sprite = new ThreeSprite(material);\n\t\tthis.group?.add(this._sprite);\n\t\tthis.redrawRect();\n\t}\n\n\tprivate redrawRect() {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tconst width = Math.max(2, Math.floor((this.options.width ?? 120)));\n\t\tconst height = Math.max(2, Math.floor((this.options.height ?? 48)));\n\t\tconst padding = this.options.padding ?? 0;\n\t\tconst strokeWidth = this.options.strokeWidth ?? 0;\n\t\tconst totalW = width + padding * 2 + strokeWidth;\n\t\tconst totalH = height + padding * 2 + strokeWidth;\n\t\tconst nextW = Math.max(2, totalW);\n\t\tconst nextH = Math.max(2, totalH);\n\t\tconst sizeChanged = nextW !== this._lastCanvasW || nextH !== this._lastCanvasH;\n\t\tthis._canvas.width = nextW;\n\t\tthis._canvas.height = nextH;\n\t\tthis._lastCanvasW = nextW;\n\t\tthis._lastCanvasH = nextH;\n\n\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\n\t\tconst radius = Math.max(0, this.options.radius ?? 0);\n\t\tconst rectX = Math.floor(padding + strokeWidth / 2);\n\t\tconst rectY = Math.floor(padding + strokeWidth / 2);\n\t\tconst rectW = Math.floor(width);\n\t\tconst rectH = Math.floor(height);\n\n\t\tthis._ctx.beginPath();\n\t\tif (radius > 0) {\n\t\t\tthis.roundedRectPath(this._ctx, rectX, rectY, rectW, rectH, radius);\n\t\t} else {\n\t\t\tthis._ctx.rect(rectX, rectY, rectW, rectH);\n\t\t}\n\n\t\tif (this.options.fillColor) {\n\t\t\tthis._ctx.fillStyle = this.toCssColor(this.options.fillColor);\n\t\t\tthis._ctx.fill();\n\t\t}\n\n\t\tif ((this.options.strokeColor && (strokeWidth > 0))) {\n\t\t\tthis._ctx.lineWidth = strokeWidth;\n\t\t\tthis._ctx.strokeStyle = this.toCssColor(this.options.strokeColor);\n\t\t\tthis._ctx.stroke();\n\t\t}\n\n\t\tif (this._texture) {\n\t\t\tif (sizeChanged) {\n\t\t\t\tthis._texture.dispose();\n\t\t\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\t\t\tthis._texture.minFilter = LinearFilter;\n\t\t\t\tthis._texture.magFilter = LinearFilter;\n\t\t\t\tthis._texture.wrapS = ClampToEdgeWrapping;\n\t\t\t\tthis._texture.wrapT = ClampToEdgeWrapping;\n\t\t\t\tif (this._sprite && this._sprite.material instanceof ShaderMaterial) {\n\t\t\t\t\tconst shader = this._sprite.material as ShaderMaterial;\n\t\t\t\t\tif (shader.uniforms?.tDiffuse) shader.uniforms.tDiffuse.value = this._texture;\n\t\t\t\t\tif (shader.uniforms?.iResolution) shader.uniforms.iResolution.value.set(this._canvas.width, this._canvas.height, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._texture.image = this._canvas;\n\t\t\tthis._texture.needsUpdate = true;\n\t\t\tif (this._sprite && this._sprite.material) {\n\t\t\t\t(this._sprite.material as any).map = this._texture;\n\t\t\t\tthis._sprite.material.needsUpdate = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tgetWidth() {\n\t\treturn this.options.width ?? 0;\n\t}\n\n\tgetHeight() {\n\t\treturn this.options.height ?? 0;\n\t}\n\n\tprivate roundedRectPath(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number) {\n\t\tconst radius = Math.min(r, Math.floor(Math.min(w, h) / 2));\n\t\tctx.moveTo(x + radius, y);\n\t\tctx.lineTo(x + w - radius, y);\n\t\tctx.quadraticCurveTo(x + w, y, x + w, y + radius);\n\t\tctx.lineTo(x + w, y + h - radius);\n\t\tctx.quadraticCurveTo(x + w, y + h, x + w - radius, y + h);\n\t\tctx.lineTo(x + radius, y + h);\n\t\tctx.quadraticCurveTo(x, y + h, x, y + h - radius);\n\t\tctx.lineTo(x, y + radius);\n\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t}\n\n\tprivate toCssColor(color: Color | string): string {\n\t\tif (typeof color === 'string') return color;\n\t\tconst c = color instanceof Color ? color : new Color(color as any);\n\t\treturn `#${c.getHexString()}`;\n\t}\n\n\t/**\n\t * Get the viewport resolution from the renderer DOM element,\n\t * falling back to the camera's screenResolution if the renderer\n\t * is not available (e.g. when using the new RendererManager path).\n\t */\n\tprivate getResolution(): { width: number; height: number } {\n\t\ttry {\n\t\t\tconst dom = this._cameraRef?.renderer?.domElement;\n\t\t\tif (dom) {\n\t\t\t\treturn { width: dom.clientWidth || 1, height: dom.clientHeight || 1 };\n\t\t\t}\n\t\t} catch { /* renderer not available */ }\n\t\treturn {\n\t\t\twidth: this._cameraRef?.screenResolution?.x ?? 1,\n\t\t\theight: this._cameraRef?.screenResolution?.y ?? 1,\n\t\t};\n\t}\n\n\tprivate rectSetup(params: SetupContext<ZylemRectOptions>) {\n\t\tthis._cameraRef = (params.camera as unknown) as ZylemCamera | null;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\t(this._cameraRef.camera as any).add(this.group);\n\t\t}\n\n\t\tif (this.materials?.length && this._sprite) {\n\t\t\tconst mat = this.materials[0];\n\t\t\tif (mat instanceof ShaderMaterial) {\n\t\t\t\tmat.transparent = true;\n\t\t\t\tmat.depthTest = false;\n\t\t\t\tmat.depthWrite = false;\n\t\t\t\tif (this._texture) {\n\t\t\t\t\tif (mat.uniforms?.tDiffuse) mat.uniforms.tDiffuse.value = this._texture;\n\t\t\t\t\tif (mat.uniforms?.iResolution && this._canvas) mat.uniforms.iResolution.value.set(this._canvas.width, this._canvas.height, 1);\n\t\t\t\t}\n\t\t\t\tthis._mesh = new Mesh(new PlaneGeometry(1, 1), mat);\n\t\t\t\tthis.group?.add(this._mesh);\n\t\t\t\tthis._sprite.visible = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate rectUpdate(params: UpdateContext<ZylemRectOptions>) {\n\t\tif (!this._sprite) return;\n\n\t\t// If bounds provided, compute screen-space rect from it and update size/position\n\t\tif (this._cameraRef && this.options.bounds) {\n\t\t\tconst screen = this.computeScreenBoundsFromOptions(this.options.bounds);\n\t\t\tif (screen) {\n\t\t\t\tconst { x, y, width, height } = screen;\n\t\t\t\tconst desiredW = Math.max(2, Math.floor(width));\n\t\t\t\tconst desiredH = Math.max(2, Math.floor(height));\n\t\t\t\tconst changed = desiredW !== (this.options.width ?? 0) || desiredH !== (this.options.height ?? 0);\n\t\t\t\tthis.options.screenPosition = new Vector2(Math.floor(x), Math.floor(y));\n\t\t\t\tthis.options.width = desiredW;\n\t\t\t\tthis.options.height = desiredH;\n\t\t\t\tthis.options.anchor = new Vector2(0, 0);\n\t\t\t\tif (changed) {\n\t\t\t\t\tthis.redrawRect();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate updateStickyTransform() {\n\t\tif (!this._sprite || !this._cameraRef) return;\n\t\tconst camera = this._cameraRef.camera;\n\t\tconst { width, height } = this.getResolution();\n\t\tconst px = (this.options.screenPosition ?? new Vector2(24, 24)).x;\n\t\tconst py = (this.options.screenPosition ?? new Vector2(24, 24)).y;\n\t\tconst zDist = Math.max(0.001, this.options.zDistance ?? 1);\n\n\t\tlet worldHalfW = 1;\n\t\tlet worldHalfH = 1;\n\t\tif ((camera as PerspectiveCamera).isPerspectiveCamera) {\n\t\t\tconst pc = camera as PerspectiveCamera;\n\t\t\tconst halfH = Math.tan((pc.fov * Math.PI) / 180 / 2) * zDist;\n\t\t\tconst halfW = halfH * pc.aspect;\n\t\t\tworldHalfW = halfW;\n\t\t\tworldHalfH = halfH;\n\t\t} else if ((camera as OrthographicCamera).isOrthographicCamera) {\n\t\t\tconst oc = camera as OrthographicCamera;\n\t\t\tworldHalfW = (oc.right - oc.left) / 2;\n\t\t\tworldHalfH = (oc.top - oc.bottom) / 2;\n\t\t}\n\n\t\tconst ndcX = (px / width) * 2 - 1;\n\t\tconst ndcY = 1 - (py / height) * 2;\n\t\tconst localX = ndcX * worldHalfW;\n\t\tconst localY = ndcY * worldHalfH;\n\n\t\tlet scaleX = 1;\n\t\tlet scaleY = 1;\n\t\tif (this._canvas) {\n\t\t\tconst planeH = worldHalfH * 2;\n\t\t\tconst unitsPerPixel = planeH / height;\n\t\t\tconst pixelH = this._canvas.height;\n\t\t\tscaleY = Math.max(0.0001, pixelH * unitsPerPixel);\n\t\t\tconst aspect = this._canvas.width / this._canvas.height;\n\t\t\tscaleX = scaleY * aspect;\n\t\t\tthis._sprite.scale.set(scaleX, scaleY, 1);\n\t\t\tif (this._mesh) this._mesh.scale.set(scaleX, scaleY, 1);\n\t\t}\n\n\t\tconst anchor = this.options.anchor ?? new Vector2(0, 0);\n\t\tconst ax = Math.min(100, Math.max(0, anchor.x)) / 100; // 0..1\n\t\tconst ay = Math.min(100, Math.max(0, anchor.y)) / 100; // 0..1\n\t\tconst offsetX = (0.5 - ax) * scaleX;\n\t\tconst offsetY = (ay - 0.5) * scaleY;\n\t\tthis.group?.position.set(localX + offsetX, localY + offsetY, -zDist);\n\t}\n\n\tprivate worldToScreen(point: Vector3) {\n\t\tif (!this._cameraRef) return { x: 0, y: 0 };\n\t\tconst camera = this._cameraRef.camera;\n\t\tconst { width, height } = this.getResolution();\n\t\tconst v = point.clone().project(camera);\n\t\tconst x = (v.x + 1) / 2 * width;\n\t\tconst y = (1 - v.y) / 2 * height;\n\t\treturn { x, y };\n\t}\n\n\tprivate computeScreenBoundsFromOptions(bounds: NonNullable<ZylemRectOptions['bounds']>): { x: number; y: number; width: number; height: number } | null {\n\t\tif (!this._cameraRef) return null;\n\t\tif (bounds.screen) {\n\t\t\treturn { ...bounds.screen };\n\t\t}\n\t\tif (bounds.world) {\n\t\t\tconst { left, right, top, bottom, z = 0 } = bounds.world;\n\t\t\tconst tl = this.worldToScreen(new Vector3(left, top, z));\n\t\t\tconst br = this.worldToScreen(new Vector3(right, bottom, z));\n\t\t\tconst x = Math.min(tl.x, br.x);\n\t\t\tconst y = Math.min(tl.y, br.y);\n\t\t\tconst width = Math.abs(br.x - tl.x);\n\t\t\tconst height = Math.abs(br.y - tl.y);\n\t\t\treturn { x, y, width, height };\n\t\t}\n\t\treturn null;\n\t}\n\n\tupdateRect(options?: Partial<Pick<ZylemRectOptions, 'width' | 'height' | 'fillColor' | 'strokeColor' | 'strokeWidth' | 'radius'>>) {\n\t\tthis.options = { ...this.options, ...options } as ZylemRectOptions;\n\t\tthis.redrawRect();\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemRect.type),\n\t\t\twidth: this.options.width ?? 0,\n\t\t\theight: this.options.height ?? 0,\n\t\t\tsticky: this.options.stickToViewport,\n\t\t};\n\t}\n}\n\ntype RectOptions = BaseNode | Partial<ZylemRectOptions>;\n\nexport function createRect(...args: Array<RectOptions>): ZylemRect {\n\treturn createEntity<ZylemRect, ZylemRectOptions>({\n\t\targs,\n\t\tdefaultConfig: { ...rectDefaults },\n\t\tEntityClass: ZylemRect,\n\t\tBuilderClass: RectBuilder,\n\t\tentityType: ZylemRect.type,\n\t\tcloneFactory: (options) => createRect(options ?? {}),\n\t});\n}\n\n","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { Group, RingGeometry } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { EntityMeshBuilder } from './builder';\nimport { DebugDelegate } from './delegates/debug';\nimport { createEntity } from './create';\nimport { commonDefaults } from './common';\n\ntype ZylemDiskOptions = GameEntityOptions & {\n\tinnerRadius?: number;\n\touterRadius?: number;\n\tthetaSegments?: number;\n};\n\nconst diskDefaults: ZylemDiskOptions = {\n\t...commonDefaults,\n\tinnerRadius: 0,\n\touterRadius: 1,\n\tthetaSegments: 32,\n};\n\nexport class DiskCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemDiskOptions): ColliderDesc {\n\t\tconst outerRadius = options.outerRadius ?? 1;\n\t\tconst height = 0.1; // thin disk\n\t\t// Use cylinder collider for disk (very flat)\n\t\tlet colliderDesc = ColliderDesc.cylinder(height / 2, outerRadius);\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class DiskMeshBuilder extends EntityMeshBuilder {\n\tbuild(options: ZylemDiskOptions): RingGeometry {\n\t\tconst innerRadius = options.innerRadius ?? 0;\n\t\tconst outerRadius = options.outerRadius ?? 1;\n\t\tconst thetaSegments = options.thetaSegments ?? 32;\n\t\tconst geometry = new RingGeometry(innerRadius, outerRadius, thetaSegments);\n\t\t// Rotate from XY plane to XZ plane to match cylinder collider\n\t\tgeometry.rotateX(-Math.PI / 2);\n\t\treturn geometry;\n\t}\n}\n\nexport class DiskBuilder extends EntityBuilder<ZylemDisk, ZylemDiskOptions> {\n\tprotected createEntity(options: Partial<ZylemDiskOptions>): ZylemDisk {\n\t\treturn new ZylemDisk(options);\n\t}\n\n\tbuild(): ZylemDisk {\n\t\tconst entity = super.build();\n\t\t// Wrap mesh in group for proper transform sync\n\t\tif (entity.mesh && !entity.group) {\n\t\t\tentity.group = new Group();\n\t\t\tentity.group.add(entity.mesh);\n\t\t}\n\t\treturn entity;\n\t}\n}\n\nexport const DISK_TYPE = Symbol('Disk');\n\nexport class ZylemDisk extends GameEntity<ZylemDiskOptions> {\n\tstatic type = DISK_TYPE;\n\n\tconstructor(options?: ZylemDiskOptions) {\n\t\tsuper();\n\t\tthis.options = { ...diskDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst innerRadius = this.options.innerRadius ?? 0;\n\t\tconst outerRadius = this.options.outerRadius ?? 1;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemDisk.type),\n\t\t\tinnerRadius: innerRadius.toFixed(2),\n\t\t\touterRadius: outerRadius.toFixed(2),\n\t\t};\n\t}\n}\n\ntype DiskOptions = BaseNode | Partial<ZylemDiskOptions>;\n\nexport function createDisk(...args: Array<DiskOptions>): ZylemDisk {\n\treturn createEntity<ZylemDisk, ZylemDiskOptions>({\n\t\targs,\n\t\tdefaultConfig: diskDefaults,\n\t\tEntityClass: ZylemDisk,\n\t\tBuilderClass: DiskBuilder,\n\t\tMeshBuilderClass: DiskMeshBuilder,\n\t\tCollisionBuilderClass: DiskCollisionBuilder,\n\t\tentityType: ZylemDisk.type,\n\t\tcloneFactory: (options) => createDisk(options ?? {}),\n\t});\n}\n","import { BaseNode } from '../core/base-node';\nimport { finalizeEntityCloneSupport, GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { coneMesh } from './parts/mesh-factories';\nimport { coneCollision } from './parts/collision-factories';\n\ntype ZylemConeOptions = GameEntityOptions & {\n\t/** Base radius of the cone */\n\tradius?: number;\n\t/** Height of the cone */\n\theight?: number;\n\t/** Number of radial segments (higher = smoother) */\n\tradialSegments?: number;\n};\n\nconst coneDefaults: ZylemConeOptions = {\n\t...commonDefaults,\n\tradius: 1,\n\theight: 2,\n\tradialSegments: 32,\n};\n\nexport const CONE_TYPE = Symbol('Cone');\n\n/**\n * A cone entity with configurable radius, height, and radial segments.\n * Uses a Rapier cone collider for physics.\n */\nexport class ZylemCone extends GameEntity<ZylemConeOptions> {\n\tstatic type = CONE_TYPE;\n\n\tconstructor(options?: ZylemConeOptions) {\n\t\tsuper();\n\t\tthis.options = { ...coneDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 1;\n\t\tconst height = this.options.height ?? 2;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemCone.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t\theight: height.toFixed(2),\n\t\t};\n\t}\n}\n\ntype ConeOptions = BaseNode | Partial<ZylemConeOptions>;\n\n/**\n * Create a cone entity.\n * @param args Options or child nodes\n */\nexport function createCone(...args: Array<ConeOptions>): ZylemCone {\n\tconst options = mergeArgs(args, coneDefaults);\n\tconst entity = new ZylemCone(options);\n\tentity.add(\n\t\tconeMesh({\n\t\t\tradius: options.radius,\n\t\t\theight: options.height,\n\t\t\tradialSegments: options.radialSegments,\n\t\t\tmaterial: options.material,\n\t\t\tcolor: options.color,\n\t\t}),\n\t\tconeCollision({\n\t\t\tradius: options.radius,\n\t\t\theight: options.height,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn finalizeEntityCloneSupport(\n\t\tentity,\n\t\t(cloneOptions) => createCone(cloneOptions ?? {}),\n\t);\n}\n","import { BaseNode } from '../core/base-node';\nimport { finalizeEntityCloneSupport, GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { pyramidMesh } from './parts/mesh-factories';\nimport { pyramidCollision } from './parts/collision-factories';\n\ntype ZylemPyramidOptions = GameEntityOptions & {\n\t/** Base radius of the pyramid */\n\tradius?: number;\n\t/** Height of the pyramid */\n\theight?: number;\n};\n\nconst pyramidDefaults: ZylemPyramidOptions = {\n\t...commonDefaults,\n\tradius: 1,\n\theight: 2,\n};\n\nexport const PYRAMID_TYPE = Symbol('Pyramid');\n\n/**\n * A pyramid entity (4-sided cone).\n * Uses ConeGeometry with 4 radial segments for the visual mesh\n * and a Rapier cone collider for physics.\n */\nexport class ZylemPyramid extends GameEntity<ZylemPyramidOptions> {\n\tstatic type = PYRAMID_TYPE;\n\n\tconstructor(options?: ZylemPyramidOptions) {\n\t\tsuper();\n\t\tthis.options = { ...pyramidDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 1;\n\t\tconst height = this.options.height ?? 2;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemPyramid.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t\theight: height.toFixed(2),\n\t\t};\n\t}\n}\n\ntype PyramidOptions = BaseNode | Partial<ZylemPyramidOptions>;\n\n/**\n * Create a pyramid entity.\n * @param args Options or child nodes\n */\nexport function createPyramid(...args: Array<PyramidOptions>): ZylemPyramid {\n\tconst options = mergeArgs(args, pyramidDefaults);\n\tconst entity = new ZylemPyramid(options);\n\tentity.add(\n\t\tpyramidMesh({\n\t\t\tradius: options.radius,\n\t\t\theight: options.height,\n\t\t\tmaterial: options.material,\n\t\t\tcolor: options.color,\n\t\t}),\n\t\tpyramidCollision({\n\t\t\tradius: options.radius,\n\t\t\theight: options.height,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn finalizeEntityCloneSupport(\n\t\tentity,\n\t\t(cloneOptions) => createPyramid(cloneOptions ?? {}),\n\t);\n}\n","import { BaseNode } from '../core/base-node';\nimport { finalizeEntityCloneSupport, GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { cylinderMesh } from './parts/mesh-factories';\nimport { cylinderCollision } from './parts/collision-factories';\n\ntype ZylemCylinderOptions = GameEntityOptions & {\n\t/** Top radius of the cylinder */\n\tradiusTop?: number;\n\t/** Bottom radius of the cylinder */\n\tradiusBottom?: number;\n\t/** Height of the cylinder */\n\theight?: number;\n\t/** Number of radial segments (higher = smoother) */\n\tradialSegments?: number;\n};\n\nconst cylinderDefaults: ZylemCylinderOptions = {\n\t...commonDefaults,\n\tradiusTop: 1,\n\tradiusBottom: 1,\n\theight: 2,\n\tradialSegments: 32,\n};\n\nexport const CYLINDER_TYPE = Symbol('Cylinder');\n\n/**\n * A cylinder entity with configurable top/bottom radii, height, and segments.\n * Uses a Rapier cylinder collider for physics.\n */\nexport class ZylemCylinder extends GameEntity<ZylemCylinderOptions> {\n\tstatic type = CYLINDER_TYPE;\n\n\tconstructor(options?: ZylemCylinderOptions) {\n\t\tsuper();\n\t\tthis.options = { ...cylinderDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radiusTop = this.options.radiusTop ?? 1;\n\t\tconst radiusBottom = this.options.radiusBottom ?? 1;\n\t\tconst height = this.options.height ?? 2;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemCylinder.type),\n\t\t\tradiusTop: radiusTop.toFixed(2),\n\t\t\tradiusBottom: radiusBottom.toFixed(2),\n\t\t\theight: height.toFixed(2),\n\t\t};\n\t}\n}\n\ntype CylinderOptions = BaseNode | Partial<ZylemCylinderOptions>;\n\n/**\n * Create a cylinder entity.\n * @param args Options or child nodes\n */\nexport function createCylinder(...args: Array<CylinderOptions>): ZylemCylinder {\n\tconst options = mergeArgs(args, cylinderDefaults);\n\tconst entity = new ZylemCylinder(options);\n\tentity.add(\n\t\tcylinderMesh({\n\t\t\tradiusTop: options.radiusTop,\n\t\t\tradiusBottom: options.radiusBottom,\n\t\t\theight: options.height,\n\t\t\tradialSegments: options.radialSegments,\n\t\t\tmaterial: options.material,\n\t\t\tcolor: options.color,\n\t\t}),\n\t\tcylinderCollision({\n\t\t\tradiusTop: options.radiusTop,\n\t\t\tradiusBottom: options.radiusBottom,\n\t\t\theight: options.height,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn finalizeEntityCloneSupport(\n\t\tentity,\n\t\t(cloneOptions) => createCylinder(cloneOptions ?? {}),\n\t);\n}\n","import { BaseNode } from '../core/base-node';\nimport { finalizeEntityCloneSupport, GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { pillMesh } from './parts/mesh-factories';\nimport { pillCollision } from './parts/collision-factories';\n\ntype ZylemPillOptions = GameEntityOptions & {\n\t/** Radius of the capsule hemispheres */\n\tradius?: number;\n\t/** Length of the cylindrical middle section */\n\tlength?: number;\n\t/** Number of cap segments (higher = smoother) */\n\tcapSegments?: number;\n\t/** Number of radial segments (higher = smoother) */\n\tradialSegments?: number;\n};\n\nconst pillDefaults: ZylemPillOptions = {\n\t...commonDefaults,\n\tradius: 0.5,\n\tlength: 1,\n\tcapSegments: 10,\n\tradialSegments: 20,\n};\n\nexport const PILL_TYPE = Symbol('Pill');\n\n/**\n * A pill/capsule entity with configurable radius and cylindrical length.\n * Uses Three.js CapsuleGeometry for rendering and Rapier capsule collider for physics.\n */\nexport class ZylemPill extends GameEntity<ZylemPillOptions> {\n\tstatic type = PILL_TYPE;\n\n\tconstructor(options?: ZylemPillOptions) {\n\t\tsuper();\n\t\tthis.options = { ...pillDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 0.5;\n\t\tconst length = this.options.length ?? 1;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemPill.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t\tlength: length.toFixed(2),\n\t\t};\n\t}\n}\n\ntype PillOptions = BaseNode | Partial<ZylemPillOptions>;\n\n/**\n * Create a pill (capsule) entity.\n * @param args Options or child nodes\n */\nexport function createPill(...args: Array<PillOptions>): ZylemPill {\n\tconst options = mergeArgs(args, pillDefaults);\n\tconst entity = new ZylemPill(options);\n\tentity.add(\n\t\tpillMesh({\n\t\t\tradius: options.radius,\n\t\t\tlength: options.length,\n\t\t\tcapSegments: options.capSegments,\n\t\t\tradialSegments: options.radialSegments,\n\t\t\tmaterial: options.material,\n\t\t\tcolor: options.color,\n\t\t}),\n\t\tpillCollision({\n\t\t\tradius: options.radius,\n\t\t\tlength: options.length,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn finalizeEntityCloneSupport(\n\t\tentity,\n\t\t(cloneOptions) => createPill(cloneOptions ?? {}),\n\t);\n}\n","export {\n\ttype CollisionComponent,\n\tisCollisionComponent,\n\tboxCollision,\n\tsphereCollision,\n\tconeCollision,\n\tpyramidCollision,\n\tcylinderCollision,\n\tpillCollision,\n\tplaneCollision,\n\tzoneCollision,\n\ttype BoxCollisionOptions,\n\ttype SphereCollisionOptions,\n\ttype ConeCollisionOptions,\n\ttype PyramidCollisionOptions,\n\ttype CylinderCollisionOptions,\n\ttype PillCollisionOptions,\n\ttype PlaneCollisionOptions,\n\ttype ZoneCollisionOptions,\n} from './collision-factories';\n\nexport {\n\tboxMesh,\n\tsphereMesh,\n\tconeMesh,\n\tpyramidMesh,\n\tcylinderMesh,\n\tpillMesh,\n\ttype BoxMeshOptions,\n\ttype SphereMeshOptions,\n\ttype ConeMeshOptions,\n\ttype PyramidMeshOptions,\n\ttype CylinderMeshOptions,\n\ttype PillMeshOptions,\n} from './mesh-factories';\n","/**\n * BehaviorDescriptor\n *\n * Type-safe behavior descriptors that provide options inference.\n * Used with entity.use() to declaratively attach behaviors to entities.\n *\n * Each behavior can define its own handle type via `createHandle`,\n * providing behavior-specific methods with full type safety.\n */\n\nimport type { BehaviorSystemFactory } from './behavior-system';\n\n/**\n * Base handle returned by entity.use() for lazy access to behavior runtime.\n * FSM is null until entity is spawned and components are initialized.\n */\nexport interface BaseBehaviorHandle<\n O extends Record<string, any> = Record<string, any>,\n> {\n /** Get the FSM instance (null until entity is spawned) */\n getFSM(): any | null;\n /** Get the current options */\n getOptions(): O;\n /** Access the underlying behavior ref */\n readonly ref: BehaviorRef<O>;\n}\n\n/**\n * Reference to a behavior stored on an entity\n */\nexport interface BehaviorRef<\n O extends Record<string, any> = Record<string, any>,\n> {\n /** The behavior descriptor */\n descriptor: BehaviorDescriptor<O, any>;\n /** Merged options (defaults + overrides) */\n options: O;\n /** Optional FSM instance - set lazily when entity is spawned */\n fsm?: any;\n}\n\n/**\n * A typed behavior descriptor that associates a symbol key with:\n * - Default options (providing type inference)\n * - A system factory to create the behavior system\n * - An optional handle factory for behavior-specific methods\n */\nexport interface BehaviorDescriptor<\n O extends Record<string, any> = Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n I = unknown,\n> {\n /** Unique symbol identifying this behavior */\n readonly key: symbol;\n /** Default options (used for type inference) */\n readonly defaultOptions: O;\n /** Factory to create the behavior system */\n readonly systemFactory: BehaviorSystemFactory;\n /**\n * Optional factory to create behavior-specific handle methods.\n * These methods are merged into the handle returned by entity.use().\n */\n readonly createHandle?: (ref: BehaviorRef<O>) => H;\n}\n\n/**\n * The full handle type returned by entity.use().\n * Combines base handle with behavior-specific methods.\n */\nexport type BehaviorHandle<\n O extends Record<string, any> = Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n> = BaseBehaviorHandle<O> & H;\n\n/**\n * Configuration for defining a new behavior\n */\nexport interface DefineBehaviorConfig<\n O extends Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n I = unknown,\n> {\n /** Human-readable name for debugging */\n name: string;\n /** Default options - these define the type */\n defaultOptions: O;\n /** Factory function to create the system */\n systemFactory: BehaviorSystemFactory;\n /**\n * Optional factory to create behavior-specific handle methods.\n * The returned object is merged into the handle returned by entity.use().\n *\n * @example\n * ```typescript\n * createHandle: (ref) => ({\n * getLastHits: () => ref.fsm?.getLastHits() ?? null,\n * getMovement: (moveX, moveY) => ref.fsm?.getMovement(moveX, moveY) ?? { moveX, moveY },\n * }),\n * ```\n */\n createHandle?: (ref: BehaviorRef<O>) => H;\n}\n\n/**\n * Define a typed behavior descriptor.\n *\n * @example\n * ```typescript\n * export const WorldBoundary2DBehavior = defineBehavior({\n * name: 'world-boundary-2d',\n * defaultOptions: { boundaries: { top: 0, bottom: 0, left: 0, right: 0 } },\n * systemFactory: (ctx) => new WorldBoundary2DSystem(ctx.world),\n * createHandle: (ref) => ({\n * getLastHits: () => ref.fsm?.getLastHits() ?? null,\n * getMovement: (moveX: number, moveY: number) =>\n * ref.fsm?.getMovement(moveX, moveY) ?? { moveX, moveY },\n * }),\n * });\n *\n * // Usage - handle has getLastHits and getMovement with full types\n * const boundary = ship.use(WorldBoundary2DBehavior, { ... });\n * const hits = boundary.getLastHits(); // Fully typed!\n * ```\n */\nexport function defineBehavior<\n O extends Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n I = unknown,\n>(\n config: DefineBehaviorConfig<O, H, I>,\n): BehaviorDescriptor<O, H, I> {\n return {\n key: Symbol.for(`zylem:behavior:${config.name}`),\n defaultOptions: config.defaultOptions,\n systemFactory: config.systemFactory,\n createHandle: config.createHandle,\n };\n}\n","import { GameEntity } from '../entities/entity';\nimport { BehaviorDescriptor } from './behavior-descriptor';\n\n/**\n * Type-safe helper to apply a behavior to an entity and return the entity cast to the behavior's interface.\n * \n * @param entity The entity to apply the behavior to\n * @param descriptor The behavior descriptor\n * @param options Behavior options\n * @returns The entity, cast to E & I (where I is the behavior's interface)\n */\nexport function useBehavior<\n E extends GameEntity<any>,\n O extends Record<string, any>,\n H extends Record<string, any>,\n I // Entity Interface\n>(\n entity: E,\n descriptor: BehaviorDescriptor<O, H, I>,\n options?: Partial<O>\n): E & I {\n entity.use(descriptor, options);\n return entity as unknown as E & I;\n}\n","/**\n * Core ECS Components\n * \n * These are pure data interfaces with no logic.\n * They work alongside the existing bitecs components in transformable.system.ts\n */\n\nimport type { RigidBody } from '@dimforge/rapier3d-compat';\nimport { Vector3, Quaternion } from 'three';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TransformComponent (render-facing)\n// Written only by PhysicsSyncBehavior, read by rendering/animation\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface TransformComponent {\n\tposition: Vector3;\n\trotation: Quaternion;\n}\n\nexport function createTransformComponent(): TransformComponent {\n\treturn {\n\t\tposition: new Vector3(),\n\t\trotation: new Quaternion(),\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// PhysicsBodyComponent (bridge to Rapier, not state)\n// ECS does not store velocity, mass, etc. - Rapier owns all physical truth\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PhysicsBodyComponent {\n\tbody: RigidBody;\n}\n\nexport function createPhysicsBodyComponent(body: RigidBody): PhysicsBodyComponent {\n\treturn { body };\n}\n","/**\n * Thruster-specific ECS Components\n * \n * These components are specific to the thruster movement system.\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThrusterMovementComponent (capability / hardware spec)\n// Defines the thrust capabilities of an entity\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ThrusterMovementComponent {\n\t/** Linear thrust force in Newtons (or scaled units) */\n\tlinearThrust: number;\n\t/** Angular thrust torque scalar */\n\tangularThrust: number;\n\t/** Optional linear damping override */\n\tlinearDamping?: number;\n\t/** Optional angular damping override */\n\tangularDamping?: number;\n}\n\nexport function createThrusterMovementComponent(\n\tlinearThrust: number,\n\tangularThrust: number,\n\toptions?: { linearDamping?: number; angularDamping?: number }\n): ThrusterMovementComponent {\n\treturn {\n\t\tlinearThrust,\n\t\tangularThrust,\n\t\tlinearDamping: options?.linearDamping,\n\t\tangularDamping: options?.angularDamping,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThrusterInputComponent (intent)\n// Written by: Player controller, AI controller, FSM adapter\n// Read by: ThrusterMovementBehavior\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ThrusterInputComponent {\n\t/** Forward thrust intent: 0..1 */\n\tthrust: number;\n\t/** Rotation intent: -1..1 */\n\trotate: number;\n\t/** World-space X thrust intent: -1..1 */\n\tthrustX: number;\n\t/** World-space Y thrust intent: -1..1 */\n\tthrustY: number;\n}\n\nexport function createThrusterInputComponent(): ThrusterInputComponent {\n\treturn {\n\t\tthrust: 0,\n\t\trotate: 0,\n\t\tthrustX: 0,\n\t\tthrustY: 0,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThrusterStateComponent (optional but useful)\n// Useful for: damage, EMP, overheating, UI feedback\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ThrusterStateComponent {\n\t/** Whether the thruster is enabled */\n\tenabled: boolean;\n\t/** Current thrust after FSM/gating */\n\tcurrentThrust: number;\n}\n\nexport function createThrusterStateComponent(): ThrusterStateComponent {\n\treturn {\n\t\tenabled: true,\n\t\tcurrentThrust: 0,\n\t};\n}\n","import {\n\tStateMachine as BaseStateMachine,\n\ttype ILogger,\n\ttype ITransition,\n\ttype SyncCallback,\n} from 'typescript-fsm';\n\nexport { t } from 'typescript-fsm';\nexport type { ILogger, ITransition, SyncCallback };\n\n/**\n * Local wrapper around typescript-fsm's SyncStateMachine.\n *\n * typescript-fsm@1.6.0 incorrectly reports callback-less transitions as\n * unhandled even after moving to the next state, which causes noisy\n * `No transition...` console errors for valid FSM dispatches.\n */\nexport class SyncStateMachine<\n\tSTATE extends string | number | symbol,\n\tEVENT extends string | number | symbol,\n\tCALLBACK extends Record<EVENT, SyncCallback> = Record<EVENT, SyncCallback>,\n> extends BaseStateMachine<STATE, EVENT, CALLBACK> {\n\tconstructor(\n\t\tinit: STATE,\n\t\ttransitions: ITransition<STATE, EVENT, CALLBACK[EVENT]>[] = [],\n\t\tlogger: ILogger = console,\n\t) {\n\t\tsuper(init, transitions, logger);\n\t}\n\n\tdispatch<E extends EVENT>(_event: E, ..._args: unknown[]): Promise<void> {\n\t\tthrow new Error('SyncStateMachine does not support async dispatch.');\n\t}\n\n\tsyncDispatch<E extends EVENT>(event: E, ...args: unknown[]): boolean {\n\t\tconst found = this.transitions.some((transition) => {\n\t\t\tif (transition.fromState !== this._current || transition.event !== event) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst current = this._current;\n\t\t\tthis._current = transition.toState;\n\n\t\t\tif (!transition.cb) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\ttransition.cb(...args);\n\t\t\t\treturn true;\n\t\t\t} catch (error) {\n\t\t\t\tthis._current = current;\n\t\t\t\tthis.logger.error('Exception in callback', error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\n\t\tif (!found) {\n\t\t\tconst errorMessage = this.formatErr(this._current, event);\n\t\t\tthis.logger.error(errorMessage);\n\t\t}\n\n\t\treturn found;\n\t}\n}\n","/**\n * ThrusterFSM\n * \n * State machine controller for thruster behavior.\n * FSM does NOT touch physics or ThrusterMovementBehavior - it only writes ThrusterInputComponent.\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { ThrusterInputComponent } from './components';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM State Model\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum ThrusterState {\n\tIdle = 'idle',\n\tActive = 'active',\n\tBoosting = 'boosting',\n\tDisabled = 'disabled',\n\tDocked = 'docked',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum ThrusterEvent {\n\tActivate = 'activate',\n\tDeactivate = 'deactivate',\n\tBoost = 'boost',\n\tEndBoost = 'endBoost',\n\tDisable = 'disable',\n\tEnable = 'enable',\n\tDock = 'dock',\n\tUndock = 'undock',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM Context Object\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ThrusterFSMContext {\n\tinput: ThrusterInputComponent;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Player Input (raw input from controller/keyboard)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PlayerInput {\n\tthrust: number;\n\trotate: number;\n\tthrustX?: number;\n\tthrustY?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThrusterFSM Controller\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThrusterFSM {\n\tmachine: SyncStateMachine<ThrusterState, ThrusterEvent, never>;\n\n\tconstructor(private ctx: ThrusterFSMContext) {\n\t\tthis.machine = new SyncStateMachine<ThrusterState, ThrusterEvent, never>(\n\t\t\tThrusterState.Idle,\n\t\t\t[\n\t\t\t\t// Core transitions\n\t\t\t\tt(ThrusterState.Idle, ThrusterEvent.Activate, ThrusterState.Active),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Deactivate, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Boost, ThrusterState.Boosting),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Disable, ThrusterState.Disabled),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Dock, ThrusterState.Docked),\n\t\t\t\tt(ThrusterState.Boosting, ThrusterEvent.EndBoost, ThrusterState.Active),\n\t\t\t\tt(ThrusterState.Boosting, ThrusterEvent.Disable, ThrusterState.Disabled),\n\t\t\t\tt(ThrusterState.Disabled, ThrusterEvent.Enable, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Docked, ThrusterEvent.Undock, ThrusterState.Idle),\n\t\t\t\t// Self-transitions (no-ops for redundant events)\n\t\t\t\tt(ThrusterState.Idle, ThrusterEvent.Deactivate, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Activate, ThrusterState.Active),\n\t\t\t]\n\t\t);\n\t}\n\n\t/**\n\t * Get current state\n\t */\n\tgetState(): ThrusterState {\n\t\treturn this.machine.getState();\n\t}\n\n\t/**\n\t * Dispatch an event to transition state\n\t */\n\tdispatch(event: ThrusterEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\t/**\n\t * Update FSM state based on player input.\n\t * Auto-transitions between Idle/Active to report current state.\n\t * Does NOT modify input - just observes and reports.\n\t */\n\tupdate(playerInput: PlayerInput): void {\n\t\tconst state = this.machine.getState();\n\t\tconst hasInput =\n\t\t\tMath.abs(playerInput.thrust) > 0.01\n\t\t\t|| Math.abs(playerInput.rotate) > 0.01\n\t\t\t|| Math.abs(playerInput.thrustX ?? 0) > 0.01\n\t\t\t|| Math.abs(playerInput.thrustY ?? 0) > 0.01;\n\n\t\t// Auto-transition to report state based on input\n\t\tif (hasInput && state === ThrusterState.Idle) {\n\t\t\tthis.dispatch(ThrusterEvent.Activate);\n\t\t} else if (!hasInput && state === ThrusterState.Active) {\n\t\t\tthis.dispatch(ThrusterEvent.Deactivate);\n\t\t}\n\t}\n}\n","export interface Direction2D {\n\tx: number;\n\ty: number;\n}\n\nconst DIRECTION_EPSILON = 1e-6;\n\nexport function normalizeDirection2D(x: number, y: number): Direction2D | null {\n\tconst length = Math.hypot(x, y);\n\tif (length <= DIRECTION_EPSILON) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tx: x / length,\n\t\ty: y / length,\n\t};\n}\n\nexport function angleFromDirection2D(direction: Direction2D): number {\n\treturn Math.atan2(-direction.x, direction.y);\n}\n\nexport function directionFromAngle2D(angle: number): Direction2D {\n\treturn {\n\t\tx: Math.sin(-angle),\n\t\ty: Math.cos(-angle),\n\t};\n}\n\nexport function rightFromAngle2D(angle: number): Direction2D {\n\treturn {\n\t\tx: Math.cos(angle),\n\t\ty: Math.sin(angle),\n\t};\n}\n\nexport function rotateLocalOffset2D(\n\toffset: Direction2D,\n\tangle: number,\n): Direction2D {\n\tconst right = rightFromAngle2D(angle);\n\tconst forward = directionFromAngle2D(angle);\n\treturn {\n\t\tx: right.x * offset.x + forward.x * offset.y,\n\t\ty: right.y * offset.x + forward.y * offset.y,\n\t};\n}\n\nexport function getRotationAngle2D(\n\trotation: { x: number; y: number; z: number; w: number },\n): number {\n\treturn Math.atan2(\n\t\t2 * (rotation.w * rotation.z + rotation.x * rotation.y),\n\t\t1 - 2 * (rotation.y * rotation.y + rotation.z * rotation.z),\n\t);\n}\n","/**\n * ThrusterMovementBehavior\n * \n * This is the heart of the thruster movement system - a pure, stateless force generator.\n * Works identically for player, AI, and replay.\n */\n\nimport type { ZylemWorld } from '../../collision/world';\nimport type { PhysicsBodyComponent } from '../components';\nimport type { ThrusterMovementComponent, ThrusterInputComponent } from './components';\nimport {\n\tgetRotationAngle2D,\n\tnormalizeDirection2D,\n} from '../shared/direction-2d';\n\n/**\n * Zylem-style Behavior interface\n */\nexport interface Behavior {\n\tupdate(dt: number): void;\n}\n\n/**\n * Entity with thruster components\n */\nexport interface ThrusterEntity {\n\tphysics: PhysicsBodyComponent;\n\tthruster: ThrusterMovementComponent;\n\t$thruster: ThrusterInputComponent;\n}\n\n/**\n * ThrusterMovementBehavior - Force generator for thruster-equipped entities\n * \n * Responsibilities:\n * - Query entities with PhysicsBody, ThrusterMovement, and ThrusterInput components\n * - Apply velocities based on thrust input (2D mode)\n * - Apply angular velocity based on rotation input\n */\nexport class ThrusterMovementBehavior implements Behavior {\n\tconstructor(private world: ZylemWorld) {}\n\n\t/**\n\t * Update a single thruster-enabled entity.\n\t */\n\tupdateEntity(gameEntity: any, _dt: number): void {\n\t\tif (!gameEntity.physics?.body || !gameEntity.thruster || !gameEntity.$thruster) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst e: ThrusterEntity = {\n\t\t\tphysics: gameEntity.physics,\n\t\t\tthruster: gameEntity.thruster,\n\t\t\t$thruster: gameEntity.$thruster,\n\t\t};\n\n\t\tconst body = e.physics.body;\n\t\tconst thruster = e.thruster;\n\t\tconst input = e.$thruster;\n\n\t\tif (thruster.linearDamping != null && typeof body.setLinearDamping === 'function') {\n\t\t\tbody.setLinearDamping(thruster.linearDamping);\n\t\t}\n\n\t\t// Get Z rotation from quaternion (for 2D sprites)\n\t\tconst rotationZ = getRotationAngle2D(body.rotation());\n\t\tconst currentVel = body.linvel();\n\t\tconst vectorThrust = normalizeDirection2D(input.thrustX, input.thrustY);\n\n\t\t// --- Linear thrust ---\n\t\tif (vectorThrust) {\n\t\t\tconst thrustScale = Math.min(1, Math.hypot(input.thrustX, input.thrustY));\n\t\t\tconst thrustAmount = thruster.linearThrust * thrustScale * 0.1;\n\t\t\tbody.setLinvel({\n\t\t\t\tx: currentVel.x + vectorThrust.x * thrustAmount,\n\t\t\t\ty: currentVel.y + vectorThrust.y * thrustAmount,\n\t\t\t\tz: currentVel.z,\n\t\t\t}, true);\n\t\t} else if (input.thrust !== 0) {\n\t\t\tconst forwardX = Math.sin(-rotationZ);\n\t\t\tconst forwardY = Math.cos(-rotationZ);\n\t\t\tconst thrustAmount = thruster.linearThrust * input.thrust * 0.1;\n\t\t\tbody.setLinvel({\n\t\t\t\tx: currentVel.x + forwardX * thrustAmount,\n\t\t\t\ty: currentVel.y + forwardY * thrustAmount,\n\t\t\t\tz: currentVel.z\n\t\t\t}, true);\n\t\t}\n\n\t\t// --- Angular thrust (Z-axis for 2D) ---\n\t\tif (input.rotate !== 0) {\n\t\t\tbody.setAngvel({ x: 0, y: 0, z: -thruster.angularThrust * input.rotate }, true);\n\t\t} else {\n\t\t\t// Stop rotation when no input\n\t\t\tconst angVel = body.angvel();\n\t\t\tbody.setAngvel({ x: angVel.x, y: angVel.y, z: 0 }, true);\n\t\t}\n\t}\n\n\tupdate(dt: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tthis.updateEntity(entity, dt);\n\t\t}\n\t}\n}\n","/**\n * Thruster Behavior Descriptor\n * \n * Type-safe descriptor for the thruster behavior system using the new entity.use() API.\n * This wraps the existing ThrusterMovementBehavior and components.\n */\n\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { ThrusterMovementBehavior, ThrusterEntity } from './thruster-movement.behavior';\nimport { ThrusterFSM } from './thruster-fsm';\nimport {\n\tcreateThrusterInputComponent,\n\tcreateThrusterMovementComponent,\n\ttype ThrusterMovementComponent,\n\ttype ThrusterInputComponent,\n} from './components';\n\n/**\n * Thruster behavior options (typed for entity.use() autocomplete)\n */\nexport interface ThrusterBehaviorOptions {\n\t/** Forward thrust force (default: 10) */\n\tlinearThrust: number;\n\t/** Rotation torque (default: 5) */\n\tangularThrust: number;\n\t/** Optional linear damping override */\n\tlinearDamping?: number;\n}\n\nconst defaultOptions: ThrusterBehaviorOptions = {\n\tlinearThrust: 10,\n\tangularThrust: 5,\n\tlinearDamping: undefined,\n};\n\nconst THRUSTER_BEHAVIOR_KEY = Symbol.for('zylem:behavior:thruster');\n\n/**\n * Adapter that wraps ThrusterMovementBehavior as a BehaviorSystem.\n * \n * This bridges the entity.use() pattern with the ECS component-based approach:\n * - Reads options from entity behaviorRefs\n * - Initializes ThrusterMovementComponent and ThrusterInputComponent on entities\n * - Creates FSM lazily and attaches to BehaviorRef for access via handle.getFSM()\n * - Delegates physics to ThrusterMovementBehavior\n * \n * NOTE: Input is controlled by the user via entity.onUpdate() - set entity.input.thrust/rotate\n */\nclass ThrusterBehaviorSystem implements BehaviorSystem {\n\tprivate movementBehavior: ThrusterMovementBehavior;\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {\n\t\tthis.movementBehavior = new ThrusterMovementBehavior(world);\n\t}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(THRUSTER_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst thrusterRef = link.ref as any;\n\t\t\tif (!gameEntity.body) continue;\n\n\t\t\tconst options = thrusterRef.options as ThrusterBehaviorOptions;\n\n\t\t\t// Ensure entity has thruster components (initialized once)\n\t\t\tif (!gameEntity.thruster) {\n\t\t\t\tgameEntity.thruster = createThrusterMovementComponent(\n\t\t\t\t\toptions.linearThrust,\n\t\t\t\t\toptions.angularThrust,\n\t\t\t\t\t{ linearDamping: options.linearDamping },\n\t\t\t\t) as ThrusterMovementComponent;\n\t\t\t}\n\n\t\t\tif (!gameEntity.$thruster) {\n\t\t\t\tgameEntity.$thruster = createThrusterInputComponent() as ThrusterInputComponent;\n\t\t\t}\n\n\t\t\tif (!gameEntity.physics) {\n\t\t\t\tgameEntity.physics = { body: gameEntity.body };\n\t\t\t}\n\n\t\t\t// Create FSM lazily and attach to the BehaviorRef for handle.getFSM()\n\t\t\tif (!thrusterRef.fsm && gameEntity.$thruster) {\n\t\t\t\tthrusterRef.fsm = new ThrusterFSM({ input: gameEntity.$thruster });\n\t\t\t}\n\n\t\t\t// Update FSM to sync state with input (auto-transitions)\n\t\t\tif (thrusterRef.fsm && gameEntity.$thruster) {\n\t\t\t\tthrusterRef.fsm.update({\n\t\t\t\t\tthrust: gameEntity.$thruster.thrust,\n\t\t\t\t\trotate: gameEntity.$thruster.rotate,\n\t\t\t\t\tthrustX: gameEntity.$thruster.thrustX,\n\t\t\t\t\tthrustY: gameEntity.$thruster.thrustY,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.movementBehavior.updateEntity(gameEntity, delta);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\t// Cleanup if needed\n\t}\n}\n\n/**\n * ThrusterBehavior - typed descriptor for thruster movement.\n * \n * Uses the existing ThrusterMovementBehavior under the hood.\n * \n * @example\n * ```typescript\n * import { ThrusterBehavior } from \"@zylem/game-lib\";\n * \n * const ship = createSprite({ ... });\n * ship.use(ThrusterBehavior, { linearThrust: 15, angularThrust: 8 });\n * ```\n */\nexport const ThrusterBehavior = defineBehavior<ThrusterBehaviorOptions, Record<string, never>, ThrusterEntity>({\n\tname: 'thruster',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew ThrusterBehaviorSystem(ctx.world, ctx.getBehaviorLinks),\n});\n","export interface TopDownMovementComponent {\n\tmoveSpeed: number;\n}\n\nexport function createTopDownMovementComponent(\n\toptions: Partial<TopDownMovementComponent> = {},\n): TopDownMovementComponent {\n\treturn {\n\t\tmoveSpeed: options.moveSpeed ?? 8,\n\t};\n}\n\nexport interface TopDownMovementInputComponent {\n\tmoveX: number;\n\tmoveY: number;\n\tfaceX: number;\n\tfaceY: number;\n}\n\nexport function createTopDownMovementInputComponent(): TopDownMovementInputComponent {\n\treturn {\n\t\tmoveX: 0,\n\t\tmoveY: 0,\n\t\tfaceX: 0,\n\t\tfaceY: 0,\n\t};\n}\n\nexport interface TopDownMovementStateComponent {\n\tfacingAngle: number;\n\tmoving: boolean;\n}\n\nexport function createTopDownMovementStateComponent(): TopDownMovementStateComponent {\n\treturn {\n\t\tfacingAngle: 0,\n\t\tmoving: false,\n\t};\n}\n","import {\n\tangleFromDirection2D,\n\tnormalizeDirection2D,\n} from '../shared/direction-2d';\nimport type {\n\tTopDownMovementComponent,\n\tTopDownMovementInputComponent,\n\tTopDownMovementStateComponent,\n} from './components';\n\nexport interface TopDownMovementEntity {\n\tbody: {\n\t\tlinvel(): { x: number; y: number; z: number };\n\t};\n\ttransformStore?: {\n\t\tvelocity: { x: number; y: number; z: number };\n\t\tdirty: { velocity: boolean };\n\t};\n\tsetRotationZ?: (angle: number) => void;\n\ttopDownMovement: TopDownMovementComponent;\n\t$topDownMovement: TopDownMovementInputComponent;\n\ttopDownMovementState: TopDownMovementStateComponent;\n}\n\nexport class TopDownMovementRuntimeBehavior {\n\tupdateEntity(entity: TopDownMovementEntity, _delta: number): void {\n\t\tif (\n\t\t\t!entity.body\n\t\t\t|| !entity.transformStore\n\t\t\t|| !entity.topDownMovement\n\t\t\t|| !entity.$topDownMovement\n\t\t\t|| !entity.topDownMovementState\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst movement = entity.topDownMovement;\n\t\tconst input = entity.$topDownMovement;\n\t\tconst state = entity.topDownMovementState;\n\t\tconst moveDirection = normalizeDirection2D(input.moveX, input.moveY);\n\t\tconst velocity = entity.body.linvel();\n\n\t\tstate.moving = moveDirection !== null;\n\t\tentity.transformStore.velocity.x = (moveDirection?.x ?? 0) * movement.moveSpeed;\n\t\tentity.transformStore.velocity.y = (moveDirection?.y ?? 0) * movement.moveSpeed;\n\t\tentity.transformStore.velocity.z = velocity.z;\n\t\tentity.transformStore.dirty.velocity = true;\n\n\t\tconst facingDirection = normalizeDirection2D(input.faceX, input.faceY);\n\t\tif (facingDirection) {\n\t\t\tstate.facingAngle = angleFromDirection2D(facingDirection);\n\t\t}\n\n\t\tentity.setRotationZ?.(state.facingAngle);\n\t}\n}\n","import type { IWorld } from 'bitecs';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport {\n\tcreateTopDownMovementComponent,\n\tcreateTopDownMovementInputComponent,\n\tcreateTopDownMovementStateComponent,\n} from './components';\nimport {\n\tTopDownMovementRuntimeBehavior,\n\ttype TopDownMovementEntity,\n} from './top-down-movement.behavior';\n\nexport interface TopDownMovementBehaviorOptions {\n\tmoveSpeed?: number;\n}\n\nexport interface TopDownMovementHandle {\n\tgetFacingAngle(): number;\n}\n\nconst defaultOptions: TopDownMovementBehaviorOptions = {\n\tmoveSpeed: 8,\n};\n\nconst TOP_DOWN_MOVEMENT_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:top-down-movement',\n);\n\nfunction createTopDownMovementHandle(\n\tref: BehaviorRef<TopDownMovementBehaviorOptions>,\n): TopDownMovementHandle {\n\treturn {\n\t\tgetFacingAngle: () =>\n\t\t\t(ref as any).__entity?.topDownMovementState?.facingAngle ?? 0,\n\t};\n}\n\nclass TopDownMovementBehaviorSystem implements BehaviorSystem {\n\tprivate behavior = new TopDownMovementRuntimeBehavior();\n\n\tconstructor(\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(TOP_DOWN_MOVEMENT_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst entity = link.entity as any;\n\t\t\tconst ref = link.ref as any;\n\t\t\tif (!entity.body || !entity.transformStore) continue;\n\n\t\t\tif (!entity.topDownMovement) {\n\t\t\t\tentity.topDownMovement = createTopDownMovementComponent(ref.options);\n\t\t\t}\n\t\t\tif (!entity.$topDownMovement) {\n\t\t\t\tentity.$topDownMovement = createTopDownMovementInputComponent();\n\t\t\t}\n\t\t\tif (!entity.topDownMovementState) {\n\t\t\t\tentity.topDownMovementState = createTopDownMovementStateComponent();\n\t\t\t}\n\n\t\t\tref.__entity = entity;\n\t\t\tthis.behavior.updateEntity(entity, delta);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {}\n}\n\nexport const TopDownMovementBehavior = defineBehavior<\n\tTopDownMovementBehaviorOptions,\n\tTopDownMovementHandle,\n\tTopDownMovementEntity\n>({\n\tname: 'top-down-movement',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew TopDownMovementBehaviorSystem(ctx.getBehaviorLinks),\n\tcreateHandle: createTopDownMovementHandle,\n});\n","export interface Shooter2DStateComponent {\n\tcooldownRemainingMs: number;\n}\n\nexport function createShooter2DStateComponent(): Shooter2DStateComponent {\n\treturn {\n\t\tcooldownRemainingMs: 0,\n\t};\n}\n","import type { IWorld } from 'bitecs';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport {\n\tangleFromDirection2D,\n\tdirectionFromAngle2D,\n\tgetRotationAngle2D,\n\tnormalizeDirection2D,\n\trotateLocalOffset2D,\n} from '../shared/direction-2d';\nimport {\n\tcreateShooter2DStateComponent,\n\ttype Shooter2DStateComponent,\n} from './components';\n\nexport interface Shooter2DTarget {\n\tx: number;\n\ty: number;\n}\n\nexport interface Shooter2DStageLike {\n\tadd(...inputs: any[]): void;\n}\n\nexport interface Shooter2DProjectileEntity {\n\ttransformStore: {\n\t\tvelocity: { x: number; y: number; z: number };\n\t\tdirty: { velocity: boolean };\n\t};\n\tprependSetup(\n\t\tcallback: (params: { me: Shooter2DProjectileEntity }) => void,\n\t): unknown;\n\tsetPosition(x: number, y: number, z: number): void;\n\tsetRotationZ(angle: number): void;\n}\n\nexport type Shooter2DProjectileFactory = () =>\n\t| Shooter2DProjectileEntity\n\t| Promise<Shooter2DProjectileEntity>;\n\nexport interface Shooter2DBehaviorOptions {\n\tprojectileFactory: Shooter2DProjectileFactory;\n\tprojectileSpeed: number;\n\tcooldownMs?: number;\n\tspawnOffset?: Shooter2DTarget;\n\trotateProjectile?: boolean;\n}\n\nexport interface Shooter2DSourceEntity {\n\tbody?: {\n\t\ttranslation(): { x: number; y: number; z: number };\n\t\trotation?: () => { x: number; y: number; z: number; w: number };\n\t} | null;\n\toptions?: {\n\t\tposition?: { x: number; y: number; z?: number };\n\t};\n\ttopDownMovementState?: {\n\t\tfacingAngle: number;\n\t};\n\tshooter2dState?: Shooter2DStateComponent;\n\t_rotation2DAngle?: number;\n}\n\nexport interface Shooter2DFireArgs {\n\tsource: Shooter2DSourceEntity;\n\tstage: Shooter2DStageLike;\n\ttarget: Shooter2DTarget;\n}\n\nexport interface Shooter2DHandle {\n\tisReady(source: Shooter2DSourceEntity): boolean;\n\tfire(args: Shooter2DFireArgs): Promise<Shooter2DProjectileEntity | null>;\n}\n\nconst defaultOptions: Shooter2DBehaviorOptions = {\n\tprojectileFactory: () => {\n\t\tthrow new Error('Shooter2DBehavior requires a projectileFactory.');\n\t},\n\tprojectileSpeed: 12,\n\tcooldownMs: 0,\n\tspawnOffset: { x: 0, y: 1 },\n\trotateProjectile: true,\n};\n\nconst SHOOTER_2D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:shooter-2d');\n\nfunction ensureShooterState(entity: Shooter2DSourceEntity): Shooter2DStateComponent {\n\tif (!entity.shooter2dState) {\n\t\tentity.shooter2dState = createShooter2DStateComponent();\n\t}\n\treturn entity.shooter2dState;\n}\n\nfunction getEntityPosition(\n\tentity: Shooter2DSourceEntity,\n): { x: number; y: number; z: number } | null {\n\tif (entity.body?.translation) {\n\t\treturn entity.body.translation();\n\t}\n\n\tconst position = entity.options?.position;\n\tif (!position) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tx: position.x,\n\t\ty: position.y,\n\t\tz: position.z ?? 0,\n\t};\n}\n\nfunction getEntityFacingAngle(entity: Shooter2DSourceEntity): number {\n\tif (entity.topDownMovementState) {\n\t\treturn entity.topDownMovementState.facingAngle;\n\t}\n\n\tif (entity.body?.rotation) {\n\t\treturn getRotationAngle2D(entity.body.rotation());\n\t}\n\n\treturn entity._rotation2DAngle ?? 0;\n}\n\nfunction createShooter2DHandle(\n\tref: BehaviorRef<Shooter2DBehaviorOptions>,\n): Shooter2DHandle {\n\treturn {\n\t\tisReady: (source: Shooter2DSourceEntity) =>\n\t\t\tensureShooterState(source).cooldownRemainingMs <= 0,\n\t\tfire: async ({\n\t\t\tsource,\n\t\t\tstage,\n\t\t\ttarget,\n\t\t}: Shooter2DFireArgs): Promise<Shooter2DProjectileEntity | null> => {\n\t\t\tconst state = ensureShooterState(source);\n\t\t\tif (state.cooldownRemainingMs > 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst sourcePosition = getEntityPosition(source);\n\t\t\tif (!sourcePosition) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst options = ref.options;\n\t\t\tconst aimDirection = normalizeDirection2D(\n\t\t\t\ttarget.x - sourcePosition.x,\n\t\t\t\ttarget.y - sourcePosition.y,\n\t\t\t);\n\t\t\tconst angle = aimDirection\n\t\t\t\t? angleFromDirection2D(aimDirection)\n\t\t\t\t: getEntityFacingAngle(source);\n\t\t\tconst direction = aimDirection ?? directionFromAngle2D(angle);\n\t\t\tconst offset = rotateLocalOffset2D(\n\t\t\t\toptions.spawnOffset ?? defaultOptions.spawnOffset!,\n\t\t\t\tangle,\n\t\t\t);\n\t\t\tconst spawnPosition = {\n\t\t\t\tx: sourcePosition.x + offset.x,\n\t\t\t\ty: sourcePosition.y + offset.y,\n\t\t\t\tz: sourcePosition.z,\n\t\t\t};\n\t\t\tconst projectile = await Promise.resolve(options.projectileFactory());\n\t\t\tprojectile.prependSetup(({ me }) => {\n\t\t\t\tme.setPosition(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n\t\t\t\tif (options.rotateProjectile ?? true) {\n\t\t\t\t\tme.setRotationZ(angle);\n\t\t\t\t}\n\t\t\t\tme.transformStore.velocity.x = direction.x * options.projectileSpeed;\n\t\t\t\tme.transformStore.velocity.y = direction.y * options.projectileSpeed;\n\t\t\t\tme.transformStore.velocity.z = 0;\n\t\t\t\tme.transformStore.dirty.velocity = true;\n\t\t\t});\n\n\t\t\tstage.add(projectile);\n\t\t\tstate.cooldownRemainingMs = Math.max(0, options.cooldownMs ?? 0);\n\t\t\treturn projectile;\n\t\t},\n\t};\n}\n\nclass Shooter2DBehaviorSystem implements BehaviorSystem {\n\tconstructor(\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(SHOOTER_2D_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst entity = link.entity as Shooter2DSourceEntity;\n\t\t\tconst ref = link.ref as any;\n\t\t\tconst state = ensureShooterState(entity);\n\t\t\tstate.cooldownRemainingMs = Math.max(\n\t\t\t\t0,\n\t\t\t\tstate.cooldownRemainingMs - delta * 1000,\n\t\t\t);\n\t\t\tref.__entity = entity;\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {}\n}\n\nexport const Shooter2DBehavior = defineBehavior<\n\tShooter2DBehaviorOptions,\n\tShooter2DHandle,\n\tShooter2DSourceEntity\n>({\n\tname: 'shooter-2d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) => new Shooter2DBehaviorSystem(ctx.getBehaviorLinks),\n\tcreateHandle: createShooter2DHandle,\n});\n","/**\n * ScreenWrapFSM\n * \n * State machine for screen wrap behavior.\n * Reports position relative to bounds edges.\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM State Model\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum ScreenWrapState {\n\tCenter = 'center',\n\tNearEdgeLeft = 'near-edge-left',\n\tNearEdgeRight = 'near-edge-right',\n\tNearEdgeTop = 'near-edge-top',\n\tNearEdgeBottom = 'near-edge-bottom',\n\tWrapped = 'wrapped',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum ScreenWrapEvent {\n\tEnterCenter = 'enter-center',\n\tApproachLeft = 'approach-left',\n\tApproachRight = 'approach-right',\n\tApproachTop = 'approach-top',\n\tApproachBottom = 'approach-bottom',\n\tWrap = 'wrap',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ScreenWrapFSM\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ScreenWrapFSM {\n\tmachine: SyncStateMachine<ScreenWrapState, ScreenWrapEvent, never>;\n\n\tconstructor() {\n\t\tthis.machine = new SyncStateMachine<ScreenWrapState, ScreenWrapEvent, never>(\n\t\t\tScreenWrapState.Center,\n\t\t\t[\n\t\t\t\t// From Center\n\t\t\t\tt(ScreenWrapState.Center, ScreenWrapEvent.ApproachLeft, ScreenWrapState.NearEdgeLeft),\n\t\t\t\tt(ScreenWrapState.Center, ScreenWrapEvent.ApproachRight, ScreenWrapState.NearEdgeRight),\n\t\t\t\tt(ScreenWrapState.Center, ScreenWrapEvent.ApproachTop, ScreenWrapState.NearEdgeTop),\n\t\t\t\tt(ScreenWrapState.Center, ScreenWrapEvent.ApproachBottom, ScreenWrapState.NearEdgeBottom),\n\t\t\t\t\n\t\t\t\t// From NearEdge to Wrapped\n\t\t\t\tt(ScreenWrapState.NearEdgeLeft, ScreenWrapEvent.Wrap, ScreenWrapState.Wrapped),\n\t\t\t\tt(ScreenWrapState.NearEdgeRight, ScreenWrapEvent.Wrap, ScreenWrapState.Wrapped),\n\t\t\t\tt(ScreenWrapState.NearEdgeTop, ScreenWrapEvent.Wrap, ScreenWrapState.Wrapped),\n\t\t\t\tt(ScreenWrapState.NearEdgeBottom, ScreenWrapEvent.Wrap, ScreenWrapState.Wrapped),\n\n\t\t\t\t// From NearEdge back to Center\n\t\t\t\tt(ScreenWrapState.NearEdgeLeft, ScreenWrapEvent.EnterCenter, ScreenWrapState.Center),\n\t\t\t\tt(ScreenWrapState.NearEdgeRight, ScreenWrapEvent.EnterCenter, ScreenWrapState.Center),\n\t\t\t\tt(ScreenWrapState.NearEdgeTop, ScreenWrapEvent.EnterCenter, ScreenWrapState.Center),\n\t\t\t\tt(ScreenWrapState.NearEdgeBottom, ScreenWrapEvent.EnterCenter, ScreenWrapState.Center),\n\n\t\t\t\t// From Wrapped back to Center\n\t\t\t\tt(ScreenWrapState.Wrapped, ScreenWrapEvent.EnterCenter, ScreenWrapState.Center),\n\n\t\t\t\t// From Wrapped to NearEdge (landed near opposite edge)\n\t\t\t\tt(ScreenWrapState.Wrapped, ScreenWrapEvent.ApproachLeft, ScreenWrapState.NearEdgeLeft),\n\t\t\t\tt(ScreenWrapState.Wrapped, ScreenWrapEvent.ApproachRight, ScreenWrapState.NearEdgeRight),\n\t\t\t\tt(ScreenWrapState.Wrapped, ScreenWrapEvent.ApproachTop, ScreenWrapState.NearEdgeTop),\n\t\t\t\tt(ScreenWrapState.Wrapped, ScreenWrapEvent.ApproachBottom, ScreenWrapState.NearEdgeBottom),\n\n\t\t\t\t// Self-transitions (no-ops for redundant events)\n\t\t\t\tt(ScreenWrapState.Center, ScreenWrapEvent.EnterCenter, ScreenWrapState.Center),\n\t\t\t\tt(ScreenWrapState.NearEdgeLeft, ScreenWrapEvent.ApproachLeft, ScreenWrapState.NearEdgeLeft),\n\t\t\t\tt(ScreenWrapState.NearEdgeRight, ScreenWrapEvent.ApproachRight, ScreenWrapState.NearEdgeRight),\n\t\t\t\tt(ScreenWrapState.NearEdgeTop, ScreenWrapEvent.ApproachTop, ScreenWrapState.NearEdgeTop),\n\t\t\t\tt(ScreenWrapState.NearEdgeBottom, ScreenWrapEvent.ApproachBottom, ScreenWrapState.NearEdgeBottom),\n\t\t\t]\n\t\t);\n\t}\n\n\tgetState(): ScreenWrapState {\n\t\treturn this.machine.getState();\n\t}\n\n\tdispatch(event: ScreenWrapEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\t/**\n\t * Update FSM based on entity position relative to bounds\n\t */\n\tupdate(position: { x: number; y: number }, bounds: {\n\t\tminX: number; maxX: number; minY: number; maxY: number;\n\t\tedgeThreshold: number;\n\t}, wrapped: boolean): void {\n\t\tconst { x, y } = position;\n\t\tconst { minX, maxX, minY, maxY, edgeThreshold } = bounds;\n\n\t\tif (wrapped) {\n\t\t\tthis.dispatch(ScreenWrapEvent.Wrap);\n\t\t\treturn;\n\t\t}\n\n\t\t// Check if near edges\n\t\tconst nearLeft = x < minX + edgeThreshold;\n\t\tconst nearRight = x > maxX - edgeThreshold;\n\t\tconst nearBottom = y < minY + edgeThreshold;\n\t\tconst nearTop = y > maxY - edgeThreshold;\n\n\t\tif (nearLeft) {\n\t\t\tthis.dispatch(ScreenWrapEvent.ApproachLeft);\n\t\t} else if (nearRight) {\n\t\t\tthis.dispatch(ScreenWrapEvent.ApproachRight);\n\t\t} else if (nearTop) {\n\t\t\tthis.dispatch(ScreenWrapEvent.ApproachTop);\n\t\t} else if (nearBottom) {\n\t\t\tthis.dispatch(ScreenWrapEvent.ApproachBottom);\n\t\t} else {\n\t\t\tthis.dispatch(ScreenWrapEvent.EnterCenter);\n\t\t}\n\t}\n}\n","export interface Bounds2DPoint {\n\tx: number;\n\ty: number;\n}\n\nexport interface Bounds2DRect {\n\tminX: number;\n\tmaxX: number;\n\tminY: number;\n\tmaxY: number;\n}\n\nexport interface Bounds2DSize {\n\twidth: number;\n\theight: number;\n\tcenterX?: number;\n\tcenterY?: number;\n}\n\nexport interface Bounds2DHits {\n\tleft: boolean;\n\tright: boolean;\n\ttop: boolean;\n\tbottom: boolean;\n}\n\nexport interface Bounds2DWrapResult {\n\tx: number;\n\ty: number;\n\twrapped: boolean;\n}\n\nexport function createBounds2DRect({\n\twidth,\n\theight,\n\tcenterX = 0,\n\tcenterY = 0,\n}: Bounds2DSize): Bounds2DRect {\n\tconst halfWidth = width / 2;\n\tconst halfHeight = height / 2;\n\treturn {\n\t\tminX: centerX - halfWidth,\n\t\tmaxX: centerX + halfWidth,\n\t\tminY: centerY - halfHeight,\n\t\tmaxY: centerY + halfHeight,\n\t};\n}\n\nexport function computeBounds2DHits(\n\tposition: Bounds2DPoint,\n\tbounds: Bounds2DRect,\n): Bounds2DHits {\n\tconst hits: Bounds2DHits = {\n\t\ttop: false,\n\t\tbottom: false,\n\t\tleft: false,\n\t\tright: false,\n\t};\n\n\tif (position.x <= bounds.minX) hits.left = true;\n\telse if (position.x >= bounds.maxX) hits.right = true;\n\n\tif (position.y <= bounds.minY) hits.bottom = true;\n\telse if (position.y >= bounds.maxY) hits.top = true;\n\n\treturn hits;\n}\n\nexport function hasAnyBounds2DHit(hits: Bounds2DHits): boolean {\n\treturn hits.left || hits.right || hits.top || hits.bottom;\n}\n\nexport function constrainMovementToBounds2D(\n\thits: Bounds2DHits,\n\tmoveX: number,\n\tmoveY: number,\n): { moveX: number; moveY: number } {\n\tlet adjustedX = moveX;\n\tlet adjustedY = moveY;\n\n\tif ((hits.left && moveX < 0) || (hits.right && moveX > 0)) {\n\t\tadjustedX = 0;\n\t}\n\n\tif ((hits.bottom && moveY < 0) || (hits.top && moveY > 0)) {\n\t\tadjustedY = 0;\n\t}\n\n\treturn { moveX: adjustedX, moveY: adjustedY };\n}\n\nexport function wrapPoint2D(\n\tposition: Bounds2DPoint,\n\tbounds: Bounds2DRect,\n): Bounds2DWrapResult {\n\tlet x = position.x;\n\tlet y = position.y;\n\tlet wrapped = false;\n\n\tif (position.x < bounds.minX) {\n\t\tx = bounds.maxX - (bounds.minX - position.x);\n\t\twrapped = true;\n\t} else if (position.x > bounds.maxX) {\n\t\tx = bounds.minX + (position.x - bounds.maxX);\n\t\twrapped = true;\n\t}\n\n\tif (position.y < bounds.minY) {\n\t\ty = bounds.maxY - (bounds.minY - position.y);\n\t\twrapped = true;\n\t} else if (position.y > bounds.maxY) {\n\t\ty = bounds.minY + (position.y - bounds.maxY);\n\t\twrapped = true;\n\t}\n\n\treturn { x, y, wrapped };\n}\n\nexport function getBounds2DNormalFromHits(\n\thits: Bounds2DHits,\n): { x: number; y: number } {\n\tlet x = 0;\n\tlet y = 0;\n\n\tif (hits.left) x = 1;\n\tif (hits.right) x = -1;\n\tif (hits.bottom) y = 1;\n\tif (hits.top) y = -1;\n\n\treturn { x, y };\n}\n","/**\n * ScreenWrapBehavior\n * \n * When an entity exits the defined 2D bounds, it wraps around to the opposite edge.\n * Asteroids-style screen wrapping with FSM for edge detection.\n */\n\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { ScreenWrapFSM } from './screen-wrap-fsm';\nimport { createBounds2DRect, wrapPoint2D } from '../shared/bounds-2d';\n\n/**\n * Screen wrap options (typed for entity.use() autocomplete)\n */\nexport interface ScreenWrapOptions {\n\t/** Width of the wrapping area (default: 20) */\n\twidth: number;\n\t/** Height of the wrapping area (default: 15) */\n\theight: number;\n\t/** Center X position (default: 0) */\n\tcenterX: number;\n\t/** Center Y position (default: 0) */\n\tcenterY: number;\n\t/** Distance from edge to trigger NearEdge state (default: 2) */\n\tedgeThreshold: number;\n}\n\nconst defaultOptions: ScreenWrapOptions = {\n\twidth: 20,\n\theight: 15,\n\tcenterX: 0,\n\tcenterY: 0,\n\tedgeThreshold: 2,\n};\n\nconst SCREEN_WRAP_BEHAVIOR_KEY = Symbol.for('zylem:behavior:screen-wrap');\n\n/**\n * ScreenWrapSystem - Wraps entities around 2D bounds\n */\nclass ScreenWrapSystem implements BehaviorSystem {\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(SCREEN_WRAP_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst wrapRef = link.ref as any;\n\t\t\tif (!gameEntity.body) continue;\n\n\t\t\tconst options = wrapRef.options as ScreenWrapOptions;\n\n\t\t\t// Create FSM lazily\n\t\t\tif (!wrapRef.fsm) {\n\t\t\t\twrapRef.fsm = new ScreenWrapFSM();\n\t\t\t}\n\n\t\t\tconst wrapped = this.wrapEntity(gameEntity, options);\n\n\t\t\t// Update FSM with position and wrap state\n\t\t\tconst pos = gameEntity.body.translation();\n\t\t\tconst { edgeThreshold } = options;\n\t\t\tconst bounds = createBounds2DRect(options);\n\n\t\t\twrapRef.fsm.update(\n\t\t\t\t{ x: pos.x, y: pos.y },\n\t\t\t\t{\n\t\t\t\t\tminX: bounds.minX,\n\t\t\t\t\tmaxX: bounds.maxX,\n\t\t\t\t\tminY: bounds.minY,\n\t\t\t\t\tmaxY: bounds.maxY,\n\t\t\t\t\tedgeThreshold,\n\t\t\t\t},\n\t\t\t\twrapped\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate wrapEntity(entity: any, options: ScreenWrapOptions): boolean {\n\t\tconst body = entity.body;\n\t\tif (!body) return false;\n\n\t\tconst pos = body.translation();\n\t\tconst bounds = createBounds2DRect(options);\n\t\tconst result = wrapPoint2D({ x: pos.x, y: pos.y }, bounds);\n\n\t\tif (result.wrapped) {\n\t\t\tbody.setTranslation({ x: result.x, y: result.y, z: pos.z }, true);\n\t\t}\n\n\t\treturn result.wrapped;\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\t// Cleanup if needed\n\t}\n}\n\n/**\n * ScreenWrapBehavior - Wraps entities around 2D bounds\n * \n * @example\n * ```typescript\n * import { ScreenWrapBehavior } from \"@zylem/game-lib\";\n * \n * const ship = createSprite({ ... });\n * const wrapRef = ship.use(ScreenWrapBehavior, { width: 20, height: 15 });\n * \n * // Access FSM to observe edge state\n * const fsm = wrapRef.getFSM();\n * console.log(fsm?.getState()); // 'center', 'near-edge-left', 'wrapped', etc.\n * ```\n */\nexport const ScreenWrapBehavior = defineBehavior({\n\tname: 'screen-wrap',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew ScreenWrapSystem(ctx.world, ctx.getBehaviorLinks),\n});\n","import type { IWorld } from 'bitecs';\nimport {\n\tBox3,\n\tFrustum,\n\tMatrix4,\n\tQuaternion,\n\tVector3,\n\ttype Object3D,\n} from 'three';\n\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { ScreenVisibilityFSM, type ScreenVisibilitySnapshot } from './screen-visibility-fsm';\nimport type { GameEntity } from '../../entities/entity';\nimport type { ZylemCamera } from '../../camera/zylem-camera';\n\nexport interface ScreenVisibilitySize {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\nexport interface ScreenVisibilityChangeContext {\n\tentity: GameEntity<any>;\n\tvisible: boolean;\n\twasVisible: boolean;\n\tjustEntered: boolean;\n\tjustExited: boolean;\n\tvisibleCameraNames: string[];\n\tcameraName: string | null;\n}\n\nexport interface ScreenVisibilityOptions {\n\t/**\n\t * Restrict visibility checks to one active camera by name.\n\t * When omitted, any active camera can make the entity visible.\n\t */\n\tcameraName: string | null;\n\t/**\n\t * Require the full entity bounds to remain inside the camera frustum.\n\t * Defaults to partial visibility (any intersection counts).\n\t */\n\trequireFullyVisible: boolean;\n\t/**\n\t * Expand or shrink the computed bounds in world units.\n\t * Positive values make visibility checks more generous.\n\t */\n\tpadding: number;\n\t/**\n\t * Optional bounds to use when the entity has no renderable mesh/group.\n\t * Falls back to the entity's configured size when available.\n\t */\n\tfallbackSize: ScreenVisibilitySize | null;\n\tonChange?: (context: ScreenVisibilityChangeContext) => void;\n\tonEnter?: (context: ScreenVisibilityChangeContext) => void;\n\tonExit?: (context: ScreenVisibilityChangeContext) => void;\n}\n\nexport interface ScreenVisibilityHandle {\n\tisVisible(): boolean;\n\tisOffscreen(): boolean;\n\twasJustEntered(): boolean;\n\twasJustExited(): boolean;\n\tgetVisibleCameraNames(): string[];\n\tgetState(): ScreenVisibilitySnapshot | null;\n}\n\nconst defaultOptions: ScreenVisibilityOptions = {\n\tcameraName: null,\n\trequireFullyVisible: false,\n\tpadding: 0,\n\tfallbackSize: null,\n\tonChange: undefined,\n\tonEnter: undefined,\n\tonExit: undefined,\n};\n\nconst SCREEN_VISIBILITY_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:screen-visibility',\n);\n\nclass ScreenVisibilitySystem implements BehaviorSystem {\n\tprivate readonly worldBounds = new Box3();\n\tprivate readonly projectionMatrix = new Matrix4();\n\tprivate readonly frustum = new Frustum();\n\tprivate readonly savedPosition = new Vector3();\n\tprivate readonly savedQuaternion = new Quaternion();\n\tprivate readonly worldPosition = new Vector3();\n\tprivate readonly fallbackMin = new Vector3();\n\tprivate readonly fallbackMax = new Vector3();\n\tprivate readonly corners = Array.from({ length: 8 }, () => new Vector3());\n\tprivate readonly boundsCache = new Map<string, {\n\t\tbounds: Box3;\n\t\tkey: string;\n\t}>();\n\n\tconstructor(\n\t\tprivate scene: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) { }\n\n\tupdate(_ecs: IWorld, _delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(SCREEN_VISIBILITY_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst entity = link.entity as GameEntity<any>;\n\t\t\tconst visibilityRef = link.ref as BehaviorRef<ScreenVisibilityOptions>;\n\t\t\tconst options = visibilityRef.options;\n\n\t\t\tif (!visibilityRef.fsm) {\n\t\t\t\tvisibilityRef.fsm = new ScreenVisibilityFSM();\n\t\t\t}\n\n\t\t\tconst fsm = visibilityRef.fsm as ScreenVisibilityFSM;\n\t\t\tconst previousState = fsm.getState();\n\t\t\tconst cameras = this.resolveActiveCameras(options.cameraName);\n\t\t\tconst visibleCameraNames: string[] = [];\n\n\t\t\tconst bounds = this.computeWorldBounds(entity, visibilityRef, options);\n\t\t\tif (bounds) {\n\t\t\t\tfor (let index = 0; index < cameras.length; index++) {\n\t\t\t\t\tconst cameraRef = cameras[index];\n\t\t\t\t\tif (this.isBoundsVisible(bounds, cameraRef, options.requireFullyVisible)) {\n\t\t\t\t\t\tvisibleCameraNames.push(this.getCameraLabel(cameraRef, index));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfsm.update(visibleCameraNames.length > 0, visibleCameraNames);\n\t\t\tthis.notifyVisibilityChange(entity, options, previousState, fsm.getState());\n\t\t}\n\t}\n\n\tprivate resolveActiveCameras(cameraName: string | null): ZylemCamera[] {\n\t\tconst activeCameras = this.scene?.cameraManager?.activeCameras?.length\n\t\t\t? [...this.scene.cameraManager.activeCameras]\n\t\t\t: this.scene?.zylemCamera\n\t\t\t\t? [this.scene.zylemCamera]\n\t\t\t\t: [];\n\n\t\tif (!cameraName) {\n\t\t\treturn activeCameras;\n\t\t}\n\n\t\treturn activeCameras.filter((camera: ZylemCamera) => camera.name === cameraName);\n\t}\n\n\tprivate computeWorldBounds(\n\t\tentity: GameEntity<any>,\n\t\tref: BehaviorRef<ScreenVisibilityOptions>,\n\t\toptions: ScreenVisibilityOptions,\n\t): Box3 | null {\n\t\tconst cacheKey = this.getBoundsCacheKey(entity, options);\n\t\tconst cached = this.boundsCache.get(entity.uuid);\n\t\tif (cached && cached.key === cacheKey) {\n\t\t\treturn cached.bounds;\n\t\t}\n\n\t\tconst target = (entity.group ?? entity.mesh) as Object3D | undefined;\n\t\tthis.worldBounds.makeEmpty();\n\n\t\tif (target) {\n\t\t\tconst body = (entity as any).body;\n\t\t\tif (body) {\n\t\t\t\tthis.savedPosition.copy(target.position);\n\t\t\t\tthis.savedQuaternion.copy(target.quaternion);\n\n\t\t\t\tconst translation = body.translation();\n\t\t\t\ttarget.position.set(translation.x, translation.y, translation.z);\n\n\t\t\t\tif (!(entity as any).controlledRotation) {\n\t\t\t\t\tconst rotation = body.rotation();\n\t\t\t\t\ttarget.quaternion.set(rotation.x, rotation.y, rotation.z, rotation.w);\n\t\t\t\t}\n\n\t\t\t\ttarget.updateWorldMatrix(true, true);\n\t\t\t\tthis.worldBounds.setFromObject(target);\n\n\t\t\t\ttarget.position.copy(this.savedPosition);\n\t\t\t\ttarget.quaternion.copy(this.savedQuaternion);\n\t\t\t\ttarget.updateWorldMatrix(true, true);\n\t\t\t} else {\n\t\t\t\ttarget.updateWorldMatrix(true, true);\n\t\t\t\tthis.worldBounds.setFromObject(target);\n\t\t\t}\n\t\t}\n\n\t\tif (this.worldBounds.isEmpty()) {\n\t\t\tconst fallbackSize = options.fallbackSize\n\t\t\t\t?? ((entity.options?.size as ScreenVisibilitySize | undefined) ?? null);\n\t\t\tthis.resolveFallbackCenter(entity, target);\n\n\t\t\tconst halfX = (fallbackSize?.x ?? 0) / 2;\n\t\t\tconst halfY = (fallbackSize?.y ?? 0) / 2;\n\t\t\tconst halfZ = (fallbackSize?.z ?? 0) / 2;\n\n\t\t\tthis.fallbackMin.set(\n\t\t\t\tthis.worldPosition.x - halfX,\n\t\t\t\tthis.worldPosition.y - halfY,\n\t\t\t\tthis.worldPosition.z - halfZ,\n\t\t\t);\n\t\t\tthis.fallbackMax.set(\n\t\t\t\tthis.worldPosition.x + halfX,\n\t\t\t\tthis.worldPosition.y + halfY,\n\t\t\t\tthis.worldPosition.z + halfZ,\n\t\t\t);\n\t\t\tthis.worldBounds.set(this.fallbackMin, this.fallbackMax);\n\t\t}\n\n\t\tif (options.padding !== 0) {\n\t\t\tthis.worldBounds.expandByScalar(options.padding);\n\t\t}\n\n\t\tif (this.worldBounds.isEmpty()) {\n\t\t\tthis.boundsCache.delete(entity.uuid);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst cachedBounds = cached?.bounds ?? new Box3();\n\t\tcachedBounds.copy(this.worldBounds);\n\t\tthis.boundsCache.set(entity.uuid, {\n\t\t\tbounds: cachedBounds,\n\t\t\tkey: cacheKey,\n\t\t});\n\t\t(ref as any).__screenVisibilityBoundsKey = cacheKey;\n\t\treturn cachedBounds;\n\t}\n\n\tprivate getBoundsCacheKey(\n\t\tentity: GameEntity<any>,\n\t\toptions: ScreenVisibilityOptions,\n\t): string {\n\t\tconst body = (entity as any).body;\n\t\tif (body) {\n\t\t\tconst translation = body.translation();\n\t\t\tconst rotation = body.rotation();\n\t\t\treturn [\n\t\t\t\t'b',\n\t\t\t\ttranslation.x.toFixed(3),\n\t\t\t\ttranslation.y.toFixed(3),\n\t\t\t\ttranslation.z.toFixed(3),\n\t\t\t\trotation.x.toFixed(3),\n\t\t\t\trotation.y.toFixed(3),\n\t\t\t\trotation.z.toFixed(3),\n\t\t\t\trotation.w.toFixed(3),\n\t\t\t\toptions.padding,\n\t\t\t\toptions.requireFullyVisible,\n\t\t\t\toptions.fallbackSize?.x ?? '',\n\t\t\t\toptions.fallbackSize?.y ?? '',\n\t\t\t\toptions.fallbackSize?.z ?? '',\n\t\t\t].join('|');\n\t\t}\n\n\t\tconst target = (entity.group ?? entity.mesh) as Object3D | undefined;\n\t\tif (target) {\n\t\t\tconst position = target.position;\n\t\t\tconst quaternion = target.quaternion;\n\t\t\tconst scale = target.scale;\n\t\t\treturn [\n\t\t\t\t'o',\n\t\t\t\tposition.x.toFixed(3),\n\t\t\t\tposition.y.toFixed(3),\n\t\t\t\tposition.z.toFixed(3),\n\t\t\t\tquaternion.x.toFixed(3),\n\t\t\t\tquaternion.y.toFixed(3),\n\t\t\t\tquaternion.z.toFixed(3),\n\t\t\t\tquaternion.w.toFixed(3),\n\t\t\t\tscale.x.toFixed(3),\n\t\t\t\tscale.y.toFixed(3),\n\t\t\t\tscale.z.toFixed(3),\n\t\t\t\toptions.padding,\n\t\t\t\toptions.requireFullyVisible,\n\t\t\t\toptions.fallbackSize?.x ?? '',\n\t\t\t\toptions.fallbackSize?.y ?? '',\n\t\t\t\toptions.fallbackSize?.z ?? '',\n\t\t\t].join('|');\n\t\t}\n\n\t\tconst position = entity.options?.position ?? { x: 0, y: 0, z: 0 };\n\t\tconst size = entity.options?.size ?? { x: 0, y: 0, z: 0 };\n\t\treturn [\n\t\t\t's',\n\t\t\tposition.x,\n\t\t\tposition.y,\n\t\t\tposition.z,\n\t\t\tsize.x,\n\t\t\tsize.y,\n\t\t\tsize.z,\n\t\t\toptions.padding,\n\t\t\toptions.requireFullyVisible,\n\t\t\toptions.fallbackSize?.x ?? '',\n\t\t\toptions.fallbackSize?.y ?? '',\n\t\t\toptions.fallbackSize?.z ?? '',\n\t\t].join('|');\n\t}\n\n\tprivate resolveFallbackCenter(\n\t\tentity: GameEntity<any>,\n\t\ttarget: Object3D | undefined,\n\t): void {\n\t\tconst body = (entity as any).body;\n\t\tif (body) {\n\t\t\tconst translation = body.translation();\n\t\t\tthis.worldPosition.set(translation.x, translation.y, translation.z);\n\t\t\treturn;\n\t\t}\n\n\t\tif (target) {\n\t\t\ttarget.updateWorldMatrix(true, false);\n\t\t\ttarget.getWorldPosition(this.worldPosition);\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = entity.options?.position ?? { x: 0, y: 0, z: 0 };\n\t\tthis.worldPosition.set(position.x, position.y, position.z);\n\t}\n\n\tprivate isBoundsVisible(\n\t\tbounds: Box3,\n\t\tcameraRef: ZylemCamera,\n\t\trequireFullyVisible: boolean,\n\t): boolean {\n\t\tconst camera = cameraRef.camera;\n\t\tcamera.updateMatrixWorld(true);\n\t\tthis.projectionMatrix.multiplyMatrices(\n\t\t\tcamera.projectionMatrix,\n\t\t\tcamera.matrixWorldInverse,\n\t\t);\n\t\tthis.frustum.setFromProjectionMatrix(this.projectionMatrix);\n\n\t\tif (!requireFullyVisible) {\n\t\t\treturn this.frustum.intersectsBox(bounds);\n\t\t}\n\n\t\treturn this.getCorners(bounds).every((corner) => this.frustum.containsPoint(corner));\n\t}\n\n\tprivate getCorners(bounds: Box3): Vector3[] {\n\t\tconst { min, max } = bounds;\n\t\tthis.corners[0].set(min.x, min.y, min.z);\n\t\tthis.corners[1].set(min.x, min.y, max.z);\n\t\tthis.corners[2].set(min.x, max.y, min.z);\n\t\tthis.corners[3].set(min.x, max.y, max.z);\n\t\tthis.corners[4].set(max.x, min.y, min.z);\n\t\tthis.corners[5].set(max.x, min.y, max.z);\n\t\tthis.corners[6].set(max.x, max.y, min.z);\n\t\tthis.corners[7].set(max.x, max.y, max.z);\n\t\treturn this.corners;\n\t}\n\n\tprivate getCameraLabel(camera: ZylemCamera, index: number): string {\n\t\treturn camera.name || (index === 0 ? 'primary' : `camera-${index}`);\n\t}\n\n\tprivate notifyVisibilityChange(\n\t\tentity: GameEntity<any>,\n\t\toptions: ScreenVisibilityOptions,\n\t\tpreviousState: ScreenVisibilitySnapshot,\n\t\tnextState: ScreenVisibilitySnapshot,\n\t): void {\n\t\tif (!nextState.justEntered && !nextState.justExited) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst context: ScreenVisibilityChangeContext = {\n\t\t\tentity,\n\t\t\tvisible: nextState.visible,\n\t\t\twasVisible: previousState.visible,\n\t\t\tjustEntered: nextState.justEntered,\n\t\t\tjustExited: nextState.justExited,\n\t\t\tvisibleCameraNames: [...nextState.visibleCameraNames],\n\t\t\tcameraName: options.cameraName,\n\t\t};\n\n\t\tif (nextState.justEntered) {\n\t\t\toptions.onEnter?.(context);\n\t\t}\n\n\t\tif (nextState.justExited) {\n\t\t\toptions.onExit?.(context);\n\t\t}\n\n\t\toptions.onChange?.(context);\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\tthis.boundsCache.clear();\n\t}\n}\n\nfunction createScreenVisibilityHandle(\n\tref: BehaviorRef<ScreenVisibilityOptions>,\n): ScreenVisibilityHandle {\n\treturn {\n\t\tisVisible: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.isVisible() ?? false;\n\t\t},\n\t\tisOffscreen: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn !(fsm?.isVisible() ?? false);\n\t\t},\n\t\twasJustEntered: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.wasJustEntered() ?? false;\n\t\t},\n\t\twasJustExited: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.wasJustExited() ?? false;\n\t\t},\n\t\tgetVisibleCameraNames: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.getVisibleCameraNames() ?? [];\n\t\t},\n\t\tgetState: () => {\n\t\t\tconst fsm = ref.fsm as ScreenVisibilityFSM | undefined;\n\t\t\treturn fsm?.getState() ?? null;\n\t\t},\n\t};\n}\n\nexport const ScreenVisibilityBehavior = defineBehavior<\n\tScreenVisibilityOptions,\n\tScreenVisibilityHandle\n>({\n\tname: 'screen-visibility',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew ScreenVisibilitySystem(ctx.scene, ctx.getBehaviorLinks),\n\tcreateHandle: createScreenVisibilityHandle,\n});\n","export interface ScreenVisibilitySnapshot {\n\tinitialized: boolean;\n\tvisible: boolean;\n\tjustEntered: boolean;\n\tjustExited: boolean;\n\tvisibleCameraNames: string[];\n}\n\nexport class ScreenVisibilityFSM {\n\tprivate initialized = false;\n\tprivate visible = false;\n\tprivate justEntered = false;\n\tprivate justExited = false;\n\tprivate visibleCameraNames: string[] = [];\n\n\tupdate(visible: boolean, visibleCameraNames: readonly string[]): void {\n\t\tconst wasVisible = this.visible;\n\n\t\tthis.justEntered = !wasVisible && visible;\n\t\tthis.justExited = wasVisible && !visible;\n\n\t\tif (!this.initialized) {\n\t\t\tthis.justEntered = visible;\n\t\t\tthis.justExited = false;\n\t\t}\n\n\t\tthis.initialized = true;\n\t\tthis.visible = visible;\n\t\tthis.visibleCameraNames = [...visibleCameraNames];\n\t}\n\n\tisInitialized(): boolean {\n\t\treturn this.initialized;\n\t}\n\n\tisVisible(): boolean {\n\t\treturn this.visible;\n\t}\n\n\twasJustEntered(): boolean {\n\t\treturn this.justEntered;\n\t}\n\n\twasJustExited(): boolean {\n\t\treturn this.justExited;\n\t}\n\n\tgetVisibleCameraNames(): string[] {\n\t\treturn [...this.visibleCameraNames];\n\t}\n\n\tgetState(): ScreenVisibilitySnapshot {\n\t\treturn {\n\t\t\tinitialized: this.initialized,\n\t\t\tvisible: this.visible,\n\t\t\tjustEntered: this.justEntered,\n\t\t\tjustExited: this.justExited,\n\t\t\tvisibleCameraNames: this.getVisibleCameraNames(),\n\t\t};\n\t}\n}\n","/**\n * WorldBoundary2DFSM\n *\n * Minimal FSM + extended state to track which world boundaries were hit.\n *\n * Notes:\n * - \"Hit boundaries\" is inherently a *set* (can hit left+bottom in one frame),\n * so we store it as extended state (`lastHits`) rather than a single FSM state.\n * - The FSM state is still useful for coarse status like \"inside\" vs \"touching\".\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport {\n\tcomputeBounds2DHits,\n\tconstrainMovementToBounds2D,\n\thasAnyBounds2DHit,\n} from '../shared/bounds-2d';\n\nexport type WorldBoundary2DHit = 'top' | 'bottom' | 'left' | 'right';\nexport type WorldBoundary2DHits = Record<WorldBoundary2DHit, boolean>;\n\nexport interface WorldBoundary2DPosition {\n\tx: number;\n\ty: number;\n}\n\nexport interface WorldBoundary2DBounds {\n\ttop: number;\n\tbottom: number;\n\tleft: number;\n\tright: number;\n}\n\nexport enum WorldBoundary2DState {\n\tInside = 'inside',\n\tTouching = 'touching',\n}\n\nexport enum WorldBoundary2DEvent {\n\tEnterInside = 'enter-inside',\n\tTouchBoundary = 'touch-boundary',\n}\n\n/**\n * Compute which boundaries are being hit for a position and bounds.\n * This matches the semantics of the legacy `boundary2d` behavior:\n * - left hit if x <= left\n * - right hit if x >= right\n * - bottom hit if y <= bottom\n * - top hit if y >= top\n */\nexport function computeWorldBoundary2DHits(\n\tposition: WorldBoundary2DPosition,\n\tbounds: WorldBoundary2DBounds\n): WorldBoundary2DHits {\n\treturn computeBounds2DHits(position, {\n\t\tminX: bounds.left,\n\t\tmaxX: bounds.right,\n\t\tminY: bounds.bottom,\n\t\tmaxY: bounds.top,\n\t});\n}\n\nexport function hasAnyWorldBoundary2DHit(hits: WorldBoundary2DHits): boolean {\n\treturn hasAnyBounds2DHit(hits);\n}\n\n/**\n * FSM wrapper with \"extended state\" (lastHits / lastPosition).\n * Systems should call `update(...)` once per frame.\n */\nexport class WorldBoundary2DFSM {\n\tpublic readonly machine: SyncStateMachine<WorldBoundary2DState, WorldBoundary2DEvent, never>;\n\n\tprivate lastHits: WorldBoundary2DHits = { top: false, bottom: false, left: false, right: false };\n\tprivate lastPosition: WorldBoundary2DPosition | null = null;\n\tprivate lastUpdatedAtMs: number | null = null;\n\n\tconstructor() {\n\t\tthis.machine = new SyncStateMachine<WorldBoundary2DState, WorldBoundary2DEvent, never>(\n\t\t\tWorldBoundary2DState.Inside,\n\t\t\t[\n\t\t\t\tt(WorldBoundary2DState.Inside, WorldBoundary2DEvent.TouchBoundary, WorldBoundary2DState.Touching),\n\t\t\t\tt(WorldBoundary2DState.Touching, WorldBoundary2DEvent.EnterInside, WorldBoundary2DState.Inside),\n\n\t\t\t\t// Self transitions (no-ops)\n\t\t\t\tt(WorldBoundary2DState.Inside, WorldBoundary2DEvent.EnterInside, WorldBoundary2DState.Inside),\n\t\t\t\tt(WorldBoundary2DState.Touching, WorldBoundary2DEvent.TouchBoundary, WorldBoundary2DState.Touching),\n\t\t\t]\n\t\t);\n\t}\n\n\tgetState(): WorldBoundary2DState {\n\t\treturn this.machine.getState();\n\t}\n\n\t/**\n\t * Returns the last computed hits (always available after first update call).\n\t */\n\tgetLastHits(): WorldBoundary2DHits {\n\t\treturn this.lastHits;\n\t}\n\n\t/**\n\t * Returns adjusted movement values based on boundary hits.\n\t * If the entity is touching a boundary and trying to move further into it,\n\t * that axis component is zeroed out.\n\t *\n\t * @param moveX - The desired X movement\n\t * @param moveY - The desired Y movement\n\t * @returns Adjusted { moveX, moveY } with boundary-blocked axes zeroed\n\t */\n\tgetMovement(moveX: number, moveY: number): { moveX: number; moveY: number } {\n\t\treturn constrainMovementToBounds2D(this.lastHits, moveX, moveY);\n\t}\n\n\t/**\n\t * Returns the last position passed to `update`, if any.\n\t */\n\tgetLastPosition(): WorldBoundary2DPosition | null {\n\t\treturn this.lastPosition;\n\t}\n\n\t/**\n\t * Best-effort timestamp (ms) of the last `update(...)` call.\n\t * This is optional metadata; systems can ignore it.\n\t */\n\tgetLastUpdatedAtMs(): number | null {\n\t\treturn this.lastUpdatedAtMs;\n\t}\n\n\t/**\n\t * Update FSM + extended state based on current position and bounds.\n\t * Returns the computed hits for convenience.\n\t */\n\tupdate(position: WorldBoundary2DPosition, bounds: WorldBoundary2DBounds): WorldBoundary2DHits {\n\t\tconst hits = computeWorldBoundary2DHits(position, bounds);\n\n\t\tthis.lastHits = hits;\n\t\tthis.lastPosition = { x: position.x, y: position.y };\n\t\tthis.lastUpdatedAtMs = Date.now();\n\n\t\tif (hasAnyWorldBoundary2DHit(hits)) {\n\t\t\tthis.dispatch(WorldBoundary2DEvent.TouchBoundary);\n\t\t} else {\n\t\t\tthis.dispatch(WorldBoundary2DEvent.EnterInside);\n\t\t}\n\n\t\treturn hits;\n\t}\n\n\tprivate dispatch(event: WorldBoundary2DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n}\n","/**\n * WorldBoundary2DBehavior\n *\n * Tracks which 2D world boundaries an entity is touching.\n * Use `getMovement()` on the behavior handle to adjust movement based on hits.\n *\n * Source of truth: `entity.body` (Rapier rigid body), consistent with other new behaviors.\n */\n\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport {\n\tWorldBoundary2DFSM,\n\ttype WorldBoundary2DBounds,\n\ttype WorldBoundary2DHits,\n} from './world-boundary-2d-fsm';\n\nexport interface WorldBoundary2DOptions {\n\t/**\n\t * World boundaries (in world units).\n\t * - left hit if x <= left\n\t * - right hit if x >= right\n\t * - bottom hit if y <= bottom\n\t * - top hit if y >= top\n\t */\n\tboundaries: WorldBoundary2DBounds;\n}\n\n/**\n * Handle methods provided by WorldBoundary2DBehavior\n */\nexport interface WorldBoundary2DHandle {\n\t/**\n\t * Get the last computed boundary hits.\n\t * Returns null until entity is spawned and FSM is initialized.\n\t */\n\tgetLastHits(): WorldBoundary2DHits | null;\n\n\t/**\n\t * Get adjusted movement values based on boundary hits.\n\t * Zeros out movement into boundaries the entity is touching.\n\t */\n\tgetMovement(moveX: number, moveY: number): { moveX: number; moveY: number };\n}\n\nconst defaultOptions: WorldBoundary2DOptions = {\n\tboundaries: { top: 0, bottom: 0, left: 0, right: 0 },\n};\n\nconst WORLD_BOUNDARY_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:world-boundary-2d',\n);\n\n/**\n * Creates behavior-specific handle methods for WorldBoundary2DBehavior.\n */\nfunction createWorldBoundary2DHandle(\n\tref: BehaviorRef<WorldBoundary2DOptions>\n): WorldBoundary2DHandle {\n\treturn {\n\t\tgetLastHits: () => {\n\t\t\tconst fsm = ref.fsm as WorldBoundary2DFSM | undefined;\n\t\t\treturn fsm?.getLastHits() ?? null;\n\t\t},\n\t\tgetMovement: (moveX: number, moveY: number) => {\n\t\t\tconst fsm = ref.fsm as WorldBoundary2DFSM | undefined;\n\t\t\treturn fsm?.getMovement(moveX, moveY) ?? { moveX, moveY };\n\t\t},\n\t};\n}\n\n/**\n * WorldBoundary2DSystem\n *\n * Stage-level system that:\n * - finds entities with this behavior attached\n * - computes and tracks boundary hits using the FSM\n */\nclass WorldBoundary2DSystem implements BehaviorSystem {\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: IWorld, _delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(WORLD_BOUNDARY_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst boundaryRef = link.ref as any;\n\t\t\tif (!gameEntity.body) continue;\n\n\t\t\tconst options = boundaryRef.options as WorldBoundary2DOptions;\n\n\t\t\t// Create FSM lazily on first update after spawn\n\t\t\tif (!boundaryRef.fsm) {\n\t\t\t\tboundaryRef.fsm = new WorldBoundary2DFSM();\n\t\t\t}\n\n\t\t\tconst body = gameEntity.body;\n\t\t\tconst pos = body.translation();\n\n\t\t\t// Update FSM with current position - consumers use getMovement() to act on hits\n\t\t\tboundaryRef.fsm.update(\n\t\t\t\t{ x: pos.x, y: pos.y },\n\t\t\t\toptions.boundaries\n\t\t\t);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\t// No explicit cleanup required (FSMs are stored on behavior refs)\n\t}\n}\n\n/**\n * WorldBoundary2DBehavior\n *\n * @example\n * ```ts\n * import { WorldBoundary2DBehavior } from \"@zylem/game-lib\";\n *\n * const ship = createSprite({ ... });\n * const boundary = ship.use(WorldBoundary2DBehavior, {\n * boundaries: { left: -10, right: 10, bottom: -7.5, top: 7.5 },\n * });\n *\n * ship.onUpdate(({ me }) => {\n * let moveX = ..., moveY = ...;\n * const hits = boundary.getLastHits(); // Fully typed!\n * ({ moveX, moveY } = boundary.getMovement(moveX, moveY));\n * me.moveXY(moveX, moveY);\n * });\n * ```\n */\nexport const WorldBoundary2DBehavior = defineBehavior({\n\tname: 'world-boundary-2d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew WorldBoundary2DSystem(ctx.world, ctx.getBehaviorLinks),\n\tcreateHandle: createWorldBoundary2DHandle,\n});\n","export interface Bounds3DPoint {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\nexport interface Bounds3DBox {\n\tminX: number;\n\tmaxX: number;\n\tminY: number;\n\tmaxY: number;\n\tminZ: number;\n\tmaxZ: number;\n}\n\nexport interface Bounds3DSize {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\tcenterX?: number;\n\tcenterY?: number;\n\tcenterZ?: number;\n}\n\nexport interface Bounds3DHits {\n\tleft: boolean;\n\tright: boolean;\n\ttop: boolean;\n\tbottom: boolean;\n\tback: boolean;\n\tfront: boolean;\n}\n\nexport interface Bounds3DPadding {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\nexport type Bounds3DPaddingInput =\n\t| number\n\t| Partial<Bounds3DPadding>\n\t| undefined;\n\nexport function createBounds3DBox({\n\twidth,\n\theight,\n\tdepth,\n\tcenterX = 0,\n\tcenterY = 0,\n\tcenterZ = 0,\n}: Bounds3DSize): Bounds3DBox {\n\tconst halfWidth = width / 2;\n\tconst halfHeight = height / 2;\n\tconst halfDepth = depth / 2;\n\treturn {\n\t\tminX: centerX - halfWidth,\n\t\tmaxX: centerX + halfWidth,\n\t\tminY: centerY - halfHeight,\n\t\tmaxY: centerY + halfHeight,\n\t\tminZ: centerZ - halfDepth,\n\t\tmaxZ: centerZ + halfDepth,\n\t};\n}\n\nexport function normalizeBounds3DPadding(\n\tpadding?: Bounds3DPaddingInput,\n): Bounds3DPadding {\n\tif (typeof padding === 'number') {\n\t\treturn { x: padding, y: padding, z: padding };\n\t}\n\n\treturn {\n\t\tx: padding?.x ?? 0,\n\t\ty: padding?.y ?? 0,\n\t\tz: padding?.z ?? 0,\n\t};\n}\n\nexport function insetBounds3D(\n\tbounds: Bounds3DBox,\n\tpadding?: Bounds3DPaddingInput,\n): Bounds3DBox {\n\tconst resolved = normalizeBounds3DPadding(padding);\n\treturn {\n\t\tminX: bounds.minX + resolved.x,\n\t\tmaxX: bounds.maxX - resolved.x,\n\t\tminY: bounds.minY + resolved.y,\n\t\tmaxY: bounds.maxY - resolved.y,\n\t\tminZ: bounds.minZ + resolved.z,\n\t\tmaxZ: bounds.maxZ - resolved.z,\n\t};\n}\n\nexport function computeBounds3DHits(\n\tposition: Bounds3DPoint,\n\tbounds: Bounds3DBox,\n): Bounds3DHits {\n\tconst hits: Bounds3DHits = {\n\t\tleft: false,\n\t\tright: false,\n\t\ttop: false,\n\t\tbottom: false,\n\t\tback: false,\n\t\tfront: false,\n\t};\n\n\tif (position.x <= bounds.minX) hits.left = true;\n\telse if (position.x >= bounds.maxX) hits.right = true;\n\n\tif (position.y <= bounds.minY) hits.bottom = true;\n\telse if (position.y >= bounds.maxY) hits.top = true;\n\n\tif (position.z <= bounds.minZ) hits.back = true;\n\telse if (position.z >= bounds.maxZ) hits.front = true;\n\n\treturn hits;\n}\n\nexport function hasAnyBounds3DHit(hits: Bounds3DHits): boolean {\n\treturn hits.left || hits.right || hits.top || hits.bottom || hits.back || hits.front;\n}\n\nexport function constrainMovementToBounds3D(\n\thits: Bounds3DHits,\n\tmoveX: number,\n\tmoveY: number,\n\tmoveZ: number,\n): { moveX: number; moveY: number; moveZ: number } {\n\tlet adjustedX = moveX;\n\tlet adjustedY = moveY;\n\tlet adjustedZ = moveZ;\n\n\tif ((hits.left && moveX < 0) || (hits.right && moveX > 0)) {\n\t\tadjustedX = 0;\n\t}\n\n\tif ((hits.bottom && moveY < 0) || (hits.top && moveY > 0)) {\n\t\tadjustedY = 0;\n\t}\n\n\tif ((hits.back && moveZ < 0) || (hits.front && moveZ > 0)) {\n\t\tadjustedZ = 0;\n\t}\n\n\treturn { moveX: adjustedX, moveY: adjustedY, moveZ: adjustedZ };\n}\n\nexport function clampPointToBounds3D(\n\tposition: Bounds3DPoint,\n\tbounds: Bounds3DBox,\n): Bounds3DPoint {\n\treturn {\n\t\tx: Math.min(bounds.maxX, Math.max(bounds.minX, position.x)),\n\t\ty: Math.min(bounds.maxY, Math.max(bounds.minY, position.y)),\n\t\tz: Math.min(bounds.maxZ, Math.max(bounds.minZ, position.z)),\n\t};\n}\n\nexport function getBounds3DNormalFromHits(\n\thits: Bounds3DHits,\n): { x: number; y: number; z: number } {\n\tlet x = 0;\n\tlet y = 0;\n\tlet z = 0;\n\n\tif (hits.left) x = 1;\n\tif (hits.right) x = -1;\n\tif (hits.bottom) y = 1;\n\tif (hits.top) y = -1;\n\tif (hits.back) z = 1;\n\tif (hits.front) z = -1;\n\n\treturn { x, y, z };\n}\n","import { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport {\n\tclampPointToBounds3D,\n\tcomputeBounds3DHits,\n\tconstrainMovementToBounds3D,\n\thasAnyBounds3DHit,\n\tinsetBounds3D,\n\ttype Bounds3DPaddingInput,\n\ttype Bounds3DPoint,\n} from '../shared/bounds-3d';\n\nexport type WorldBoundary3DHit =\n\t| 'top'\n\t| 'bottom'\n\t| 'left'\n\t| 'right'\n\t| 'back'\n\t| 'front';\n\nexport type WorldBoundary3DHits = Record<WorldBoundary3DHit, boolean>;\n\nexport interface WorldBoundary3DPosition extends Bounds3DPoint {}\n\nexport interface WorldBoundary3DBounds {\n\ttop: number;\n\tbottom: number;\n\tleft: number;\n\tright: number;\n\tback: number;\n\tfront: number;\n}\n\nexport enum WorldBoundary3DState {\n\tInside = 'inside',\n\tTouching = 'touching',\n}\n\nexport enum WorldBoundary3DEvent {\n\tEnterInside = 'enter-inside',\n\tTouchBoundary = 'touch-boundary',\n}\n\nexport function computeWorldBoundary3DHits(\n\tposition: WorldBoundary3DPosition,\n\tbounds: WorldBoundary3DBounds,\n\tpadding?: Bounds3DPaddingInput,\n): WorldBoundary3DHits {\n\treturn computeBounds3DHits(position, insetBounds3D({\n\t\tminX: bounds.left,\n\t\tmaxX: bounds.right,\n\t\tminY: bounds.bottom,\n\t\tmaxY: bounds.top,\n\t\tminZ: bounds.back,\n\t\tmaxZ: bounds.front,\n\t}, padding));\n}\n\nexport function hasAnyWorldBoundary3DHit(hits: WorldBoundary3DHits): boolean {\n\treturn hasAnyBounds3DHit(hits);\n}\n\nexport class WorldBoundary3DFSM {\n\tpublic readonly machine: SyncStateMachine<WorldBoundary3DState, WorldBoundary3DEvent, never>;\n\n\tprivate lastHits: WorldBoundary3DHits = {\n\t\ttop: false,\n\t\tbottom: false,\n\t\tleft: false,\n\t\tright: false,\n\t\tback: false,\n\t\tfront: false,\n\t};\n\tprivate lastPosition: WorldBoundary3DPosition | null = null;\n\tprivate lastClampedPosition: WorldBoundary3DPosition | null = null;\n\tprivate lastUpdatedAtMs: number | null = null;\n\n\tconstructor() {\n\t\tthis.machine = new SyncStateMachine<WorldBoundary3DState, WorldBoundary3DEvent, never>(\n\t\t\tWorldBoundary3DState.Inside,\n\t\t\t[\n\t\t\t\tt(WorldBoundary3DState.Inside, WorldBoundary3DEvent.TouchBoundary, WorldBoundary3DState.Touching),\n\t\t\t\tt(WorldBoundary3DState.Touching, WorldBoundary3DEvent.EnterInside, WorldBoundary3DState.Inside),\n\t\t\t\tt(WorldBoundary3DState.Inside, WorldBoundary3DEvent.EnterInside, WorldBoundary3DState.Inside),\n\t\t\t\tt(WorldBoundary3DState.Touching, WorldBoundary3DEvent.TouchBoundary, WorldBoundary3DState.Touching),\n\t\t\t],\n\t\t);\n\t}\n\n\tgetState(): WorldBoundary3DState {\n\t\treturn this.machine.getState();\n\t}\n\n\tgetLastHits(): WorldBoundary3DHits {\n\t\treturn this.lastHits;\n\t}\n\n\tgetMovement(\n\t\tmoveX: number,\n\t\tmoveY: number,\n\t\tmoveZ: number,\n\t): { moveX: number; moveY: number; moveZ: number } {\n\t\treturn constrainMovementToBounds3D(this.lastHits, moveX, moveY, moveZ);\n\t}\n\n\tgetLastPosition(): WorldBoundary3DPosition | null {\n\t\treturn this.lastPosition;\n\t}\n\n\tgetLastClampedPosition(): WorldBoundary3DPosition | null {\n\t\treturn this.lastClampedPosition;\n\t}\n\n\tgetLastUpdatedAtMs(): number | null {\n\t\treturn this.lastUpdatedAtMs;\n\t}\n\n\tupdate(\n\t\tposition: WorldBoundary3DPosition,\n\t\tbounds: WorldBoundary3DBounds,\n\t\tpadding?: Bounds3DPaddingInput,\n\t): WorldBoundary3DHits {\n\t\tconst effectiveBounds = insetBounds3D({\n\t\t\tminX: bounds.left,\n\t\t\tmaxX: bounds.right,\n\t\t\tminY: bounds.bottom,\n\t\t\tmaxY: bounds.top,\n\t\t\tminZ: bounds.back,\n\t\t\tmaxZ: bounds.front,\n\t\t}, padding);\n\n\t\tconst hits = computeBounds3DHits(position, effectiveBounds);\n\t\tthis.lastHits = hits;\n\t\tthis.lastPosition = { x: position.x, y: position.y, z: position.z };\n\t\tthis.lastClampedPosition = clampPointToBounds3D(position, effectiveBounds);\n\t\tthis.lastUpdatedAtMs = Date.now();\n\n\t\tif (hasAnyWorldBoundary3DHit(hits)) {\n\t\t\tthis.dispatch(WorldBoundary3DEvent.TouchBoundary);\n\t\t} else {\n\t\t\tthis.dispatch(WorldBoundary3DEvent.EnterInside);\n\t\t}\n\n\t\treturn hits;\n\t}\n\n\tprivate dispatch(event: WorldBoundary3DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n}\n","import type { IWorld } from 'bitecs';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport type { Bounds3DPaddingInput } from '../shared/bounds-3d';\nimport {\n\tWorldBoundary3DFSM,\n\ttype WorldBoundary3DBounds,\n\ttype WorldBoundary3DHits,\n\ttype WorldBoundary3DPosition,\n} from './world-boundary-3d-fsm';\n\nexport interface WorldBoundary3DOptions {\n\tboundaries: WorldBoundary3DBounds;\n\tpadding?: Bounds3DPaddingInput;\n}\n\nexport interface WorldBoundary3DHandle {\n\tgetLastHits(): WorldBoundary3DHits | null;\n\tgetMovement(\n\t\tmoveX: number,\n\t\tmoveY: number,\n\t\tmoveZ: number,\n\t): { moveX: number; moveY: number; moveZ: number };\n\tgetLastClampedPosition(): WorldBoundary3DPosition | null;\n}\n\nconst defaultOptions: WorldBoundary3DOptions = {\n\tboundaries: { top: 0, bottom: 0, left: 0, right: 0, back: 0, front: 0 },\n\tpadding: 0,\n};\n\nconst WORLD_BOUNDARY_3D_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:world-boundary-3d',\n);\n\nfunction createWorldBoundary3DHandle(\n\tref: BehaviorRef<WorldBoundary3DOptions>,\n): WorldBoundary3DHandle {\n\treturn {\n\t\tgetLastHits: () => {\n\t\t\tconst fsm = ref.fsm as WorldBoundary3DFSM | undefined;\n\t\t\treturn fsm?.getLastHits() ?? null;\n\t\t},\n\t\tgetMovement: (moveX: number, moveY: number, moveZ: number) => {\n\t\t\tconst fsm = ref.fsm as WorldBoundary3DFSM | undefined;\n\t\t\treturn fsm?.getMovement(moveX, moveY, moveZ) ?? { moveX, moveY, moveZ };\n\t\t},\n\t\tgetLastClampedPosition: () => {\n\t\t\tconst fsm = ref.fsm as WorldBoundary3DFSM | undefined;\n\t\t\treturn fsm?.getLastClampedPosition() ?? null;\n\t\t},\n\t};\n}\n\nclass WorldBoundary3DSystem implements BehaviorSystem {\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: IWorld, _delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(WORLD_BOUNDARY_3D_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst boundaryRef = link.ref as any;\n\t\t\tif (!gameEntity.body) continue;\n\n\t\t\tconst options = boundaryRef.options as WorldBoundary3DOptions;\n\t\t\tif (!boundaryRef.fsm) {\n\t\t\t\tboundaryRef.fsm = new WorldBoundary3DFSM();\n\t\t\t}\n\n\t\t\tconst pos = gameEntity.body.translation();\n\t\t\tboundaryRef.fsm.update(\n\t\t\t\t{ x: pos.x, y: pos.y, z: pos.z },\n\t\t\t\toptions.boundaries,\n\t\t\t\toptions.padding,\n\t\t\t);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {}\n}\n\nexport const WorldBoundary3DBehavior = defineBehavior({\n\tname: 'world-boundary-3d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew WorldBoundary3DSystem(ctx.world, ctx.getBehaviorLinks),\n\tcreateHandle: createWorldBoundary3DHandle,\n});\n","/**\n * Ricochet2DFSM\n *\n * FSM + extended state to track ricochet events and results.\n * The FSM state tracks whether a ricochet is currently occurring.\n */\nimport { BaseEntityInterface } from \"../../types/entity-types\";\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\n\nexport interface Ricochet2DResult {\n\t/** The reflected velocity vector */\n\tvelocity: { x: number; y: number; z?: number };\n\t/** The resulting speed after reflection */\n\tspeed: number;\n\t/** The collision normal used for reflection */\n\tnormal: { x: number; y: number; z?: number };\n}\n\nexport interface Ricochet2DCollisionContext {\n\tentity?: BaseEntityInterface;\n\totherEntity?: BaseEntityInterface;\n\t/** Current velocity of the entity (optional if entity is provided) */\n\tselfVelocity?: { x: number; y: number; z?: number };\n\t/** Contact information from the collision */\n\tcontact: {\n\t\t/** The collision normal */\n\t\tnormal?: { x: number; y: number; z?: number };\n\t\t/**\n\t\t * Optional position where the collision occurred.\n\t\t * If provided, used for precise offset calculation.\n\t\t */\n\t\tposition?: { x: number; y: number; z?: number };\n\t};\n\t/**\n\t * Optional position of the entity that owns this behavior.\n\t * Used with contact.position for offset calculations.\n\t */\n\tselfPosition?: { x: number; y: number; z?: number };\n\t/**\n\t * Optional position of the other entity in the collision.\n\t * Used for paddle-style deflection: offset = (contactY - otherY) / halfHeight.\n\t */\n\totherPosition?: { x: number; y: number; z?: number };\n\t/**\n\t * Optional size of the other entity (e.g., paddle size).\n\t * If provided, used to normalize the offset based on the collision face.\n\t */\n\totherSize?: { x: number; y: number; z?: number };\n}\n\nexport enum Ricochet2DState {\n\tIdle = 'idle',\n\tRicocheting = 'ricocheting',\n}\n\nexport enum Ricochet2DEvent {\n\tStartRicochet = 'start-ricochet',\n\tEndRicochet = 'end-ricochet',\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.max(min, Math.min(max, value));\n}\n\n/**\n * Callback type for ricochet event listeners.\n */\nexport type RicochetCallback = (result: Ricochet2DResult) => void;\n\n/**\n * FSM wrapper with extended state (lastResult).\n * Systems or consumers call `computeRicochet(...)` when a collision occurs.\n */\nexport class Ricochet2DFSM {\n\tpublic readonly machine: SyncStateMachine<Ricochet2DState, Ricochet2DEvent, never>;\n\n\tprivate lastResult: Ricochet2DResult | null = null;\n\tprivate lastUpdatedAtMs: number | null = null;\n\tprivate currentTimeMs: number = 0;\n\tprivate listeners: Set<RicochetCallback> = new Set();\n\n\tconstructor() {\n\t\tthis.machine = new SyncStateMachine<Ricochet2DState, Ricochet2DEvent, never>(\n\t\t\tRicochet2DState.Idle,\n\t\t\t[\n\t\t\t\tt(Ricochet2DState.Idle, Ricochet2DEvent.StartRicochet, Ricochet2DState.Ricocheting),\n\t\t\t\tt(Ricochet2DState.Ricocheting, Ricochet2DEvent.EndRicochet, Ricochet2DState.Idle),\n\n\t\t\t\t// Self transitions (no-ops)\n\t\t\t\tt(Ricochet2DState.Idle, Ricochet2DEvent.EndRicochet, Ricochet2DState.Idle),\n\t\t\t\tt(Ricochet2DState.Ricocheting, Ricochet2DEvent.StartRicochet, Ricochet2DState.Ricocheting),\n\t\t\t]\n\t\t);\n\t}\n\n\t/**\n\t * Add a listener for ricochet events.\n\t * @returns Unsubscribe function\n\t */\n\taddListener(callback: RicochetCallback): () => void {\n\t\tthis.listeners.add(callback);\n\t\treturn () => this.listeners.delete(callback);\n\t}\n\n\t/**\n\t * Emit result to all listeners.\n\t */\n\tprivate emitToListeners(result: Ricochet2DResult): void {\n\t\tfor (const callback of this.listeners) {\n\t\t\ttry {\n\t\t\t\tcallback(result);\n\t\t\t} catch (e) {\n\t\t\t\tconsole.error('[Ricochet2DFSM] Listener error:', e);\n\t\t\t}\n\t\t}\n\t}\n\n\tgetState(): Ricochet2DState {\n\t\treturn this.machine.getState();\n\t}\n\n\t/**\n\t * Returns the last computed ricochet result, or null if none.\n\t */\n\tgetLastResult(): Ricochet2DResult | null {\n\t\treturn this.lastResult;\n\t}\n\n\t/**\n\t * Best-effort timestamp (ms) of the last computation.\n\t */\n\tgetLastUpdatedAtMs(): number | null {\n\t\treturn this.lastUpdatedAtMs;\n\t}\n\n\t/**\n\t * Set current game time (called by system each frame).\n\t * Used for cooldown calculations.\n\t */\n\tsetCurrentTimeMs(timeMs: number): void {\n\t\tthis.currentTimeMs = timeMs;\n\t}\n\n\t/**\n\t * Check if ricochet is on cooldown (to prevent rapid duplicate applications).\n\t * @param cooldownMs Cooldown duration in milliseconds (default: 50ms)\n\t */\n\tisOnCooldown(cooldownMs: number = 50): boolean {\n\t\tif (this.lastUpdatedAtMs === null) return false;\n\t\treturn (this.currentTimeMs - this.lastUpdatedAtMs) < cooldownMs;\n\t}\n\n\t/**\n\t * Reset cooldown state (e.g., on entity respawn).\n\t */\n\tresetCooldown(): void {\n\t\tthis.lastUpdatedAtMs = null;\n\t}\n\n\t/**\n\t * Compute a ricochet result from collision context.\n\t * Returns the result for the consumer to apply, or null if invalid input.\n\t */\n\tcomputeRicochet(\n\t\tctx: Ricochet2DCollisionContext,\n\t\toptions: {\n\t\t\tminSpeed?: number;\n\t\t\tmaxSpeed?: number;\n\t\t\tspeedMultiplier?: number;\n\t\t\treflectionMode?: 'simple' | 'angled';\n\t\t\tmaxAngleDeg?: number;\n\t\t} = {}\n\t): Ricochet2DResult | null {\n\t\tconst {\n\t\t\tminSpeed = 2,\n\t\t\tmaxSpeed = 20,\n\t\t\tspeedMultiplier = 1.05,\n\t\t\treflectionMode = 'angled',\n\t\t\tmaxAngleDeg = 60,\n\t\t} = options;\n\n\t\t// Extract data from entities if provided\n\t\tconst { selfVelocity, selfPosition, otherPosition, otherSize } = this.extractDataFromEntities(ctx);\n\n\t\tif (!selfVelocity) {\n\t\t\tthis.dispatch(Ricochet2DEvent.EndRicochet);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst speed = Math.hypot(selfVelocity.x, selfVelocity.y);\n\t\tif (speed === 0) {\n\t\t\tthis.dispatch(Ricochet2DEvent.EndRicochet);\n\t\t\treturn null;\n\t\t}\n\n\t\t// Compute or extract collision normal\n\t\tconst normal = ctx.contact.normal ?? this.computeNormalFromPositions(selfPosition, otherPosition);\n\t\tif (!normal) {\n\t\t\tthis.dispatch(Ricochet2DEvent.EndRicochet);\n\t\t\treturn null;\n\t\t}\n\n\t\t// Compute basic reflection\n\t\tlet reflected = this.computeBasicReflection(selfVelocity, normal);\n\n\t\t// Apply angled deflection if requested\n\t\tif (reflectionMode === 'angled') {\n\t\t\treflected = this.computeAngledDeflection(\n\t\t\t\tselfVelocity,\n\t\t\t\tnormal,\n\t\t\t\tspeed,\n\t\t\t\tmaxAngleDeg,\n\t\t\t\tspeedMultiplier,\n\t\t\t\tselfPosition,\n\t\t\t\totherPosition,\n\t\t\t\totherSize,\n\t\t\t\tctx.contact.position\n\t\t\t);\n\t\t}\n\n\t\t// Apply final speed constraints\n\t\treflected = this.applySpeedClamp(reflected, minSpeed, maxSpeed);\n\n\t\tconst result: Ricochet2DResult = {\n\t\t\tvelocity: { x: reflected.x, y: reflected.y, z: 0 },\n\t\t\tspeed: Math.hypot(reflected.x, reflected.y),\n\t\t\tnormal: { x: normal.x, y: normal.y, z: 0 },\n\t\t};\n\n\t\tthis.lastResult = result;\n\t\tthis.lastUpdatedAtMs = this.currentTimeMs;\n\t\tthis.dispatch(Ricochet2DEvent.StartRicochet);\n\t\tthis.emitToListeners(result);\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Extract velocity, position, and size data from entities or context.\n\t */\n\tprivate extractDataFromEntities(ctx: Ricochet2DCollisionContext) {\n\t\tlet selfVelocity = ctx.selfVelocity;\n\t\tlet selfPosition = ctx.selfPosition;\n\t\tlet otherPosition = ctx.otherPosition;\n\t\tlet otherSize = ctx.otherSize;\n\n\t\tif (ctx.entity?.body) {\n\t\t\tconst vel = ctx.entity.body.linvel();\n\t\t\tselfVelocity = selfVelocity ?? { x: vel.x, y: vel.y, z: vel.z };\n\t\t\tconst pos = ctx.entity.body.translation();\n\t\t\tselfPosition = selfPosition ?? { x: pos.x, y: pos.y, z: pos.z };\n\t\t}\n\n\t\tif (ctx.otherEntity?.body) {\n\t\t\tconst pos = ctx.otherEntity.body.translation();\n\t\t\totherPosition = otherPosition ?? { x: pos.x, y: pos.y, z: pos.z };\n\t\t}\n\n\t\tif (ctx.otherEntity && 'size' in ctx.otherEntity) {\n\t\t\tconst size = (ctx.otherEntity as any).size;\n\t\t\tif (size && typeof size.x === 'number') {\n\t\t\t\totherSize = otherSize ?? { x: size.x, y: size.y, z: size.z };\n\t\t\t}\n\t\t}\n\n\t\treturn { selfVelocity, selfPosition, otherPosition, otherSize };\n\t}\n\n\t/**\n\t * Compute collision normal from entity positions using AABB heuristic.\n\t */\n\tprivate computeNormalFromPositions(\n\t\tselfPosition?: { x: number; y: number; z?: number },\n\t\totherPosition?: { x: number; y: number; z?: number }\n\t): { x: number; y: number; z?: number } | null {\n\t\tif (!selfPosition || !otherPosition) return null;\n\n\t\tconst dx = selfPosition.x - otherPosition.x;\n\t\tconst dy = selfPosition.y - otherPosition.y;\n\n\t\t// Simple \"which face was hit\" logic for box collisions\n\t\tif (Math.abs(dx) > Math.abs(dy)) {\n\t\t\treturn { x: dx > 0 ? 1 : -1, y: 0, z: 0 };\n\t\t} else {\n\t\t\treturn { x: 0, y: dy > 0 ? 1 : -1, z: 0 };\n\t\t}\n\t}\n\n\t/**\n\t * Compute basic reflection using the formula: v' = v - 2(v·n)n\n\t */\n\tprivate computeBasicReflection(\n\t\tvelocity: { x: number; y: number },\n\t\tnormal: { x: number; y: number; z?: number }\n\t): { x: number; y: number } {\n\t\tconst vx = velocity.x;\n\t\tconst vy = velocity.y;\n\t\tconst dotProduct = vx * normal.x + vy * normal.y;\n\n\t\treturn {\n\t\t\tx: vx - 2 * dotProduct * normal.x,\n\t\t\ty: vy - 2 * dotProduct * normal.y,\n\t\t};\n\t}\n\n\t/**\n\t * Compute angled deflection for paddle-style reflections.\n\t */\n\tprivate computeAngledDeflection(\n\t\tvelocity: { x: number; y: number },\n\t\tnormal: { x: number; y: number; z?: number },\n\t\tspeed: number,\n\t\tmaxAngleDeg: number,\n\t\tspeedMultiplier: number,\n\t\tselfPosition?: { x: number; y: number; z?: number },\n\t\totherPosition?: { x: number; y: number; z?: number },\n\t\totherSize?: { x: number; y: number; z?: number },\n\t\tcontactPosition?: { x: number; y: number; z?: number }\n\t): { x: number; y: number } {\n\t\tconst maxAngleRad = (maxAngleDeg * Math.PI) / 180;\n\n\t\t// Tangent vector (perpendicular to normal)\n\t\tlet tx = -normal.y;\n\t\tlet ty = normal.x;\n\n\t\t// Ensure tangent points in positive direction of the deflection axis\n\t\t// so that positive offset (right/top) results in positive deflection\n\t\tif (Math.abs(normal.x) > Math.abs(normal.y)) {\n\t\t\t// Vertical face (Normal is X-aligned). Deflection axis is Y.\n\t\t\t// We want ty > 0.\n\t\t\tif (ty < 0) {\n\t\t\t\ttx = -tx;\n\t\t\t\tty = -ty;\n\t\t\t}\n\t\t} else {\n\t\t\t// Horizontal face (Normal is Y-aligned). Deflection axis is X.\n\t\t\t// We want tx > 0.\n\t\t\tif (tx < 0) {\n\t\t\t\ttx = -tx;\n\t\t\t\tty = -ty;\n\t\t\t}\n\t\t}\n\n\t\t// Compute offset based on hit position\n\t\tconst offset = this.computeHitOffset(\n\t\t\tvelocity,\n\t\t\tnormal,\n\t\t\tspeed,\n\t\t\ttx,\n\t\t\tty,\n\t\t\tselfPosition,\n\t\t\totherPosition,\n\t\t\totherSize,\n\t\t\tcontactPosition\n\t\t);\n\n\t\tconst angle = clamp(offset, -1, 1) * maxAngleRad;\n\n\t\tconst cosA = Math.cos(angle);\n\t\tconst sinA = Math.sin(angle);\n\n\t\tconst newSpeed = speed * speedMultiplier;\n\n\t\treturn {\n\t\t\tx: newSpeed * (normal.x * cosA + tx * sinA),\n\t\t\ty: newSpeed * (normal.y * cosA + ty * sinA),\n\t\t};\n\t}\n\n\t/**\n\t * Compute hit offset for angled deflection (-1 to 1).\n\t */\n\tprivate computeHitOffset(\n\t\tvelocity: { x: number; y: number },\n\t\tnormal: { x: number; y: number; z?: number },\n\t\tspeed: number,\n\t\ttx: number,\n\t\tty: number,\n\t\tselfPosition?: { x: number; y: number; z?: number },\n\t\totherPosition?: { x: number; y: number; z?: number },\n\t\totherSize?: { x: number; y: number; z?: number },\n\t\tcontactPosition?: { x: number; y: number; z?: number }\n\t): number {\n\t\t// Use position-based offset if available\n\t\tif (otherPosition && otherSize) {\n\t\t\tconst useY = Math.abs(normal.x) > Math.abs(normal.y);\n\t\t\tconst halfExtent = useY ? otherSize.y / 2 : otherSize.x / 2;\n\n\t\t\tif (useY) {\n\t\t\t\tconst selfY = selfPosition?.y ?? contactPosition?.y ?? 0;\n\t\t\t\tconst paddleY = otherPosition.y;\n\t\t\t\treturn (selfY - paddleY) / halfExtent;\n\t\t\t} else {\n\t\t\t\tconst selfX = selfPosition?.x ?? contactPosition?.x ?? 0;\n\t\t\t\tconst paddleX = otherPosition.x;\n\t\t\t\treturn (selfX - paddleX) / halfExtent;\n\t\t\t}\n\t\t}\n\n\t\t// Fallback: use velocity-based offset\n\t\treturn (velocity.x * tx + velocity.y * ty) / speed;\n\t}\n\n\t/**\n\t * Apply speed constraints to the reflected velocity.\n\t */\n\tprivate applySpeedClamp(\n\t\tvelocity: { x: number; y: number },\n\t\tminSpeed: number,\n\t\tmaxSpeed: number\n\t): { x: number; y: number } {\n\t\tconst currentSpeed = Math.hypot(velocity.x, velocity.y);\n\t\tif (currentSpeed === 0) return velocity;\n\n\t\tconst targetSpeed = clamp(currentSpeed, minSpeed, maxSpeed);\n\t\tconst scale = targetSpeed / currentSpeed;\n\n\t\treturn {\n\t\t\tx: velocity.x * scale,\n\t\t\ty: velocity.y * scale,\n\t\t};\n\t}\n\n\t/**\n\t * Clear the ricochet state (call after consumer has applied the result).\n\t */\n\tclearRicochet(): void {\n\t\tthis.dispatch(Ricochet2DEvent.EndRicochet);\n\t}\n\n\tprivate dispatch(event: Ricochet2DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n}\n","/**\n * Ricochet2DBehavior\n *\n * Computes 2D ricochet/reflection results for entities during collisions.\n * The behavior computes the result; the consumer decides how to apply it.\n *\n * Use `getRicochet(ctx)` on the behavior handle to compute reflection results.\n */\n\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { Ricochet2DFSM, type Ricochet2DResult, type Ricochet2DCollisionContext, type RicochetCallback } from './ricochet-2d-fsm';\nexport type { Ricochet2DResult };\n\nexport interface Ricochet2DOptions {\n\t/**\n\t * Minimum speed after reflection.\n\t * Default: 2\n\t */\n\tminSpeed: number;\n\n\t/**\n\t * Maximum speed after reflection.\n\t * Default: 20\n\t */\n\tmaxSpeed: number;\n\n\t/**\n\t * Speed multiplier applied during angled reflection.\n\t * Default: 1.05\n\t */\n\tspeedMultiplier: number;\n\n\t/**\n\t * Reflection mode:\n\t * - 'simple': Basic axis inversion\n\t * - 'angled': Paddle-style deflection based on contact point\n\t * Default: 'angled'\n\t */\n\treflectionMode: 'simple' | 'angled';\n\n\t/**\n\t * Maximum deflection angle in degrees for angled mode.\n\t * Default: 60\n\t */\n\tmaxAngleDeg: number;\n}\n\n/**\n * Handle methods provided by Ricochet2DBehavior\n */\nexport interface Ricochet2DHandle {\n\t/**\n\t * Compute a ricochet/reflection result from collision context.\n\t * Returns the result for the consumer to apply, or null if invalid input.\n\t *\n\t * @param ctx - Collision context with selfVelocity and contact normal\n\t * @returns Ricochet result with velocity, speed, and normal, or null\n\t */\n\tgetRicochet(ctx: Ricochet2DCollisionContext): Ricochet2DResult | null;\n\n\t/**\n\t * Compute ricochet and apply velocity directly via transformStore.\n\t * Emits to onRicochet listeners if successful.\n\t *\n\t * @param ctx - Collision context with entity and contact normal\n\t * @returns true if ricochet was computed and applied, false otherwise\n\t */\n\tapplyRicochet(ctx: Ricochet2DCollisionContext): boolean;\n\n\t/**\n\t * Get the last computed ricochet result, or null if none.\n\t */\n\tgetLastResult(): Ricochet2DResult | null;\n\n\t/**\n\t * Register a listener for ricochet events.\n\t * Called whenever a ricochet is computed (from getRicochet or applyRicochet).\n\t *\n\t * @param callback - Function to call with ricochet result\n\t * @returns Unsubscribe function\n\t */\n\tonRicochet(callback: RicochetCallback): () => void;\n}\n\nconst defaultOptions: Ricochet2DOptions = {\n\tminSpeed: 2,\n\tmaxSpeed: 20,\n\tspeedMultiplier: 1.05,\n\treflectionMode: 'angled',\n\tmaxAngleDeg: 60,\n};\n\nconst RICOCHET_BEHAVIOR_KEY = Symbol.for('zylem:behavior:ricochet-2d');\n\n/**\n * Creates behavior-specific handle methods for Ricochet2DBehavior.\n */\nfunction createRicochet2DHandle(\n\tref: BehaviorRef<Ricochet2DOptions>\n): Ricochet2DHandle {\n\treturn {\n\t\tgetRicochet: (ctx: Ricochet2DCollisionContext) => {\n\t\t\tconst fsm = ref.fsm as Ricochet2DFSM | undefined;\n\t\t\tif (!fsm) return null;\n\t\t\treturn fsm.computeRicochet(ctx, ref.options);\n\t\t},\n\t\tapplyRicochet: (ctx: Ricochet2DCollisionContext): boolean => {\n\t\t\tconst fsm = ref.fsm as Ricochet2DFSM | undefined;\n\t\t\tif (!fsm) return false;\n\n\t\t\t// Skip if on cooldown (prevents rapid duplicate applications)\n\t\t\tif (fsm.isOnCooldown()) return false;\n\n\t\t\tconst result = fsm.computeRicochet(ctx, ref.options);\n\t\t\tif (!result) return false;\n\n\t\t\t// Apply velocity via transformStore\n\t\t\tconst entity = ctx.entity as any;\n\t\t\tif (entity?.transformStore) {\n\t\t\t\tentity.transformStore.velocity.x = result.velocity.x;\n\t\t\t\tentity.transformStore.velocity.y = result.velocity.y;\n\t\t\t\tentity.transformStore.velocity.z = result.velocity.z ?? 0;\n\t\t\t\tentity.transformStore.dirty.velocity = true;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t\tgetLastResult: () => {\n\t\t\tconst fsm = ref.fsm as Ricochet2DFSM | undefined;\n\t\t\treturn fsm?.getLastResult() ?? null;\n\t\t},\n\t\tonRicochet: (callback: RicochetCallback): (() => void) => {\n\t\t\tconst fsm = ref.fsm as Ricochet2DFSM | undefined;\n\t\t\tif (!fsm) {\n\t\t\t\t// FSM not ready yet - queue callback for later\n\t\t\t\t// System will apply pending callbacks when FSM is created\n\t\t\t\tif (!(ref as any).pendingListeners) {\n\t\t\t\t\t(ref as any).pendingListeners = [];\n\t\t\t\t}\n\t\t\t\t(ref as any).pendingListeners.push(callback);\n\t\t\t\t\n\t\t\t\t// Return unsubscribe that removes from pending queue\n\t\t\t\treturn () => {\n\t\t\t\t\tconst pending = (ref as any).pendingListeners as RicochetCallback[];\n\t\t\t\t\tconst idx = pending.indexOf(callback);\n\t\t\t\t\tif (idx >= 0) pending.splice(idx, 1);\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn fsm.addListener(callback);\n\t\t},\n\t};\n}\n\n/**\n * Ricochet2DSystem\n *\n * Stage-level system that:\n * - finds entities with this behavior attached\n * - lazily creates FSM instances for each entity\n *\n * Note: This behavior is consumer-driven. The system only manages FSM lifecycle.\n * Consumers call `getRicochet(ctx)` during collision callbacks to compute results.\n */\nclass Ricochet2DSystem implements BehaviorSystem {\n\tprivate elapsedMs: number = 0;\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\t// Accumulate elapsed time (delta is in seconds)\n\t\tthis.elapsedMs += delta * 1000;\n\n\t\tconst links = this.getBehaviorLinks?.(RICOCHET_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst ricochetRef = link.ref as any;\n\n\t\t\t// Create FSM lazily on first update after spawn\n\t\t\tif (!ricochetRef.fsm) {\n\t\t\t\tricochetRef.fsm = new Ricochet2DFSM();\n\t\t\t\t\n\t\t\t\t// Apply any pending listeners that were registered before FSM existed\n\t\t\t\tconst pending = (ricochetRef as any).pendingListeners as RicochetCallback[] | undefined;\n\t\t\t\tif (pending) {\n\t\t\t\t\tfor (const cb of pending) {\n\t\t\t\t\t\tricochetRef.fsm.addListener(cb);\n\t\t\t\t\t}\n\t\t\t\t\t(ricochetRef as any).pendingListeners = [];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Sync current game time to FSM\n\t\t\tricochetRef.fsm.setCurrentTimeMs(this.elapsedMs);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\tconst links = this.getBehaviorLinks?.(RICOCHET_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\t\tfor (const link of links) {\n\t\t\tconst ricochetRef = link.ref as any;\n\t\t\tif (ricochetRef?.fsm) {\n\t\t\t\tricochetRef.fsm.resetCooldown();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Ricochet2DBehavior\n *\n * @example\n * ```ts\n * import { Ricochet2DBehavior } from \"@zylem/game-lib\";\n *\n * const ball = createSphere({ ... });\n * const ricochet = ball.use(Ricochet2DBehavior, {\n * minSpeed: 3,\n * maxSpeed: 15,\n * reflectionMode: 'angled',\n * });\n *\n * ball.onCollision(({ entity, other }) => {\n * const velocity = entity.body.linvel();\n * const result = ricochet.getRicochet({\n * selfVelocity: velocity,\n * contact: { normal: { x: 1, y: 0 } }, // from collision data\n * });\n *\n * if (result) {\n * entity.body.setLinvel(result.velocity, true);\n * }\n * });\n * ```\n */\nexport const Ricochet2DBehavior = defineBehavior({\n\tname: 'ricochet-2d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew Ricochet2DSystem(ctx.world, ctx.getBehaviorLinks),\n\tcreateHandle: createRicochet2DHandle,\n});\n","import { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport { BaseEntityInterface } from '../../types/entity-types';\n\nexport interface Ricochet3DResult {\n\tvelocity: { x: number; y: number; z: number };\n\tspeed: number;\n\tnormal: { x: number; y: number; z: number };\n}\n\nexport interface Ricochet3DCollisionContext {\n\tentity?: BaseEntityInterface;\n\totherEntity?: BaseEntityInterface;\n\tselfVelocity?: { x: number; y: number; z: number };\n\tcontact: {\n\t\tnormal?: { x: number; y: number; z: number };\n\t\tposition?: { x: number; y: number; z: number };\n\t};\n\tselfPosition?: { x: number; y: number; z: number };\n\totherPosition?: { x: number; y: number; z: number };\n\totherSize?: { x: number; y: number; z: number };\n}\n\nexport enum Ricochet3DState {\n\tIdle = 'idle',\n\tRicocheting = 'ricocheting',\n}\n\nexport enum Ricochet3DEvent {\n\tStartRicochet = 'start-ricochet',\n\tEndRicochet = 'end-ricochet',\n}\n\nexport type Ricochet3DCallback = (result: Ricochet3DResult) => void;\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.max(min, Math.min(max, value));\n}\n\nfunction length3(x: number, y: number, z: number): number {\n\treturn Math.sqrt(x * x + y * y + z * z);\n}\n\nexport class Ricochet3DFSM {\n\tpublic readonly machine: SyncStateMachine<Ricochet3DState, Ricochet3DEvent, never>;\n\n\tprivate lastResult: Ricochet3DResult | null = null;\n\tprivate lastUpdatedAtMs: number | null = null;\n\tprivate currentTimeMs = 0;\n\tprivate listeners = new Set<Ricochet3DCallback>();\n\n\tconstructor() {\n\t\tthis.machine = new SyncStateMachine<Ricochet3DState, Ricochet3DEvent, never>(\n\t\t\tRicochet3DState.Idle,\n\t\t\t[\n\t\t\t\tt(Ricochet3DState.Idle, Ricochet3DEvent.StartRicochet, Ricochet3DState.Ricocheting),\n\t\t\t\tt(Ricochet3DState.Ricocheting, Ricochet3DEvent.EndRicochet, Ricochet3DState.Idle),\n\t\t\t\tt(Ricochet3DState.Idle, Ricochet3DEvent.EndRicochet, Ricochet3DState.Idle),\n\t\t\t\tt(Ricochet3DState.Ricocheting, Ricochet3DEvent.StartRicochet, Ricochet3DState.Ricocheting),\n\t\t\t],\n\t\t);\n\t}\n\n\taddListener(callback: Ricochet3DCallback): () => void {\n\t\tthis.listeners.add(callback);\n\t\treturn () => this.listeners.delete(callback);\n\t}\n\n\tgetState(): Ricochet3DState {\n\t\treturn this.machine.getState();\n\t}\n\n\tgetLastResult(): Ricochet3DResult | null {\n\t\treturn this.lastResult;\n\t}\n\n\tgetLastUpdatedAtMs(): number | null {\n\t\treturn this.lastUpdatedAtMs;\n\t}\n\n\tsetCurrentTimeMs(timeMs: number): void {\n\t\tthis.currentTimeMs = timeMs;\n\t}\n\n\tisOnCooldown(cooldownMs: number = 50): boolean {\n\t\tif (this.lastUpdatedAtMs === null) return false;\n\t\treturn (this.currentTimeMs - this.lastUpdatedAtMs) < cooldownMs;\n\t}\n\n\tresetCooldown(): void {\n\t\tthis.lastUpdatedAtMs = null;\n\t}\n\n\tcomputeRicochet(\n\t\tctx: Ricochet3DCollisionContext,\n\t\toptions: {\n\t\t\tminSpeed?: number;\n\t\t\tmaxSpeed?: number;\n\t\t\tspeedMultiplier?: number;\n\t\t\treflectionMode?: 'simple' | 'angled';\n\t\t\tmaxAngleDeg?: number;\n\t\t} = {},\n\t): Ricochet3DResult | null {\n\t\tconst {\n\t\t\tminSpeed = 2,\n\t\t\tmaxSpeed = 20,\n\t\t\tspeedMultiplier = 1.05,\n\t\t\treflectionMode = 'angled',\n\t\t\tmaxAngleDeg = 45,\n\t\t} = options;\n\n\t\tconst {\n\t\t\tselfVelocity,\n\t\t\tselfPosition,\n\t\t\totherPosition,\n\t\t\totherSize,\n\t\t} = this.extractDataFromEntities(ctx);\n\n\t\tif (!selfVelocity) {\n\t\t\tthis.dispatch(Ricochet3DEvent.EndRicochet);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst speed = length3(selfVelocity.x, selfVelocity.y, selfVelocity.z);\n\t\tif (speed === 0) {\n\t\t\tthis.dispatch(Ricochet3DEvent.EndRicochet);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst normal = ctx.contact.normal ?? this.computeNormalFromPositions(selfPosition, otherPosition);\n\t\tif (!normal) {\n\t\t\tthis.dispatch(Ricochet3DEvent.EndRicochet);\n\t\t\treturn null;\n\t\t}\n\n\t\tconst unitNormal = this.normalizeVector(normal);\n\t\tlet reflected = this.computeBasicReflection(selfVelocity, unitNormal);\n\n\t\tif (reflectionMode === 'angled') {\n\t\t\treflected = this.computeAngledDeflection(\n\t\t\t\treflected,\n\t\t\t\tselfVelocity,\n\t\t\t\tunitNormal,\n\t\t\t\tspeed,\n\t\t\t\tmaxAngleDeg,\n\t\t\t\tspeedMultiplier,\n\t\t\t\tselfPosition,\n\t\t\t\totherPosition,\n\t\t\t\totherSize,\n\t\t\t\tctx.contact.position,\n\t\t\t);\n\t\t} else {\n\t\t\treflected = {\n\t\t\t\tx: reflected.x * speedMultiplier,\n\t\t\t\ty: reflected.y * speedMultiplier,\n\t\t\t\tz: reflected.z * speedMultiplier,\n\t\t\t};\n\t\t}\n\n\t\treflected = this.applySpeedClamp(reflected, minSpeed, maxSpeed);\n\n\t\tconst result: Ricochet3DResult = {\n\t\t\tvelocity: reflected,\n\t\t\tspeed: length3(reflected.x, reflected.y, reflected.z),\n\t\t\tnormal: unitNormal,\n\t\t};\n\n\t\tthis.lastResult = result;\n\t\tthis.lastUpdatedAtMs = this.currentTimeMs;\n\t\tthis.dispatch(Ricochet3DEvent.StartRicochet);\n\t\tthis.emitToListeners(result);\n\t\treturn result;\n\t}\n\n\tclearRicochet(): void {\n\t\tthis.dispatch(Ricochet3DEvent.EndRicochet);\n\t}\n\n\tprivate emitToListeners(result: Ricochet3DResult): void {\n\t\tfor (const callback of this.listeners) {\n\t\t\ttry {\n\t\t\t\tcallback(result);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[Ricochet3DFSM] Listener error:', error);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate extractDataFromEntities(ctx: Ricochet3DCollisionContext) {\n\t\tlet selfVelocity = ctx.selfVelocity;\n\t\tlet selfPosition = ctx.selfPosition;\n\t\tlet otherPosition = ctx.otherPosition;\n\t\tlet otherSize = ctx.otherSize;\n\n\t\tif (ctx.entity?.body) {\n\t\t\tconst velocity = ctx.entity.body.linvel();\n\t\t\tselfVelocity = selfVelocity ?? { x: velocity.x, y: velocity.y, z: velocity.z };\n\t\t\tconst position = ctx.entity.body.translation();\n\t\t\tselfPosition = selfPosition ?? { x: position.x, y: position.y, z: position.z };\n\t\t}\n\n\t\tif (ctx.otherEntity?.body) {\n\t\t\tconst position = ctx.otherEntity.body.translation();\n\t\t\totherPosition = otherPosition ?? { x: position.x, y: position.y, z: position.z };\n\t\t}\n\n\t\tif (ctx.otherEntity && 'size' in ctx.otherEntity) {\n\t\t\tconst size = (ctx.otherEntity as any).size;\n\t\t\tif (size && typeof size.x === 'number') {\n\t\t\t\totherSize = otherSize ?? { x: size.x, y: size.y, z: size.z };\n\t\t\t}\n\t\t}\n\n\t\treturn { selfVelocity, selfPosition, otherPosition, otherSize };\n\t}\n\n\tprivate computeNormalFromPositions(\n\t\tselfPosition?: { x: number; y: number; z: number },\n\t\totherPosition?: { x: number; y: number; z: number },\n\t): { x: number; y: number; z: number } | null {\n\t\tif (!selfPosition || !otherPosition) return null;\n\n\t\tconst delta = {\n\t\t\tx: selfPosition.x - otherPosition.x,\n\t\t\ty: selfPosition.y - otherPosition.y,\n\t\t\tz: selfPosition.z - otherPosition.z,\n\t\t};\n\t\tconst absX = Math.abs(delta.x);\n\t\tconst absY = Math.abs(delta.y);\n\t\tconst absZ = Math.abs(delta.z);\n\n\t\tif (absX >= absY && absX >= absZ) {\n\t\t\treturn { x: delta.x >= 0 ? 1 : -1, y: 0, z: 0 };\n\t\t}\n\t\tif (absY >= absX && absY >= absZ) {\n\t\t\treturn { x: 0, y: delta.y >= 0 ? 1 : -1, z: 0 };\n\t\t}\n\t\treturn { x: 0, y: 0, z: delta.z >= 0 ? 1 : -1 };\n\t}\n\n\tprivate normalizeVector(vector: { x: number; y: number; z: number }) {\n\t\tconst magnitude = length3(vector.x, vector.y, vector.z);\n\t\tif (magnitude <= 1e-6) {\n\t\t\treturn { x: 0, y: 1, z: 0 };\n\t\t}\n\t\treturn {\n\t\t\tx: vector.x / magnitude,\n\t\t\ty: vector.y / magnitude,\n\t\t\tz: vector.z / magnitude,\n\t\t};\n\t}\n\n\tprivate dot(\n\t\ta: { x: number; y: number; z: number },\n\t\tb: { x: number; y: number; z: number },\n\t): number {\n\t\treturn a.x * b.x + a.y * b.y + a.z * b.z;\n\t}\n\n\tprivate computeBasicReflection(\n\t\tvelocity: { x: number; y: number; z: number },\n\t\tnormal: { x: number; y: number; z: number },\n\t): { x: number; y: number; z: number } {\n\t\tconst dotProduct = this.dot(velocity, normal);\n\t\treturn {\n\t\t\tx: velocity.x - 2 * dotProduct * normal.x,\n\t\t\ty: velocity.y - 2 * dotProduct * normal.y,\n\t\t\tz: velocity.z - 2 * dotProduct * normal.z,\n\t\t};\n\t}\n\n\tprivate computeAngledDeflection(\n\t\treflected: { x: number; y: number; z: number },\n\t\tincoming: { x: number; y: number; z: number },\n\t\tnormal: { x: number; y: number; z: number },\n\t\tspeed: number,\n\t\tmaxAngleDeg: number,\n\t\tspeedMultiplier: number,\n\t\tselfPosition?: { x: number; y: number; z: number },\n\t\totherPosition?: { x: number; y: number; z: number },\n\t\totherSize?: { x: number; y: number; z: number },\n\t\tcontactPosition?: { x: number; y: number; z: number },\n\t): { x: number; y: number; z: number } {\n\t\tconst baseDirection = this.normalizeVector(reflected);\n\t\tconst tangentVector = this.computeHitOffsetVector(\n\t\t\tincoming,\n\t\t\tnormal,\n\t\t\tselfPosition,\n\t\t\totherPosition,\n\t\t\totherSize,\n\t\t\tcontactPosition,\n\t\t);\n\n\t\tconst offsetStrength = clamp(\n\t\t\tlength3(tangentVector.x, tangentVector.y, tangentVector.z),\n\t\t\t0,\n\t\t\t1,\n\t\t);\n\t\tif (offsetStrength === 0) {\n\t\t\treturn {\n\t\t\t\tx: baseDirection.x * speed * speedMultiplier,\n\t\t\t\ty: baseDirection.y * speed * speedMultiplier,\n\t\t\t\tz: baseDirection.z * speed * speedMultiplier,\n\t\t\t};\n\t\t}\n\n\t\tconst tangentDirection = this.normalizeVector(tangentVector);\n\t\tconst angle = offsetStrength * (maxAngleDeg * Math.PI / 180);\n\t\tconst cosAngle = Math.cos(angle);\n\t\tconst sinAngle = Math.sin(angle);\n\t\tconst direction = this.normalizeVector({\n\t\t\tx: baseDirection.x * cosAngle + tangentDirection.x * sinAngle,\n\t\t\ty: baseDirection.y * cosAngle + tangentDirection.y * sinAngle,\n\t\t\tz: baseDirection.z * cosAngle + tangentDirection.z * sinAngle,\n\t\t});\n\t\tconst newSpeed = speed * speedMultiplier;\n\n\t\treturn {\n\t\t\tx: direction.x * newSpeed,\n\t\t\ty: direction.y * newSpeed,\n\t\t\tz: direction.z * newSpeed,\n\t\t};\n\t}\n\n\tprivate computeHitOffsetVector(\n\t\tvelocity: { x: number; y: number; z: number },\n\t\tnormal: { x: number; y: number; z: number },\n\t\tselfPosition?: { x: number; y: number; z: number },\n\t\totherPosition?: { x: number; y: number; z: number },\n\t\totherSize?: { x: number; y: number; z: number },\n\t\tcontactPosition?: { x: number; y: number; z: number },\n\t): { x: number; y: number; z: number } {\n\t\tif (otherPosition && otherSize) {\n\t\t\tconst faceAxis = this.getDominantAxis(normal);\n\t\t\tif (faceAxis === 'x') {\n\t\t\t\treturn {\n\t\t\t\t\tx: 0,\n\t\t\t\t\ty: ((selfPosition?.y ?? contactPosition?.y ?? otherPosition.y) - otherPosition.y) / Math.max(otherSize.y / 2, 1e-6),\n\t\t\t\t\tz: ((selfPosition?.z ?? contactPosition?.z ?? otherPosition.z) - otherPosition.z) / Math.max(otherSize.z / 2, 1e-6),\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (faceAxis === 'y') {\n\t\t\t\treturn {\n\t\t\t\t\tx: ((selfPosition?.x ?? contactPosition?.x ?? otherPosition.x) - otherPosition.x) / Math.max(otherSize.x / 2, 1e-6),\n\t\t\t\t\ty: 0,\n\t\t\t\t\tz: ((selfPosition?.z ?? contactPosition?.z ?? otherPosition.z) - otherPosition.z) / Math.max(otherSize.z / 2, 1e-6),\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tx: ((selfPosition?.x ?? contactPosition?.x ?? otherPosition.x) - otherPosition.x) / Math.max(otherSize.x / 2, 1e-6),\n\t\t\t\ty: ((selfPosition?.y ?? contactPosition?.y ?? otherPosition.y) - otherPosition.y) / Math.max(otherSize.y / 2, 1e-6),\n\t\t\t\tz: 0,\n\t\t\t};\n\t\t}\n\n\t\tconst tangent = {\n\t\t\tx: velocity.x - this.dot(velocity, normal) * normal.x,\n\t\t\ty: velocity.y - this.dot(velocity, normal) * normal.y,\n\t\t\tz: velocity.z - this.dot(velocity, normal) * normal.z,\n\t\t};\n\t\tconst tangentLength = length3(tangent.x, tangent.y, tangent.z);\n\t\tif (tangentLength <= 1e-6) {\n\t\t\treturn { x: 0, y: 0, z: 0 };\n\t\t}\n\t\treturn {\n\t\t\tx: tangent.x / tangentLength,\n\t\t\ty: tangent.y / tangentLength,\n\t\t\tz: tangent.z / tangentLength,\n\t\t};\n\t}\n\n\tprivate getDominantAxis(vector: { x: number; y: number; z: number }): 'x' | 'y' | 'z' {\n\t\tconst absX = Math.abs(vector.x);\n\t\tconst absY = Math.abs(vector.y);\n\t\tconst absZ = Math.abs(vector.z);\n\t\tif (absX >= absY && absX >= absZ) return 'x';\n\t\tif (absY >= absX && absY >= absZ) return 'y';\n\t\treturn 'z';\n\t}\n\n\tprivate applySpeedClamp(\n\t\tvelocity: { x: number; y: number; z: number },\n\t\tminSpeed: number,\n\t\tmaxSpeed: number,\n\t): { x: number; y: number; z: number } {\n\t\tconst currentSpeed = length3(velocity.x, velocity.y, velocity.z);\n\t\tif (currentSpeed === 0) return velocity;\n\n\t\tconst targetSpeed = clamp(currentSpeed, minSpeed, maxSpeed);\n\t\tconst scale = targetSpeed / currentSpeed;\n\t\treturn {\n\t\t\tx: velocity.x * scale,\n\t\t\ty: velocity.y * scale,\n\t\t\tz: velocity.z * scale,\n\t\t};\n\t}\n\n\tprivate dispatch(event: Ricochet3DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n}\n","import type { IWorld } from 'bitecs';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport {\n\tRicochet3DFSM,\n\ttype Ricochet3DResult,\n\ttype Ricochet3DCollisionContext,\n\ttype Ricochet3DCallback,\n} from './ricochet-3d-fsm';\n\nexport type { Ricochet3DResult };\n\nexport interface Ricochet3DOptions {\n\tminSpeed: number;\n\tmaxSpeed: number;\n\tspeedMultiplier: number;\n\treflectionMode: 'simple' | 'angled';\n\tmaxAngleDeg: number;\n}\n\nexport interface Ricochet3DHandle {\n\tgetRicochet(ctx: Ricochet3DCollisionContext): Ricochet3DResult | null;\n\tapplyRicochet(ctx: Ricochet3DCollisionContext): boolean;\n\tgetLastResult(): Ricochet3DResult | null;\n\tonRicochet(callback: Ricochet3DCallback): () => void;\n}\n\nconst defaultOptions: Ricochet3DOptions = {\n\tminSpeed: 2,\n\tmaxSpeed: 20,\n\tspeedMultiplier: 1.05,\n\treflectionMode: 'angled',\n\tmaxAngleDeg: 45,\n};\n\nconst RICOCHET_3D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:ricochet-3d');\n\nfunction createRicochet3DHandle(\n\tref: BehaviorRef<Ricochet3DOptions>,\n): Ricochet3DHandle {\n\treturn {\n\t\tgetRicochet: (ctx: Ricochet3DCollisionContext) => {\n\t\t\tconst fsm = ref.fsm as Ricochet3DFSM | undefined;\n\t\t\tif (!fsm) return null;\n\t\t\treturn fsm.computeRicochet(ctx, ref.options);\n\t\t},\n\t\tapplyRicochet: (ctx: Ricochet3DCollisionContext): boolean => {\n\t\t\tconst fsm = ref.fsm as Ricochet3DFSM | undefined;\n\t\t\tif (!fsm || fsm.isOnCooldown()) return false;\n\n\t\t\tconst result = fsm.computeRicochet(ctx, ref.options);\n\t\t\tif (!result) return false;\n\n\t\t\tconst entity = ctx.entity as any;\n\t\t\tif (entity?.transformStore) {\n\t\t\t\tentity.transformStore.velocity.x = result.velocity.x;\n\t\t\t\tentity.transformStore.velocity.y = result.velocity.y;\n\t\t\t\tentity.transformStore.velocity.z = result.velocity.z;\n\t\t\t\tentity.transformStore.dirty.velocity = true;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t\tgetLastResult: () => {\n\t\t\tconst fsm = ref.fsm as Ricochet3DFSM | undefined;\n\t\t\treturn fsm?.getLastResult() ?? null;\n\t\t},\n\t\tonRicochet: (callback: Ricochet3DCallback) => {\n\t\t\tconst fsm = ref.fsm as Ricochet3DFSM | undefined;\n\t\t\tif (!fsm) {\n\t\t\t\tif (!(ref as any).pendingListeners) {\n\t\t\t\t\t(ref as any).pendingListeners = [];\n\t\t\t\t}\n\t\t\t\t(ref as any).pendingListeners.push(callback);\n\t\t\t\treturn () => {\n\t\t\t\t\tconst pending = (ref as any).pendingListeners as Ricochet3DCallback[];\n\t\t\t\t\tconst index = pending.indexOf(callback);\n\t\t\t\t\tif (index >= 0) pending.splice(index, 1);\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn fsm.addListener(callback);\n\t\t},\n\t};\n}\n\nclass Ricochet3DSystem implements BehaviorSystem {\n\tprivate elapsedMs = 0;\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tthis.elapsedMs += delta * 1000;\n\n\t\tconst links = this.getBehaviorLinks?.(RICOCHET_3D_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst ref = link.ref as any;\n\t\t\tif (!ref.fsm) {\n\t\t\t\tref.fsm = new Ricochet3DFSM();\n\t\t\t\tconst pending = ref.pendingListeners as Ricochet3DCallback[] | undefined;\n\t\t\t\tif (pending) {\n\t\t\t\t\tfor (const callback of pending) {\n\t\t\t\t\t\tref.fsm.addListener(callback);\n\t\t\t\t\t}\n\t\t\t\t\tref.pendingListeners = [];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tref.fsm.setCurrentTimeMs(this.elapsedMs);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\tconst links = this.getBehaviorLinks?.(RICOCHET_3D_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\t\tfor (const link of links) {\n\t\t\tconst ref = link.ref as any;\n\t\t\tref.fsm?.resetCooldown();\n\t\t}\n\t}\n}\n\nexport const Ricochet3DBehavior = defineBehavior({\n\tname: 'ricochet-3d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew Ricochet3DSystem(ctx.world, ctx.getBehaviorLinks),\n\tcreateHandle: createRicochet3DHandle,\n});\n","/**\n * Platformer 3D ECS Components\n * \n * Components for 3D platformer movement system including walking, running,\n * jumping with multi-jump support, and falling/landing states.\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Platformer3DMovementComponent (capability / configuration)\n// Defines the movement capabilities and physics parameters\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Platformer3DMovementComponent {\n\t/** Base walking speed */\n\twalkSpeed: number;\n\t/** Sprint/run speed */\n\trunSpeed: number;\n\t/** Initial jump force/velocity */\n\tjumpForce: number;\n\t/** Maximum number of jumps (1 = single jump, 2 = double jump, etc.) */\n\tmaxJumps: number;\n\t/** Gravity force (optional override) */\n\tgravity: number;\n\t/** Ray length for ground detection */\n\tgroundRayLength: number;\n\t/** Coyote time in seconds (grace period after leaving ground) */\n\tcoyoteTime: number;\n\t/** Jump buffer time in seconds (queue jump input before landing) */\n\tjumpBufferTime: number;\n\t/** Velocity multiplier when releasing jump button early (0-1) */\n\tjumpCutMultiplier: number;\n\t/** Time in seconds before multi-jump becomes available (0 = after button release) */\n\tmultiJumpWindowTime: number;\n\t/** Enable ground-ray debug visualization */\n\tdebugGroundProbe: boolean;\n}\n\nexport function createPlatformer3DMovementComponent(\n\toptions: Partial<Platformer3DMovementComponent> = {}\n): Platformer3DMovementComponent {\n\treturn {\n\t\twalkSpeed: options.walkSpeed ?? 12,\n\t\trunSpeed: options.runSpeed ?? 24,\n\t\tjumpForce: options.jumpForce ?? 12,\n\t\tmaxJumps: options.maxJumps ?? 1,\n\t\tgravity: options.gravity ?? 9.82,\n\t\tgroundRayLength: options.groundRayLength ?? 1.0,\n\t\tcoyoteTime: options.coyoteTime ?? 0.1,\n\t\tjumpBufferTime: options.jumpBufferTime ?? 0.1,\n\t\tjumpCutMultiplier: options.jumpCutMultiplier ?? 0.5,\n\t\tmultiJumpWindowTime: options.multiJumpWindowTime ?? 0.15, // 150ms default\n\t\tdebugGroundProbe: options.debugGroundProbe ?? false,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Platformer3DInputComponent (intent)\n// Written by: Player controller, AI controller\n// Read by: Platformer3DBehavior\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Platformer3DInputComponent {\n\t/** Horizontal movement input (-1 to 1) */\n\tmoveX: number;\n\t/** Forward/backward movement input (-1 to 1) */\n\tmoveZ: number;\n\t/** Jump button pressed */\n\tjump: boolean;\n\t/** Run/sprint button held */\n\trun: boolean;\n}\n\nexport function createPlatformer3DInputComponent(): Platformer3DInputComponent {\n\treturn {\n\t\tmoveX: 0,\n\t\tmoveZ: 0,\n\t\tjump: false,\n\t\trun: false,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Platformer3DStateComponent (runtime state)\n// Tracks the current state of the platformer entity\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Platformer3DStateComponent {\n\t/** Is the entity on the ground */\n\tgrounded: boolean;\n\t/** Is currently in a jump arc */\n\tjumping: boolean;\n\t/** Is falling (not jumping) */\n\tfalling: boolean;\n\t/** Current jump count (for multi-jump) */\n\tjumpCount: number;\n\t/** Y position when jump started */\n\tjumpStartHeight: number;\n\t/** Current movement speed being applied */\n\tcurrentSpeed: number;\n\t/** Last known ground Y position */\n\tlastGroundedY: number;\n\t/** Was jump button pressed last frame (for edge detection) */\n\tjumpPressedLastFrame: boolean;\n\t\n\t// -- New fields --\n\t/** Is currently colliding with ground (from physics collision callback) */\n\tcollisionGrounded: boolean;\n\t/** Timestamp of last ground collision */\n\tgroundedCollisionTime: number;\n\t/** Time in seconds since last grounded */\n\ttimeSinceGrounded: number;\n\t/** Is a jump allowed due to buffer? */\n\tjumpBuffered: boolean;\n\t/** Time remaining in jump buffer */\n\tjumpBufferTimer: number;\n\t/** Is jump button currently held */\n\tjumpHeld: boolean;\n\t/** Has the jump cut been applied for this jump? */\n\tjumpCutApplied: boolean;\n\t/** Has jump button been released since last jump (required for multi-jump) */\n\tjumpReleasedSinceLastJump: boolean;\n\t/** Time since current jump started (for multi-jump window) */\n\ttimeSinceJump: number;\n}\n\nexport function createPlatformer3DStateComponent(): Platformer3DStateComponent {\n\treturn {\n\t\tgrounded: false,\n\t\tjumping: false,\n\t\tfalling: false,\n\t\tjumpCount: 0,\n\t\tjumpStartHeight: 0,\n\t\tcurrentSpeed: 0,\n\t\tlastGroundedY: 0,\n\t\tjumpPressedLastFrame: false,\n\t\tcollisionGrounded: false,\n\t\tgroundedCollisionTime: 0,\n\t\ttimeSinceGrounded: 0,\n\t\tjumpBuffered: false,\n\t\tjumpBufferTimer: 0,\n\t\tjumpHeld: false,\n\t\tjumpCutApplied: false,\n\t\tjumpReleasedSinceLastJump: true,\n\t\ttimeSinceJump: 0,\n\t};\n}\n","/**\n * Platformer 3D Finite State Machine\n * \n * Manages state transitions for 3D platformer movement:\n * - Idle: Standing still on ground\n * - Walking: Moving on ground (slow)\n * - Running: Moving on ground (fast)\n * - Jumping: Ascending from jump\n * - Falling: Descending (gravity)\n * - Landing: Just touched ground\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { Platformer3DInputComponent, Platformer3DStateComponent } from './components';\n\n/**\n * Simplified Collision Context interface\n */\nexport interface PlatformerCollisionContext {\n\tcontact: {\n\t\tnormal: { x: number; y: number; z?: number };\n\t};\n}\n\n/**\n * Platformer states\n */\nexport enum Platformer3DState {\n\tIdle = 'idle',\n\tWalking = 'walking',\n\tRunning = 'running',\n\tJumping = 'jumping',\n\tFalling = 'falling',\n\tLanding = 'landing',\n}\n\n/**\n * Events that trigger state transitions\n */\nexport enum Platformer3DEvent {\n\tWalk = 'walk',\n\tRun = 'run',\n\tJump = 'jump',\n\tFall = 'fall',\n\tLand = 'land',\n\tStop = 'stop',\n}\n\n/**\n * Context for the FSM\n */\nexport interface Platformer3DContext {\n\tinput: Platformer3DInputComponent;\n\tstate: Platformer3DStateComponent;\n}\n\n/**\n * Platformer 3D FSM\n */\nexport class Platformer3DFSM {\n\tmachine: SyncStateMachine<Platformer3DState, Platformer3DEvent, never>;\n\n\tconstructor(private ctx: Platformer3DContext) {\n\t\tthis.machine = new SyncStateMachine<Platformer3DState, Platformer3DEvent, never>(\n\t\t\tPlatformer3DState.Idle,\n\t\t\t[\n\t\t\t\t// Idle transitions\n\t\t\t\tt(Platformer3DState.Idle, Platformer3DEvent.Walk, Platformer3DState.Walking),\n\t\t\t\tt(Platformer3DState.Idle, Platformer3DEvent.Run, Platformer3DState.Running),\n\t\t\t\tt(Platformer3DState.Idle, Platformer3DEvent.Jump, Platformer3DState.Jumping),\n\t\t\t\tt(Platformer3DState.Idle, Platformer3DEvent.Fall, Platformer3DState.Falling),\n\t\t\t\t\n\t\t\t\t// Walking transitions\n\t\t\t\tt(Platformer3DState.Walking, Platformer3DEvent.Run, Platformer3DState.Running),\n\t\t\t\tt(Platformer3DState.Walking, Platformer3DEvent.Jump, Platformer3DState.Jumping),\n\t\t\t\tt(Platformer3DState.Walking, Platformer3DEvent.Stop, Platformer3DState.Idle),\n\t\t\t\tt(Platformer3DState.Walking, Platformer3DEvent.Fall, Platformer3DState.Falling),\n\t\t\t\t\n\t\t\t\t// Running transitions\n\t\t\t\tt(Platformer3DState.Running, Platformer3DEvent.Walk, Platformer3DState.Walking),\n\t\t\t\tt(Platformer3DState.Running, Platformer3DEvent.Jump, Platformer3DState.Jumping),\n\t\t\t\tt(Platformer3DState.Running, Platformer3DEvent.Stop, Platformer3DState.Idle),\n\t\t\t\tt(Platformer3DState.Running, Platformer3DEvent.Fall, Platformer3DState.Falling),\n\t\t\t\t\n\t\t\t\t// Jumping transitions\n\t\t\t\tt(Platformer3DState.Jumping, Platformer3DEvent.Fall, Platformer3DState.Falling),\n\t\t\t\tt(Platformer3DState.Jumping, Platformer3DEvent.Land, Platformer3DState.Landing),\n\t\t\t\tt(Platformer3DState.Jumping, Platformer3DEvent.Jump, Platformer3DState.Jumping), // Multi-jump\n\t\t\t\t\n\t\t\t\t// Falling transitions\n\t\t\t\tt(Platformer3DState.Falling, Platformer3DEvent.Land, Platformer3DState.Landing),\n\t\t\t\t\n\t\t\t\t// Landing transitions\n\t\t\t\tt(Platformer3DState.Landing, Platformer3DEvent.Walk, Platformer3DState.Walking),\n\t\t\t\tt(Platformer3DState.Landing, Platformer3DEvent.Run, Platformer3DState.Running),\n\t\t\t\tt(Platformer3DState.Landing, Platformer3DEvent.Stop, Platformer3DState.Idle),\n\t\t\t\t\n\t\t\t\t// Self-transitions (no-ops)\n\t\t\t\tt(Platformer3DState.Idle, Platformer3DEvent.Stop, Platformer3DState.Idle),\n\t\t\t]\n\t\t);\n\t}\n\n\t/**\n\t * Get the current state\n\t */\n\tgetState(): Platformer3DState {\n\t\treturn this.machine.getState();\n\t}\n\n\t/**\n\t * Dispatch an event to the FSM\n\t */\n\tdispatch(event: Platformer3DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\t/**\n\t * Check if grounded\n\t */\n\tisGrounded(): boolean {\n\t\tconst state = this.getState();\n\t\treturn state === Platformer3DState.Idle || \n\t\t state === Platformer3DState.Walking || \n\t\t state === Platformer3DState.Running || \n\t\t state === Platformer3DState.Landing;\n\t}\n\n\t/**\n\t * Get current jump count from context\n\t */\n\tgetJumpCount(): number {\n\t\treturn this.ctx.state.jumpCount;\n\t}\n\n\t/**\n\t * Handle collision event to update ground state\n\t */\n\thandleCollision(ctx: PlatformerCollisionContext): void {\n\t\t// Check if collision is ground (normal pointing up)\n\t\t// Y normal > 0.5 means roughly within 60 degrees of up\n\t\tif (ctx.contact.normal.y > 0.5) {\n\t\t\tthis.ctx.state.collisionGrounded = true;\n\t\t\tthis.ctx.state.groundedCollisionTime = performance.now();\n\t\t}\n\t}\n\n\t/**\n\t * Update FSM based on current state\n\t */\n\tupdate(input: Platformer3DInputComponent, state: Platformer3DStateComponent): void {\n\t\t// Update context\n\t\tthis.ctx.input = input;\n\t\tthis.ctx.state = state;\n\n\t\t// Get current FSM state\n\t\tconst currentState = this.getState();\n\n\t\t// Determine movement state\n\t\tconst hasInput = Math.abs(input.moveX) > 0.1 || Math.abs(input.moveZ) > 0.1;\n\t\tconst isRunning = input.run;\n\n\t\t// Handle landing: if we're in falling state and now grounded, land\n\t\tif (currentState === Platformer3DState.Falling && state.grounded) {\n\t\t\tthis.dispatch(Platformer3DEvent.Land);\n\t\t\t// Don't return - allow immediate transition to movement state\n\t\t}\n\n\t\t// Send appropriate events based on state\n\t\tif (state.grounded) {\n\t\t\tif (hasInput) {\n\t\t\t\tif (isRunning) {\n\t\t\t\t\tthis.dispatch(Platformer3DEvent.Run);\n\t\t\t\t} else {\n\t\t\t\t\tthis.dispatch(Platformer3DEvent.Walk);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.dispatch(Platformer3DEvent.Stop);\n\t\t\t}\n\t\t} else {\n\t\t\t// Not grounded - check if we should be falling\n\t\t\t// Transition to falling if: We're in jumping state and now falling, \n\t\t\t// OR we walked off a ledge (idle/walking/running and now falling)\n\t\t\tif (state.falling) {\n\t\t\t\tthis.dispatch(Platformer3DEvent.Fall);\n\t\t\t}\n\t\t}\n\n\t\t// Handle jump input (edge detection handled in behavior)\n\t\tif (input.jump && !state.jumpPressedLastFrame) {\n\t\t\tthis.dispatch(Platformer3DEvent.Jump);\n\t\t}\n\t}\n}\n","import { Ray } from '@dimforge/rapier3d-compat';\nimport { BufferGeometry, Line, LineBasicMaterial, Vector3 } from 'three';\nimport { serializeColliderDesc } from '../../physics/serialize-descriptors';\n\nexport interface GroundProbeOffset {\n\tx: number;\n\tz: number;\n}\n\nexport type GroundProbeMode = 'center' | 'any';\n\nexport interface GroundProbeEntity {\n\tuuid: string;\n\tbody: any;\n}\n\nexport interface GroundProbeOptions {\n\trayLength: number;\n\toffsets?: readonly GroundProbeOffset[];\n\tmode?: GroundProbeMode;\n\tdebug?: boolean;\n\tscene?: any;\n\toriginYOffset?: number;\n}\n\nexport interface GroundProbeSupportHit {\n\ttoi: number;\n\tpoint: {\n\t\tx: number;\n\t\ty: number;\n\t\tz: number;\n\t};\n\torigin: {\n\t\tx: number;\n\t\ty: number;\n\t\tz: number;\n\t};\n\trayIndex: number;\n\tcolliderUuid?: string;\n}\n\nexport const GROUND_SNAP_EPSILON = 0.001;\n\nconst DEFAULT_OFFSETS: readonly GroundProbeOffset[] = [\n\t{ x: 0, z: 0 },\n\t{ x: 0.4, z: 0.4 },\n\t{ x: -0.4, z: 0.4 },\n\t{ x: 0.4, z: -0.4 },\n\t{ x: -0.4, z: -0.4 },\n] as const;\n\nexport class GroundProbe3D {\n\tprivate rays = new Map<string, Ray[]>();\n\tprivate debugLines = new Map<string, Line[]>();\n\n\tconstructor(private world: any) {}\n\n\tprobeSupport(\n\t\tentity: GroundProbeEntity,\n\t\toptions: GroundProbeOptions,\n\t): GroundProbeSupportHit | null {\n\t\tif (!this.world?.world || !entity.body) return null;\n\n\t\tconst mode = options.mode ?? 'any';\n\t\tconst offsets =\n\t\t\tmode === 'center'\n\t\t\t\t? (options.offsets ?? DEFAULT_OFFSETS).slice(0, 1)\n\t\t\t\t: (options.offsets ?? DEFAULT_OFFSETS);\n\t\tconst translation = entity.body.translation();\n\t\tconst rays = this.getOrCreateRays(entity.uuid, offsets.length);\n\t\tconst originYOffset = options.originYOffset ?? 0;\n\t\tlet support: GroundProbeSupportHit | null = null;\n\n\t\tfor (let index = 0; index < offsets.length; index++) {\n\t\t\tconst offset = offsets[index];\n\t\t\tconst ray = rays[index];\n\n\t\t\tray.origin = {\n\t\t\t\tx: translation.x + offset.x,\n\t\t\t\ty: translation.y + originYOffset,\n\t\t\t\tz: translation.z + offset.z,\n\t\t\t};\n\t\t\tray.dir = { x: 0, y: -1, z: 0 };\n\n\t\t\tconst hit = this.world.world.castRay(\n\t\t\t\tray,\n\t\t\t\toptions.rayLength,\n\t\t\t\ttrue,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tentity.body,\n\t\t\t);\n\t\t\tif (!hit) continue;\n\n\t\t\tconst nextSupport: GroundProbeSupportHit = {\n\t\t\t\ttoi: hit.toi,\n\t\t\t\tpoint: {\n\t\t\t\t\tx: ray.origin.x + ray.dir.x * hit.toi,\n\t\t\t\t\ty: ray.origin.y + ray.dir.y * hit.toi,\n\t\t\t\t\tz: ray.origin.z + ray.dir.z * hit.toi,\n\t\t\t\t},\n\t\t\t\torigin: {\n\t\t\t\t\tx: ray.origin.x,\n\t\t\t\t\ty: ray.origin.y,\n\t\t\t\t\tz: ray.origin.z,\n\t\t\t\t},\n\t\t\t\trayIndex: index,\n\t\t\t\tcolliderUuid: hit.collider?._parent?.userData?.uuid,\n\t\t\t};\n\n\t\t\tif (mode === 'center') {\n\t\t\t\tsupport = nextSupport;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (!support || nextSupport.toi < support.toi) {\n\t\t\t\tsupport = nextSupport;\n\t\t\t}\n\t\t}\n\n\t\tif (options.debug && options.scene) {\n\t\t\tthis.updateDebugLines(\n\t\t\t\tentity.uuid,\n\t\t\t\trays,\n\t\t\t\tBoolean(support),\n\t\t\t\toptions.rayLength,\n\t\t\t\toptions.scene,\n\t\t\t);\n\t\t} else {\n\t\t\tthis.disposeDebugLines(entity.uuid);\n\t\t}\n\n\t\treturn support;\n\t}\n\n\tdetect(entity: GroundProbeEntity, options: GroundProbeOptions): boolean {\n\t\treturn this.probeSupport(entity, options) != null;\n\t}\n\n\tdestroyEntity(uuid: string): void {\n\t\tthis.rays.delete(uuid);\n\t\tthis.disposeDebugLines(uuid);\n\t}\n\n\tdestroy(): void {\n\t\tthis.rays.clear();\n\t\tfor (const uuid of this.debugLines.keys()) {\n\t\t\tthis.disposeDebugLines(uuid);\n\t\t}\n\t\tthis.debugLines.clear();\n\t}\n\n\tprivate getOrCreateRays(uuid: string, count: number): Ray[] {\n\t\tlet rays = this.rays.get(uuid);\n\t\tif (!rays || rays.length !== count) {\n\t\t\trays = Array.from(\n\t\t\t\t{ length: count },\n\t\t\t\t() => new Ray({ x: 0, y: 0, z: 0 }, { x: 0, y: -1, z: 0 }),\n\t\t\t);\n\t\t\tthis.rays.set(uuid, rays);\n\t\t}\n\t\treturn rays;\n\t}\n\n\tprivate updateDebugLines(\n\t\tuuid: string,\n\t\trays: Ray[],\n\t\thasGround: boolean,\n\t\tlength: number,\n\t\tscene: any,\n\t): void {\n\t\tlet lines = this.debugLines.get(uuid);\n\t\tif (!lines) {\n\t\t\tlines = rays.map(() => {\n\t\t\t\tconst geometry = new BufferGeometry().setFromPoints([\n\t\t\t\t\tnew Vector3(),\n\t\t\t\t\tnew Vector3(),\n\t\t\t\t]);\n\t\t\t\tconst material = new LineBasicMaterial({ color: 0xff0000 });\n\t\t\t\tconst line = new Line(geometry, material);\n\t\t\t\tscene.add(line);\n\t\t\t\treturn line;\n\t\t\t});\n\t\t\tthis.debugLines.set(uuid, lines);\n\t\t}\n\n\t\trays.forEach((ray, index) => {\n\t\t\tconst line = lines![index];\n\t\t\tconst start = new Vector3(ray.origin.x, ray.origin.y, ray.origin.z);\n\t\t\tconst end = new Vector3(\n\t\t\t\tray.origin.x + ray.dir.x * length,\n\t\t\t\tray.origin.y + ray.dir.y * length,\n\t\t\t\tray.origin.z + ray.dir.z * length,\n\t\t\t);\n\t\t\tline.visible = true;\n\t\t\tline.geometry.setFromPoints([start, end]);\n\t\t\t(line.material as LineBasicMaterial).color.setHex(\n\t\t\t\thasGround ? 0x00ff00 : 0xff0000,\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate disposeDebugLines(uuid: string): void {\n\t\tconst lines = this.debugLines.get(uuid);\n\t\tif (!lines) return;\n\n\t\tfor (const line of lines) {\n\t\t\tline.removeFromParent();\n\t\t\tline.geometry.dispose();\n\t\t\t(line.material as LineBasicMaterial).dispose();\n\t\t}\n\n\t\tthis.debugLines.delete(uuid);\n\t}\n}\n\nexport function getGroundAnchorOffsetY(entity: any): number {\n\tconst runtimeColliderDesc = entity?.colliderDesc;\n\tif (runtimeColliderDesc) {\n\t\tconst serialized = serializeColliderDesc(runtimeColliderDesc);\n\t\tconst centerY = serialized.translation?.[1] ?? 0;\n\t\tif (serialized.shape === 'capsule' && serialized.dimensions.length >= 2) {\n\t\t\tconst halfCylinder = serialized.dimensions[0] ?? 0;\n\t\t\tconst radius = serialized.dimensions[1] ?? 0;\n\t\t\treturn halfCylinder + radius - centerY;\n\t\t}\n\t\tif (serialized.shape === 'cuboid' && serialized.dimensions.length >= 2) {\n\t\t\tconst halfHeight = serialized.dimensions[1] ?? 0;\n\t\t\treturn halfHeight - centerY;\n\t\t}\n\t}\n\n\tconst collisionSize =\n\t\tentity?.options?.collision?.size ??\n\t\tentity?.options?.collisionSize ??\n\t\tentity?.options?.size;\n\tconst height = collisionSize?.y ?? 0;\n\tif (height <= 0) {\n\t\treturn 0;\n\t}\n\n\tconst collisionPosition =\n\t\tentity?.options?.collision?.position ??\n\t\tentity?.options?.collisionPosition;\n\tconst centerY = collisionPosition?.y ?? height / 2;\n\treturn (height / 2) - centerY;\n}\n\nexport function getGroundSnapTargetY(\n\tentity: any,\n\tsupport: GroundProbeSupportHit,\n\tepsilon: number = GROUND_SNAP_EPSILON,\n): number {\n\treturn support.point.y + getGroundAnchorOffsetY(entity) + epsilon;\n}\n","/**\n * Platformer 3D Behavior System\n * \n * Handles 3D platformer physics including:\n * - Ground detection via raycasting\n * - Horizontal movement (walk/run)\n * - Jumping with multi-jump support\n * - Gravity application\n * - State synchronization with FSM\n */\n\nimport { GroundProbe3D, getGroundAnchorOffsetY } from '../shared/ground-probe-3d';\nimport type {\n\tPlatformer3DMovementComponent,\n\tPlatformer3DInputComponent,\n\tPlatformer3DStateComponent,\n} from './components';\n\n/**\n * Entity with platformer components\n */\nexport interface Platformer3DEntity {\n\tuuid: string;\n\tbody: any; // RigidBody\n\tplatformer: Platformer3DMovementComponent;\n\t$platformer: Platformer3DInputComponent;\n\tplatformerState: Platformer3DStateComponent;\n\ttransformStore?: any;\n}\n\n/**\n * Platformer 3D Movement Behavior\n * \n * Core physics system for 3D platformer movement\n */\nexport class Platformer3DBehavior {\n\tprivate world: any;\n\tprivate scene: any;\n\tprivate groundProbe: GroundProbe3D;\n\n\tconstructor(world: any, scene: any) {\n\t\tthis.world = world;\n\t\tthis.scene = scene;\n\t\tthis.groundProbe = new GroundProbe3D(world);\n\t}\n\n\t/**\n\t * Apply horizontal movement based on input\n\t */\n\tprivate applyMovement(entity: Platformer3DEntity, delta: number): void {\n\t\tconst input = entity.$platformer;\n\t\tconst movement = entity.platformer;\n\t\tconst state = entity.platformerState;\n\n\t\t// Determine current speed\n\t\tconst speed = input.run ? movement.runSpeed : movement.walkSpeed;\n\t\tstate.currentSpeed = speed;\n\n\t\t// Calculate horizontal movement\n\t\tconst moveX = input.moveX * speed;\n\t\tconst moveZ = input.moveZ * speed;\n\n\t\t// Get current Y velocity from physics body (preserve vertical momentum)\n\t\tconst currentVel = entity.body.linvel();\n\n\t\t// Set complete velocity - horizontal from input, vertical preserved\n\t\tentity.transformStore.velocity.x = moveX;\n\t\tentity.transformStore.velocity.y = currentVel.y;\n\t\tentity.transformStore.velocity.z = moveZ;\n\t\tentity.transformStore.dirty.velocity = true;\n\t}\n\n\t/**\n\t * Handle jump logic with multi-jump support\n\t */\n\t/**\n\t * Handle jump logic with multi-jump, coyote time, and buffering\n\t */\n\tprivate handleJump(entity: Platformer3DEntity, delta: number): void {\n\t\tconst input = entity.$platformer;\n\t\tconst movement = entity.platformer;\n\t\tconst state = entity.platformerState;\n\n\t\t// Track time since last jump (for multi-jump window)\n\t\tif (state.jumping || state.falling) {\n\t\t\tstate.timeSinceJump += delta;\n\t\t}\n\n\t\t// Track jump button release (required for multi-jump)\n\t\tif (!input.jump && state.jumpHeld) {\n\t\t\tstate.jumpReleasedSinceLastJump = true;\n\t\t}\n\n\t\t// 1. Jump Buffering - queue on new press\n\t\tif (input.jump && !state.jumpPressedLastFrame) {\n\t\t\tstate.jumpBuffered = true;\n\t\t\tstate.jumpBufferTimer = movement.jumpBufferTime;\n\t\t}\n\t\t\n\t\tstate.jumpPressedLastFrame = input.jump;\n\t\tstate.jumpHeld = input.jump;\n\n\t\t// Decrement buffer timer\n\t\tif (state.jumpBuffered) {\n\t\t\tstate.jumpBufferTimer -= delta;\n\t\t\tif (state.jumpBufferTimer <= 0) {\n\t\t\t\tstate.jumpBuffered = false;\n\t\t\t}\n\t\t}\n\n\t\t// 2. Variable Jump Height (Jump Cut)\n\t\t// Only apply jump cut if we've been jumping for a bit (prevents cutting multi-jump immediately)\n\t\tconst minTimeBeforeCut = 0.1; // 100ms minimum before cut can apply\n\t\tconst canApplyCut = state.timeSinceJump >= minTimeBeforeCut;\n\t\tif (!input.jump && state.jumping && !state.jumpCutApplied && canApplyCut) {\n\t\t\tconst velocity = entity.body.linvel();\n\t\t\tentity.transformStore.velocity.y = velocity.y * movement.jumpCutMultiplier;\n\t\t\tentity.transformStore.dirty.velocity = true;\n\t\t\tstate.jumpCutApplied = true;\n\t\t}\n\n\t\t// Execute Jump (if buffered input exists)\n\t\tif (!state.jumpBuffered) return;\n\n\t\t// 3. Jump eligibility check\n\t\tconst inCoyoteWindow = !state.grounded && state.timeSinceGrounded <= movement.coyoteTime;\n\t\tconst isFirstJump = state.grounded || (inCoyoteWindow && state.jumpCount === 0);\n\t\t\n\t\t// Multi-jump requirements:\n\t\t// 1. Not grounded\n\t\t// 2. Have jumps remaining\n\t\t// 3. Button was released since last jump (no holding for double jump)\n\t\t// 4. Within the jump window (after multiJumpWindowTime has passed)\n\t\tconst hasJumpsRemaining = state.jumpCount < movement.maxJumps;\n\t\tconst buttonReleased = state.jumpReleasedSinceLastJump;\n\t\tconst inMultiJumpWindow = state.timeSinceJump >= movement.multiJumpWindowTime;\n\t\tconst canMultiJump = !state.grounded && hasJumpsRemaining && buttonReleased && inMultiJumpWindow;\n\n\t\tif (isFirstJump || canMultiJump) {\n\t\t\t// Consume buffered input\n\t\t\tstate.jumpBuffered = false;\n\n\t\t\t// Increment jump count and reset tracking\n\t\t\tstate.jumpCount++;\n\t\t\tstate.jumpReleasedSinceLastJump = false; // Must release again for next jump\n\t\t\tstate.timeSinceJump = 0; // Reset window timer\n\n\t\t\t// Record jump start height\n\t\t\tstate.jumpStartHeight = entity.body.translation().y;\n\n\t\t\t// Apply jump force\n\t\t\tstate.jumping = true;\n\t\t\tstate.falling = false;\n\t\t\tstate.jumpCutApplied = false;\n\n\t\t\t// Apply jump force via transform store\n\t\t\tentity.transformStore.velocity.y = movement.jumpForce;\n\t\t\tentity.transformStore.dirty.velocity = true;\n\t\t}\n\t}\n\n\t/**\n\t * Apply gravity when not grounded\n\t */\n\tprivate applyGravity(entity: Platformer3DEntity, delta: number): void {\n\t\tconst movement = entity.platformer;\n\t\tconst state = entity.platformerState;\n\n\t\tif (state.grounded) return;\n\t\t\n\t\t// Skip gravity on the same frame as a jump (prevents overwriting jump velocity)\n\t\t// timeSinceJump is reset to 0 when we jump, so if it's very small, we just jumped\n\t\tif (state.jumping && state.timeSinceJump < 0.01) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Get current velocity from physics body and add gravity\n\t\tconst currentVel = entity.body.linvel();\n\t\tconst newYVelocity = currentVel.y - movement.gravity * delta;\n\n\t\t// Update the Y velocity in transform store (applyMovement already set x/z and old y)\n\t\tentity.transformStore.velocity.y = newYVelocity;\n\t\tentity.transformStore.dirty.velocity = true;\n\t}\n\n\t/**\n\t * Update entity state based on physics\n\t */\n\tprivate updateState(entity: Platformer3DEntity, delta: number): void {\n\t\tconst state = entity.platformerState;\n\n\t\t// 1. Reset grounded state before detection\n\t\tconst wasGrounded = state.grounded;\n\t\t\n\t\t// Read ACTUAL velocity from physics body\n\t\tconst velocity = entity.body.linvel();\n\t\t\n\t\tlet isGrounded = false;\n\t\t\n\t\t// Separate ground detection for airborne vs walking\n\t\tconst isAirborne = state.jumping || state.falling;\n\t\t\n\t\tif (isAirborne) {\n\t\t\t// Airborne: Must be FALLING (not jumping) with very low velocity to land\n\t\t\t// This prevents false grounding at jump apex or during descent\n\t\t\tconst probeOriginYOffset = 0.05 - getGroundAnchorOffsetY(entity);\n\t\t\tconst nearGround = this.groundProbe.detect(entity, {\n\t\t\t\trayLength: entity.platformer.groundRayLength,\n\t\t\t\tmode: 'any',\n\t\t\t\tdebug: entity.platformer.debugGroundProbe,\n\t\t\t\tscene: this.scene,\n\t\t\t\toriginYOffset: probeOriginYOffset,\n\t\t\t});\n\t\t\tconst canLand = state.falling && !state.jumping; // Only land when falling, not jumping\n\t\t\tconst hasLanded = Math.abs(velocity.y) < 0.5; // Very strict threshold for landing\n\t\t\tisGrounded = nearGround && canLand && hasLanded;\n\t\t} else {\n\t\t\t// On ground (walking/idle): Normal raycast detection with lenient threshold\n\t\t\tconst probeOriginYOffset = 0.05 - getGroundAnchorOffsetY(entity);\n\t\t\tconst nearGround = this.groundProbe.detect(entity, {\n\t\t\t\trayLength: entity.platformer.groundRayLength,\n\t\t\t\tmode: 'any',\n\t\t\t\tdebug: entity.platformer.debugGroundProbe,\n\t\t\t\tscene: this.scene,\n\t\t\t\toriginYOffset: probeOriginYOffset,\n\t\t\t});\n\t\t\tconst notFallingFast = velocity.y > -2.0; // Lenient - don't ground while falling fast\n\t\t\tisGrounded = nearGround && notFallingFast;\n\t\t}\n\n\t\tstate.grounded = isGrounded;\n\n\t\t// 2. Update Coyote Timer\n\t\tif (state.grounded) {\n\t\t\tstate.timeSinceGrounded = 0;\n\t\t\tstate.lastGroundedY = entity.body.translation().y;\n\t\t} else {\n\t\t\tstate.timeSinceGrounded += delta;\n\t\t}\n\n\t\t// 3. Landing Logic\n\t\tif (!wasGrounded && state.grounded) {\n\t\t\tstate.jumpCount = 0;\n\t\t\tstate.jumping = false;\n\t\t\tstate.falling = false;\n\t\t\tstate.jumpCutApplied = false;\n\t\t}\n\n\t\t// 4. Falling Logic (negative Y velocity and not grounded)\n\t\tif (velocity.y < -0.1 && !state.grounded) {\n\t\t\tif (state.jumping && velocity.y < 0) {\n\t\t\t\tstate.jumping = false;\n\t\t\t\tstate.falling = true;\n\t\t\t} else if (!state.jumping) {\n\t\t\t\tstate.falling = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update one platformer entity.\n\t */\n\tupdateEntity(entity: any, delta: number): void {\n\t\tif (!entity.platformer || !entity.$platformer || !entity.platformerState) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst platformerEntity = entity as Platformer3DEntity;\n\t\tthis.updateState(platformerEntity, delta);\n\t\tthis.applyMovement(platformerEntity, delta);\n\t\tthis.handleJump(platformerEntity, delta);\n\t\tthis.applyGravity(platformerEntity, delta);\n\t}\n\n\t/**\n\t * Update all platformer entities.\n\t */\n\tupdate(delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tthis.updateEntity(entity, delta);\n\t\t}\n\t}\n\n\t/**\n\t * Cleanup\n\t */\n\tdestroy(): void {\n\t\tthis.groundProbe.destroy();\n\t}\n}\n","/**\n * Platformer 3D Behavior Descriptor\n * \n * Type-safe descriptor for the platformer 3D behavior system.\n * Provides entity.use() API for 3D platformer movement.\n */\n\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { Platformer3DBehavior as Platformer3DMovementBehavior, Platformer3DEntity } from './platformer-3d.behavior';\nimport { Platformer3DFSM, Platformer3DState, PlatformerCollisionContext } from './platformer-3d-fsm';\nimport {\n\tcreatePlatformer3DMovementComponent,\n\tcreatePlatformer3DInputComponent,\n\tcreatePlatformer3DStateComponent,\n} from './components';\n\n/**\n * Platformer behavior options (typed for entity.use() autocomplete)\n */\nexport interface Platformer3DBehaviorOptions {\n\t/** Base walking speed (default: 12) */\n\twalkSpeed?: number;\n\t/** Sprint/run speed (default: 24) */\n\trunSpeed?: number;\n\t/** Initial jump force (default: 12) */\n\tjumpForce?: number;\n\t/** Maximum number of jumps (default: 1) */\n\tmaxJumps?: number;\n\t/** Gravity force (default: 9.82) */\n\tgravity?: number;\n\t/** Ray length for ground detection (default: 1.0) */\n\tgroundRayLength?: number;\n\t/** Enable debug visualization for ground probe rays (default: false) */\n\tdebugGroundProbe?: boolean;\n}\n\nconst defaultOptions: Platformer3DBehaviorOptions = {\n\twalkSpeed: 12,\n\trunSpeed: 24,\n\tjumpForce: 12,\n\tmaxJumps: 1,\n\tgravity: 9.82,\n\tgroundRayLength: 1.0,\n\tdebugGroundProbe: false,\n};\n\nconst PLATFORMER_BEHAVIOR_KEY = Symbol.for('zylem:behavior:platformer-3d');\n\n/**\n * Adapter that wraps Platformer3DBehavior as a BehaviorSystem\n */\nclass Platformer3DBehaviorSystem implements BehaviorSystem {\n\tprivate movementBehavior: Platformer3DMovementBehavior;\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate scene: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {\n\t\tthis.movementBehavior = new Platformer3DMovementBehavior(world, scene);\n\t}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(PLATFORMER_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst platformerRef = link.ref as any;\n\t\t\tif (!gameEntity.body) continue;\n\n\t\t\tconst options = platformerRef.options as Platformer3DBehaviorOptions;\n\n\t\t\t// Ensure entity has platformer components (initialized once)\n\t\t\tif (!gameEntity.platformer) {\n\t\t\t\tgameEntity.platformer = createPlatformer3DMovementComponent(options);\n\t\t\t}\n\n\t\t\tif (!gameEntity.$platformer) {\n\t\t\t\tgameEntity.$platformer = createPlatformer3DInputComponent();\n\t\t\t}\n\n\t\t\tif (!gameEntity.platformerState) {\n\t\t\t\tgameEntity.platformerState = createPlatformer3DStateComponent();\n\t\t\t}\n\n\t\t\t// Create FSM lazily and attach to the BehaviorRef\n\t\t\tif (!platformerRef.fsm && gameEntity.$platformer && gameEntity.platformerState) {\n\t\t\t\tplatformerRef.fsm = new Platformer3DFSM({\n\t\t\t\t\tinput: gameEntity.$platformer,\n\t\t\t\t\tstate: gameEntity.platformerState,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Update FSM to sync state with physics\n\t\t\tif (platformerRef.fsm && gameEntity.$platformer && gameEntity.platformerState) {\n\t\t\t\tplatformerRef.fsm.update(gameEntity.$platformer, gameEntity.platformerState);\n\t\t\t}\n\n\t\t\tthis.movementBehavior.updateEntity(gameEntity, delta);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\tthis.movementBehavior.destroy();\n\t}\n}\n\n/**\n * Platformer3DBehavior - typed descriptor for 3D platformer movement\n * \n * Provides complete 3D platformer physics including:\n * - Walking and running\n * - Jumping with multi-jump support\n * - Gravity and falling\n * - Ground detection\n * \n * @example\n * ```typescript\n * import { Platformer3DBehavior } from \"@zylem/game-lib\";\n * \n * const player = await playgroundActor('player');\n * const platformer = player.use(Platformer3DBehavior, {\n * walkSpeed: 12,\n * runSpeed: 24,\n * jumpForce: 12,\n * maxJumps: 2, // Double jump!\n * });\n * \n * // In update loop\n * player.onUpdate(({ inputs }) => {\n * player.$platformer.moveX = inputs.p1.axes.Horizontal.value;\n * player.$platformer.moveZ = inputs.p1.axes.Vertical.value;\n * player.$platformer.jump = inputs.p1.buttons.A.held > 0;\n * player.$platformer.run = inputs.p1.shoulders.LTrigger.held > 0;\n * \n * const state = platformer.getState();\n * const grounded = platformer.isGrounded();\n * });\n * ```\n */\nexport const Platformer3DBehavior = defineBehavior<\n\tPlatformer3DBehaviorOptions,\n\t{\n\t\tgetState: () => Platformer3DState;\n\t\tisGrounded: () => boolean;\n\t\tgetJumpCount: () => number;\n\t\tonPlatformCollision: (ctx: PlatformerCollisionContext) => void;\n\t},\n\tPlatformer3DEntity\n>({\n\tname: 'platformer-3d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew Platformer3DBehaviorSystem(\n\t\t\tctx.world,\n\t\t\tctx.scene,\n\t\t\tctx.getBehaviorLinks,\n\t\t),\n\tcreateHandle: (ref) => ({\n\t\tgetState: () => ref.fsm?.getState() ?? Platformer3DState.Idle,\n\t\tisGrounded: () => ref.fsm?.isGrounded() ?? false,\n\t\tgetJumpCount: () => ref.fsm?.getJumpCount() ?? 0,\n\t\tonPlatformCollision: (ctx) => ref.fsm?.handleCollision(ctx),\n\t}),\n});\n","/**\n * First Person Controller ECS Components\n *\n * Components for first-person movement and camera control:\n * - Movement configuration (walk/run speed, sensitivity, eye height)\n * - Input intent (WASD movement + mouse look deltas)\n * - Runtime state (yaw, pitch, speed)\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FirstPersonMovementComponent (capability / configuration)\n// Defines movement capabilities and look parameters\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface FirstPersonMovementComponent {\n\t/** Base walking speed (units/sec) */\n\twalkSpeed: number;\n\t/** Sprint/run speed (units/sec) */\n\trunSpeed: number;\n\t/** Look sensitivity multiplier applied to raw input deltas */\n\tlookSensitivity: number;\n\t/** Vertical offset above entity position for eye/camera placement */\n\teyeHeight: number;\n}\n\nexport function createFirstPersonMovementComponent(\n\toptions: Partial<FirstPersonMovementComponent> = {},\n): FirstPersonMovementComponent {\n\treturn {\n\t\twalkSpeed: options.walkSpeed ?? 8,\n\t\trunSpeed: options.runSpeed ?? 16,\n\t\tlookSensitivity: options.lookSensitivity ?? 2,\n\t\teyeHeight: options.eyeHeight ?? 1.7,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FirstPersonInputComponent (intent)\n// Written by: Player controller (game.onUpdate / entity.onUpdate)\n// Read by: FirstPersonControllerBehavior\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface FirstPersonInputComponent {\n\t/** Horizontal movement input (-1 to 1, strafe) */\n\tmoveX: number;\n\t/** Forward/backward movement input (-1 to 1) */\n\tmoveZ: number;\n\t/** Horizontal look delta (mouse/stick, raw value before sensitivity) */\n\tlookX: number;\n\t/** Vertical look delta (mouse/stick, raw value before sensitivity) */\n\tlookY: number;\n\t/** Sprint button held */\n\tsprint: boolean;\n}\n\nexport function createFirstPersonInputComponent(): FirstPersonInputComponent {\n\treturn {\n\t\tmoveX: 0,\n\t\tmoveZ: 0,\n\t\tlookX: 0,\n\t\tlookY: 0,\n\t\tsprint: false,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FirstPersonStateComponent (runtime state)\n// Tracks the current state of the first-person entity\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface FirstPersonStateComponent {\n\t/** Current yaw in radians */\n\tyaw: number;\n\t/** Current pitch in radians */\n\tpitch: number;\n\t/** Current movement speed being applied */\n\tcurrentSpeed: number;\n}\n\nexport function createFirstPersonStateComponent(): FirstPersonStateComponent {\n\treturn {\n\t\tyaw: 0,\n\t\tpitch: 0,\n\t\tcurrentSpeed: 0,\n\t};\n}\n","/**\n * First Person Controller Finite State Machine\n *\n * Manages state transitions for first-person movement:\n * - Idle: Standing still\n * - Walking: Moving at walk speed\n * - Running: Moving at run/sprint speed\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { FirstPersonInputComponent, FirstPersonStateComponent } from './components';\n\n/**\n * First-person movement states\n */\nexport enum FirstPersonState {\n\tIdle = 'idle',\n\tWalking = 'walking',\n\tRunning = 'running',\n}\n\n/**\n * Events that trigger state transitions\n */\nexport enum FirstPersonEvent {\n\tWalk = 'walk',\n\tRun = 'run',\n\tStop = 'stop',\n}\n\n/**\n * Context for the FSM\n */\nexport interface FirstPersonContext {\n\tinput: FirstPersonInputComponent;\n\tstate: FirstPersonStateComponent;\n}\n\n/**\n * First Person Controller FSM\n */\nexport class FirstPersonFSM {\n\tmachine: SyncStateMachine<FirstPersonState, FirstPersonEvent, never>;\n\n\tconstructor(private ctx: FirstPersonContext) {\n\t\tthis.machine = new SyncStateMachine<FirstPersonState, FirstPersonEvent, never>(\n\t\t\tFirstPersonState.Idle,\n\t\t\t[\n\t\t\t\t// Idle transitions\n\t\t\t\tt(FirstPersonState.Idle, FirstPersonEvent.Walk, FirstPersonState.Walking),\n\t\t\t\tt(FirstPersonState.Idle, FirstPersonEvent.Run, FirstPersonState.Running),\n\t\t\t\tt(FirstPersonState.Idle, FirstPersonEvent.Stop, FirstPersonState.Idle),\n\n\t\t\t\t// Walking transitions\n\t\t\t\tt(FirstPersonState.Walking, FirstPersonEvent.Run, FirstPersonState.Running),\n\t\t\t\tt(FirstPersonState.Walking, FirstPersonEvent.Stop, FirstPersonState.Idle),\n\t\t\t\tt(FirstPersonState.Walking, FirstPersonEvent.Walk, FirstPersonState.Walking),\n\n\t\t\t\t// Running transitions\n\t\t\t\tt(FirstPersonState.Running, FirstPersonEvent.Walk, FirstPersonState.Walking),\n\t\t\t\tt(FirstPersonState.Running, FirstPersonEvent.Stop, FirstPersonState.Idle),\n\t\t\t\tt(FirstPersonState.Running, FirstPersonEvent.Run, FirstPersonState.Running),\n\t\t\t],\n\t\t);\n\t}\n\n\t/** Get the current state */\n\tgetState(): FirstPersonState {\n\t\treturn this.machine.getState();\n\t}\n\n\t/** Dispatch an event to the FSM */\n\tdispatch(event: FirstPersonEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\t/** Get the current yaw from context */\n\tgetYaw(): number {\n\t\treturn this.ctx.state.yaw;\n\t}\n\n\t/** Get the current pitch from context */\n\tgetPitch(): number {\n\t\treturn this.ctx.state.pitch;\n\t}\n\n\t/**\n\t * Update FSM based on current input and state.\n\t */\n\tupdate(input: FirstPersonInputComponent, state: FirstPersonStateComponent): void {\n\t\tthis.ctx.input = input;\n\t\tthis.ctx.state = state;\n\n\t\tconst hasMovement = Math.abs(input.moveX) > 0.1 || Math.abs(input.moveZ) > 0.1;\n\n\t\tif (hasMovement) {\n\t\t\tif (input.sprint) {\n\t\t\t\tthis.dispatch(FirstPersonEvent.Run);\n\t\t\t} else {\n\t\t\t\tthis.dispatch(FirstPersonEvent.Walk);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.dispatch(FirstPersonEvent.Stop);\n\t\t}\n\t}\n}\n","/**\n * First Person Controller Behavior System\n *\n * Handles first-person camera control and movement:\n * - Reads input component for WASD movement and mouse look deltas\n * - Drives a FirstPersonPerspective (yaw/pitch accumulation)\n * - Writes velocity to transformStore (physics-based movement)\n * - Syncs camera position from the entity's rigid body each frame\n * - Positions an optional viewmodel entity relative to the camera\n */\n\nimport { Vector3, Quaternion, Euler } from 'three';\nimport type { FirstPersonPerspective } from '../../camera/perspectives/first-person-perspective';\nimport { setVelocityIntent } from '../../actions/capabilities/velocity-intents';\nimport type {\n\tFirstPersonMovementComponent,\n\tFirstPersonInputComponent,\n\tFirstPersonStateComponent,\n} from './components';\n\n/**\n * Viewmodel configuration for an entity that follows the camera.\n */\nexport interface ViewmodelConfig {\n\t/** The entity whose visual group should be positioned relative to the camera. */\n\tentity: any;\n\t/** Offset from the eye position in camera-local space (right, down, forward). */\n\toffset: Vector3;\n\t/** Additional rotation applied to the viewmodel in local space (Euler angles in radians). */\n\trotation?: Euler;\n}\n\n/**\n * Entity interface for first-person controller.\n * Entities with this behavior have these components attached.\n */\nexport interface FirstPersonEntity {\n\tuuid: string;\n\tbody: any;\n\ttransformStore: any;\n\tfirstPerson: FirstPersonMovementComponent;\n\t$fps: FirstPersonInputComponent;\n\tfirstPersonState: FirstPersonStateComponent;\n}\n\n// Reusable temporaries (avoid per-frame allocations)\nconst _forward = new Vector3();\nconst _right = new Vector3();\nconst _up = new Vector3(0, 1, 0);\nconst _viewmodelQuat = new Quaternion();\nconst _viewmodelLocalQuat = new Quaternion();\nconst _viewmodelEuler = new Euler();\nconst _offset = new Vector3();\n\n/**\n * First Person Controller Behavior\n *\n * Core movement + look system for first-person cameras.\n * Reads from entity.$fps input component and drives a FirstPersonPerspective.\n */\nexport class FirstPersonControllerBehavior {\n\tprivate world: any;\n\tprivate perspectives = new Map<string, FirstPersonPerspective>();\n\tprivate viewmodels = new Map<string, ViewmodelConfig>();\n\n\tconstructor(world: any) {\n\t\tthis.world = world;\n\t}\n\n\t/**\n\t * Associate a FirstPersonPerspective with an entity (by uuid).\n\t * Called once by the descriptor system when the behavior is initialized.\n\t */\n\tsetPerspective(entityUuid: string, perspective: FirstPersonPerspective): void {\n\t\tthis.perspectives.set(entityUuid, perspective);\n\t}\n\n\thasPerspective(entityUuid: string): boolean {\n\t\treturn this.perspectives.has(entityUuid);\n\t}\n\n\t/**\n\t * Attach a viewmodel (weapon/item) to an entity.\n\t * The viewmodel entity's group will be positioned relative to the camera each frame.\n\t */\n\tsetViewmodel(entityUuid: string, config: ViewmodelConfig): void {\n\t\tthis.viewmodels.set(entityUuid, config);\n\t}\n\n\thasViewmodel(entityUuid: string): boolean {\n\t\treturn this.viewmodels.has(entityUuid);\n\t}\n\n\t/**\n\t * Update one first-person entity.\n\t */\n\tupdateEntity(entity: any, _delta: number): void {\n\t\tconst fpEntity = entity as any;\n\t\tif (!fpEntity.firstPerson || !fpEntity.$fps || !fpEntity.firstPersonState) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst input: FirstPersonInputComponent = fpEntity.$fps;\n\t\tconst movement: FirstPersonMovementComponent = fpEntity.firstPerson;\n\t\tconst state: FirstPersonStateComponent = fpEntity.firstPersonState;\n\t\tconst perspective = this.perspectives.get(fpEntity.uuid);\n\n\t\t// 1. Sync camera position from physics body\n\t\tif (perspective?.initialPosition && fpEntity.body) {\n\t\t\tconst pos = fpEntity.body.translation();\n\t\t\tperspective.initialPosition.set(\n\t\t\t\tpos.x,\n\t\t\t\tpos.y + movement.eyeHeight,\n\t\t\t\tpos.z,\n\t\t\t);\n\t\t}\n\n\t\t// 2. Apply look\n\t\tif (perspective) {\n\t\t\tperspective.look(\n\t\t\t\t-input.lookX * movement.lookSensitivity,\n\t\t\t\t-input.lookY * movement.lookSensitivity,\n\t\t\t);\n\n\t\t\tstate.yaw = perspective.yaw;\n\t\t\tstate.pitch = perspective.pitch;\n\t\t}\n\n\t\t// 3. Compute velocity-based movement and write to transformStore\n\t\tconst speed = input.sprint ? movement.runSpeed : movement.walkSpeed;\n\t\tstate.currentSpeed = speed;\n\n\t\tconst hasMovement = Math.abs(input.moveX) > 0.1 || Math.abs(input.moveZ) > 0.1;\n\n\t\tif (fpEntity.transformStore) {\n\t\t\tif (hasMovement) {\n\t\t\t\t_forward.set(0, 0, -1).applyAxisAngle(_up, state.yaw);\n\t\t\t\t_right.set(1, 0, 0).applyAxisAngle(_up, state.yaw);\n\n\t\t\t\tconst vx =\n\t\t\t\t\t_right.x * input.moveX * speed +\n\t\t\t\t\t_forward.x * (-input.moveZ) * speed;\n\t\t\t\tconst vz =\n\t\t\t\t\t_right.z * input.moveX * speed +\n\t\t\t\t\t_forward.z * (-input.moveZ) * speed;\n\t\t\t\tsetVelocityIntent(\n\t\t\t\t\tfpEntity.transformStore,\n\t\t\t\t\t'first-person',\n\t\t\t\t\t{ x: vx, z: vz },\n\t\t\t\t\t{ mode: 'replace', priority: 10 },\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tsetVelocityIntent(\n\t\t\t\t\tfpEntity.transformStore,\n\t\t\t\t\t'first-person',\n\t\t\t\t\t{ x: 0, z: 0 },\n\t\t\t\t\t{ mode: 'replace', priority: 10 },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// 4. Position viewmodel\n\t\tconst vm = this.viewmodels.get(fpEntity.uuid);\n\t\tif (vm && perspective?.initialPosition) {\n\t\t\tthis.positionViewmodel(vm, perspective, state);\n\t\t}\n\t}\n\n\t/**\n\t * Update all first-person entities.\n\t */\n\tupdate(delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tthis.updateEntity(entity, delta);\n\t\t}\n\t}\n\n\t/**\n\t * Position a viewmodel entity relative to the camera's eye position and rotation.\n\t *\n\t * The physics transform system overwrites group.position from the rigid body\n\t * each frame, so we must also move the body to keep them in sync.\n\t */\n\tprivate positionViewmodel(\n\t\tvm: ViewmodelConfig,\n\t\tperspective: FirstPersonPerspective,\n\t\tstate: FirstPersonStateComponent,\n\t): void {\n\t\tconst eyePos = perspective.initialPosition;\n\t\tif (!eyePos) return;\n\n\t\t// Build camera rotation quaternion\n\t\t_viewmodelQuat.setFromEuler(\n\t\t\t_viewmodelEuler.set(state.pitch, state.yaw, 0, 'YXZ'),\n\t\t);\n\n\t\t// Compose with the viewmodel's local rotation (model orientation fix)\n\t\tif (vm.rotation) {\n\t\t\t_viewmodelLocalQuat.setFromEuler(vm.rotation);\n\t\t\t_viewmodelQuat.multiply(_viewmodelLocalQuat);\n\t\t}\n\n\t\t// Transform the local offset into world space (use camera rotation, not the composed one)\n\t\t_offset.copy(vm.offset).applyQuaternion(_viewmodelQuat);\n\n\t\tconst wx = eyePos.x + _offset.x;\n\t\tconst wy = eyePos.y + _offset.y;\n\t\tconst wz = eyePos.z + _offset.z;\n\n\t\tconst entity = vm.entity;\n\n\t\t// Move the physics body so the transform system stays in sync\n\t\tif (entity?.body) {\n\t\t\tentity.body.setTranslation({ x: wx, y: wy, z: wz }, true);\n\t\t\tentity.body.setRotation(\n\t\t\t\t{ x: _viewmodelQuat.x, y: _viewmodelQuat.y, z: _viewmodelQuat.z, w: _viewmodelQuat.w },\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\n\t\t// Also set the group directly for immediate visual update\n\t\tif (entity?.group) {\n\t\t\tentity.group.position.set(wx, wy, wz);\n\t\t\tentity.group.quaternion.copy(_viewmodelQuat);\n\t\t}\n\t}\n\n\t/** Cleanup */\n\tdestroy(): void {\n\t\tthis.perspectives.clear();\n\t\tthis.viewmodels.clear();\n\t}\n}\n","/**\n * First Person Controller Behavior Descriptor\n *\n * Type-safe descriptor for the first-person controller behavior system.\n * Provides entity.use() API for FPS movement and camera control.\n */\n\nimport { Vector3, Euler } from 'three';\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport type { FirstPersonPerspective } from '../../camera/perspectives/first-person-perspective';\nimport {\n\tFirstPersonControllerBehavior,\n\ttype FirstPersonEntity,\n\ttype ViewmodelConfig,\n} from './first-person.behavior';\nimport { FirstPersonFSM, FirstPersonState } from './first-person-fsm';\nimport {\n\tcreateFirstPersonMovementComponent,\n\tcreateFirstPersonInputComponent,\n\tcreateFirstPersonStateComponent,\n} from './components';\n\n/**\n * First-person controller behavior options (typed for entity.use() autocomplete).\n */\nexport interface FirstPersonControllerOptions {\n\t/** Base walking speed (default: 8) */\n\twalkSpeed?: number;\n\t/** Sprint/run speed (default: 16) */\n\trunSpeed?: number;\n\t/** Look sensitivity multiplier (default: 2) */\n\tlookSensitivity?: number;\n\t/** Eye height offset above entity position (default: 1.7) */\n\teyeHeight?: number;\n\t/** The FirstPersonPerspective to drive (from camera.getPerspective()) */\n\tperspective?: FirstPersonPerspective;\n\t/** Optional viewmodel (weapon/item) to position relative to the camera */\n\tviewmodel?: { entity: any; offset: Vector3; rotation?: Euler };\n}\n\nconst defaultOptions: FirstPersonControllerOptions = {\n\twalkSpeed: 8,\n\trunSpeed: 16,\n\tlookSensitivity: 2,\n\teyeHeight: 1.7,\n};\n\nconst FIRST_PERSON_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:first-person-controller',\n);\n\n/**\n * Adapter that wraps FirstPersonControllerBehavior as a BehaviorSystem.\n */\nclass FirstPersonControllerSystem implements BehaviorSystem {\n\tprivate behavior: FirstPersonControllerBehavior;\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {\n\t\tthis.behavior = new FirstPersonControllerBehavior(world);\n\t}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(FIRST_PERSON_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst fpsRef = link.ref as any;\n\n\t\t\tconst options = fpsRef.options as FirstPersonControllerOptions;\n\n\t\t\t// Initialize components (once)\n\t\t\tif (!gameEntity.firstPerson) {\n\t\t\t\tgameEntity.firstPerson = createFirstPersonMovementComponent(options);\n\t\t\t}\n\n\t\t\tif (!gameEntity.$fps) {\n\t\t\t\tgameEntity.$fps = createFirstPersonInputComponent();\n\t\t\t}\n\n\t\t\tif (!gameEntity.firstPersonState) {\n\t\t\t\tgameEntity.firstPersonState = createFirstPersonStateComponent();\n\t\t\t}\n\n\t\t\t// Wire up perspective (once)\n\t\t\tif (options.perspective && !this.behavior.hasPerspective(gameEntity.uuid)) {\n\t\t\t\tthis.behavior.setPerspective(gameEntity.uuid, options.perspective);\n\t\t\t}\n\n\t\t\t// Wire up viewmodel (once)\n\t\t\tif (options.viewmodel && !this.behavior.hasViewmodel(gameEntity.uuid)) {\n\t\t\t\tthis.behavior.setViewmodel(gameEntity.uuid, options.viewmodel as ViewmodelConfig);\n\t\t\t}\n\n\t\t\t// Create FSM lazily\n\t\t\tif (!fpsRef.fsm && gameEntity.$fps && gameEntity.firstPersonState) {\n\t\t\t\tfpsRef.fsm = new FirstPersonFSM({\n\t\t\t\t\tinput: gameEntity.$fps,\n\t\t\t\t\tstate: gameEntity.firstPersonState,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Update FSM\n\t\t\tif (fpsRef.fsm && gameEntity.$fps && gameEntity.firstPersonState) {\n\t\t\t\tfpsRef.fsm.update(gameEntity.$fps, gameEntity.firstPersonState);\n\t\t\t}\n\n\t\t\tthis.behavior.updateEntity(gameEntity, delta);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\tthis.behavior.destroy();\n\t}\n}\n\n/**\n * FirstPersonController - typed descriptor for first-person movement and camera control.\n *\n * Provides complete first-person controller including:\n * - WASD movement relative to camera yaw\n * - Mouse look driving a FirstPersonPerspective\n * - Optional viewmodel positioning (weapon/item following camera)\n * - Walk/run state tracking via FSM\n *\n * @example\n * ```typescript\n * import { FirstPersonController, FirstPersonPerspective, createActor, createCamera, Perspectives } from \"@zylem/game-lib\";\n *\n * const fpsCamera = createCamera({ perspective: Perspectives.FirstPerson, ... });\n * const fps = fpsCamera.getPerspective<FirstPersonPerspective>();\n *\n * const player = createActor({ name: 'player', ... });\n * const controller = player.use(FirstPersonController, {\n * perspective: fps,\n * walkSpeed: 8,\n * runSpeed: 16,\n * lookSensitivity: 2,\n * });\n *\n * // In update loop - write input, behavior handles the rest\n * player.onUpdate(({ inputs }) => {\n * player.$fps.moveX = inputs.p1.axes.Horizontal.value;\n * player.$fps.moveZ = inputs.p1.axes.Vertical.value;\n * player.$fps.lookX = inputs.p1.axes.SecondaryHorizontal.value;\n * player.$fps.lookY = inputs.p1.axes.SecondaryVertical.value;\n * player.$fps.sprint = inputs.p1.shoulders.LTrigger.held > 0;\n * });\n * ```\n */\nexport const FirstPersonController = defineBehavior<\n\tFirstPersonControllerOptions,\n\t{\n\t\tgetState: () => FirstPersonState;\n\t\tgetYaw: () => number;\n\t\tgetPitch: () => number;\n\t\tattachViewmodel: (entity: any, offset: Vector3) => void;\n\t},\n\tFirstPersonEntity\n>({\n\tname: 'first-person-controller',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew FirstPersonControllerSystem(ctx.world, ctx.getBehaviorLinks),\n\tcreateHandle: (ref) => ({\n\t\tgetState: () => ref.fsm?.getState() ?? FirstPersonState.Idle,\n\t\tgetYaw: () => ref.fsm?.getYaw() ?? 0,\n\t\tgetPitch: () => ref.fsm?.getPitch() ?? 0,\n\t\tattachViewmodel: (entity: any, offset: Vector3) => {\n\t\t\tif (ref.options) {\n\t\t\t\tref.options.viewmodel = { entity, offset };\n\t\t\t}\n\t\t},\n\t}),\n});\n","/**\n * Jumper 3D ECS Components\n *\n * Type definitions and factory functions for the 3D jump behavior system.\n *\n * - JumpConfig3D: tunable parameters (stored as the capability component)\n * - JumpInput3D: per-tick intent written by the player/AI controller\n * - JumpContext3D: per-tick snapshot provided by the system adapter\n * - JumpState3D: internal runtime state owned by the behavior\n */\n\nimport type { Vector3 } from 'three';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Vec3-like interface for cross-library compatibility\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Vec3Like {\n\tx: number;\n\ty: number;\n\tz: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// JumpConfig3D (capability / configuration)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface JumpConfig3D {\n\t/** Desired peak height in world units */\n\tjumpHeight: number;\n\t/** Gravity magnitude (positive, e.g. 20) */\n\tgravity: number;\n\t/** Terminal fall speed magnitude (optional) */\n\tmaxFallSpeed?: number;\n\n\t/** 1 = single jump, 2 = double, etc. */\n\tmaxJumps: number;\n\t/** Reset jump counter when grounded (usually true) */\n\tresetJumpsOnGround: boolean;\n\t/** Reset jump counter on wall contact (future wall-jump support) */\n\tresetJumpsOnWall?: boolean;\n\n\t/** Grace period after leaving ground where first jump is still allowed (ms) */\n\tcoyoteTimeMs: number;\n\t/** Queue a jump press this many ms before landing (ms) */\n\tjumpBufferMs: number;\n\t/** Optional cooldown between consecutive jumps (ms) */\n\tminTimeBetweenJumpsMs?: number;\n\n\t/** Variable jump height via early release */\n\tvariableJump?: {\n\t\tenabled: boolean;\n\t\t/** Gravity multiplier applied when jump is released early while ascending */\n\t\tcutGravityMultiplier: number;\n\t\t/** Max hold duration before the cut triggers automatically (ms, optional) */\n\t\tmaxHoldMs?: number;\n\t};\n\n\t/** Optional planar (XZ) launch / air-control overrides */\n\tplanar?: {\n\t\t/** One-time planar speed applied at takeoff */\n\t\tlaunchPlanarSpeed?: number;\n\t\t/** If true, preserve current planar speed instead of replacing it */\n\t\tpreservePlanarSpeed?: boolean;\n\t\tairControl?: {\n\t\t\tmaxPlanarSpeed: number;\n\t\t\t/** Acceleration per second while airborne */\n\t\t\tacceleration: number;\n\t\t\t/** Deceleration per second when no input */\n\t\t\tdeceleration: number;\n\t\t};\n\t};\n\n\t/** Snappier descent tuning */\n\tfall?: {\n\t\t/** Gravity multiplier while falling (e.g. 1.5-2.5) */\n\t\tfallGravityMultiplier: number;\n\t\t/** Additional multiplier when fast-fall input is held */\n\t\tfastFallMultiplier?: number;\n\t};\n}\n\nexport function createJumpConfig3D(\n\toptions: Partial<JumpConfig3D> = {},\n): JumpConfig3D {\n\treturn {\n\t\tjumpHeight: options.jumpHeight ?? 2.5,\n\t\tgravity: options.gravity ?? 20,\n\t\tmaxFallSpeed: options.maxFallSpeed,\n\t\tmaxJumps: options.maxJumps ?? 1,\n\t\tresetJumpsOnGround: options.resetJumpsOnGround ?? true,\n\t\tresetJumpsOnWall: options.resetJumpsOnWall,\n\t\tcoyoteTimeMs: options.coyoteTimeMs ?? 100,\n\t\tjumpBufferMs: options.jumpBufferMs ?? 80,\n\t\tminTimeBetweenJumpsMs: options.minTimeBetweenJumpsMs,\n\t\tvariableJump: options.variableJump,\n\t\tplanar: options.planar,\n\t\tfall: options.fall,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// JumpInput3D (intent)\n// Written by: Player controller, AI controller\n// Read by: Jumper3DBehavior\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface JumpInput3D {\n\t/** True on the frame the jump button is first pressed (rising edge) */\n\tjumpPressed: boolean;\n\t/** True while the jump button is held down */\n\tjumpHeld: boolean;\n\t/** True on the frame the jump button is released (falling edge) */\n\tjumpReleased: boolean;\n\t/** Desired planar direction in world space (camera-relative), optional */\n\tmoveDirWorld?: Vec3Like;\n\t/** Hold to drop faster (e.g. crouch / down input) */\n\tfastFall?: boolean;\n}\n\nexport function createJumpInput3D(): JumpInput3D {\n\treturn {\n\t\tjumpPressed: false,\n\t\tjumpHeld: false,\n\t\tjumpReleased: false,\n\t\tmoveDirWorld: undefined,\n\t\tfastFall: false,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// JumpContext3D (per-tick snapshot from entity / controller)\n// Built by the system adapter — never written to by user code.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface JumpContext3D {\n\t/** Frame delta in seconds */\n\tdt: number;\n\t/** World up direction (usually 0,1,0) */\n\tup: Vec3Like;\n\t/** Current vertical (Y) velocity of the entity */\n\tvelocityY: number;\n\t/** Current horizontal velocity of the entity (read from body) */\n\thorizontalVelocity: { x: number; z: number };\n\t/** Whether the entity is on the ground */\n\tisGrounded: boolean;\n\t/** Surface normal at ground contact (optional) */\n\tgroundNormal?: Vec3Like;\n\t/** Time since entity was last grounded (ms) */\n\ttimeSinceGroundedMs: number;\n\n\t/** Set only the vertical (Y) component of velocity */\n\tsetVerticalVelocity(y: number): void;\n\t/** Set only the horizontal (X/Z) components of velocity */\n\tsetHorizontalVelocity(x: number, z: number): void;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// JumpState3D (internal runtime state)\n// Owned and mutated exclusively by Jumper3DBehavior.tick()\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface JumpState3D {\n\t/** Number of jumps consumed since last reset */\n\tjumpsUsed: number;\n\t/** Timestamp (ms) of the most recent jump execution */\n\tlastJumpTimeMs: number;\n\t/** Remaining ms in the jump-buffer window (counts down) */\n\tbufferedJumpMs: number;\n\t/** Remaining ms in the coyote-time window (counts down) */\n\tcoyoteMs: number;\n\t/** True while the entity is in a jump arc (ascending phase) */\n\tisJumping: boolean;\n\t/** Elapsed ms since jump button was first held (for variable jump) */\n\tjumpHoldMs: number;\n\t/** Whether the variable-jump cut has already been applied this jump */\n\tjumpCutApplied: boolean;\n}\n\nexport function createJumpState3D(): JumpState3D {\n\treturn {\n\t\tjumpsUsed: 0,\n\t\tlastJumpTimeMs: 0,\n\t\tbufferedJumpMs: 0,\n\t\tcoyoteMs: 0,\n\t\tisJumping: false,\n\t\tjumpHoldMs: 0,\n\t\tjumpCutApplied: false,\n\t};\n}\n","/**\n * Jumper 3D Behavior — Pure Jump Physics\n *\n * A stateless tick function that receives configuration, input, context, and\n * state, then applies jump physics through the context's velocity helpers.\n *\n * Vertical velocity (Y) is owned exclusively by this behavior.\n * Horizontal velocity (X/Z) is only touched when airborne planar control\n * is configured; otherwise the movement controller owns X/Z.\n */\n\nimport type {\n\tJumpConfig3D,\n\tJumpInput3D,\n\tJumpContext3D,\n\tJumpState3D,\n} from './components';\n\n/** v = sqrt(2 * g * h) */\nfunction jumpVelocityFromHeight(gravity: number, height: number): number {\n\treturn Math.sqrt(2 * gravity * height);\n}\n\nfunction planarSpeed(x: number, z: number): number {\n\treturn Math.sqrt(x * x + z * z);\n}\n\nfunction normalizeMut(v: { x: number; y: number; z: number }): number {\n\tconst len = Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);\n\tif (len > 1e-6) {\n\t\tv.x /= len;\n\t\tv.y /= len;\n\t\tv.z /= len;\n\t}\n\treturn len;\n}\n\nexport class Jumper3DBehavior {\n\t/**\n\t * Advance the jump system by one frame.\n\t *\n\t * Call order within a frame:\n\t * 1. Movement controller writes X/Z via transformStore.dirty.velocityX/Z.\n\t * 2. `tick()` writes Y via ctx.setVerticalVelocity().\n\t * (Optionally writes X/Z when airborne planar control is active.)\n\t */\n\ttick(\n\t\tconfig: JumpConfig3D,\n\t\tinput: JumpInput3D,\n\t\tctx: JumpContext3D,\n\t\tstate: JumpState3D,\n\t): JumperTickResult {\n\t\tconst dtMs = ctx.dt * 1000;\n\t\tconst now = performance.now();\n\t\tlet event: JumperTickEvent = JumperTickEvent.None;\n\t\tlet jumpedThisFrame = false;\n\n\t\t// ── 1. Ground-contact bookkeeping ──────────────────────────────────\n\t\tif (ctx.isGrounded) {\n\t\t\tstate.coyoteMs = config.coyoteTimeMs;\n\t\t\tif (config.resetJumpsOnGround) {\n\t\t\t\tstate.jumpsUsed = 0;\n\t\t\t}\n\t\t\tif (state.isJumping) {\n\t\t\t\tstate.isJumping = false;\n\t\t\t\tstate.jumpCutApplied = false;\n\t\t\t\tevent = JumperTickEvent.Land;\n\t\t\t}\n\t\t} else {\n\t\t\tstate.coyoteMs = Math.max(0, state.coyoteMs - dtMs);\n\t\t}\n\n\t\t// ── 2. Jump buffer ─────────────────────────────────────────────────\n\t\tif (input.jumpPressed) {\n\t\t\tstate.bufferedJumpMs = config.jumpBufferMs;\n\t\t} else {\n\t\t\tstate.bufferedJumpMs = Math.max(0, state.bufferedJumpMs - dtMs);\n\t\t}\n\n\t\t// ── 3. Variable-jump hold tracking ─────────────────────────────────\n\t\tif (state.isJumping && input.jumpHeld) {\n\t\t\tstate.jumpHoldMs += dtMs;\n\t\t}\n\n\t\t// ── 4. Jump eligibility & execution ────────────────────────────────\n\t\tconst wantsJump = state.bufferedJumpMs > 0;\n\n\t\tconst isFirstJump =\n\t\t\tctx.isGrounded || (state.coyoteMs > 0 && state.jumpsUsed === 0);\n\t\tconst hasAirJumps = state.jumpsUsed > 0 && state.jumpsUsed < config.maxJumps;\n\t\tconst canJump = isFirstJump || hasAirJumps;\n\n\t\t\tconst cooldownOk =\n\t\t\t\tconfig.minTimeBetweenJumpsMs == null ||\n\t\t\t\tnow - state.lastJumpTimeMs >= config.minTimeBetweenJumpsMs;\n\n\t\t\tif (wantsJump && canJump && cooldownOk) {\n\t\t\t\tconst vy = jumpVelocityFromHeight(config.gravity, config.jumpHeight);\n\n\t\t\t\tctx.setVerticalVelocity(vy);\n\t\t\t\tjumpedThisFrame = true;\n\n\t\t\tif (config.planar?.launchPlanarSpeed != null && !config.planar.preservePlanarSpeed) {\n\t\t\t\tconst dir = input.moveDirWorld;\n\t\t\t\tif (dir && (Math.abs(dir.x) > 1e-6 || Math.abs(dir.z) > 1e-6)) {\n\t\t\t\t\tconst d = { x: dir.x, y: 0, z: dir.z };\n\t\t\t\t\tnormalizeMut(d);\n\t\t\t\t\tctx.setHorizontalVelocity(\n\t\t\t\t\t\td.x * config.planar.launchPlanarSpeed,\n\t\t\t\t\t\td.z * config.planar.launchPlanarSpeed,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstate.jumpsUsed++;\n\t\t\tstate.lastJumpTimeMs = now;\n\t\t\tstate.bufferedJumpMs = 0;\n\t\t\tstate.coyoteMs = 0;\n\t\t\tstate.isJumping = true;\n\t\t\tstate.jumpHoldMs = 0;\n\t\t\tstate.jumpCutApplied = false;\n\n\t\t\tevent = JumperTickEvent.Jump;\n\t\t}\n\n\t\t// ── 5. Gravity (with variable-jump and fall multipliers) ───────────\n\t\t// Treat a jump-launch frame as airborne so we don't immediately clamp\n\t\t// the freshly applied jump velocity back to zero.\n\t\tif (!ctx.isGrounded || jumpedThisFrame) {\n\t\t\tlet gravityMul = 1;\n\t\t\tconst vy = ctx.velocityY;\n\t\t\tconst isFalling = vy < 0;\n\n\t\t\tif (isFalling) {\n\t\t\t\tgravityMul = config.fall?.fallGravityMultiplier ?? 1;\n\t\t\t\tif (input.fastFall && config.fall?.fastFallMultiplier != null) {\n\t\t\t\t\tgravityMul *= config.fall.fastFallMultiplier;\n\t\t\t\t}\n\t\t\t\tif (event !== JumperTickEvent.Land) {\n\t\t\t\t\tevent = JumperTickEvent.Fall;\n\t\t\t\t}\n\t\t\t} else if (state.isJumping) {\n\t\t\t\tconst vj = config.variableJump;\n\t\t\t\tif (vj?.enabled && !state.jumpCutApplied) {\n\t\t\t\t\tconst holdExpired =\n\t\t\t\t\t\tvj.maxHoldMs != null && state.jumpHoldMs >= vj.maxHoldMs;\n\t\t\t\t\tif (!input.jumpHeld || holdExpired) {\n\t\t\t\t\t\tgravityMul = vj.cutGravityMultiplier;\n\t\t\t\t\t\tstate.jumpCutApplied = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet newVy = ctx.velocityY - config.gravity * gravityMul * ctx.dt;\n\n\t\t\tif (config.maxFallSpeed != null) {\n\t\t\t\tnewVy = Math.max(-config.maxFallSpeed, newVy);\n\t\t\t}\n\n\t\t\tctx.setVerticalVelocity(newVy);\n\t\t} else {\n\t\t\t// Grounded: clamp Y to 0 so the entity doesn't drift\n\t\t\tctx.setVerticalVelocity(0);\n\t\t}\n\n\t\t// ── 6. Airborne planar control ─────────────────────────────────────\n\t\tconst airCtrl = config.planar?.airControl;\n\t\tif (airCtrl && !ctx.isGrounded) {\n\t\t\tconst dir = input.moveDirWorld;\n\t\t\tconst hasDir = dir && (Math.abs(dir.x) > 1e-6 || Math.abs(dir.z) > 1e-6);\n\n\t\t\tlet vx = ctx.horizontalVelocity.x;\n\t\t\tlet vz = ctx.horizontalVelocity.z;\n\n\t\t\tif (hasDir) {\n\t\t\t\tconst d = { x: dir!.x, y: 0, z: dir!.z };\n\t\t\t\tnormalizeMut(d);\n\n\t\t\t\tvx += d.x * airCtrl.acceleration * ctx.dt;\n\t\t\t\tvz += d.z * airCtrl.acceleration * ctx.dt;\n\n\t\t\t\tconst speed = Math.sqrt(vx * vx + vz * vz);\n\t\t\t\tif (speed > airCtrl.maxPlanarSpeed) {\n\t\t\t\t\tconst scale = airCtrl.maxPlanarSpeed / speed;\n\t\t\t\t\tvx *= scale;\n\t\t\t\t\tvz *= scale;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst speed = planarSpeed(vx, vz);\n\t\t\t\tif (speed > 1e-6) {\n\t\t\t\t\tconst decel = Math.min(airCtrl.deceleration * ctx.dt, speed);\n\t\t\t\t\tconst scale = (speed - decel) / speed;\n\t\t\t\t\tvx *= scale;\n\t\t\t\t\tvz *= scale;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.setHorizontalVelocity(vx, vz);\n\t\t}\n\n\t\treturn { event };\n\t}\n}\n\n/** Events emitted by a single tick (used by FSM). */\nexport enum JumperTickEvent {\n\tNone = 'none',\n\tJump = 'jump',\n\tFall = 'fall',\n\tLand = 'land',\n}\n\nexport interface JumperTickResult {\n\tevent: JumperTickEvent;\n}\n","/**\n * Jumper 3D Finite State Machine\n *\n * Three high-level states driven by events emitted from the behavior tick:\n * Grounded ──Jump──▶ Jumping\n * Grounded ──Fall──▶ Falling (walked off a ledge)\n * Jumping ──Fall──▶ Falling (apex / descending)\n * Jumping ──Jump──▶ Jumping (multi-jump)\n * Jumping ──Land──▶ Grounded (rare — very short hop)\n * Falling ──Land──▶ Grounded\n * Falling ──Jump──▶ Jumping (air-jump while falling)\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { JumpState3D } from './components';\n\nexport enum Jumper3DState {\n\tGrounded = 'grounded',\n\tJumping = 'jumping',\n\tFalling = 'falling',\n}\n\nexport enum Jumper3DEvent {\n\tJump = 'jump',\n\tFall = 'fall',\n\tLand = 'land',\n}\n\nexport interface Jumper3DFSMContext {\n\tstate: JumpState3D;\n}\n\nexport class Jumper3DFSM {\n\tmachine: SyncStateMachine<Jumper3DState, Jumper3DEvent, never>;\n\n\tconstructor(private ctx: Jumper3DFSMContext) {\n\t\tthis.machine = new SyncStateMachine<Jumper3DState, Jumper3DEvent, never>(\n\t\t\tJumper3DState.Grounded,\n\t\t\t[\n\t\t\t\t// Grounded\n\t\t\t\tt(Jumper3DState.Grounded, Jumper3DEvent.Jump, Jumper3DState.Jumping),\n\t\t\t\tt(Jumper3DState.Grounded, Jumper3DEvent.Fall, Jumper3DState.Falling),\n\t\t\t\tt(Jumper3DState.Grounded, Jumper3DEvent.Land, Jumper3DState.Grounded),\n\n\t\t\t\t// Jumping\n\t\t\t\tt(Jumper3DState.Jumping, Jumper3DEvent.Fall, Jumper3DState.Falling),\n\t\t\t\tt(Jumper3DState.Jumping, Jumper3DEvent.Land, Jumper3DState.Grounded),\n\t\t\t\tt(Jumper3DState.Jumping, Jumper3DEvent.Jump, Jumper3DState.Jumping),\n\n\t\t\t\t// Falling\n\t\t\t\tt(Jumper3DState.Falling, Jumper3DEvent.Land, Jumper3DState.Grounded),\n\t\t\t\tt(Jumper3DState.Falling, Jumper3DEvent.Jump, Jumper3DState.Jumping),\n\t\t\t\tt(Jumper3DState.Falling, Jumper3DEvent.Fall, Jumper3DState.Falling),\n\t\t\t],\n\t\t);\n\t}\n\n\tgetState(): Jumper3DState {\n\t\treturn this.machine.getState();\n\t}\n\n\tdispatch(event: Jumper3DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\tisJumping(): boolean {\n\t\treturn this.getState() === Jumper3DState.Jumping;\n\t}\n\n\tisFalling(): boolean {\n\t\treturn this.getState() === Jumper3DState.Falling;\n\t}\n\n\tisGrounded(): boolean {\n\t\treturn this.getState() === Jumper3DState.Grounded;\n\t}\n\n\tgetJumpsUsed(): number {\n\t\treturn this.ctx.state.jumpsUsed;\n\t}\n\n\t/**\n\t * Translate a tick event into an FSM dispatch.\n\t * Also handles the implicit Grounded→Falling transition when the entity\n\t * is no longer grounded but no explicit event was emitted (e.g. walked\n\t * off a ledge without jumping).\n\t */\n\tapplyTickEvent(tickEvent: string, isGrounded: boolean): void {\n\t\tswitch (tickEvent) {\n\t\t\tcase 'jump':\n\t\t\t\tthis.dispatch(Jumper3DEvent.Jump);\n\t\t\t\tbreak;\n\t\t\tcase 'fall':\n\t\t\t\tthis.dispatch(Jumper3DEvent.Fall);\n\t\t\t\tbreak;\n\t\t\tcase 'land':\n\t\t\t\tthis.dispatch(Jumper3DEvent.Land);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// No explicit event — detect implicit fall\n\t\t\t\tif (!isGrounded && this.getState() === Jumper3DState.Grounded) {\n\t\t\t\t\tthis.dispatch(Jumper3DEvent.Fall);\n\t\t\t\t}\n\t\t\t\tif (isGrounded && this.getState() !== Jumper3DState.Grounded) {\n\t\t\t\t\tthis.dispatch(Jumper3DEvent.Land);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n","/**\n * Jumper 3D Behavior Descriptor\n *\n * Type-safe descriptor for the jumper-3d behavior system.\n * Provides `entity.use()` API for composable 3D jumping.\n */\n\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { setVelocityIntent } from '../../actions/capabilities/velocity-intents';\nimport { Jumper3DBehavior } from './jumper-3d.behavior';\nimport { Jumper3DFSM, Jumper3DState } from './jumper-3d-fsm';\nimport {\n\tGroundProbe3D,\n\tgetGroundAnchorOffsetY,\n\tgetGroundSnapTargetY,\n\ttype GroundProbeSupportHit,\n} from '../shared/ground-probe-3d';\nimport {\n\tcreateJumpConfig3D,\n\tcreateJumpInput3D,\n\tcreateJumpState3D,\n\ttype JumpConfig3D,\n\ttype JumpInput3D,\n\ttype JumpState3D,\n\ttype JumpContext3D,\n} from './components';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Options exposed through entity.use()\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Jumper3DBehaviorOptions {\n\t/** Desired peak height in world units (default: 2.5) */\n\tjumpHeight?: number;\n\t/** Gravity magnitude applied by the behavior (default: 20) */\n\tgravity?: number;\n\t/** Terminal fall speed (optional) */\n\tmaxFallSpeed?: number;\n\t/** Max concurrent jumps, 1 = single, 2 = double, etc. (default: 1) */\n\tmaxJumps?: number;\n\t/** Reset jump counter on ground (default: true) */\n\tresetJumpsOnGround?: boolean;\n\t/** Reset jump counter on wall contact (default: undefined) */\n\tresetJumpsOnWall?: boolean;\n\t/** Coyote time in ms (default: 100) */\n\tcoyoteTimeMs?: number;\n\t/** Jump buffer in ms (default: 80) */\n\tjumpBufferMs?: number;\n\t/** Min cooldown between jumps in ms (optional) */\n\tminTimeBetweenJumpsMs?: number;\n\t/** Variable jump height config (optional) */\n\tvariableJump?: JumpConfig3D['variableJump'];\n\t/** Planar control config (optional) */\n\tplanar?: JumpConfig3D['planar'];\n\t/** Fall tuning (optional) */\n\tfall?: JumpConfig3D['fall'];\n\t/** Ground-detection ray length (default: 1.0) */\n\tgroundRayLength?: number;\n\t/** Max support distance that counts as grounded and can snap to ground */\n\tsnapToGroundDistance?: number;\n\t/** Enable debug visualization for ground probe rays (default: false) */\n\tdebugGroundProbe?: boolean;\n}\n\nconst defaultOptions: Jumper3DBehaviorOptions = {\n\tjumpHeight: 2.5,\n\tgravity: 20,\n\tmaxJumps: 1,\n\tresetJumpsOnGround: true,\n\tcoyoteTimeMs: 100,\n\tjumpBufferMs: 80,\n\tgroundRayLength: 1.0,\n\tdebugGroundProbe: false,\n};\n\nconst JUMPER_BEHAVIOR_KEY = Symbol.for('zylem:behavior:jumper-3d');\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Entity shape expected by the system\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface Jumper3DEntity {\n\tuuid: string;\n\tbody: any;\n\ttransformStore: any;\n\tjumper: JumpConfig3D;\n\t$jumper: JumpInput3D;\n\tjumperState: JumpState3D;\n}\n\nexport function isJumper3DGrounded(params: {\n\tsupportToi?: number | null;\n\tvelocityY: number;\n\tsnapToGroundDistance?: number;\n}): boolean {\n\tif (params.snapToGroundDistance != null) {\n\t\treturn (\n\t\t\tparams.supportToi != null &&\n\t\t\tparams.supportToi <= params.snapToGroundDistance &&\n\t\t\tparams.velocityY <= 0.25\n\t\t);\n\t}\n\n\treturn (\n\t\tparams.supportToi != null &&\n\t\tparams.velocityY > -2.0 &&\n\t\tparams.velocityY < 2.0\n\t);\n}\n\nfunction shouldSnapJumper3DToGround(\n\tsupport: GroundProbeSupportHit | null,\n\toptions: Jumper3DBehaviorOptions,\n\tvelocityY: number,\n): support is GroundProbeSupportHit {\n\treturn (\n\t\tsupport != null &&\n\t\toptions.snapToGroundDistance != null &&\n\t\tvelocityY <= 0.25 &&\n\t\tsupport.toi <= options.snapToGroundDistance\n\t);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Behavior System adapter\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass Jumper3DBehaviorSystem implements BehaviorSystem {\n\tprivate behavior = new Jumper3DBehavior();\n\tprivate groundProbe: GroundProbe3D;\n\tprivate initializedEntities = new Set<string>();\n\tprivate timeSinceGroundedMs = new Map<string, number>();\n\tprivate wasJumpHeld = new Map<string, boolean>();\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate scene: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {\n\t\tthis.groundProbe = new GroundProbe3D(world);\n\t}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(JUMPER_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst jumperRef = link.ref as any;\n\t\t\tif (!gameEntity.body) continue;\n\n\t\t\tconst options = jumperRef.options as Jumper3DBehaviorOptions;\n\n\t\t\t// ── Lazy component init ────────────────────────────────────────\n\t\t\tif (!gameEntity.jumper) {\n\t\t\t\tgameEntity.jumper = createJumpConfig3D(options);\n\t\t\t}\n\t\t\tif (!gameEntity.$jumper) {\n\t\t\t\tgameEntity.$jumper = createJumpInput3D();\n\t\t\t}\n\t\t\tif (!gameEntity.jumperState) {\n\t\t\t\tgameEntity.jumperState = createJumpState3D();\n\t\t\t}\n\n\t\t\tif (!this.initializedEntities.has(gameEntity.uuid)) {\n\t\t\t\tthis.initializedEntities.add(gameEntity.uuid);\n\t\t\t\tgameEntity.body.setGravityScale(0, true);\n\t\t\t}\n\n\t\t\t// ── Lazy FSM init ──────────────────────────────────────────────\n\t\t\tif (!jumperRef.fsm && gameEntity.jumperState) {\n\t\t\t\tjumperRef.fsm = new Jumper3DFSM({\n\t\t\t\t\tstate: gameEntity.jumperState,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// ── Ground detection ───────────────────────────────────────────\n\t\t\tconst rayLength = options.groundRayLength ?? 1.0;\n\t\t\tconst bodyVel = gameEntity.body.linvel();\n\t\t\tconst probeOriginYOffset = 0.05 - getGroundAnchorOffsetY(gameEntity);\n\t\t\tconst support = this.groundProbe.probeSupport(gameEntity, {\n\t\t\t\trayLength,\n\t\t\t\tmode: 'center',\n\t\t\t\tdebug: options.debugGroundProbe ?? false,\n\t\t\t\tscene: this.scene,\n\t\t\t\toriginYOffset: probeOriginYOffset,\n\t\t\t});\n\t\t\tconst isGrounded = isJumper3DGrounded({\n\t\t\t\tsupportToi: support?.toi ?? null,\n\t\t\t\tvelocityY: bodyVel.y,\n\t\t\t\tsnapToGroundDistance: options.snapToGroundDistance,\n\t\t\t});\n\t\t\tif (shouldSnapJumper3DToGround(support, options, bodyVel.y)) {\n\t\t\t\tconst currentPosition = gameEntity.body.translation();\n\t\t\t\tgameEntity.body.setTranslation(\n\t\t\t\t\t{\n\t\t\t\t\t\tx: currentPosition.x,\n\t\t\t\t\t\ty: getGroundSnapTargetY(gameEntity, support),\n\t\t\t\t\t\tz: currentPosition.z,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet tsg = this.timeSinceGroundedMs.get(gameEntity.uuid) ?? 0;\n\t\t\tif (isGrounded) {\n\t\t\t\ttsg = 0;\n\t\t\t} else {\n\t\t\t\ttsg += delta * 1000;\n\t\t\t}\n\t\t\tthis.timeSinceGroundedMs.set(gameEntity.uuid, tsg);\n\n\t\t\t// ── Build context ──────────────────────────────────────────────\n\t\t\t// Each behavior owns its own velocity axes. The jumper only\n\t\t\t// reads/writes Y; horizontal axes are left to the movement\n\t\t\t// controller. We read the current Y from the physics body\n\t\t\t// (post-step) so the jumper always sees the real vertical state.\n\t\t\tconst config: JumpConfig3D = gameEntity.jumper;\n\t\t\tconst input: JumpInput3D = gameEntity.$jumper;\n\t\t\tconst state: JumpState3D = gameEntity.jumperState;\n\t\t\tconst prevHeld = this.wasJumpHeld.get(gameEntity.uuid) ?? false;\n\t\t\tconst held = input.jumpHeld === true;\n\n\t\t\t// Input callbacks run after behavior systems in the frame loop.\n\t\t\t// Reconstruct button edges from held-state history so one-frame\n\t\t\t// `pressed`/`released` pulses are not missed by the jumper tick.\n\t\t\tconst effectiveInput: JumpInput3D = {\n\t\t\t\t...input,\n\t\t\t\tjumpPressed: input.jumpPressed || (held && !prevHeld),\n\t\t\t\tjumpReleased: input.jumpReleased || (!held && prevHeld),\n\t\t\t};\n\n\t\t\tconst store = gameEntity.transformStore;\n\n\t\t\tconst ctx: JumpContext3D = {\n\t\t\t\tdt: delta,\n\t\t\t\tup: { x: 0, y: 1, z: 0 },\n\t\t\t\tvelocityY: bodyVel.y,\n\t\t\t\thorizontalVelocity: { x: bodyVel.x, z: bodyVel.z },\n\t\t\t\tisGrounded,\n\t\t\t\ttimeSinceGroundedMs: tsg,\n\t\t\t\tsetVerticalVelocity: (y: number) => {\n\t\t\t\t\tsetVelocityIntent(\n\t\t\t\t\t\tstore,\n\t\t\t\t\t\t'jumper-3d',\n\t\t\t\t\t\t{ y },\n\t\t\t\t\t\t{ mode: 'replace', priority: 20 },\n\t\t\t\t\t);\n\t\t\t\t\tctx.velocityY = y;\n\t\t\t\t},\n\t\t\t\tsetHorizontalVelocity: (x: number, z: number) => {\n\t\t\t\t\tsetVelocityIntent(\n\t\t\t\t\t\tstore,\n\t\t\t\t\t\t'jumper-3d',\n\t\t\t\t\t\t{ x, z },\n\t\t\t\t\t\t{ mode: 'replace', priority: 20 },\n\t\t\t\t\t);\n\t\t\t\t\tctx.horizontalVelocity.x = x;\n\t\t\t\t\tctx.horizontalVelocity.z = z;\n\t\t\t\t},\n\t\t\t};\n\n\t\t\t// ── Tick ───────────────────────────────────────────────────────\n\t\t\tconst result = this.behavior.tick(config, effectiveInput, ctx, state);\n\t\t\tthis.wasJumpHeld.set(gameEntity.uuid, held);\n\n\t\t\t// ── FSM sync ───────────────────────────────────────────────────\n\t\t\tif (jumperRef.fsm) {\n\t\t\t\t(jumperRef.fsm as Jumper3DFSM).applyTickEvent(\n\t\t\t\t\tresult.event,\n\t\t\t\t\tisGrounded,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\tthis.groundProbe.destroy();\n\t\tthis.initializedEntities.clear();\n\t\tthis.timeSinceGroundedMs.clear();\n\t\tthis.wasJumpHeld.clear();\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public descriptor\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Jumper3D — composable 3D jump behavior.\n *\n * Provides height-based jumping, multi-jump, coyote time, jump buffering,\n * variable jump height, configurable fall gravity, and optional air control.\n *\n * Designed to compose with any movement controller (e.g. FirstPersonController)\n * — the controller writes X/Z velocity and Jumper3D writes Y velocity.\n *\n * @example\n * ```typescript\n * import { Jumper3D } from \"@zylem/game-lib\";\n *\n * const jumper = player.use(Jumper3D, {\n * jumpHeight: 2.5,\n * gravity: 20,\n * maxJumps: 2,\n * coyoteTimeMs: 100,\n * jumpBufferMs: 80,\n * variableJump: { enabled: true, cutGravityMultiplier: 3 },\n * fall: { fallGravityMultiplier: 1.5 },\n * });\n *\n * player.onUpdate(({ inputs }) => {\n * player.$jumper.jumpPressed = inputs.p1.buttons.A.pressed;\n * player.$jumper.jumpHeld = inputs.p1.buttons.A.held > 0;\n * player.$jumper.jumpReleased = inputs.p1.buttons.A.released;\n *\n * const state = jumper.getState(); // Grounded | Jumping | Falling\n * });\n * ```\n */\nexport const Jumper3D = defineBehavior<\n\tJumper3DBehaviorOptions,\n\t{\n\t\tgetState: () => Jumper3DState;\n\t\tisJumping: () => boolean;\n\t\tgetJumpsUsed: () => number;\n\t\tgetJumpsRemaining: () => number;\n\t},\n\tJumper3DEntity\n>({\n\tname: 'jumper-3d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew Jumper3DBehaviorSystem(\n\t\t\tctx.world,\n\t\t\tctx.scene,\n\t\t\tctx.getBehaviorLinks,\n\t\t),\n\tcreateHandle: (ref) => ({\n\t\tgetState: () =>\n\t\t\t(ref.fsm as Jumper3DFSM | undefined)?.getState() ??\n\t\t\tJumper3DState.Grounded,\n\t\tisJumping: () =>\n\t\t\t(ref.fsm as Jumper3DFSM | undefined)?.isJumping() ?? false,\n\t\tgetJumpsUsed: () =>\n\t\t\t(ref.fsm as Jumper3DFSM | undefined)?.getJumpsUsed() ?? 0,\n\t\tgetJumpsRemaining: () => {\n\t\t\tconst maxJumps = ref.options.maxJumps ?? 1;\n\t\t\tconst used =\n\t\t\t\t(ref.fsm as Jumper3DFSM | undefined)?.getJumpsUsed() ?? 0;\n\t\t\treturn maxJumps - used;\n\t\t},\n\t}),\n});\n","export interface JumpConfig2D {\n\tjumpHeight: number;\n\tgravity: number;\n\tmaxFallSpeed?: number;\n\tmaxJumps: number;\n\tresetJumpsOnGround: boolean;\n\tcoyoteTimeMs: number;\n\tjumpBufferMs: number;\n\tminTimeBetweenJumpsMs?: number;\n\tvariableJump?: {\n\t\tenabled: boolean;\n\t\tcutGravityMultiplier: number;\n\t\tmaxHoldMs?: number;\n\t};\n}\n\nexport function createJumpConfig2D(\n\toptions: Partial<JumpConfig2D> = {},\n): JumpConfig2D {\n\treturn {\n\t\tjumpHeight: options.jumpHeight ?? 2.5,\n\t\tgravity: options.gravity ?? 20,\n\t\tmaxFallSpeed: options.maxFallSpeed,\n\t\tmaxJumps: options.maxJumps ?? 1,\n\t\tresetJumpsOnGround: options.resetJumpsOnGround ?? true,\n\t\tcoyoteTimeMs: options.coyoteTimeMs ?? 100,\n\t\tjumpBufferMs: options.jumpBufferMs ?? 80,\n\t\tminTimeBetweenJumpsMs: options.minTimeBetweenJumpsMs,\n\t\tvariableJump: options.variableJump,\n\t};\n}\n\nexport interface JumpInput2D {\n\tjumpPressed: boolean;\n\tjumpHeld: boolean;\n\tjumpReleased: boolean;\n\tfastFall?: boolean;\n}\n\nexport function createJumpInput2D(): JumpInput2D {\n\treturn {\n\t\tjumpPressed: false,\n\t\tjumpHeld: false,\n\t\tjumpReleased: false,\n\t\tfastFall: false,\n\t};\n}\n\nexport interface JumpContext2D {\n\tdt: number;\n\tvelocityY: number;\n\tisGrounded: boolean;\n\ttimeSinceGroundedMs: number;\n\tsetVerticalVelocity(y: number): void;\n}\n\nexport interface JumpState2D {\n\tjumpsUsed: number;\n\tlastJumpTimeMs: number;\n\tbufferedJumpMs: number;\n\tcoyoteMs: number;\n\tisJumping: boolean;\n\tjumpHoldMs: number;\n\tjumpCutApplied: boolean;\n}\n\nexport function createJumpState2D(): JumpState2D {\n\treturn {\n\t\tjumpsUsed: 0,\n\t\tlastJumpTimeMs: 0,\n\t\tbufferedJumpMs: 0,\n\t\tcoyoteMs: 0,\n\t\tisJumping: false,\n\t\tjumpHoldMs: 0,\n\t\tjumpCutApplied: false,\n\t};\n}\n","import type {\n\tJumpConfig2D,\n\tJumpContext2D,\n\tJumpInput2D,\n\tJumpState2D,\n} from './components';\n\nfunction jumpVelocityFromHeight(gravity: number, height: number): number {\n\treturn Math.sqrt(2 * gravity * height);\n}\n\nexport enum Jumper2DTickEvent {\n\tNone = 'none',\n\tJump = 'jump',\n\tFall = 'fall',\n\tLand = 'land',\n}\n\nexport interface Jumper2DTickResult {\n\tevent: Jumper2DTickEvent;\n}\n\nexport class Jumper2DBehavior {\n\ttick(\n\t\tconfig: JumpConfig2D,\n\t\tinput: JumpInput2D,\n\t\tctx: JumpContext2D,\n\t\tstate: JumpState2D,\n\t): Jumper2DTickResult {\n\t\tconst dtMs = ctx.dt * 1000;\n\t\tconst now = performance.now();\n\t\tlet event = Jumper2DTickEvent.None;\n\t\tlet jumpedThisFrame = false;\n\n\t\tif (ctx.isGrounded) {\n\t\t\tstate.coyoteMs = config.coyoteTimeMs;\n\t\t\tif (config.resetJumpsOnGround) {\n\t\t\t\tstate.jumpsUsed = 0;\n\t\t\t}\n\t\t\tif (state.isJumping) {\n\t\t\t\tstate.isJumping = false;\n\t\t\t\tstate.jumpCutApplied = false;\n\t\t\t\tevent = Jumper2DTickEvent.Land;\n\t\t\t}\n\t\t} else {\n\t\t\tstate.coyoteMs = Math.max(0, state.coyoteMs - dtMs);\n\t\t}\n\n\t\tif (input.jumpPressed) {\n\t\t\tstate.bufferedJumpMs = config.jumpBufferMs;\n\t\t} else {\n\t\t\tstate.bufferedJumpMs = Math.max(0, state.bufferedJumpMs - dtMs);\n\t\t}\n\n\t\tif (state.isJumping && input.jumpHeld) {\n\t\t\tstate.jumpHoldMs += dtMs;\n\t\t}\n\n\t\tconst wantsJump = state.bufferedJumpMs > 0;\n\t\tconst isFirstJump =\n\t\t\tctx.isGrounded || (state.coyoteMs > 0 && state.jumpsUsed === 0);\n\t\tconst hasAirJumps = state.jumpsUsed > 0 && state.jumpsUsed < config.maxJumps;\n\t\tconst canJump = isFirstJump || hasAirJumps;\n\t\tconst cooldownOk =\n\t\t\tconfig.minTimeBetweenJumpsMs == null ||\n\t\t\tnow - state.lastJumpTimeMs >= config.minTimeBetweenJumpsMs;\n\n\t\tif (wantsJump && canJump && cooldownOk) {\n\t\t\tctx.setVerticalVelocity(jumpVelocityFromHeight(config.gravity, config.jumpHeight));\n\t\t\tjumpedThisFrame = true;\n\t\t\tstate.jumpsUsed++;\n\t\t\tstate.lastJumpTimeMs = now;\n\t\t\tstate.bufferedJumpMs = 0;\n\t\t\tstate.coyoteMs = 0;\n\t\t\tstate.isJumping = true;\n\t\t\tstate.jumpHoldMs = 0;\n\t\t\tstate.jumpCutApplied = false;\n\t\t\tevent = Jumper2DTickEvent.Jump;\n\t\t}\n\n\t\tif (!ctx.isGrounded || jumpedThisFrame) {\n\t\t\tlet gravityMul = 1;\n\t\t\tconst isFalling = ctx.velocityY < 0;\n\n\t\t\tif (isFalling) {\n\t\t\t\tgravityMul = input.fastFall ? 1.75 : 1;\n\t\t\t\tif (event !== Jumper2DTickEvent.Land) {\n\t\t\t\t\tevent = Jumper2DTickEvent.Fall;\n\t\t\t\t}\n\t\t\t} else if (state.isJumping) {\n\t\t\t\tconst variableJump = config.variableJump;\n\t\t\t\tif (variableJump?.enabled && !state.jumpCutApplied) {\n\t\t\t\t\tconst holdExpired =\n\t\t\t\t\t\tvariableJump.maxHoldMs != null &&\n\t\t\t\t\t\tstate.jumpHoldMs >= variableJump.maxHoldMs;\n\t\t\t\t\tif (!input.jumpHeld || holdExpired) {\n\t\t\t\t\t\tgravityMul = variableJump.cutGravityMultiplier;\n\t\t\t\t\t\tstate.jumpCutApplied = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet newVelocityY = ctx.velocityY - config.gravity * gravityMul * ctx.dt;\n\t\t\tif (config.maxFallSpeed != null) {\n\t\t\t\tnewVelocityY = Math.max(-config.maxFallSpeed, newVelocityY);\n\t\t\t}\n\t\t\tctx.setVerticalVelocity(newVelocityY);\n\t\t} else {\n\t\t\tctx.setVerticalVelocity(0);\n\t\t}\n\n\t\treturn { event };\n\t}\n}\n","import { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { JumpState2D } from './components';\n\nexport enum Jumper2DState {\n\tGrounded = 'grounded',\n\tJumping = 'jumping',\n\tFalling = 'falling',\n}\n\nexport enum Jumper2DEvent {\n\tJump = 'jump',\n\tFall = 'fall',\n\tLand = 'land',\n}\n\nexport interface Jumper2DFSMContext {\n\tstate: JumpState2D;\n}\n\nexport class Jumper2DFSM {\n\tmachine: SyncStateMachine<Jumper2DState, Jumper2DEvent, never>;\n\n\tconstructor(private ctx: Jumper2DFSMContext) {\n\t\tthis.machine = new SyncStateMachine<Jumper2DState, Jumper2DEvent, never>(\n\t\t\tJumper2DState.Grounded,\n\t\t\t[\n\t\t\t\tt(Jumper2DState.Grounded, Jumper2DEvent.Jump, Jumper2DState.Jumping),\n\t\t\t\tt(Jumper2DState.Grounded, Jumper2DEvent.Fall, Jumper2DState.Falling),\n\t\t\t\tt(Jumper2DState.Grounded, Jumper2DEvent.Land, Jumper2DState.Grounded),\n\t\t\t\tt(Jumper2DState.Jumping, Jumper2DEvent.Fall, Jumper2DState.Falling),\n\t\t\t\tt(Jumper2DState.Jumping, Jumper2DEvent.Land, Jumper2DState.Grounded),\n\t\t\t\tt(Jumper2DState.Jumping, Jumper2DEvent.Jump, Jumper2DState.Jumping),\n\t\t\t\tt(Jumper2DState.Falling, Jumper2DEvent.Land, Jumper2DState.Grounded),\n\t\t\t\tt(Jumper2DState.Falling, Jumper2DEvent.Jump, Jumper2DState.Jumping),\n\t\t\t\tt(Jumper2DState.Falling, Jumper2DEvent.Fall, Jumper2DState.Falling),\n\t\t\t],\n\t\t);\n\t}\n\n\tgetState(): Jumper2DState {\n\t\treturn this.machine.getState();\n\t}\n\n\tdispatch(event: Jumper2DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\tisJumping(): boolean {\n\t\treturn this.getState() === Jumper2DState.Jumping;\n\t}\n\n\tisGrounded(): boolean {\n\t\treturn this.getState() === Jumper2DState.Grounded;\n\t}\n\n\tgetJumpsUsed(): number {\n\t\treturn this.ctx.state.jumpsUsed;\n\t}\n\n\tapplyTickEvent(tickEvent: string, isGrounded: boolean): void {\n\t\tswitch (tickEvent) {\n\t\t\tcase 'jump':\n\t\t\t\tthis.dispatch(Jumper2DEvent.Jump);\n\t\t\t\tbreak;\n\t\t\tcase 'fall':\n\t\t\t\tthis.dispatch(Jumper2DEvent.Fall);\n\t\t\t\tbreak;\n\t\t\tcase 'land':\n\t\t\t\tthis.dispatch(Jumper2DEvent.Land);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (!isGrounded && this.getState() === Jumper2DState.Grounded) {\n\t\t\t\t\tthis.dispatch(Jumper2DEvent.Fall);\n\t\t\t\t}\n\t\t\t\tif (isGrounded && this.getState() !== Jumper2DState.Grounded) {\n\t\t\t\t\tthis.dispatch(Jumper2DEvent.Land);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n","import type { IWorld } from 'bitecs';\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { setVelocityIntent } from '../../actions/capabilities/velocity-intents';\nimport {\n\tGroundProbe3D,\n\tgetGroundAnchorOffsetY,\n\tgetGroundSnapTargetY,\n\ttype GroundProbeSupportHit,\n} from '../shared/ground-probe-3d';\nimport {\n\tcreateJumpConfig2D,\n\tcreateJumpInput2D,\n\tcreateJumpState2D,\n\ttype JumpConfig2D,\n\ttype JumpContext2D,\n\ttype JumpInput2D,\n\ttype JumpState2D,\n} from './components';\nimport {\n\tJumper2DBehavior,\n\tJumper2DTickEvent,\n} from './jumper-2d.behavior';\nimport { Jumper2DFSM, Jumper2DState } from './jumper-2d-fsm';\n\nexport interface Jumper2DBehaviorOptions {\n\tjumpHeight?: number;\n\tgravity?: number;\n\tmaxFallSpeed?: number;\n\tmaxJumps?: number;\n\tresetJumpsOnGround?: boolean;\n\tcoyoteTimeMs?: number;\n\tjumpBufferMs?: number;\n\tminTimeBetweenJumpsMs?: number;\n\tvariableJump?: JumpConfig2D['variableJump'];\n\tgroundRayLength?: number;\n\tsnapToGroundDistance?: number;\n\tdebugGroundProbe?: boolean;\n}\n\nconst defaultOptions: Jumper2DBehaviorOptions = {\n\tjumpHeight: 2.5,\n\tgravity: 20,\n\tmaxJumps: 1,\n\tresetJumpsOnGround: true,\n\tcoyoteTimeMs: 100,\n\tjumpBufferMs: 80,\n\tgroundRayLength: 1,\n\tdebugGroundProbe: false,\n};\n\nconst JUMPER_2D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:jumper-2d');\nconst JUMPER_2D_OFFSETS = [\n\t{ x: 0, z: 0 },\n\t{ x: 0.35, z: 0 },\n\t{ x: -0.35, z: 0 },\n] as const;\n\nexport function isJumper2DGrounded(params: {\n\tnearGround?: boolean;\n\tvelocityY: number;\n\tsupportToi?: number | null;\n\tsnapToGroundDistance?: number;\n}): boolean {\n\tif (params.velocityY > 0) {\n\t\treturn false;\n\t}\n\n\tif (params.snapToGroundDistance != null) {\n\t\treturn (\n\t\t\tparams.supportToi != null &&\n\t\t\tparams.supportToi <= params.snapToGroundDistance\n\t\t);\n\t}\n\n\treturn params.nearGround === true;\n}\n\nfunction shouldSnapJumper2DToGround(\n\tsupport: GroundProbeSupportHit | null,\n\toptions: Jumper2DBehaviorOptions,\n\tvelocityY: number,\n): support is GroundProbeSupportHit {\n\treturn (\n\t\tsupport != null &&\n\t\toptions.snapToGroundDistance != null &&\n\t\tvelocityY <= 0 &&\n\t\tsupport.toi <= options.snapToGroundDistance\n\t);\n}\n\nexport interface Jumper2DEntity {\n\tuuid: string;\n\tbody: any;\n\ttransformStore: any;\n\tjumper2d: JumpConfig2D;\n\t$jumper2d: JumpInput2D;\n\tjumper2dState: JumpState2D;\n}\n\nclass Jumper2DBehaviorSystem implements BehaviorSystem {\n\tprivate behavior = new Jumper2DBehavior();\n\tprivate groundProbe: GroundProbe3D;\n\tprivate initializedEntities = new Set<string>();\n\tprivate timeSinceGroundedMs = new Map<string, number>();\n\tprivate wasJumpHeld = new Map<string, boolean>();\n\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate scene: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {\n\t\tthis.groundProbe = new GroundProbe3D(world);\n\t}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(JUMPER_2D_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst jumperRef = link.ref as any;\n\t\t\tif (!gameEntity.body) continue;\n\n\t\t\tconst options = jumperRef.options as Jumper2DBehaviorOptions;\n\n\t\t\tif (!gameEntity.jumper2d) {\n\t\t\t\tgameEntity.jumper2d = createJumpConfig2D(options);\n\t\t\t}\n\t\t\tif (!gameEntity.$jumper2d) {\n\t\t\t\tgameEntity.$jumper2d = createJumpInput2D();\n\t\t\t}\n\t\t\tif (!gameEntity.jumper2dState) {\n\t\t\t\tgameEntity.jumper2dState = createJumpState2D();\n\t\t\t}\n\t\t\tif (!this.initializedEntities.has(gameEntity.uuid)) {\n\t\t\t\tthis.initializedEntities.add(gameEntity.uuid);\n\t\t\t\tgameEntity.body.setGravityScale(0, true);\n\t\t\t}\n\t\t\tif (!jumperRef.fsm && gameEntity.jumper2dState) {\n\t\t\t\tjumperRef.fsm = new Jumper2DFSM({\n\t\t\t\t\tstate: gameEntity.jumper2dState,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst rayLength = options.groundRayLength ?? 1;\n\t\t\tconst bodyVelocity = gameEntity.body.linvel();\n\t\t\tconst probeOriginYOffset = 0.05 - getGroundAnchorOffsetY(gameEntity);\n\t\t\tconst support = this.groundProbe.probeSupport(gameEntity, {\n\t\t\t\trayLength,\n\t\t\t\toffsets: JUMPER_2D_OFFSETS,\n\t\t\t\tmode: 'any',\n\t\t\t\tdebug: options.debugGroundProbe ?? false,\n\t\t\t\tscene: this.scene,\n\t\t\t\toriginYOffset: probeOriginYOffset,\n\t\t\t});\n\t\t\tconst nearGround = support != null;\n\t\t\tconst isGrounded = isJumper2DGrounded({\n\t\t\t\tnearGround,\n\t\t\t\tvelocityY: bodyVelocity.y,\n\t\t\t\tsupportToi: support?.toi ?? null,\n\t\t\t\tsnapToGroundDistance: options.snapToGroundDistance,\n\t\t\t});\n\t\t\tif (shouldSnapJumper2DToGround(support, options, bodyVelocity.y)) {\n\t\t\t\tconst currentPosition = gameEntity.body.translation();\n\t\t\t\tgameEntity.body.setTranslation(\n\t\t\t\t\t{\n\t\t\t\t\t\tx: currentPosition.x,\n\t\t\t\t\t\ty: getGroundSnapTargetY(gameEntity, support),\n\t\t\t\t\t\tz: currentPosition.z,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet timeSinceGroundedMs = this.timeSinceGroundedMs.get(gameEntity.uuid) ?? 0;\n\t\t\tif (isGrounded) {\n\t\t\t\ttimeSinceGroundedMs = 0;\n\t\t\t} else {\n\t\t\t\ttimeSinceGroundedMs += delta * 1000;\n\t\t\t}\n\t\t\tthis.timeSinceGroundedMs.set(gameEntity.uuid, timeSinceGroundedMs);\n\n\t\t\tconst config: JumpConfig2D = gameEntity.jumper2d;\n\t\t\tconst input: JumpInput2D = gameEntity.$jumper2d;\n\t\t\tconst state: JumpState2D = gameEntity.jumper2dState;\n\t\t\tconst previousHeld = this.wasJumpHeld.get(gameEntity.uuid) ?? false;\n\t\t\tconst held = input.jumpHeld === true;\n\t\t\tconst effectiveInput: JumpInput2D = {\n\t\t\t\t...input,\n\t\t\t\tjumpPressed: input.jumpPressed || (held && !previousHeld),\n\t\t\t\tjumpReleased: input.jumpReleased || (!held && previousHeld),\n\t\t\t};\n\n\t\t\tconst store = gameEntity.transformStore;\n\t\t\tconst ctx: JumpContext2D = {\n\t\t\t\tdt: delta,\n\t\t\t\tvelocityY: bodyVelocity.y,\n\t\t\t\tisGrounded,\n\t\t\t\ttimeSinceGroundedMs,\n\t\t\t\tsetVerticalVelocity: (y: number) => {\n\t\t\t\t\tsetVelocityIntent(\n\t\t\t\t\t\tstore,\n\t\t\t\t\t\t'jumper-2d',\n\t\t\t\t\t\t{ y },\n\t\t\t\t\t\t{ mode: 'replace', priority: 20 },\n\t\t\t\t\t);\n\t\t\t\t\tctx.velocityY = y;\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst result = this.behavior.tick(config, effectiveInput, ctx, state);\n\t\t\tthis.wasJumpHeld.set(gameEntity.uuid, held);\n\n\t\t\tif (jumperRef.fsm) {\n\t\t\t\t(jumperRef.fsm as Jumper2DFSM).applyTickEvent(result.event, isGrounded);\n\t\t\t}\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {\n\t\tthis.groundProbe.destroy();\n\t\tthis.initializedEntities.clear();\n\t\tthis.timeSinceGroundedMs.clear();\n\t\tthis.wasJumpHeld.clear();\n\t}\n}\n\nexport const Jumper2D = defineBehavior<\n\tJumper2DBehaviorOptions,\n\t{\n\t\tgetState: () => Jumper2DState;\n\t\tisJumping: () => boolean;\n\t\tgetJumpsUsed: () => number;\n\t\tgetJumpsRemaining: () => number;\n\t},\n\tJumper2DEntity\n>({\n\tname: 'jumper-2d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew Jumper2DBehaviorSystem(ctx.world, ctx.scene, ctx.getBehaviorLinks),\n\tcreateHandle: (ref) => ({\n\t\tgetState: () =>\n\t\t\t(ref.fsm as Jumper2DFSM | undefined)?.getState() ??\n\t\t\tJumper2DState.Grounded,\n\t\tisJumping: () =>\n\t\t\t(ref.fsm as Jumper2DFSM | undefined)?.isJumping() ?? false,\n\t\tgetJumpsUsed: () =>\n\t\t\t(ref.fsm as Jumper2DFSM | undefined)?.getJumpsUsed() ?? 0,\n\t\tgetJumpsRemaining: () => {\n\t\t\tconst maxJumps = ref.options.maxJumps ?? 1;\n\t\t\tconst used =\n\t\t\t\t(ref.fsm as Jumper2DFSM | undefined)?.getJumpsUsed() ?? 0;\n\t\t\treturn maxJumps - used;\n\t\t},\n\t}),\n});\n","import { proxy } from 'valtio';\n\n/**\n * A single cooldown entry in the global store.\n */\nexport interface CooldownEntry {\n\t/** Identifier for this cooldown */\n\tname: string;\n\t/** Total cooldown time in seconds */\n\tduration: number;\n\t/** Time accumulated since last fire */\n\telapsed: number;\n\t/** Whether the cooldown is ready (elapsed >= duration) */\n\tready: boolean;\n\t/** Normalized progress 0..1 (0 = just fired, 1 = ready) */\n\tprogress: number;\n\t/** Whether this cooldown is currently counting down */\n\tactive: boolean;\n}\n\n/**\n * Global reactive cooldown registry (valtio proxy).\n * Accessible from entities, behaviors, and UI components.\n */\nconst cooldownStore = proxy<Record<string, CooldownEntry>>({});\n\n/**\n * Register a named cooldown in the global store.\n * If a cooldown with the same name already exists, it is overwritten.\n *\n * @param name Unique cooldown identifier\n * @param duration Cooldown duration in seconds\n * @param immediate If true, the cooldown starts ready (default: true)\n */\nexport function registerCooldown(\n\tname: string,\n\tduration: number,\n\timmediate: boolean = true,\n): void {\n\tcooldownStore[name] = {\n\t\tname,\n\t\tduration,\n\t\telapsed: immediate ? duration : 0,\n\t\tready: immediate,\n\t\tprogress: immediate ? 1 : 0,\n\t\tactive: !immediate,\n\t};\n}\n\n/**\n * Get a cooldown entry by name.\n * Returns undefined if the cooldown has not been registered.\n */\nexport function getCooldown(name: string): CooldownEntry | undefined {\n\treturn cooldownStore[name];\n}\n\n/**\n * Fire (trigger) a cooldown, resetting its timer.\n * Sets the cooldown to not-ready and starts the countdown.\n */\nexport function fireCooldown(name: string): void {\n\tconst entry = cooldownStore[name];\n\tif (!entry) return;\n\tentry.elapsed = 0;\n\tentry.ready = false;\n\tentry.progress = 0;\n\tentry.active = true;\n}\n\n/**\n * Force a cooldown to ready immediately.\n */\nexport function resetCooldown(name: string): void {\n\tconst entry = cooldownStore[name];\n\tif (!entry) return;\n\tentry.elapsed = entry.duration;\n\tentry.ready = true;\n\tentry.progress = 1;\n\tentry.active = false;\n}\n\n/**\n * Advance all active cooldowns by delta seconds.\n * Called once per frame by the CooldownBehavior system.\n */\nexport function tickCooldowns(delta: number): void {\n\tfor (const name in cooldownStore) {\n\t\tconst entry = cooldownStore[name];\n\t\tif (!entry.active) continue;\n\n\t\tentry.elapsed += delta;\n\t\tif (entry.elapsed >= entry.duration) {\n\t\t\tentry.elapsed = entry.duration;\n\t\t\tentry.ready = true;\n\t\t\tentry.progress = 1;\n\t\t\tentry.active = false;\n\t\t} else {\n\t\t\tentry.progress = entry.duration > 0 ? entry.elapsed / entry.duration : 1;\n\t\t}\n\t}\n}\n\n/**\n * Get the raw cooldown store (for advanced/debugging use).\n */\nexport function getCooldownStore(): Record<string, CooldownEntry> {\n\treturn cooldownStore;\n}\n","/**\n * CooldownBehavior\n *\n * A stage-scoped behavior that manages named cooldowns via the global CooldownStore.\n * Entities use this to register, check, and fire cooldowns.\n * UI components (CooldownIcon) can read from the same store.\n */\n\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport {\n\tregisterCooldown,\n\tgetCooldown,\n\tfireCooldown,\n\tresetCooldown,\n\ttickCooldowns,\n} from './cooldown-store';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Options\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface CooldownConfig {\n\t/** Duration in seconds */\n\tduration: number;\n\t/** Whether the cooldown starts ready (default: true) */\n\timmediate?: boolean;\n}\n\nexport interface CooldownOptions {\n\t/**\n\t * Named cooldowns to register.\n\t * Keys are the cooldown names, values are their config.\n\t */\n\tcooldowns: Record<string, CooldownConfig>;\n}\n\ninterface CompiledCooldownEntry {\n\tname: string;\n\tduration: number;\n\timmediate: boolean;\n}\n\nconst COOLDOWN_BEHAVIOR_KEY = Symbol.for('zylem:behavior:cooldown');\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Handle\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Handle methods returned by entity.use(CooldownBehavior, ...).\n */\nexport interface CooldownHandle {\n\t/** Check if a named cooldown is ready */\n\tisReady(name: string): boolean;\n\t/** Fire (trigger) a named cooldown, resetting its timer */\n\tfire(name: string): void;\n\t/** Force a cooldown to ready immediately */\n\treset(name: string): void;\n\t/** Get cooldown progress 0..1 (0 = just fired, 1 = ready) */\n\tgetProgress(name: string): number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// System\n// ─────────────────────────────────────────────────────────────────────────────\n\nclass CooldownSystem implements BehaviorSystem {\n\tconstructor(\n\t\tprivate world: any,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) { }\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(COOLDOWN_BEHAVIOR_KEY);\n\t\tif (links) {\n\t\t\tfor (const link of links) {\n\t\t\t\tensureCooldownEntriesRegistered(link.ref as BehaviorRef<CooldownOptions>);\n\t\t\t}\n\t\t}\n\n\t\t// Tick all active cooldowns\n\t\ttickCooldowns(delta);\n\t}\n\n\tdestroy(_ecs: IWorld): void { }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Handle factory\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction createCooldownHandle(ref: BehaviorRef<CooldownOptions>): CooldownHandle {\n\tensureCooldownEntriesRegistered(ref);\n\n\treturn {\n\t\tisReady: (name: string) => getCooldown(name)?.ready ?? false,\n\t\tfire: (name: string) => fireCooldown(name),\n\t\treset: (name: string) => resetCooldown(name),\n\t\tgetProgress: (name: string) => getCooldown(name)?.progress ?? 1,\n\t};\n}\n\nfunction getCompiledCooldownEntries(\n\tref: BehaviorRef<CooldownOptions>,\n): CompiledCooldownEntry[] {\n\tconst compiled = (ref as any).__compiledCooldownEntries as CompiledCooldownEntry[] | undefined;\n\tif (compiled) return compiled;\n\n\tconst entries = Object.entries(ref.options.cooldowns).map(([name, config]) => ({\n\t\tname,\n\t\tduration: config.duration,\n\t\timmediate: config.immediate ?? true,\n\t}));\n\t(ref as any).__compiledCooldownEntries = entries;\n\treturn entries;\n}\n\nfunction ensureCooldownEntriesRegistered(ref: BehaviorRef<CooldownOptions>): void {\n\tif ((ref as any).__cooldownsRegistered) return;\n\n\tfor (const entry of getCompiledCooldownEntries(ref)) {\n\t\tregisterCooldown(entry.name, entry.duration, entry.immediate);\n\t}\n\n\t(ref as any).__cooldownsRegistered = true;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Behavior Definition\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * CooldownBehavior\n *\n * @example\n * ```ts\n * import { CooldownBehavior, moveBy } from '@zylem/game-lib';\n *\n * const hero = createBox({ ... });\n * const cd = hero.use(CooldownBehavior, {\n * cooldowns: {\n * attack: { duration: 5 },\n * dash: { duration: 2, immediate: false },\n * },\n * });\n *\n * hero.onUpdate(({ me, inputs }) => {\n * if (cd.isReady('attack') && inputs.p1.buttons.A.pressed) {\n * cd.fire('attack');\n * // perform attack\n * }\n * if (cd.isReady('dash') && inputs.p1.buttons.B.pressed) {\n * cd.fire('dash');\n * me.runAction(moveBy({ x: 10, duration: 0.3 }));\n * }\n * });\n * ```\n */\nexport const CooldownBehavior = defineBehavior<CooldownOptions, CooldownHandle>({\n\tname: 'cooldown',\n\tdefaultOptions: { cooldowns: {} },\n\tsystemFactory: (ctx) =>\n\t\tnew CooldownSystem(ctx.world, ctx.getBehaviorLinks),\n\tcreateHandle: createCooldownHandle,\n});\n","import { GameEntity } from '../entities/entity';\nimport { Ricochet2DHandle } from '../behaviors/ricochet-2d/ricochet-2d.descriptor';\nimport { WorldBoundary2DHandle } from '../behaviors/world-boundary-2d/world-boundary-2d.descriptor';\nimport { MoveableEntity } from '../actions/capabilities/moveable';\nimport { getBounds2DNormalFromHits } from '../behaviors/shared/bounds-2d';\n\n/**\n * Coordinator that bridges WorldBoundary2DBehavior and Ricochet2DBehavior.\n * \n * Automatically handles:\n * 1. Checking boundary hits\n * 2. Computing collision normals\n * 3. Requesting ricochet result\n * 4. Applying movement\n */\nexport class BoundaryRicochetCoordinator {\n constructor(\n private entity: GameEntity<any> & MoveableEntity,\n private boundary: WorldBoundary2DHandle,\n private ricochet: Ricochet2DHandle\n ) {}\n\n /**\n * Update loop - call this every frame.\n * Applies ricochet via transformStore and notifies listeners.\n * \n * @returns true if ricochet was applied, false otherwise\n */\n public update(): boolean {\n const hits = this.boundary.getLastHits();\n if (!hits) return false;\n\n const anyHit = hits.left || hits.right || hits.top || hits.bottom;\n if (!anyHit) return false;\n\n const normal = getBounds2DNormalFromHits(hits);\n\n // Apply ricochet (also emits to listeners)\n return this.ricochet.applyRicochet({\n entity: this.entity,\n contact: { normal: { x: normal.x, y: normal.y } },\n });\n }\n}\n","import { GameEntity } from '../entities/entity';\nimport type { MoveableEntity } from '../actions/capabilities/moveable';\nimport type { Ricochet3DHandle } from '../behaviors/ricochet-3d/ricochet-3d.descriptor';\nimport type { WorldBoundary3DHandle } from '../behaviors/world-boundary-3d/world-boundary-3d.descriptor';\nimport { getBounds3DNormalFromHits } from '../behaviors/shared/bounds-3d';\n\nexport class BoundaryRicochet3DCoordinator {\n\tconstructor(\n\t\tprivate entity: GameEntity<any> & MoveableEntity,\n\t\tprivate boundary: WorldBoundary3DHandle,\n\t\tprivate ricochet: Ricochet3DHandle,\n\t) {}\n\n\tpublic update(): boolean {\n\t\tconst hits = this.boundary.getLastHits();\n\t\tif (!hits) return false;\n\n\t\tconst anyHit =\n\t\t\thits.left || hits.right || hits.top || hits.bottom || hits.back || hits.front;\n\t\tif (!anyHit) return false;\n\n\t\tconst clamped = this.boundary.getLastClampedPosition();\n\t\tif (clamped && this.entity.body) {\n\t\t\tthis.entity.body.setTranslation(clamped, true);\n\t\t}\n\n\t\tconst normal = getBounds3DNormalFromHits(hits);\n\t\treturn this.ricochet.applyRicochet({\n\t\t\tentity: this.entity,\n\t\t\tcontact: { normal },\n\t\t});\n\t}\n}\n","import type { GameEntity } from '../entities/entity';\nimport {\n\tcreateFirstPersonInputComponent,\n\ttype FirstPersonInputComponent,\n} from '../behaviors/first-person/components';\nimport {\n\tcreateJumpInput3D,\n\ttype JumpInput3D,\n} from '../behaviors/jumper-3d/components';\n\nexport interface FirstPersonShooterInput {\n\tmoveX: number;\n\tmoveZ: number;\n\tlookX: number;\n\tlookY: number;\n\tsprint: boolean;\n\tjumpPressed: boolean;\n\tjumpHeld: boolean;\n\tjumpReleased: boolean;\n\tfastFall?: boolean;\n}\n\ninterface FirstPersonShooterControllerHandle {\n\tgetYaw(): number;\n}\n\ninterface FirstPersonShooterJumperHandle {\n\tgetState(): unknown;\n}\n\ntype FirstPersonShooterEntity = GameEntity<any> & {\n\t$fps?: FirstPersonInputComponent;\n\t$jumper?: JumpInput3D;\n};\n\nexport class FirstPersonShooterCoordinator {\n\tconstructor(\n\t\tprivate entity: FirstPersonShooterEntity,\n\t\tprivate fpsController: FirstPersonShooterControllerHandle,\n\t\tprivate jumper: FirstPersonShooterJumperHandle,\n\t) {}\n\n\tpublic update(input: FirstPersonShooterInput): void {\n\t\tif (!this.entity.$fps) {\n\t\t\tthis.entity.$fps = createFirstPersonInputComponent();\n\t\t}\n\t\tif (!this.entity.$jumper) {\n\t\t\tthis.entity.$jumper = createJumpInput3D();\n\t\t}\n\n\t\tconst fpsInput = this.entity.$fps;\n\t\tfpsInput.moveX = input.moveX;\n\t\tfpsInput.moveZ = input.moveZ;\n\t\tfpsInput.lookX = input.lookX;\n\t\tfpsInput.lookY = input.lookY;\n\t\tfpsInput.sprint = input.sprint;\n\n\t\tconst jumperInput = this.entity.$jumper;\n\t\tjumperInput.jumpPressed = input.jumpPressed;\n\t\tjumperInput.jumpHeld = input.jumpHeld;\n\t\tjumperInput.jumpReleased = input.jumpReleased;\n\t\tjumperInput.fastFall = input.fastFall ?? false;\n\t\tjumperInput.moveDirWorld = this.getMoveDirWorld(\n\t\t\tinput.moveX,\n\t\t\tinput.moveZ,\n\t\t\tthis.fpsController.getYaw(),\n\t\t);\n\n\t\t// Keep the jumper handle in the public contract even though the\n\t\t// coordinator only needs its current state for future extensions.\n\t\tvoid this.jumper.getState();\n\t}\n\n\tprivate getMoveDirWorld(\n\t\tmoveX: number,\n\t\tmoveZ: number,\n\t\tyaw: number,\n\t): { x: number; y: number; z: number } | undefined {\n\t\tconst sinYaw = Math.sin(yaw);\n\t\tconst cosYaw = Math.cos(yaw);\n\t\tconst rightX = cosYaw;\n\t\tconst rightZ = -sinYaw;\n\t\tconst forwardX = -sinYaw;\n\t\tconst forwardZ = -cosYaw;\n\t\tconst worldX = rightX * moveX + forwardX * -moveZ;\n\t\tconst worldZ = rightZ * moveX + forwardZ * -moveZ;\n\t\tconst length = Math.hypot(worldX, worldZ);\n\t\tif (length <= 1e-6) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\tx: worldX / length,\n\t\t\ty: 0,\n\t\t\tz: worldZ / length,\n\t\t};\n\t}\n}\n","import {\n\tangleFromDirection2D,\n\tdirectionFromAngle2D,\n\tgetRotationAngle2D,\n\tnormalizeDirection2D,\n} from '../../behaviors/shared/direction-2d';\n\nexport interface ResolvedAim2D {\n\tangle: number;\n\tdirection: { x: number; y: number };\n\thasAimInput: boolean;\n}\n\nexport function getEntityFacingAngle2D(entity: any): number {\n\tif (entity.topDownMovementState) {\n\t\treturn entity.topDownMovementState.facingAngle;\n\t}\n\n\tif (entity.body?.rotation) {\n\t\treturn getRotationAngle2D(entity.body.rotation());\n\t}\n\n\treturn entity._rotation2DAngle ?? 0;\n}\n\nexport function resolveAim2D(\n\taimX: number,\n\taimY: number,\n\tfallbackAngle: number,\n): ResolvedAim2D {\n\tconst direction = normalizeDirection2D(aimX, aimY);\n\tif (direction) {\n\t\treturn {\n\t\t\tangle: angleFromDirection2D(direction),\n\t\t\tdirection,\n\t\t\thasAimInput: true,\n\t\t};\n\t}\n\n\treturn {\n\t\tangle: fallbackAngle,\n\t\tdirection: directionFromAngle2D(fallbackAngle),\n\t\thasAimInput: false,\n\t};\n}\n","import {\n\tcreateTopDownMovementInputComponent,\n\ttype TopDownMovementInputComponent,\n} from '../behaviors/top-down-movement/components';\nimport type {\n\tShooter2DHandle,\n\tShooter2DSourceEntity,\n\tShooter2DStageLike,\n} from '../behaviors/shooter-2d/shooter-2d.descriptor';\nimport { getEntityFacingAngle2D, resolveAim2D } from './shared/top-down-aim';\n\nexport interface TopDownShooterInput {\n\tmoveX: number;\n\tmoveY: number;\n\taimX: number;\n\taimY: number;\n\tshootPressed: boolean;\n\tshootHeld: boolean;\n}\n\ntype TopDownShooterEntity = Shooter2DSourceEntity & {\n\t$topDownMovement?: TopDownMovementInputComponent;\n};\n\nexport class TopDownShooterCoordinator {\n\tconstructor(\n\t\tprivate entity: TopDownShooterEntity,\n\t\tprivate shooter: Shooter2DHandle,\n\t\tprivate stage: Shooter2DStageLike,\n\t) {}\n\n\tpublic update(input: TopDownShooterInput): void {\n\t\tif (!this.entity.$topDownMovement) {\n\t\t\tthis.entity.$topDownMovement = createTopDownMovementInputComponent();\n\t\t}\n\n\t\tthis.entity.$topDownMovement.moveX = input.moveX;\n\t\tthis.entity.$topDownMovement.moveY = input.moveY;\n\t\tthis.entity.$topDownMovement.faceX = input.aimX;\n\t\tthis.entity.$topDownMovement.faceY = input.aimY;\n\n\t\tif (!input.shootPressed && !input.shootHeld) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst sourcePosition = this.entity.body?.translation();\n\t\tif (!sourcePosition) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst aim = resolveAim2D(\n\t\t\tinput.aimX,\n\t\t\tinput.aimY,\n\t\t\tgetEntityFacingAngle2D(this.entity),\n\t\t);\n\t\tvoid this.shooter.fire({\n\t\t\tsource: this.entity,\n\t\t\tstage: this.stage,\n\t\t\ttarget: {\n\t\t\t\tx: sourcePosition.x + aim.direction.x,\n\t\t\t\ty: sourcePosition.y + aim.direction.y,\n\t\t\t},\n\t\t});\n\t}\n}\n","import type { GameEntity } from '../entities/entity';\nimport {\n\tcreateThrusterInputComponent,\n\ttype ThrusterInputComponent,\n} from '../behaviors/thruster/components';\nimport type {\n\tShooter2DHandle,\n\tShooter2DSourceEntity,\n\tShooter2DStageLike,\n} from '../behaviors/shooter-2d/shooter-2d.descriptor';\nimport { getEntityFacingAngle2D, resolveAim2D } from './shared/top-down-aim';\n\nexport interface MultidirectionalSpaceShooterInput {\n\tmoveX: number;\n\tmoveY: number;\n\taimX: number;\n\taimY: number;\n\tshootPressed: boolean;\n\tshootHeld: boolean;\n}\n\ntype MultidirectionalSpaceShooterEntity = GameEntity<any> & Shooter2DSourceEntity & {\n\t$thruster?: ThrusterInputComponent;\n};\n\nexport class MultidirectionalSpaceShooterCoordinator {\n\tconstructor(\n\t\tprivate entity: MultidirectionalSpaceShooterEntity,\n\t\tprivate shooter: Shooter2DHandle,\n\t\tprivate stage: Shooter2DStageLike,\n\t) {}\n\n\tpublic update(input: MultidirectionalSpaceShooterInput): void {\n\t\tif (!this.entity.$thruster) {\n\t\t\tthis.entity.$thruster = createThrusterInputComponent();\n\t\t}\n\n\t\tthis.entity.$thruster.thrustX = input.moveX;\n\t\tthis.entity.$thruster.thrustY = input.moveY;\n\t\tthis.entity.$thruster.thrust = 0;\n\t\tthis.entity.$thruster.rotate = 0;\n\n\t\tconst aim = resolveAim2D(\n\t\t\tinput.aimX,\n\t\t\tinput.aimY,\n\t\t\tgetEntityFacingAngle2D(this.entity),\n\t\t);\n\t\tif (aim.hasAimInput) {\n\t\t\tthis.entity.setRotationZ(aim.angle);\n\t\t}\n\n\t\tif (!input.shootPressed && !input.shootHeld) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst sourcePosition = this.entity.body?.translation();\n\t\tif (!sourcePosition) {\n\t\t\treturn;\n\t\t}\n\n\t\tvoid this.shooter.fire({\n\t\t\tsource: this.entity,\n\t\t\tstage: this.stage,\n\t\t\ttarget: {\n\t\t\t\tx: sourcePosition.x + aim.direction.x,\n\t\t\t\ty: sourcePosition.y + aim.direction.y,\n\t\t\t},\n\t\t});\n\t}\n}\n","import type { GameEntity, GameEntityOptions } from '../entities/entity';\n\n/**\n * Action interface -- the base contract for all actions.\n *\n * Actions are entity-scoped, self-contained objects that modify entity state\n * over time. They are ticked automatically by the entity update loop.\n */\nexport interface Action {\n\t/** Internal duration in seconds (0 = instant, Infinity = persistent) */\n\treadonly duration: number;\n\t/** Whether this action has completed */\n\treadonly done: boolean;\n\t/** Whether this action auto-removes when done (set by entity.action()) */\n\tpersistent: boolean;\n\t/** Advance the action by delta seconds */\n\ttick(entity: GameEntity<any>, delta: number): void;\n\t/** Reset the action to its initial state */\n\treset(): void;\n}\n\n/**\n * Base class for interval actions that run over a fixed duration.\n * Accepts duration in **milliseconds**; converts to seconds internally\n * since the game loop delta is in seconds.\n */\nexport abstract class BaseAction implements Action {\n\tpublic readonly duration: number;\n\tpublic done: boolean = false;\n\tpublic persistent: boolean = false;\n\tprotected elapsed: number = 0;\n\n\t/** @param durationMs Duration in milliseconds */\n\tconstructor(durationMs: number) {\n\t\tthis.duration = durationMs / 1000;\n\t}\n\n\ttick(entity: GameEntity<any>, delta: number): void {\n\t\tif (this.done) return;\n\t\tthis.elapsed += delta;\n\t\tconst progress = this.duration > 0 ? Math.min(this.elapsed / this.duration, 1) : 1;\n\t\tthis.onTick(entity, delta, progress);\n\t\tif (this.elapsed >= this.duration) {\n\t\t\tthis.done = true;\n\t\t}\n\t}\n\n\treset(): void {\n\t\tthis.elapsed = 0;\n\t\tthis.done = false;\n\t}\n\n\t/**\n\t * Subclasses implement this to apply their effect each frame.\n\t * @param entity The entity this action is running on\n\t * @param delta Frame delta in seconds\n\t * @param progress 0..1 normalized progress through the duration\n\t */\n\tprotected abstract onTick(\n\t\tentity: GameEntity<any>,\n\t\tdelta: number,\n\t\tprogress: number,\n\t): void;\n}\n","import type { GameEntity } from '../entities/entity';\nimport { BaseAction, type Action } from './action';\nimport { setVelocityIntent } from './capabilities/velocity-intents';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// MoveBy -- accumulate position delta over duration via velocity\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MoveByOptions {\n\t/** X displacement (default: 0) */\n\tx?: number;\n\t/** Y displacement (default: 0) */\n\ty?: number;\n\t/** Z displacement (default: 0) */\n\tz?: number;\n\t/** Duration in milliseconds */\n\tduration: number;\n}\n\n/**\n * Move an entity by a displacement over a duration.\n * Distributes the movement as velocity each frame so physics stays in sync.\n *\n * @example\n * ```ts\n * entity.runAction(moveBy({ x: 10, duration: 500 }));\n * ```\n */\nexport function moveBy(opts: MoveByOptions): Action {\n\treturn new MoveByAction(opts);\n}\n\nclass MoveByAction extends BaseAction {\n\tprivate dx: number;\n\tprivate dy: number;\n\tprivate dz: number;\n\n\tconstructor(opts: MoveByOptions) {\n\t\tsuper(opts.duration);\n\t\tthis.dx = opts.x ?? 0;\n\t\tthis.dy = opts.y ?? 0;\n\t\tthis.dz = opts.z ?? 0;\n\t}\n\n\tprotected onTick(entity: GameEntity<any>, delta: number, _progress: number): void {\n\t\tif (this.duration <= 0) return;\n\t\t// Distribute displacement as velocity: displacement/duration per second\n\t\tconst vx = this.dx / this.duration;\n\t\tconst vy = this.dy / this.duration;\n\t\tconst vz = this.dz / this.duration;\n\t\tconst store = entity.transformStore;\n\t\tif (!store) return;\n\t\tsetVelocityIntent(store, 'actions', { x: vx, y: vy, z: vz }, { mode: 'add' });\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// MoveTo -- move to an absolute position over duration\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MoveToOptions {\n\t/** Target X position */\n\tx: number;\n\t/** Target Y position */\n\ty: number;\n\t/** Target Z position */\n\tz: number;\n\t/** Duration in milliseconds */\n\tduration: number;\n}\n\n/**\n * Move an entity to an absolute position over a duration.\n * Calculates displacement from the entity's position on the first tick.\n *\n * @example\n * ```ts\n * entity.runAction(moveTo({ x: 0, y: 10, z: 0, duration: 2000 }));\n * ```\n */\nexport function moveTo(opts: MoveToOptions): Action {\n\treturn new MoveToAction(opts);\n}\n\nclass MoveToAction extends BaseAction {\n\tprivate targetX: number;\n\tprivate targetY: number;\n\tprivate targetZ: number;\n\tprivate dx = 0;\n\tprivate dy = 0;\n\tprivate dz = 0;\n\tprivate initialized = false;\n\n\tconstructor(opts: MoveToOptions) {\n\t\tsuper(opts.duration);\n\t\tthis.targetX = opts.x;\n\t\tthis.targetY = opts.y;\n\t\tthis.targetZ = opts.z;\n\t}\n\n\tprotected onTick(entity: GameEntity<any>, delta: number, _progress: number): void {\n\t\tif (this.duration <= 0) return;\n\t\tif (!this.initialized) {\n\t\t\tconst pos = entity.getPosition?.();\n\t\t\tconst cx = pos?.x ?? 0;\n\t\t\tconst cy = pos?.y ?? 0;\n\t\t\tconst cz = pos?.z ?? 0;\n\t\t\tthis.dx = this.targetX - cx;\n\t\t\tthis.dy = this.targetY - cy;\n\t\t\tthis.dz = this.targetZ - cz;\n\t\t\tthis.initialized = true;\n\t\t}\n\t\tconst vx = this.dx / this.duration;\n\t\tconst vy = this.dy / this.duration;\n\t\tconst vz = this.dz / this.duration;\n\t\tconst store = entity.transformStore;\n\t\tif (!store) return;\n\t\tsetVelocityIntent(store, 'actions', { x: vx, y: vy, z: vz }, { mode: 'add' });\n\t}\n\n\treset(): void {\n\t\tsuper.reset();\n\t\tthis.initialized = false;\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// RotateBy -- rotate by euler angles (degrees) over duration\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface RotateByOptions {\n\t/** X rotation in degrees (default: 0) */\n\tx?: number;\n\t/** Y rotation in degrees (default: 0) */\n\ty?: number;\n\t/** Z rotation in degrees (default: 0) */\n\tz?: number;\n\t/** Duration in milliseconds */\n\tduration: number;\n}\n\n/**\n * Rotate an entity by euler angles (degrees) over a duration.\n *\n * @example\n * ```ts\n * entity.runAction(rotateBy({ y: 360, duration: 2000 }));\n * ```\n */\nexport function rotateBy(opts: RotateByOptions): Action {\n\treturn new RotateByAction(opts);\n}\n\nclass RotateByAction extends BaseAction {\n\tprivate rx: number;\n\tprivate ry: number;\n\tprivate rz: number;\n\n\tconstructor(opts: RotateByOptions) {\n\t\tsuper(opts.duration);\n\t\tconst toRad = Math.PI / 180;\n\t\tthis.rx = (opts.x ?? 0) * toRad;\n\t\tthis.ry = (opts.y ?? 0) * toRad;\n\t\tthis.rz = (opts.z ?? 0) * toRad;\n\t}\n\n\tprotected onTick(entity: GameEntity<any>, delta: number, _progress: number): void {\n\t\tif (this.duration <= 0) return;\n\t\t// Distribute angular velocity in radians/sec\n\t\tconst wx = this.rx / this.duration;\n\t\tconst wy = this.ry / this.duration;\n\t\tconst wz = this.rz / this.duration;\n\t\tconst store = entity.transformStore;\n\t\tstore.angularVelocity.x += wx;\n\t\tstore.angularVelocity.y += wy;\n\t\tstore.angularVelocity.z += wz;\n\t\tstore.dirty.angularVelocity = true;\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Delay -- no-op for a duration (used in sequences)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Wait for a duration. Useful inside `sequence()`.\n *\n * @param ms Duration in milliseconds\n * @example\n * ```ts\n * entity.runAction(sequence(moveBy({ x: 5, duration: 1000 }), delay(500), moveBy({ y: 3, duration: 1000 })));\n * ```\n */\nexport function delay(ms: number): Action {\n\treturn new DelayAction(ms);\n}\n\nclass DelayAction extends BaseAction {\n\tconstructor(ms: number) {\n\t\tsuper(ms);\n\t}\n\n\tprotected onTick(): void {\n\t\t// no-op -- just waits\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CallFunc -- instant action that calls a function\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Call a function immediately. Completes in one frame.\n * Useful inside `sequence()` for side effects.\n *\n * @example\n * ```ts\n * entity.runAction(sequence(moveBy({ x: 5, duration: 1000 }), callFunc(() => console.log('done'))));\n * ```\n */\nexport function callFunc(fn: () => void): Action {\n\treturn new CallFuncAction(fn);\n}\n\nclass CallFuncAction extends BaseAction {\n\tprivate fn: () => void;\n\tprivate called = false;\n\n\tconstructor(fn: () => void) {\n\t\tsuper(0);\n\t\tthis.fn = fn;\n\t}\n\n\tprotected onTick(): void {\n\t\tif (!this.called) {\n\t\t\tthis.fn();\n\t\t\tthis.called = true;\n\t\t}\n\t}\n\n\treset(): void {\n\t\tsuper.reset();\n\t\tthis.called = false;\n\t}\n}\n","import type { GameEntity } from '../entities/entity';\nimport type { Action } from './action';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Throttle -- auto-resetting timer\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ThrottleOptions {\n\t/** Interval in milliseconds between ready cycles */\n\tduration: number;\n}\n\n/**\n * A repeating timer that becomes ready every N milliseconds.\n * Register with `entity.action(throttle(...))`.\n *\n * @example\n * ```ts\n * const t = entity.action(throttle({ duration: 500 }));\n * entity.onUpdate(() => {\n * if (t.ready) { t.consume(); // do something every 500ms }\n * });\n * ```\n */\nexport function throttle(opts: ThrottleOptions): ThrottleAction {\n\treturn new ThrottleAction(opts.duration);\n}\n\nexport class ThrottleAction implements Action {\n\tpublic readonly duration: number;\n\tpublic done: boolean = false;\n\tpublic persistent: boolean = true;\n\tpublic ready: boolean = false;\n\tprivate elapsed: number = 0;\n\n\t/** @param durationMs Duration in milliseconds */\n\tconstructor(durationMs: number) {\n\t\tthis.duration = durationMs / 1000;\n\t}\n\n\ttick(_entity: GameEntity<any>, delta: number): void {\n\t\tthis.elapsed += delta;\n\t\tif (this.elapsed >= this.duration) {\n\t\t\tthis.ready = true;\n\t\t}\n\t}\n\n\t/** Consume the ready state and reset the timer */\n\tconsume(): void {\n\t\tthis.ready = false;\n\t\tthis.elapsed = 0;\n\t}\n\n\treset(): void {\n\t\tthis.elapsed = 0;\n\t\tthis.ready = false;\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OnPress -- edge-detection for button press\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Detects the rising edge of a boolean signal (press).\n * Call `.check(isPressed)` each frame in your onUpdate; `.triggered` is\n * true for one frame on press.\n *\n * @example\n * ```ts\n * const press = entity.action(onPress());\n * entity.onUpdate(({ inputs }) => {\n * press.check(inputs.p1.buttons.A.pressed);\n * if (press.triggered) { // do something once on press }\n * });\n * ```\n */\nexport function onPress(): OnPressAction {\n\treturn new OnPressAction();\n}\n\nexport class OnPressAction implements Action {\n\tpublic readonly duration = Infinity;\n\tpublic done: boolean = false;\n\tpublic persistent: boolean = true;\n\tpublic triggered: boolean = false;\n\tprivate wasPressed: boolean = false;\n\n\ttick(): void {\n\t\t// Reset triggered each frame; .check() sets it\n\t\tthis.triggered = false;\n\t}\n\n\t/**\n\t * Feed the current pressed state. Sets `.triggered = true` on the\n\t * frame where `isPressed` transitions from false to true.\n\t */\n\tcheck(isPressed: boolean): void {\n\t\tif (isPressed && !this.wasPressed) {\n\t\t\tthis.triggered = true;\n\t\t}\n\t\tthis.wasPressed = isPressed;\n\t}\n\n\treset(): void {\n\t\tthis.triggered = false;\n\t\tthis.wasPressed = false;\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OnRelease -- edge-detection for button release\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Detects the falling edge of a boolean signal (release).\n * Call `.check(isPressed)` each frame; `.triggered` is true for one frame\n * on release.\n *\n * @example\n * ```ts\n * const release = entity.action(onRelease());\n * entity.onUpdate(({ inputs }) => {\n * release.check(inputs.p1.buttons.A.pressed);\n * if (release.triggered) { // do something once on release }\n * });\n * ```\n */\nexport function onRelease(): OnReleaseAction {\n\treturn new OnReleaseAction();\n}\n\nexport class OnReleaseAction implements Action {\n\tpublic readonly duration = Infinity;\n\tpublic done: boolean = false;\n\tpublic persistent: boolean = true;\n\tpublic triggered: boolean = false;\n\tprivate wasPressed: boolean = false;\n\n\ttick(): void {\n\t\tthis.triggered = false;\n\t}\n\n\t/**\n\t * Feed the current pressed state. Sets `.triggered = true` on the\n\t * frame where `isPressed` transitions from true to false.\n\t */\n\tcheck(isPressed: boolean): void {\n\t\tif (!isPressed && this.wasPressed) {\n\t\t\tthis.triggered = true;\n\t\t}\n\t\tthis.wasPressed = isPressed;\n\t}\n\n\treset(): void {\n\t\tthis.triggered = false;\n\t\tthis.wasPressed = false;\n\t}\n}\n","import type { GameEntity } from '../entities/entity';\nimport type { Action } from './action';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Sequence -- runs actions one after another\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Run actions in order, one after another.\n *\n * @example\n * ```ts\n * entity.runAction(sequence(\n * moveBy({ x: 5, duration: 1000 }),\n * delay(500),\n * moveBy({ y: 3, duration: 1000 }),\n * ));\n * ```\n */\nexport function sequence(...actions: Action[]): Action {\n\treturn new SequenceAction(actions);\n}\n\nclass SequenceAction implements Action {\n\tpublic duration: number;\n\tpublic done: boolean = false;\n\tpublic persistent: boolean = false;\n\tprivate actions: Action[];\n\tprivate currentIndex: number = 0;\n\n\tconstructor(actions: Action[]) {\n\t\tthis.actions = actions;\n\t\tthis.duration = actions.reduce((sum, a) => sum + a.duration, 0);\n\t}\n\n\ttick(entity: GameEntity<any>, delta: number): void {\n\t\tif (this.done || this.actions.length === 0) {\n\t\t\tthis.done = true;\n\t\t\treturn;\n\t\t}\n\n\t\tlet remaining = delta;\n\t\twhile (remaining > 0 && this.currentIndex < this.actions.length) {\n\t\t\tconst current = this.actions[this.currentIndex];\n\t\t\tcurrent.tick(entity, remaining);\n\t\t\tif (current.done) {\n\t\t\t\t// Calculate overflow time for the next action\n\t\t\t\tconst actionDuration = current.duration;\n\t\t\t\tconst actionElapsed = (current as any).elapsed ?? actionDuration;\n\t\t\t\tconst overflow = Math.max(0, actionElapsed - actionDuration);\n\t\t\t\tremaining = overflow;\n\t\t\t\tthis.currentIndex++;\n\t\t\t} else {\n\t\t\t\tremaining = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (this.currentIndex >= this.actions.length) {\n\t\t\tthis.done = true;\n\t\t}\n\t}\n\n\treset(): void {\n\t\tthis.currentIndex = 0;\n\t\tthis.done = false;\n\t\tfor (const action of this.actions) {\n\t\t\taction.reset();\n\t\t}\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Parallel -- runs all actions simultaneously\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Run all actions simultaneously. Done when all children are done.\n *\n * @example\n * ```ts\n * entity.runAction(parallel(\n * moveBy({ x: 5, duration: 1000 }),\n * rotateBy({ y: 360, duration: 1000 }),\n * ));\n * ```\n */\nexport function parallel(...actions: Action[]): Action {\n\treturn new ParallelAction(actions);\n}\n\nclass ParallelAction implements Action {\n\tpublic duration: number;\n\tpublic done: boolean = false;\n\tpublic persistent: boolean = false;\n\tprivate actions: Action[];\n\n\tconstructor(actions: Action[]) {\n\t\tthis.actions = actions;\n\t\tthis.duration = Math.max(0, ...actions.map(a => a.duration));\n\t}\n\n\ttick(entity: GameEntity<any>, delta: number): void {\n\t\tif (this.done) return;\n\n\t\tlet allDone = true;\n\t\tfor (const action of this.actions) {\n\t\t\tif (!action.done) {\n\t\t\t\taction.tick(entity, delta);\n\t\t\t}\n\t\t\tif (!action.done) {\n\t\t\t\tallDone = false;\n\t\t\t}\n\t\t}\n\n\t\tif (allDone) {\n\t\t\tthis.done = true;\n\t\t}\n\t}\n\n\treset(): void {\n\t\tthis.done = false;\n\t\tfor (const action of this.actions) {\n\t\t\taction.reset();\n\t\t}\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Repeat -- repeats an action N times\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Repeat an action a fixed number of times.\n *\n * @example\n * ```ts\n * entity.runAction(repeat(moveBy({ x: 2, duration: 500 }), 5));\n * ```\n */\nexport function repeat(action: Action, times: number): Action {\n\treturn new RepeatAction(action, times);\n}\n\nclass RepeatAction implements Action {\n\tpublic duration: number;\n\tpublic done: boolean = false;\n\tpublic persistent: boolean = false;\n\tprivate action: Action;\n\tprivate totalTimes: number;\n\tprivate currentCount: number = 0;\n\n\tconstructor(action: Action, times: number) {\n\t\tthis.action = action;\n\t\tthis.totalTimes = times;\n\t\tthis.duration = action.duration * times;\n\t}\n\n\ttick(entity: GameEntity<any>, delta: number): void {\n\t\tif (this.done) return;\n\n\t\tthis.action.tick(entity, delta);\n\t\tif (this.action.done) {\n\t\t\tthis.currentCount++;\n\t\t\tif (this.currentCount >= this.totalTimes) {\n\t\t\t\tthis.done = true;\n\t\t\t} else {\n\t\t\t\tthis.action.reset();\n\t\t\t}\n\t\t}\n\t}\n\n\treset(): void {\n\t\tthis.currentCount = 0;\n\t\tthis.done = false;\n\t\tthis.action.reset();\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// RepeatForever -- repeats an action indefinitely\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Repeat an action forever. Never completes.\n *\n * @example\n * ```ts\n * enemy.runAction(repeatForever(\n * sequence(moveBy({ x: 3, duration: 2000 }), moveBy({ x: -3, duration: 2000 })),\n * ));\n * ```\n */\nexport function repeatForever(action: Action): Action {\n\treturn new RepeatForeverAction(action);\n}\n\nclass RepeatForeverAction implements Action {\n\tpublic readonly duration = Infinity;\n\tpublic done: boolean = false;\n\tpublic persistent: boolean = false;\n\tprivate action: Action;\n\n\tconstructor(action: Action) {\n\t\tthis.action = action;\n\t}\n\n\ttick(entity: GameEntity<any>, delta: number): void {\n\t\tthis.action.tick(entity, delta);\n\t\tif (this.action.done) {\n\t\t\tthis.action.reset();\n\t\t}\n\t}\n\n\treset(): void {\n\t\tthis.done = false;\n\t\tthis.action.reset();\n\t}\n}\n","/**\n * CooldownIcon -- a WoW-style cooldown icon UI entity.\n *\n * Renders a square icon with a semi-transparent clockwise sweep overlay\n * that reflects cooldown progress from the CooldownStore. Optionally shows\n * remaining time text in the center.\n *\n * Modeled after ZylemRect's canvas-based viewport-attached sprite pattern.\n */\n\nimport {\n\tGroup,\n\tSprite as ThreeSprite,\n\tSpriteMaterial,\n\tCanvasTexture,\n\tLinearFilter,\n\tVector2,\n\tPerspectiveCamera,\n\tOrthographicCamera,\n\tColor,\n\tTexture,\n\tClampToEdgeWrapping,\n} from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { finalizeEntityCloneSupport, GameEntityOptions, GameEntity } from './entity';\nimport { UpdateContext, SetupContext } from '../core/base-node-life-cycle';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { getCooldown } from '../behaviors/cooldown/cooldown-store';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Screen anchor system\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Reference point on the viewport for positioning UI elements.\n * The offset in `screenPosition` is applied relative to this anchor.\n */\nexport type ScreenAnchor =\n\t| 'top-left' | 'top-center' | 'top-right'\n\t| 'center-left' | 'center' | 'center-right'\n\t| 'bottom-left' | 'bottom-center' | 'bottom-right';\n\n/** Fractional viewport coordinates for each anchor point. */\nconst ANCHOR_FRACTIONS: Record<ScreenAnchor, { fx: number; fy: number }> = {\n\t'top-left': { fx: 0, fy: 0 },\n\t'top-center': { fx: 0.5, fy: 0 },\n\t'top-right': { fx: 1, fy: 0 },\n\t'center-left': { fx: 0, fy: 0.5 },\n\t'center': { fx: 0.5, fy: 0.5 },\n\t'center-right': { fx: 1, fy: 0.5 },\n\t'bottom-left': { fx: 0, fy: 1 },\n\t'bottom-center': { fx: 0.5, fy: 1 },\n\t'bottom-right': { fx: 1, fy: 1 },\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Icon size unit system\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Height of the virtual unit grid (in abstract \"view units\").\n * Width scales with aspect ratio.\n * At 4:3 the grid is 256 × 192, fitting exactly 12 extra-large (64-unit) icons.\n */\nconst VIEW_UNITS_HEIGHT = 192;\n\n/** Preset icon sizes in view units. */\nconst ICON_SIZE_PRESETS = {\n\txs: 8,\n\tsm: 16,\n\tmd: 32,\n\tlg: 48,\n\txl: 64,\n} as const;\n\n/** Named size preset. */\nexport type IconSizePreset = keyof typeof ICON_SIZE_PRESETS;\n\n/**\n * Icon size expressed as a named preset, a square unit value, or\n * a `{ width, height }` object for non-square icons.\n *\n * All numeric values are in **view units** (viewport height = 192 units).\n */\nexport type IconSize = IconSizePreset | number | { width: number; height: number };\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Options\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype ZylemCooldownIconOptions = GameEntityOptions & {\n\t/** Name of the cooldown in the CooldownStore */\n\tcooldown: string;\n\t/** Texture path for the icon background (optional) */\n\ticon?: string;\n\t/** Solid fill color when no icon texture is provided */\n\tfillColor?: Color | string;\n\t/**\n\t * Size of the icon in view units, a named preset, or a `{ width, height }` object.\n\t *\n\t * Presets: `'xs'` (8), `'sm'` (16), `'md'` (32), `'lg'` (48), `'xl'` (64).\n\t * A bare number creates a square icon of that many units.\n\t * The viewport height equals 192 units; width scales with aspect ratio.\n\t *\n\t * @default 'md'\n\t */\n\ticonSize?: IconSize;\n\t/** Whether to show remaining time text */\n\tshowTimer?: boolean;\n\t/** Whether to attach to the camera viewport (default: true) */\n\tstickToViewport?: boolean;\n\t/**\n\t * Viewport anchor the icon is positioned relative to.\n\t * @default 'top-left'\n\t */\n\tscreenAnchor?: ScreenAnchor;\n\t/**\n\t * Offset from the {@link screenAnchor} in **view units**.\n\t * Positive x = right, positive y = down.\n\t * Accepts a `Vector2` or a plain `{ x, y }` object.\n\t * @default { x: 0, y: 0 }\n\t */\n\tscreenPosition?: Vector2 | { x: number; y: number };\n\t/** Distance from camera (default: 1) */\n\tzDistance?: number;\n\t/** Color of the sweep overlay (default: semi-transparent black) */\n\toverlayColor?: string;\n};\n\nconst cooldownIconDefaults: ZylemCooldownIconOptions = {\n\tposition: undefined,\n\tcooldown: '',\n\ticonSize: 'md',\n\tfillColor: '#333333',\n\tshowTimer: true,\n\tstickToViewport: true,\n\tscreenAnchor: 'top-left',\n\tscreenPosition: { x: 0, y: 0 },\n\tzDistance: 1,\n\toverlayColor: 'rgba(0, 0, 0, 0.65)',\n};\n\nexport const COOLDOWN_ICON_TYPE = Symbol('CooldownIcon');\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Entity class\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ZylemCooldownIcon extends GameEntity<ZylemCooldownIconOptions> {\n\tstatic type = COOLDOWN_ICON_TYPE;\n\n\tprivate _sprite: ThreeSprite | null = null;\n\tprivate _texture: CanvasTexture | null = null;\n\tprivate _canvas: HTMLCanvasElement | null = null;\n\tprivate _ctx: CanvasRenderingContext2D | null = null;\n\tprivate _cameraRef: ZylemCamera | null = null;\n\tprivate _iconTexture: Texture | null = null;\n\tprivate _iconImage: HTMLImageElement | null = null;\n\tprivate _lastRenderedProgress: number = -1;\n\n\tconstructor(options?: ZylemCooldownIconOptions) {\n\t\tsuper();\n\t\tthis.options = { ...cooldownIconDefaults, ...options } as ZylemCooldownIconOptions;\n\t\tthis.group = new Group();\n\t\tthis.createSprite();\n\t\tthis.prependSetup(this.iconSetup.bind(this) as any);\n\t\tthis.prependUpdate(this.iconUpdate.bind(this) as any);\n\t\tthis.onCleanup(this.iconDestroy.bind(this) as any);\n\t}\n\n\tprivate createSprite(): void {\n\t\t// Use a fixed canvas resolution for all icon sizes.\n\t\t// The actual display size is controlled by sprite scaling in updateStickyTransform.\n\t\tconst canvasPixels = 128;\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._canvas.width = canvasPixels * 2; // 2x for retina\n\t\tthis._canvas.height = canvasPixels * 2;\n\t\tthis._ctx = this._canvas.getContext('2d');\n\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\tthis._texture.minFilter = LinearFilter;\n\t\tthis._texture.magFilter = LinearFilter;\n\t\tthis._texture.wrapS = ClampToEdgeWrapping;\n\t\tthis._texture.wrapT = ClampToEdgeWrapping;\n\t\tconst material = new SpriteMaterial({\n\t\t\tmap: this._texture,\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t});\n\t\tthis._sprite = new ThreeSprite(material);\n\t\tthis.group?.add(this._sprite);\n\n\t\t// Load icon texture if provided\n\t\tif (this.options.icon) {\n\t\t\tconst img = new Image();\n\t\t\timg.crossOrigin = 'anonymous';\n\t\t\timg.onload = () => {\n\t\t\t\tthis._iconImage = img;\n\t\t\t\tthis.redraw(this._lastRenderedProgress >= 0 ? this._lastRenderedProgress : 1);\n\t\t\t};\n\t\t\timg.src = this.options.icon;\n\t\t}\n\n\t\tthis.redraw(1); // Initial draw at \"ready\" state\n\t}\n\n\tprivate redraw(progress: number): void {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tconst ctx = this._ctx;\n\t\tconst w = this._canvas.width;\n\t\tconst h = this._canvas.height;\n\t\tconst cx = w / 2;\n\t\tconst cy = h / 2;\n\t\tconst radius = Math.min(cx, cy);\n\n\t\tctx.clearRect(0, 0, w, h);\n\n\t\t// Draw icon background (image or solid color)\n\t\tif (this._iconImage) {\n\t\t\tctx.drawImage(this._iconImage, 0, 0, w, h);\n\t\t} else {\n\t\t\tctx.fillStyle = this.toCssColor(this.options.fillColor ?? '#333333');\n\t\t\tctx.fillRect(0, 0, w, h);\n\t\t}\n\n\t\t// Draw sweep overlay (clockwise from top, covering the \"not ready\" portion)\n\t\tif (progress < 1) {\n\t\t\tconst sweepAngle = (1 - progress) * Math.PI * 2;\n\t\t\tconst startAngle = -Math.PI / 2; // 12 o'clock\n\t\t\tconst endAngle = startAngle + sweepAngle;\n\n\t\t\tctx.save();\n\t\t\tctx.fillStyle = this.options.overlayColor ?? 'rgba(0, 0, 0, 0.65)';\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(cx, cy);\n\t\t\tctx.arc(cx, cy, radius + 1, startAngle, endAngle, false);\n\t\t\tctx.closePath();\n\t\t\tctx.fill();\n\t\t\tctx.restore();\n\n\t\t\t// Draw remaining time text\n\t\t\tif (this.options.showTimer) {\n\t\t\t\tconst entry = getCooldown(this.options.cooldown);\n\t\t\t\tif (entry) {\n\t\t\t\t\tconst remaining = Math.max(0, entry.duration - entry.elapsed);\n\t\t\t\t\tconst text = remaining >= 10 ? Math.ceil(remaining).toString() : remaining.toFixed(1);\n\t\t\t\t\tconst fontSize = Math.floor(w * 0.3);\n\t\t\t\t\tctx.font = `bold ${fontSize}px sans-serif`;\n\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\tctx.fillStyle = '#FFFFFF';\n\t\t\t\t\tctx.strokeStyle = '#000000';\n\t\t\t\t\tctx.lineWidth = 2;\n\t\t\t\t\tctx.strokeText(text, cx, cy);\n\t\t\t\t\tctx.fillText(text, cx, cy);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this._texture) {\n\t\t\tthis._texture.needsUpdate = true;\n\t\t}\n\t\tthis._lastRenderedProgress = progress;\n\t}\n\n\tprivate toCssColor(color: Color | string): string {\n\t\tif (typeof color === 'string') return color;\n\t\tconst c = color instanceof Color ? color : new Color(color as any);\n\t\treturn `#${c.getHexString()}`;\n\t}\n\n\tprivate getResolution(): { width: number; height: number } {\n\t\ttry {\n\t\t\tconst dom = this._cameraRef?.renderer?.domElement;\n\t\t\tif (dom) {\n\t\t\t\treturn { width: dom.clientWidth || 1, height: dom.clientHeight || 1 };\n\t\t\t}\n\t\t} catch { /* renderer not available */ }\n\t\treturn {\n\t\t\twidth: this._cameraRef?.screenResolution?.x ?? 1,\n\t\t\theight: this._cameraRef?.screenResolution?.y ?? 1,\n\t\t};\n\t}\n\n\tprivate iconSetup(params: SetupContext<ZylemCooldownIconOptions>): void {\n\t\t// Recreate sprite resources if they were disposed by a previous cleanup\n\t\tif (!this._sprite) {\n\t\t\tthis.createSprite();\n\t\t}\n\t\tthis._cameraRef = (params.camera as unknown) as ZylemCamera | null;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\t(this._cameraRef.camera as any).add(this.group);\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate iconUpdate(_params: UpdateContext<ZylemCooldownIconOptions>): void {\n\t\t// Read cooldown progress from the global store\n\t\tconst entry = getCooldown(this.options.cooldown);\n\t\tconst progress = entry?.progress ?? 1;\n\n\t\t// Only redraw if progress changed visibly (threshold ~2%)\n\t\tif (Math.abs(progress - this._lastRenderedProgress) > 0.02 || progress === 1 && this._lastRenderedProgress !== 1) {\n\t\t\tthis.redraw(progress);\n\t\t}\n\n\t\t// Update viewport-attached position\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\t/**\n\t * Resolve screen position to pixels.\n\t * Computes the anchor point in pixels, then adds the view-unit offset.\n\t */\n\tprivate resolveScreenPosition(width: number, height: number): { px: number; py: number } {\n\t\tconst anchor = this.options.screenAnchor ?? 'top-left';\n\t\tconst pos = this.options.screenPosition ?? { x: 0, y: 0 };\n\t\tconst ox = pos instanceof Vector2 ? pos.x : pos.x;\n\t\tconst oy = pos instanceof Vector2 ? pos.y : pos.y;\n\n\t\tconst { fx, fy } = ANCHOR_FRACTIONS[anchor];\n\t\tconst ax = fx * width;\n\t\tconst ay = fy * height;\n\n\t\tconst pxPerUnit = height / VIEW_UNITS_HEIGHT;\n\t\treturn { px: ax + ox * pxPerUnit, py: ay + oy * pxPerUnit };\n\t}\n\n\t/**\n\t * Resolve `iconSize` to screen pixels using the view-unit grid.\n\t * Viewport height = {@link VIEW_UNITS_HEIGHT} units; width scales with aspect ratio.\n\t */\n\tprivate resolveIconSize(viewportHeight: number): { widthPx: number; heightPx: number } {\n\t\tconst raw = this.options.iconSize ?? 'md';\n\t\tlet w: number, h: number;\n\t\tif (typeof raw === 'string') {\n\t\t\tw = h = ICON_SIZE_PRESETS[raw as IconSizePreset];\n\t\t} else if (typeof raw === 'number') {\n\t\t\tw = h = raw;\n\t\t} else {\n\t\t\tw = raw.width;\n\t\t\th = raw.height;\n\t\t}\n\t\tconst pxPerUnit = viewportHeight / VIEW_UNITS_HEIGHT;\n\t\treturn { widthPx: w * pxPerUnit, heightPx: h * pxPerUnit };\n\t}\n\n\t/** Compute the world-space half-extents at a given distance from the camera. */\n\tprivate computeWorldExtents(camera: PerspectiveCamera | OrthographicCamera, zDist: number) {\n\t\tlet worldHalfW = 1;\n\t\tlet worldHalfH = 1;\n\t\tif ((camera as PerspectiveCamera).isPerspectiveCamera) {\n\t\t\tconst pc = camera as PerspectiveCamera;\n\t\t\tconst halfH = Math.tan((pc.fov * Math.PI) / 180 / 2) * zDist;\n\t\t\tconst halfW = halfH * pc.aspect;\n\t\t\tworldHalfW = halfW;\n\t\t\tworldHalfH = halfH;\n\t\t} else if ((camera as OrthographicCamera).isOrthographicCamera) {\n\t\t\tconst oc = camera as OrthographicCamera;\n\t\t\tworldHalfW = (oc.right - oc.left) / 2;\n\t\t\tworldHalfH = (oc.top - oc.bottom) / 2;\n\t\t}\n\t\treturn { worldHalfW, worldHalfH };\n\t}\n\n\tprivate updateStickyTransform(): void {\n\t\tif (!this._sprite || !this._cameraRef) return;\n\t\tconst camera = this._cameraRef.camera as PerspectiveCamera | OrthographicCamera;\n\t\tconst { width, height } = this.getResolution();\n\t\tconst { px, py } = this.resolveScreenPosition(width, height);\n\t\tconst zDist = Math.max(0.001, this.options.zDistance ?? 1);\n\t\tconst { worldHalfW, worldHalfH } = this.computeWorldExtents(camera, zDist);\n\n\t\tconst ndcX = (px / width) * 2 - 1;\n\t\tconst ndcY = 1 - (py / height) * 2;\n\t\tconst localX = ndcX * worldHalfW;\n\t\tconst localY = ndcY * worldHalfH;\n\n\t\t{\n\t\t\tconst planeH = worldHalfH * 2;\n\t\t\tconst unitsPerPixel = planeH / height;\n\t\t\tconst { widthPx, heightPx } = this.resolveIconSize(height);\n\t\t\tconst scaleX = Math.max(0.0001, widthPx * unitsPerPixel);\n\t\t\tconst scaleY = Math.max(0.0001, heightPx * unitsPerPixel);\n\t\t\tthis._sprite.scale.set(scaleX, scaleY, 1);\n\t\t}\n\n\t\tthis.group?.position.set(localX, localY, -zDist);\n\t}\n\n\t/**\n\t * Dispose Three.js / DOM resources when the entity is destroyed.\n\t */\n\tprivate iconDestroy(): void {\n\t\t// Dispose canvas texture (GPU memory)\n\t\tthis._texture?.dispose();\n\n\t\t// Dispose sprite material\n\t\tif (this._sprite?.material) {\n\t\t\t(this._sprite.material as SpriteMaterial).dispose();\n\t\t}\n\n\t\t// Remove sprite from group\n\t\tif (this._sprite) {\n\t\t\tthis._sprite.removeFromParent();\n\t\t}\n\n\t\t// Remove group from parent (camera or scene)\n\t\tthis.group?.removeFromParent();\n\n\t\t// Dispose loaded icon texture\n\t\tthis._iconTexture?.dispose();\n\n\t\t// Clear references\n\t\tthis._sprite = null;\n\t\tthis._texture = null;\n\t\tthis._canvas = null;\n\t\tthis._ctx = null;\n\t\tthis._cameraRef = null;\n\t\tthis._iconTexture = null;\n\t\tthis._iconImage = null;\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Factory\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype CooldownIconOptions = BaseNode | Partial<ZylemCooldownIconOptions>;\n\n/**\n * Create a WoW-style cooldown icon UI entity.\n *\n * @example\n * ```ts\n * const attackIcon = createCooldownIcon({\n * cooldown: 'attack',\n * icon: swordIconPath,\n * screenAnchor: 'top-center', // reference point on the viewport\n * screenPosition: { x: 0, y: 10 }, // offset in view units from anchor\n * iconSize: 'sm', // preset (16 × 16 view units)\n * // iconSize: 24, // square (24 × 24 view units)\n * // iconSize: { width: 16, height: 24 }, // custom rectangle\n * });\n * ```\n */\nexport function createCooldownIcon(...args: Array<CooldownIconOptions>): ZylemCooldownIcon {\n\tconst configArgs = args.filter(\n\t\t(arg): arg is Partial<ZylemCooldownIconOptions> => !(arg instanceof BaseNode),\n\t);\n\tlet options: Partial<ZylemCooldownIconOptions> = { ...cooldownIconDefaults };\n\tfor (const opt of configArgs) {\n\t\toptions = { ...options, ...opt };\n\t}\n\treturn finalizeEntityCloneSupport(\n\t\tnew ZylemCooldownIcon(options as ZylemCooldownIconOptions),\n\t\t(cloneOptions) => createCooldownIcon(cloneOptions ?? {}),\n\t);\n}\n","import { DestroyContext, DestroyFunction } from \"../core/base-node-life-cycle\";\nimport { getGlobals } from \"../game/game-state\";\n\nexport function destroyEntity<T>(entity: T, globals: any, destroyFunction: DestroyFunction<T>): void {\n\tconst context: DestroyContext<T> = {\n\t\tme: entity,\n\t\tglobals\n\t};\n\tdestroyFunction(context);\n}\n\nexport function destroy(entity: any, globals?: any): void {\n\tconst resolvedGlobals = globals ?? getGlobals();\n\tdestroyEntity(entity, resolvedGlobals, entity.nodeDestroy.bind(entity));\n}","/**\n * Plays a ricochet sound effect when boundary collision occurs\n */\nexport function ricochetSound(frequency: number = 800, duration: number = 0.05) {\n\t_ricochetSound(frequency, duration);\n}\n\nfunction _ricochetSound(frequency: number, duration: number) {\n\tconst audioCtx = new (window.AudioContext || (window as any).webkitAudioContext)();\n\tconst oscillator = audioCtx.createOscillator();\n\tconst gain = audioCtx.createGain();\n\n\toscillator.type = 'sawtooth';\n\toscillator.frequency.value = frequency;\n\n\tgain.gain.setValueAtTime(0.05, audioCtx.currentTime);\n\tgain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + duration);\n\n\toscillator.connect(gain);\n\tgain.connect(audioCtx.destination);\n\n\toscillator.start();\n\toscillator.stop(audioCtx.currentTime + duration);\n} ","/**\n * Plays a ping-pong beep sound effect.\n */\nexport function pingPongBeep(frequency: number = 440, duration: number = 0.1) {\n\t_pingPongBeep(frequency, duration);\n}\n\nfunction _pingPongBeep(frequency: number, duration: number) {\n\tconst audioCtx = new (window.AudioContext || (window as any).webkitAudioContext)();\n\tconst oscillator = audioCtx.createOscillator();\n\tconst gain = audioCtx.createGain();\n\n\toscillator.type = 'square';\n\toscillator.frequency.value = frequency;\n\n\tgain.gain.setValueAtTime(0.05, audioCtx.currentTime);\n\tgain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + duration);\n\n\toscillator.connect(gain);\n\tgain.connect(audioCtx.destination);\n\n\toscillator.start();\n\toscillator.stop(audioCtx.currentTime + duration);\n} ","import { UpdateContext } from \"../core/base-node-life-cycle\";\n\n/**\n * Listen for a single global key change inside an onUpdate pipeline.\n * Usage: onUpdate(globalChange('p1Score', (value) => { ... }))\n */\nexport function globalChange<T = any>(\n\tkey: string,\n\tcallback: (value: T, ctx: UpdateContext<any>) => void\n) {\n\tlet previousValue: T | undefined = undefined;\n\treturn (ctx: UpdateContext<any>) => {\n\t\tconst currentValue = ctx.globals?.[key] as T;\n\t\tif (previousValue !== currentValue) {\n\t\t\t// Ignore the very first undefined->value transition only if both are undefined\n\t\t\tif (!(previousValue === undefined && currentValue === undefined)) {\n\t\t\t\tcallback(currentValue, ctx);\n\t\t\t}\n\t\t\tpreviousValue = currentValue;\n\t\t}\n\t};\n}\n\n/**\n * Listen for multiple global key changes inside an onUpdate pipeline.\n * Calls back when any of the provided keys changes.\n * Usage: onUpdate(globalChanges(['p1Score','p2Score'], ([p1,p2]) => { ... }))\n */\nexport function globalChanges<T = any>(\n\tkeys: string[],\n\tcallback: (values: T[], ctx: UpdateContext<any>) => void\n) {\n\tlet previousValues: (T | undefined)[] = new Array(keys.length).fill(undefined);\n\treturn (ctx: UpdateContext<any>) => {\n\t\tconst currentValues = keys.map((k) => ctx.globals?.[k] as T);\n\t\tconst hasAnyChange = currentValues.some((val, idx) => previousValues[idx] !== val);\n\t\tif (hasAnyChange) {\n\t\t\t// Ignore initial all-undefined state\n\t\t\tconst allPrevUndef = previousValues.every((v) => v === undefined);\n\t\t\tconst allCurrUndef = currentValues.every((v) => v === undefined);\n\t\t\tif (!(allPrevUndef && allCurrUndef)) {\n\t\t\t\tcallback(currentValues as T[], ctx);\n\t\t\t}\n\t\t\tpreviousValues = currentValues;\n\t\t}\n\t};\n}\n\n\n/**\n * Listen for a single stage variable change inside an onUpdate pipeline.\n * Usage: onUpdate(variableChange('score', (value, ctx) => { ... }))\n */\nexport function variableChange<T = any>(\n\tkey: string,\n\tcallback: (value: T, ctx: UpdateContext<any>) => void\n) {\n\tlet previousValue: T | undefined = undefined;\n\treturn (ctx: UpdateContext<any>) => {\n\t\t// @ts-ignore - stage is optional on UpdateContext\n\t\tconst currentValue = (ctx.stage?.getVariable?.(key) ?? undefined) as T;\n\t\tif (previousValue !== currentValue) {\n\t\t\tif (!(previousValue === undefined && currentValue === undefined)) {\n\t\t\t\tcallback(currentValue, ctx);\n\t\t\t}\n\t\t\tpreviousValue = currentValue;\n\t\t}\n\t};\n}\n\n/**\n * Listen for multiple stage variable changes; fires when any changes.\n * Usage: onUpdate(variableChanges(['a','b'], ([a,b], ctx) => { ... }))\n */\nexport function variableChanges<T = any>(\n\tkeys: string[],\n\tcallback: (values: T[], ctx: UpdateContext<any>) => void\n) {\n\tlet previousValues: (T | undefined)[] = new Array(keys.length).fill(undefined);\n\treturn (ctx: UpdateContext<any>) => {\n\t\t// @ts-ignore - stage is optional on UpdateContext\n\t\tconst reader = (k: string) => ctx.stage?.getVariable?.(k) as T;\n\t\tconst currentValues = keys.map(reader);\n\t\tconst hasAnyChange = currentValues.some((val, idx) => previousValues[idx] !== val);\n\t\tif (hasAnyChange) {\n\t\t\tconst allPrevUndef = previousValues.every((v) => v === undefined);\n\t\t\tconst allCurrUndef = currentValues.every((v) => v === undefined);\n\t\t\tif (!(allPrevUndef && allCurrUndef)) {\n\t\t\t\tcallback(currentValues as T[], ctx);\n\t\t\t}\n\t\t\tpreviousValues = currentValues;\n\t\t}\n\t};\n}\n\n\n","import { Game } from '../lib/game/game';\nimport {\n debugState,\n setDebugTool,\n setPaused,\n type DebugTools,\n} from '../lib/debug/debug-state';\nimport type { DeviceProfile } from '../lib/game/game-config';\n\n/**\n * State interface for editor-to-game communication\n */\nexport interface ZylemGameState {\n gameState?: {\n debugFlag?: boolean;\n [key: string]: unknown;\n };\n toolbarState?: {\n tool?: DebugTools;\n paused?: boolean;\n };\n [key: string]: unknown;\n}\n\nexport class ZylemGameElement extends HTMLElement {\n private _game: Game<any> | null = null;\n private _state: ZylemGameState = {};\n private container: HTMLElement;\n private resizeObserver: ResizeObserver | null = null;\n private _viewportProfile: DeviceProfile = 'auto';\n private static readonly HOST_CONFIG_MARKER = Symbol('zylem:host-config');\n\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n const style = document.createElement('style');\n style.textContent = `\n :host {\n display: block;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n }\n `;\n this.container = document.createElement('div');\n this.container.style.width = '100%';\n this.container.style.height = '100%';\n this.container.style.position = 'relative';\n this.container.style.outline = 'none'; // Remove focus outline\n this.container.tabIndex = 0; // Make focusable for keyboard input\n this.shadowRoot!.append(style, this.container);\n }\n\n /**\n * Focus the game container for keyboard input\n */\n public focus(): void {\n this.container.focus();\n }\n\n connectedCallback(): void {\n if (typeof ResizeObserver !== 'undefined' && !this.resizeObserver) {\n this.resizeObserver = new ResizeObserver(() => {\n this.syncDisplayRuntime();\n });\n this.resizeObserver.observe(this);\n }\n this.syncDisplayRuntime();\n }\n\n set game(game: Game<any>) {\n // Dispose previous game if one exists\n if (this._game) {\n this._game.dispose();\n }\n\n this._game = game;\n this.attachHostContainer(game);\n this.syncDisplayRuntime();\n game.start();\n }\n\n get game(): Game<any> | null {\n return this._game;\n }\n\n set state(value: ZylemGameState) {\n this._state = value;\n this.syncDebugState();\n this.syncToolbarState();\n }\n\n get state(): ZylemGameState {\n return this._state;\n }\n\n set viewportProfile(value: DeviceProfile) {\n const normalized: DeviceProfile =\n value === 'mobile' || value === 'desktop' ? value : 'auto';\n if (this._viewportProfile === normalized) {\n return;\n }\n this._viewportProfile = normalized;\n this.syncDisplayRuntime();\n }\n\n get viewportProfile(): DeviceProfile {\n return this._viewportProfile;\n }\n\n static get observedAttributes(): string[] {\n return ['viewport-profile'];\n }\n\n attributeChangedCallback(\n name: string,\n _oldValue: string | null,\n newValue: string | null,\n ): void {\n if (name === 'viewport-profile') {\n this.viewportProfile = (newValue ?? 'auto') as DeviceProfile;\n }\n }\n\n /**\n * Sync the web component's state with the game-lib's internal debug state\n */\n private syncDebugState(): void {\n const debugFlag = this._state.gameState?.debugFlag;\n if (debugFlag !== undefined) {\n debugState.enabled = debugFlag;\n }\n }\n\n /**\n * Sync toolbar state with game-lib's debug state\n */\n private syncToolbarState(): void {\n const { tool, paused } = this._state.toolbarState ?? {};\n if (tool !== undefined) {\n setDebugTool(tool);\n }\n if (paused !== undefined) {\n setPaused(paused);\n }\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n if (this._game) {\n this._game.dispose();\n this._game = null;\n }\n }\n\n private attachHostContainer(game: Game<any>): void {\n const marker = ZylemGameElement.HOST_CONFIG_MARKER;\n const existing = game.options.find((option) =>\n Boolean((option as Record<symbol, unknown>)?.[marker]),\n ) as ({ container: HTMLElement } & Record<symbol, boolean>) | undefined;\n\n if (existing) {\n existing.container = this.container;\n return;\n }\n\n game.options.push({\n container: this.container,\n [marker]: true,\n } as any);\n }\n\n private syncDisplayRuntime(): void {\n if (!this._game) {\n return;\n }\n\n const rect = this.getBoundingClientRect();\n const width = Math.round(rect.width || this.clientWidth || 0);\n const height = Math.round(rect.height || this.clientHeight || 0);\n\n this._game.setDisplayRuntime({\n deviceProfile: this._viewportProfile,\n viewportSize: width > 0 && height > 0 ? { width, height } : undefined,\n });\n }\n}\n\ncustomElements.define('zylem-game', ZylemGameElement);\n","import { ZylemSprite, SPRITE_TYPE } from '../entities/sprite';\nimport { ZylemSphere, SPHERE_TYPE } from '../entities/sphere';\nimport { ZylemRect, RECT_TYPE } from '../entities/rect';\nimport { ZylemText, TEXT_TYPE } from '../entities/text';\nimport { ZylemBox, BOX_TYPE } from '../entities/box';\nimport { ZylemPlane, PLANE_TYPE } from '../entities/plane';\nimport { ZylemZone, ZONE_TYPE } from '../entities/zone';\nimport { ZylemActor, ACTOR_TYPE } from '../entities/actor';\nimport { ZylemDisk, DISK_TYPE } from '../entities/disk';\nimport { ZylemCone, CONE_TYPE } from '../entities/cone';\nimport { ZylemPyramid, PYRAMID_TYPE } from '../entities/pyramid';\nimport { ZylemCylinder, CYLINDER_TYPE } from '../entities/cylinder';\nimport { ZylemPill, PILL_TYPE } from '../entities/pill';\nimport { BaseNode } from '../core/base-node';\n\n/**\n * Maps entity type symbols to their class types.\n * Used by getEntityByName to infer return types.\n */\nexport interface EntityTypeMap {\n\t[SPRITE_TYPE]: ZylemSprite;\n\t[SPHERE_TYPE]: ZylemSphere;\n\t[RECT_TYPE]: ZylemRect;\n\t[TEXT_TYPE]: ZylemText;\n\t[BOX_TYPE]: ZylemBox;\n\t[PLANE_TYPE]: ZylemPlane;\n\t[ZONE_TYPE]: ZylemZone;\n\t[ACTOR_TYPE]: ZylemActor;\n\t[DISK_TYPE]: ZylemDisk;\n\t[CONE_TYPE]: ZylemCone;\n\t[PYRAMID_TYPE]: ZylemPyramid;\n\t[CYLINDER_TYPE]: ZylemCylinder;\n\t[PILL_TYPE]: ZylemPill;\n}\n\n/**\n * Type helper: if T is a known type symbol, return the mapped entity type.\n * Otherwise return BaseNode.\n */\nexport type EntityForType<T> = T extends keyof EntityTypeMap\n\t? EntityTypeMap[T]\n\t: BaseNode;\n\n// Re-export type symbols for convenience\nexport {\n\tSPRITE_TYPE,\n\tSPHERE_TYPE,\n\tRECT_TYPE,\n\tTEXT_TYPE,\n\tBOX_TYPE,\n\tPLANE_TYPE,\n\tZONE_TYPE,\n\tACTOR_TYPE,\n\tDISK_TYPE,\n\tCONE_TYPE,\n\tPYRAMID_TYPE,\n\tCYLINDER_TYPE,\n\tPILL_TYPE,\n};\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\n#include <common>\n \nuniform vec3 iResolution;\nuniform float iTime;\nuniform vec2 iOffset;\nvarying vec2 vUv;\n\nfloat snoise(vec3 uv, float res)\n{\n\tconst vec3 s = vec3(1e0, 1e2, 1e3);\n\t\n\tuv *= res;\n\t\n\tvec3 uv0 = floor(mod(uv, res))*s;\n\tvec3 uv1 = floor(mod(uv+vec3(1.), res))*s;\n\t\n\tvec3 f = fract(uv); f = f*f*(3.0-2.0*f);\n\n\tvec4 v = vec4(uv0.x+uv0.y+uv0.z, uv1.x+uv0.y+uv0.z,\n\t\t \t uv0.x+uv1.y+uv0.z, uv1.x+uv1.y+uv0.z);\n\n\tvec4 r = fract(sin(v*1e-1)*1e3);\n\tfloat r0 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);\n\t\n\tr = fract(sin((v + uv1.z - uv0.z)*1e-1)*1e3);\n\tfloat r1 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);\n\t\n\treturn mix(r0, r1, f.z)*2.-1.;\n}\n\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n\tvec2 p = -.5 + fragCoord.xy / iResolution.xy;\n\tp.x *= iResolution.x/iResolution.y;\n\t\n\tfloat color = 3.0 - (3.*length(2.*p));\n\t\n\tvec3 coord = vec3(atan(p.x,p.y)/6.2832+.5, length(p)*.4, .5);\n\t\n\tfor(int i = 1; i <= 7; i++)\n\t{\n\t\tfloat power = pow(2.0, float(i));\n\t\tcolor += (1.5 / power) * snoise(coord + vec3(0.,-iTime*.05, iTime*.01), power*16.);\n\t}\n\tfragColor = vec4( color, pow(max(color,0.),2.)*0.4, pow(max(color,0.),3.)*0.15 , 1.0);\n}\n\nvoid main() {\n mainImage(gl_FragColor, vUv);\n}\n`;\n\nexport const fireShader = {\n vertex: objectVertexShader,\n fragment\n};\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\n#include <common>\n\nuniform vec3 iResolution;\nuniform float iTime;\nvarying vec2 vUv;\n\n// Credit goes to:\n// https://www.shadertoy.com/view/mtyGWy\n\nvec3 palette( float t ) {\n vec3 a = vec3(0.5, 0.5, 0.5);\n vec3 b = vec3(0.5, 0.5, 0.5);\n vec3 c = vec3(1.0, 1.0, 1.0);\n vec3 d = vec3(0.263,0.416,0.557);\n\n return a + b*cos( 6.28318*(c*t+d) );\n}\n\nvoid mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = (fragCoord * 2.0 - iResolution.xy) / iResolution.y;\n vec2 uv0 = uv;\n vec3 finalColor = vec3(0.0);\n \n for (float i = 0.0; i < 4.0; i++) {\n uv = fract(uv * 1.5) - 0.5;\n\n float d = length(uv) * exp(-length(uv0));\n\n vec3 col = palette(length(uv0) + i*.4 + iTime*.4);\n\n d = sin(d*5. + iTime)/5.;\n d = abs(d);\n\n d = pow(0.01 / d, 1.2);\n\n finalColor += col * d;\n }\n \n fragColor = vec4(finalColor, 1.0);\n}\n \nvoid main() {\n mainImage(gl_FragColor, vUv);\n}\n`;\n\nexport const starShader = {\n vertex: objectVertexShader,\n fragment\n};\n","export const debugVertexShader = `\nuniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n\tvUv = uv;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n}\n`;\n","import { debugVertexShader } from './vertex/debug.shader';\n\nconst fragment = `\nvarying vec3 vBarycentric;\nuniform vec3 baseColor;\nuniform vec3 wireframeColor;\nuniform float wireframeThickness;\n\nfloat edgeFactor() {\n vec3 d = fwidth(vBarycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * wireframeThickness, vBarycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n\nvoid main() {\n float edge = edgeFactor();\n\n vec3 wireColor = wireframeColor;\n\n vec3 finalColor = mix(wireColor, baseColor, edge);\n \n gl_FragColor = vec4(finalColor, 1.0);\n}\n`;\n\nexport const debugShader = {\n vertex: debugVertexShader,\n fragment\n};\n"],"mappings":"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","names":["proxy","WebGLRenderer","all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map","position","rotation","t","Quaternion","destroy","proxy","position","Vector3","Quaternion","rotation","Vector3","Vector2","Vector3","ActiveCollisionTypes","ColliderDesc","RigidBodyDesc","RigidBodyType","Vector3","Color","Vector3","ShaderMaterial","Mesh","Mesh","Color","Vector2","Vector3","RepeatWrapping","ShaderMaterial","repeat","fragment","BufferGeometry","Mesh","Color","ActiveCollisionTypes","ColliderDesc","MeshStandardMaterial","Group","Vector3","position","scale","rotation","RigidBodyType","t","result","proxy","rotation","Scene","Color","Vector3","ShaderMaterial","Mesh","Texture","MeshBasicNodeMaterial","state","position","Matrix4","Vector3","Quaternion","scale","rotation","Color","Vector3","Color","Vector3","proxy","subscribe","subscribe","Box3","BoxGeometry","Color","Group","Mesh","Vector3","BufferAttribute","BufferGeometry","LineBasicMaterial","LineSegments","Vector2","subscribe","hoveredUuid","Vector3","state","Vector3","Quaternion","MathUtils","t","Vector3","Quaternion","position","t","Vector3","Quaternion","DEFAULTS","Vector3","Quaternion","Euler","MathUtils","DEFAULTS","position","rotation","t","PerspectiveCamera","Vector3","WebGLRenderTarget","position","Vector2","Vector2","Vector3","Color","Vector3","nanoid","Vector2","Vector3","position","proxy","Vector3","proxy","initialDefaults","state","state","state","document","height","width","time","height","width","subscribe","state","position","rotation","scale","getGameDefaultConfig","proxy","stageState","Color","Group","LinearFilter","Vector2","MeshStandardMaterial","MeshBasicMaterial","MeshPhongMaterial","x","y","z","toDeg","Vector2","Group","LinearFilter","Color","ColliderDesc","Euler","Group","Quaternion","Vector3","TextureLoader","SpriteMaterial","ThreeSprite","Vector3","ColliderDesc","TextureLoader","SpriteMaterial","ThreeSprite","Group","Quaternion","Euler","stageState","Euler","Quaternion","Vector2","Vector3","DEFAULTS","MeshBasicMaterial","Vector3","BoxGeometry","Mesh","MeshStandardMaterial","Vector3","ColliderDesc","Vector2","Vector3","BufferGeometry","Vector2","Vector3","scale","ColliderDesc","Vector3","Color","Group","ThreeSprite","SpriteMaterial","CanvasTexture","LinearFilter","Vector2","ClampToEdgeWrapping","ShaderMaterial","Mesh","PlaneGeometry","Vector3","Vector2","Group","CanvasTexture","LinearFilter","SpriteMaterial","ThreeSprite","ClampToEdgeWrapping","ShaderMaterial","Color","Mesh","PlaneGeometry","Vector3","ColliderDesc","Group","ColliderDesc","Group","Vector3","Quaternion","ThrusterState","ThrusterEvent","state","rotation","state","defaultOptions","defaultOptions","position","state","ScreenWrapState","ScreenWrapEvent","position","position","moveX","moveY","defaultOptions","Box3","Matrix4","Quaternion","Vector3","defaultOptions","Box3","Matrix4","Vector3","Quaternion","rotation","position","scale","WorldBoundary2DState","WorldBoundary2DEvent","position","moveX","moveY","defaultOptions","moveX","moveY","position","moveX","moveY","moveZ","WorldBoundary3DState","WorldBoundary3DEvent","position","moveX","moveY","moveZ","defaultOptions","moveX","moveY","moveZ","Ricochet2DState","Ricochet2DEvent","scale","defaultOptions","Ricochet3DState","Ricochet3DEvent","clamp","position","scale","defaultOptions","Platformer3DState","Platformer3DEvent","state","Ray","BufferGeometry","LineBasicMaterial","Vector3","centerY","state","moveX","moveZ","defaultOptions","Platformer3DBehavior","FirstPersonState","FirstPersonEvent","state","Vector3","Quaternion","Euler","state","defaultOptions","state","now","scale","JumperTickEvent","Jumper3DState","Jumper3DEvent","defaultOptions","state","jumpVelocityFromHeight","Jumper2DTickEvent","state","now","Jumper2DState","Jumper2DEvent","defaultOptions","state","proxy","moveX","moveZ","Group","ThreeSprite","SpriteMaterial","CanvasTexture","LinearFilter","Vector2","Color","ClampToEdgeWrapping","Group","CanvasTexture","LinearFilter","ClampToEdgeWrapping","SpriteMaterial","ThreeSprite","Color","Vector2","THREE","RAPIER","fragment","fragment","fragment"]}