@zylem/game-lib 0.6.2 → 0.6.3

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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +9 -16
  3. package/dist/actions.d.ts +30 -21
  4. package/dist/actions.js +628 -145
  5. package/dist/actions.js.map +1 -1
  6. package/dist/behavior/platformer-3d.d.ts +296 -0
  7. package/dist/behavior/platformer-3d.js +518 -0
  8. package/dist/behavior/platformer-3d.js.map +1 -0
  9. package/dist/behavior/ricochet-2d.d.ts +274 -0
  10. package/dist/behavior/ricochet-2d.js +394 -0
  11. package/dist/behavior/ricochet-2d.js.map +1 -0
  12. package/dist/behavior/screen-wrap.d.ts +86 -0
  13. package/dist/behavior/screen-wrap.js +195 -0
  14. package/dist/behavior/screen-wrap.js.map +1 -0
  15. package/dist/behavior/thruster.d.ts +10 -0
  16. package/dist/behavior/thruster.js +234 -0
  17. package/dist/behavior/thruster.js.map +1 -0
  18. package/dist/behavior/world-boundary-2d.d.ts +141 -0
  19. package/dist/behavior/world-boundary-2d.js +181 -0
  20. package/dist/behavior/world-boundary-2d.js.map +1 -0
  21. package/dist/behavior-descriptor-BWNWmIjv.d.ts +142 -0
  22. package/dist/{blueprints-Cq3Ko6_G.d.ts → blueprints-BWGz8fII.d.ts} +2 -2
  23. package/dist/camera-B5e4c78l.d.ts +468 -0
  24. package/dist/camera.d.ts +3 -2
  25. package/dist/camera.js +900 -211
  26. package/dist/camera.js.map +1 -1
  27. package/dist/composition-DrzFrbqI.d.ts +218 -0
  28. package/dist/{core-bO8TzV7u.d.ts → core-DAkskq6Y.d.ts} +60 -62
  29. package/dist/core.d.ts +10 -6
  30. package/dist/core.js +6896 -5020
  31. package/dist/core.js.map +1 -1
  32. package/dist/{entities-DvByhMGU.d.ts → entities-DC9ce_vx.d.ts} +113 -3
  33. package/dist/entities.d.ts +5 -3
  34. package/dist/entities.js +3727 -3167
  35. package/dist/entities.js.map +1 -1
  36. package/dist/entity-BpbZqg19.d.ts +1100 -0
  37. package/dist/global-change-Dc8uCKi2.d.ts +25 -0
  38. package/dist/main.d.ts +418 -15
  39. package/dist/main.js +11384 -8515
  40. package/dist/main.js.map +1 -1
  41. package/dist/{stage-types-Bd-KtcYT.d.ts → stage-types-BFsm3qsZ.d.ts} +205 -13
  42. package/dist/stage.d.ts +10 -7
  43. package/dist/stage.js +5311 -3880
  44. package/dist/stage.js.map +1 -1
  45. package/dist/thruster-DhRaJnoL.d.ts +172 -0
  46. package/dist/world-Be5m1XC1.d.ts +31 -0
  47. package/package.json +29 -13
  48. package/dist/behaviors.d.ts +0 -854
  49. package/dist/behaviors.js +0 -1209
  50. package/dist/behaviors.js.map +0 -1
  51. package/dist/camera-CeJPAgGg.d.ts +0 -116
  52. package/dist/moveable-B_vyA6cw.d.ts +0 -67
  53. package/dist/transformable-CUhvyuYO.d.ts +0 -67
  54. package/dist/world-C8tQ7Plj.d.ts +0 -774
package/dist/main.js.map CHANGED
@@ -1 +1 @@
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-state.ts","../src/lib/input/keyboard-provider.ts","../src/lib/input/gamepad-provider.ts","../src/lib/input/input-manager.ts","../src/lib/core/three-addons/Timer.ts","../src/lib/device/aspect-ratio.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","../../../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/game/game-loading-delegate.ts","../src/lib/game/game-renderer-observer.ts","../src/lib/game/zylem-game.ts","../src/lib/core/flags.ts","../src/lib/core/base-node.ts","../src/lib/systems/transformable.system.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/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/collision/collision-builder.ts","../src/lib/graphics/mesh.ts","../src/lib/core/utility/strings.ts","../src/lib/graphics/shaders/vertex/object.shader.ts","../src/lib/graphics/shaders/standard.shader.ts","../src/lib/graphics/material.ts","../src/lib/entities/builder.ts","../src/lib/entities/common.ts","../src/lib/entities/actor.ts","../src/lib/collision/world.ts","../src/lib/graphics/zylem-scene.ts","../src/lib/core/utility/vector.ts","../src/lib/stage/stage-state.ts","../src/lib/core/lifecycle-base.ts","../src/lib/stage/debug-entity-cursor.ts","../src/lib/stage/stage-debug-delegate.ts","../src/lib/stage/stage-camera-debug-delegate.ts","../src/lib/camera/perspective.ts","../src/lib/camera/third-person.ts","../src/lib/camera/fixed-2d.ts","../src/lib/graphics/render-pass.ts","../src/lib/camera/camera-debug-delegate.ts","../src/lib/camera/zylem-camera.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/core/utility/options-parser.ts","../src/lib/stage/stage-config.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/core/utility/nodes.ts","../src/lib/stage/stage-manager.ts","../src/lib/entities/delegates/debug.ts","../src/lib/entities/text.ts","../src/lib/entities/sprite.ts","../src/lib/entities/entity-factory.ts","../src/lib/stage/stage-factory.ts","../src/lib/game/game.ts","../src/lib/stage/entity-spawner.ts","../src/lib/core/vessel.ts","../src/lib/entities/box.ts","../src/lib/entities/sphere.ts","../src/lib/graphics/geometries/XZPlaneGeometry.ts","../src/lib/entities/plane.ts","../src/lib/entities/zone.ts","../src/lib/entities/rect.ts","../src/lib/entities/disk.ts","../src/lib/behaviors/behavior-descriptor.ts","../src/lib/behaviors/use-behavior.ts","../src/lib/behaviors/components.ts","../src/lib/behaviors/physics-step.behavior.ts","../src/lib/behaviors/physics-sync.behavior.ts","../src/lib/behaviors/thruster/components.ts","../src/lib/behaviors/thruster/thruster-fsm.ts","../src/lib/behaviors/thruster/thruster-movement.behavior.ts","../src/lib/behaviors/thruster/thruster.descriptor.ts","../src/lib/behaviors/thruster/index.ts","../src/lib/behaviors/screen-wrap/screen-wrap-fsm.ts","../src/lib/behaviors/screen-wrap/screen-wrap.descriptor.ts","../src/lib/behaviors/screen-wrap/index.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/world-boundary-2d/index.ts","../src/lib/behaviors/ricochet-2d/ricochet-2d-fsm.ts","../src/lib/behaviors/ricochet-2d/ricochet-2d.descriptor.ts","../src/lib/behaviors/ricochet-2d/index.ts","../src/lib/behaviors/movement-sequence-2d/movement-sequence-2d-fsm.ts","../src/lib/behaviors/movement-sequence-2d/movement-sequence-2d.descriptor.ts","../src/lib/behaviors/movement-sequence-2d/index.ts","../src/lib/coordinators/boundary-ricochet.coordinator.ts","../src/lib/behaviors/index.ts","../src/lib/actions/capabilities/moveable.ts","../src/lib/actions/capabilities/rotatable.ts","../src/lib/actions/capabilities/transformable.ts","../src/lib/entities/destroy.ts","../src/lib/sounds/ricochet-sound.ts","../src/lib/sounds/ping-pong-sound.ts","../src/lib/sounds/index.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","../src/api/main.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 { 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 */\ninterface PropertyPath {\n\tcategory: 'buttons' | 'directions' | 'shoulders' | 'axes';\n\tproperty: string;\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},\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}\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}\n}\n","import { InputProvider } from './input-provider';\nimport { AnalogState, ButtonState, InputGamepad } from './input';\nimport { compileMapping, createInputGamepadState, mergeButtonState } 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 mapping: Record<string, string[]> | null = null;\n\tprivate compiledMapping: Map<string, Array<{ category: string; property: string }>>;\n\tprivate includeDefaultBase: boolean = true;\n\n\tconstructor(mapping?: Record<string, string[]>, options?: { includeDefaultBase?: boolean }) {\n\t\tconsole.log('[KeyboardProvider] Constructor called with mapping:', mapping, 'options:', options);\n\t\tthis.mapping = mapping ?? null;\n\t\tthis.includeDefaultBase = options?.includeDefaultBase ?? true;\n\t\t\n\t\t// Pre-compute the mapping at construction time\n\t\tconsole.log('[KeyboardProvider] About to call compileMapping with:', this.mapping);\n\t\tthis.compiledMapping = compileMapping(this.mapping);\n\t\tconsole.log('[KeyboardProvider] compileMapping returned, size:', this.compiledMapping.size);\n\t\t\n\t\twindow.addEventListener('keydown', ({ key }) => this.keyStates.set(key, true));\n\t\twindow.addEventListener('keyup', ({ key }) => this.keyStates.set(key, false));\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 buttonState = this.keyButtonStates.get(key);\n\t\tconst isPressed = this.isKeyPressed(key);\n\n\t\tif (!buttonState) {\n\t\t\tbuttonState = { pressed: false, released: false, held: 0 };\n\t\t\tthis.keyButtonStates.set(key, buttonState);\n\t\t}\n\n\t\tif (isPressed) {\n\t\t\tif (buttonState.held === 0) {\n\t\t\t\tbuttonState.pressed = true;\n\t\t\t} else {\n\t\t\t\tbuttonState.pressed = false;\n\t\t\t}\n\t\t\tbuttonState.held += delta;\n\t\t\tbuttonState.released = false;\n\t\t} else {\n\t\t\tif (buttonState.held > 0) {\n\t\t\t\tbuttonState.released = true;\n\t\t\t\tbuttonState.held = 0;\n\t\t\t} else {\n\t\t\t\tbuttonState.released = false;\n\t\t\t}\n\t\t\tbuttonState.pressed = false;\n\t\t}\n\n\t\treturn buttonState;\n\t}\n\n\tprivate handleAnalogState(negativeKey: string, positiveKey: string, delta: number): AnalogState {\n\t\tconst value = this.getAxisValue(negativeKey, positiveKey);\n\t\treturn { value, held: delta };\n\t}\n\n\t/**\n\t * Optimized custom mapping application using pre-computed paths.\n\t * No string parsing happens here - all lookups are O(1).\n\t */\n\tprivate applyCustomMapping(input: Partial<InputGamepad>, delta: number): Partial<InputGamepad> {\n\t\tif (this.compiledMapping.size === 0) return input;\n\n\t\tfor (const [key, paths] of this.compiledMapping.entries()) {\n\t\t\tconst state = this.handleButtonState(key, delta);\n\t\t\t\n\t\t\tfor (const path of paths) {\n\t\t\t\tconst { category, property } = path;\n\t\t\t\t\n\t\t\t\tif (category === 'buttons') {\n\t\t\t\t\tif (!input.buttons) input.buttons = {} as any;\n\t\t\t\t\tconst nextButtons = input.buttons as any;\n\t\t\t\t\tnextButtons[property] = mergeButtonState(nextButtons[property], state);\n\t\t\t\t} else if (category === 'directions') {\n\t\t\t\t\tif (!input.directions) input.directions = {} as any;\n\t\t\t\t\tconst nextDirections = input.directions as any;\n\t\t\t\t\tnextDirections[property] = mergeButtonState(nextDirections[property], state);\n\t\t\t\t} else if (category === 'shoulders') {\n\t\t\t\t\tif (!input.shoulders) input.shoulders = {} as any;\n\t\t\t\t\tconst nextShoulders = input.shoulders as any;\n\t\t\t\t\tnextShoulders[property] = mergeButtonState(nextShoulders[property], state);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\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.axes = {\n\t\t\t\tHorizontal: this.handleAnalogState('ArrowLeft', 'ArrowRight', delta),\n\t\t\t\tVertical: this.handleAnalogState('ArrowUp', 'ArrowDown', 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\t\tconst result = this.applyCustomMapping(base, delta);\n\t\t\n\t\t// DEBUG: Log when keys are pressed\n\t\tif (this.isKeyPressed('w') || this.isKeyPressed('s') || this.isKeyPressed('ArrowUp') || this.isKeyPressed('ArrowDown')) {\n\t\t\tconsole.log('[KeyboardProvider] includeDefaultBase:', this.includeDefaultBase);\n\t\t\tconsole.log('[KeyboardProvider] compiledMapping size:', this.compiledMapping.size);\n\t\t\tconsole.log('[KeyboardProvider] result.directions:', result.directions);\n\t\t}\n\t\t\n\t\treturn result;\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} ","import { InputProvider } from './input-provider';\nimport { 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\n\tconstructor(gamepadIndex: number) {\n\t\tthis.gamepadIndex = gamepadIndex;\n\t\twindow.addEventListener('gamepadconnected', (e) => {\n\t\t\tif (e.gamepad.index === this.gamepadIndex) {\n\t\t\t\tthis.connected = true;\n\t\t\t}\n\t\t});\n\t\twindow.addEventListener('gamepaddisconnected', (e) => {\n\t\t\tif (e.gamepad.index === this.gamepadIndex) {\n\t\t\t\tthis.connected = false;\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate handleButtonState(index: number, gamepad: Gamepad, delta: number): ButtonState {\n\t\tconst isPressed = gamepad.buttons[index].pressed;\n\t\tlet buttonState = this.buttonStates[index];\n\n\t\tif (!buttonState) {\n\t\t\tbuttonState = { pressed: false, released: false, held: 0 };\n\t\t\tthis.buttonStates[index] = buttonState;\n\t\t}\n\n\t\tif (isPressed) {\n\t\t\tif (buttonState.held === 0) {\n\t\t\t\tbuttonState.pressed = true;\n\t\t\t} else {\n\t\t\t\tbuttonState.pressed = false;\n\t\t\t}\n\t\t\tbuttonState.held += delta;\n\t\t\tbuttonState.released = false;\n\t\t} else {\n\t\t\tif (buttonState.held > 0) {\n\t\t\t\tbuttonState.released = true;\n\t\t\t\tbuttonState.held = 0;\n\t\t\t} else {\n\t\t\t\tbuttonState.released = false;\n\t\t\t}\n\t\t\tbuttonState.pressed = false;\n\t\t}\n\n\t\treturn buttonState;\n\t}\n\n\tprivate handleAnalogState(index: number, gamepad: Gamepad, delta: number): AnalogState {\n\t\tconst value = gamepad.axes[index];\n\t\treturn { value, held: delta };\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\t\taxes: {\n\t\t\t\tHorizontal: this.handleAnalogState(0, gamepad, delta),\n\t\t\t\tVertical: this.handleAnalogState(1, gamepad, delta),\n\t\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 } from './input-provider';\nimport { AnalogState, ButtonState, InputGamepad, InputPlayerNumber, Inputs } from './input';\nimport { KeyboardProvider } from './keyboard-provider';\nimport { GamepadProvider } from './gamepad-provider';\nimport { GameInputConfig } from '../game/game-interfaces';\nimport { mergeButtonState, mergeAnalogState } from './input-state';\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\tconsole.log('[InputManager] Constructor called with config:', config);\n\t\tconsole.log('[InputManager] config?.p1:', config?.p1);\n\t\tconsole.log('[InputManager] config?.p1?.key:', config?.p1?.key);\n\t\t\n\t\tif (config?.p1?.key) {\n\t\t\tconsole.log('[InputManager] Creating P1 KeyboardProvider with custom mapping:', config.p1.key);\n\t\t\tthis.addInputProvider(1, new KeyboardProvider(config.p1.key, { includeDefaultBase: false }));\n\t\t} else {\n\t\t\tconsole.log('[InputManager] Creating P1 KeyboardProvider with default mapping');\n\t\t\tthis.addInputProvider(1, new KeyboardProvider());\n\t\t}\n\t\tthis.addInputProvider(1, new GamepadProvider(0));\n\t\tif (config?.p2?.key) {\n\t\t\tthis.addInputProvider(2, new KeyboardProvider(config.p2.key, { includeDefaultBase: false }));\n\t\t}\n\t\tthis.addInputProvider(2, new GamepadProvider(1));\n\t\tif (config?.p3?.key) {\n\t\t\tthis.addInputProvider(3, new KeyboardProvider(config.p3.key, { includeDefaultBase: false }));\n\t\t}\n\t\tthis.addInputProvider(3, new GamepadProvider(2));\n\t\tif (config?.p4?.key) {\n\t\t\tthis.addInputProvider(4, new KeyboardProvider(config.p4.key, { includeDefaultBase: false }));\n\t\t}\n\t\tthis.addInputProvider(4, new GamepadProvider(3));\n\t\tif (config?.p5?.key) {\n\t\t\tthis.addInputProvider(5, new KeyboardProvider(config.p5.key, { includeDefaultBase: false }));\n\t\t}\n\t\tthis.addInputProvider(5, new GamepadProvider(4));\n\t\tif (config?.p6?.key) {\n\t\t\tthis.addInputProvider(6, new KeyboardProvider(config.p6.key, { includeDefaultBase: false }));\n\t\t}\n\t\tthis.addInputProvider(6, new GamepadProvider(5));\n\t\tif (config?.p7?.key) {\n\t\t\tthis.addInputProvider(7, new KeyboardProvider(config.p7.key, { includeDefaultBase: false }));\n\t\t}\n\t\tthis.addInputProvider(7, new GamepadProvider(6));\n\t\tif (config?.p8?.key) {\n\t\t\tthis.addInputProvider(8, new KeyboardProvider(config.p8.key, { includeDefaultBase: false }));\n\t\t}\n\t\tthis.addInputProvider(8, new GamepadProvider(7));\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 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},\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};\n\t}\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\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\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\tthis.apply();\n\t}\n\n\t/** Detach window resize listener. */\n\tdetach() {\n\t\twindow.removeEventListener('resize', this.handleResizeBound);\n\t}\n\n\t/** Compute the largest size that fits container while preserving aspect. */\n\tmeasure(): { width: number; height: number } {\n\t\tconst containerWidth = this.container.clientWidth || window.innerWidth;\n\t\tconst containerHeight = this.container.clientHeight || window.innerHeight;\n\n\t\tconst containerRatio = containerWidth / containerHeight;\n\t\tif (containerRatio > this.aspectRatio) {\n\t\t\t// container is wider than target; limit by height\n\t\t\tconst height = containerHeight;\n\t\t\tconst width = Math.round(height * this.aspectRatio);\n\t\t\treturn { width, height };\n\t\t} else {\n\t\t\t// container is taller/narrower; limit by width\n\t\t\tconst width = containerWidth;\n\t\t\tconst height = Math.round(width / this.aspectRatio);\n\t\t\treturn { width, height };\n\t\t}\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}","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 and console 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};\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\n","import { StageInterface } from \"../types\";\nimport { GameInputConfig } from \"./game-interfaces\";\nimport { AspectRatio, AspectRatioValue } from \"../device/aspect-ratio\";\nimport { getDisplayAspect, getPresetResolution, parseResolution, RetroPresetKey } from \"./game-retro-resolutions\";\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 resolution (e.g., '256x240' or { width, height }) */\n\tresolution: string | { width: number; height: number };\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 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\nexport function resolveGameConfig(user?: GameConfigLike): 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\n\t// Derive aspect ratio: explicit numeric -> preset -> default\n\tconst explicitAspect = user?.aspectRatio as any;\n\tlet aspectRatio = defaults.aspectRatio;\n\tif (typeof explicitAspect === 'number' || (explicitAspect && typeof explicitAspect === 'string')) {\n\t\taspectRatio = typeof explicitAspect === 'number' ? explicitAspect : (AspectRatio as any)[explicitAspect] ?? defaults.aspectRatio;\n\t} else if (user?.preset) {\n\t\ttry {\n\t\t\taspectRatio = getDisplayAspect(user.preset as RetroPresetKey) || defaults.aspectRatio;\n\t\t} catch {\n\t\t\taspectRatio = defaults.aspectRatio;\n\t\t}\n\t}\n\n\tconst fullscreen = (user?.fullscreen as boolean) ?? defaults.fullscreen;\n\tconst bodyBackground = (user?.bodyBackground as string) ?? defaults.bodyBackground;\n\n\t// Normalize internal resolution lock\n\tlet internalResolution: { width: number; height: number } | undefined;\n\tif (user?.resolution) {\n\t\tif (typeof user.resolution === 'string') {\n\t\t\tconst parsed = parseResolution(user.resolution);\n\t\t\tif (parsed) internalResolution = parsed;\n\t\t\t// fallback: allow preset resolution keys like '256x240' under a preset\n\t\t\tif (!internalResolution && user.preset) {\n\t\t\t\tconst res = getPresetResolution(user.preset as RetroPresetKey, user.resolution);\n\t\t\t\tif (res) internalResolution = { width: res.width, height: res.height };\n\t\t\t}\n\t\t} else if (typeof user.resolution === 'object') {\n\t\t\tconst w = (user.resolution as any).width;\n\t\t\tconst h = (user.resolution as any).height;\n\t\t\tif (Number.isFinite(w) && Number.isFinite(h)) {\n\t\t\t\tinternalResolution = { width: w, height: h };\n\t\t\t}\n\t\t}\n\t}\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}","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\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","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","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 { GameCanvas } from './game-canvas';\nimport { GameConfig } from './game-config';\n\n/**\n * Observer that triggers renderer mounting when container and camera are both available.\n * Decouples renderer mounting from stage loading.\n */\nexport class GameRendererObserver {\n\tprivate container: HTMLElement | null = null;\n\tprivate camera: ZylemCamera | null = null;\n\tprivate gameCanvas: GameCanvas | null = null;\n\tprivate config: GameConfig | 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\tsetCamera(camera: ZylemCamera): void {\n\t\tthis.camera = camera;\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.camera || !this.gameCanvas) return;\n\n\t\tconst dom = this.camera.getDomElement();\n\t\tconst internal = this.config?.internalResolution;\n\t\t\n\t\tthis.gameCanvas.mountRenderer(dom, (cssW, cssH) => {\n\t\t\tif (!this.camera) return;\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.mounted = false;\n\t}\n\n\tdispose(): void {\n\t\tthis.container = null;\n\t\tthis.camera = null;\n\t\tthis.gameCanvas = null;\n\t\tthis.config = null;\n\t\tthis.mounted = false;\n\t}\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 { Timer } from '../core/three-addons/Timer';\nimport { ZylemCamera } from '~/lib/camera/zylem-camera';\nimport { Stage } from '../stage/stage';\nimport { BaseGlobals, ZylemGameConfig } from './game-interfaces';\nimport { GameConfig, resolveGameConfig } 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\nexport class ZylemGame<TGlobals extends BaseGlobals> {\n\tid: string;\n\tinitialGlobals = {} as TGlobals;\n\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\tdefaultCamera: ZylemCamera | 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\n\tstatic FRAME_LIMIT = 120;\n\tstatic FRAME_DURATION = 1000 / ZylemGame.FRAME_LIMIT;\n\tstatic MAX_DELTA_SECONDS = 1 / 30;\n\n\tconstructor(options: ZylemGameOptions<TGlobals>, wrapperRef: Game<TGlobals>) {\n\t\tthis.wrapperRef = wrapperRef;\n\t\tthis.timer = new Timer();\n\t\tthis.timer.connect(document);\n\t\t\n\t\tconsole.log('[ZylemGame] options:', options);\n\t\tconsole.log('[ZylemGame] options.input:', options.input);\n\t\t\n\t\t// Resolve config first to get the proper input configuration\n\t\tconst config = resolveGameConfig(options as any);\n\t\tconsole.log(config);\n\t\tconsole.log('[ZylemGame] config.input:', config.input);\n\t\t\n\t\t// Now create InputManager with the resolved config's input settings\n\t\tthis.inputManager = new InputManager(config.input);\n\t\t\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\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\tloadStage(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// Start stage loading and return promise for backward compatibility\n\t\treturn stage.load(this.id, config?.camera as ZylemCamera | null).then(() => {\n\t\t\tthis.stageMap.set(stage.wrappedStage!.uuid, stage);\n\t\t\tthis.currentStageId = stage.wrappedStage!.uuid;\n\t\t\tthis.defaultCamera = stage.wrappedStage!.cameraRef!;\n\t\t\t\n\t\t\t// Trigger renderer observer with new camera\n\t\t\tif (this.defaultCamera) {\n\t\t\t\tthis.rendererObserver.setCamera(this.defaultCamera);\n\t\t\t}\n\n\t\t\t// Emit state dispatch after stage is loaded so editor receives initial config\n\t\t\tthis.emitStateDispatch('@stage:loaded');\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\t\t\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\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\t\treturn {\n\t\t\tdelta,\n\t\t\tinputs,\n\t\t\tglobals: getGlobals<TGlobals>(),\n\t\t\tme: this,\n\t\t\tcamera: camera!,\n\t\t};\n\t}\n\n\tstart() {\n\t\tconst stage = this.currentStage();\n\t\tconst params = this.params();\n\t\tstage!.start({ ...params, me: stage!.wrappedStage as ZylemStage });\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\tconst clampedParams = { ...params, delta: clampedDelta };\n\n\t\tif (this.customUpdate) {\n\t\t\tthis.customUpdate(clampedParams);\n\t\t}\n\n\t\tstage.wrappedStage?.nodeUpdate({ ...clampedParams, me: stage.wrappedStage as ZylemStage });\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.loop.bind(this));\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\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\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._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 * 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\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>;\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 */\n\tprotected lifecycleCallbacks: LifecycleCallbacks<this> = {\n\t\tsetup: [],\n\t\tloaded: [],\n\t\tupdate: [],\n\t\tdestroy: [],\n\t\tcleanup: [],\n\t};\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\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\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\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\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\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\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\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\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>): Promise<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\n\t\t// 1. Internal setup\n\t\tif (typeof this._setup === 'function') {\n\t\t\tthis._setup(params);\n\t\t}\n\n\t\t// 2. Run all setup callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.setup) {\n\t\t\tcallback(params);\n\t\t}\n\n\t\t// 3. Setup children\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\n\t\t// 1. Internal update\n\t\tif (typeof this._update === 'function') {\n\t\t\tthis._update(params);\n\t\t}\n\n\t\t// 2. Run all update callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.update) {\n\t\t\tcallback(params);\n\t\t}\n\n\t\t// 3. Update children\n\t\tthis.children.forEach(child => child.nodeUpdate(params));\n\t}\n\n\tpublic nodeDestroy(params: DestroyContext<this>): void {\n\t\t// 1. Destroy children first\n\t\tthis.children.forEach(child => child.nodeDestroy(params));\n\n\t\t// 2. Run all destroy callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.destroy) {\n\t\t\tcallback(params);\n\t\t}\n\n\t\t// 3. Internal destroy\n\t\tif (typeof this._destroy === 'function') {\n\t\t\tthis._destroy(params);\n\t\t}\n\n\t\tthis.markedForRemoval = true;\n\t}\n\n\tpublic async nodeLoaded(params: LoadedContext<this>): Promise<void> {\n\t\t// 1. Internal loaded\n\t\tif (typeof this._loaded === 'function') {\n\t\t\tawait this._loaded(params);\n\t\t}\n\n\t\t// 2. Run all loaded callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.loaded) {\n\t\t\tcallback(params);\n\t\t}\n\t}\n\n\tpublic async nodeCleanup(params: CleanupContext<this>): Promise<void> {\n\t\t// 1. Run all cleanup callbacks in order\n\t\tfor (const callback of this.lifecycleCallbacks.cleanup) {\n\t\t\tcallback(params);\n\t\t}\n\n\t\t// 2. Internal cleanup\n\t\tif (typeof this._cleanup === 'function') {\n\t\t\tawait this._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}","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 RAPIER from '@dimforge/rapier3d-compat';\n\nexport type StageSystem = {\n\t_childrenMap: Map<number, StageEntity & { body: RAPIER.RigidBody }>;\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\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\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) {\n\t\t\t\ttarget.position.set(translation.x, translation.y, translation.z);\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) {\n\t\t\t\t_tempQuaternion.set(rot.x, rot.y, rot.z, rot.w);\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}","import { Mesh, Material, ShaderMaterial, Group, Color } from 'three';\nimport {\n Collider,\n ColliderDesc,\n RigidBody,\n RigidBodyDesc,\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 DestroyContext,\n SetupContext,\n UpdateContext,\n LoadedContext,\n CleanupContext,\n} from '../core/base-node-life-cycle';\nimport type { EntityMeshBuilder, EntityCollisionBuilder } from './builder';\nimport { Behavior } from '../actions/behaviors/behavior';\nimport {\n EventEmitterDelegate,\n zylemEventBus,\n type EntityEvents,\n} from '../events';\nimport type {\n BehaviorDescriptor,\n BehaviorRef,\n BehaviorHandle,\n} from '../behaviors/behavior-descriptor';\n\nexport interface CollisionContext<\n T,\n O extends GameEntityOptions,\n TGlobals extends Record<string, unknown> = any,\n> {\n entity: T;\n // Use 'any' for other's options type to break recursive type variance issues\n other: GameEntity<O | any>;\n globals: TGlobals;\n}\n\nexport type BehaviorContext<T, O extends GameEntityOptions> =\n | SetupContext<T, O>\n | UpdateContext<T, O>\n | CollisionContext<T, O>\n | DestroyContext<T, O>;\n\nexport type BehaviorCallback<T, O extends GameEntityOptions> = (\n params: BehaviorContext<T, O>,\n) => void;\n\nexport interface CollisionDelegate<T, O extends GameEntityOptions> {\n // Use 'any' for entity and options types to avoid contravariance issues\n // with function parameters. Type safety is still enforced at the call site via onCollision()\n collision?: ((params: CollisionContext<any, any>) => void)[];\n}\n\nexport type IBuilder<BuilderOptions = any> = {\n preBuild: (options: BuilderOptions) => BuilderOptions;\n build: (options: BuilderOptions) => BuilderOptions;\n postBuild: (options: BuilderOptions) => BuilderOptions;\n};\n\nexport type GameEntityOptions = {\n name?: string;\n color?: Color;\n size?: Vec3;\n position?: Vec3;\n batched?: boolean;\n collision?: Partial<CollisionOptions>;\n material?: Partial<MaterialOptions>;\n custom?: { [key: string]: any };\n collisionType?: string;\n collisionGroup?: string;\n collisionFilter?: string[];\n _builders?: {\n meshBuilder?: IBuilder | EntityMeshBuilder | null;\n collisionBuilder?: IBuilder | EntityCollisionBuilder | null;\n materialBuilder?: MaterialBuilder | null;\n };\n};\n\nexport abstract class GameEntityLifeCycle {\n abstract _setup(params: SetupContext<this>): void;\n abstract _update(params: UpdateContext<this>): void;\n abstract _destroy(params: DestroyContext<this>): void;\n}\n\nexport interface EntityDebugInfo {\n buildInfo: () => Record<string, string>;\n}\n\nexport type BehaviorCallbackType = 'setup' | 'update' | 'destroy' | 'collision';\n\nexport class GameEntity<O extends GameEntityOptions>\n extends BaseNode<O>\n implements GameEntityLifeCycle, EntityDebugInfo\n{\n public behaviors: Behavior[] = [];\n public group: Group | undefined;\n public mesh: Mesh | undefined;\n public materials: Material[] | undefined;\n public bodyDesc: RigidBodyDesc | null = null;\n public body: RigidBody | null = null;\n public colliderDesc: ColliderDesc | undefined;\n public collider: Collider | undefined;\n public custom: Record<string, any> = {};\n\n public debugInfo: Record<string, any> = {};\n public debugMaterial: ShaderMaterial | undefined;\n\n public collisionDelegate: CollisionDelegate<this, O> = {\n collision: [],\n };\n public collisionType?: string;\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * Use 'any' for callback types to avoid contravariance issues\n * with function parameters. Type safety is enforced where callbacks are registered.\n */\n public behaviorCallbackMap: Record<\n BehaviorCallbackType,\n BehaviorCallback<any, any>[]\n > = {\n setup: [],\n update: [],\n destroy: [],\n collision: [],\n };\n\n // Event delegate for dispatch/listen API\n protected eventDelegate = new EventEmitterDelegate<EntityEvents>();\n\n // Behavior references (new ECS pattern)\n private behaviorRefs: BehaviorRef[] = [];\n\n constructor() {\n super();\n }\n\n public create(): this {\n const { position: setupPosition } = this.options;\n const { x, y, z } = setupPosition || { x: 0, y: 0, z: 0 };\n this.behaviors = [\n { component: position, values: { x, y, z } },\n { component: scale, values: { x: 0, y: 0, z: 0 } },\n { component: rotation, values: { x: 0, y: 0, z: 0, w: 0 } },\n ];\n this.name = this.options.name || '';\n return this;\n }\n\n /**\n * Add collision callbacks\n */\n public onCollision(\n ...callbacks: ((params: CollisionContext<this, O>) => void)[]\n ): this {\n const existing = this.collisionDelegate.collision ?? [];\n this.collisionDelegate.collision = [...existing, ...callbacks];\n return this;\n }\n\n /**\n * Use a behavior on this entity via typed descriptor.\n * Behaviors will be auto-registered as systems when the entity is spawned.\n * @param descriptor The behavior descriptor (import from behaviors module)\n * @param options Optional overrides for the behavior's default options\n * @returns BehaviorHandle with behavior-specific methods for lazy FSM access\n */\n public use<\n O extends Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n >(\n descriptor: BehaviorDescriptor<O, H>,\n options?: Partial<O>,\n ): BehaviorHandle<O, H> {\n const behaviorRef: BehaviorRef<O> = {\n descriptor: descriptor as BehaviorDescriptor<O, any>,\n options: { ...descriptor.defaultOptions, ...options } as O,\n };\n this.behaviorRefs.push(behaviorRef as BehaviorRef<any>);\n\n // Create base handle\n const baseHandle = {\n getFSM: () => behaviorRef.fsm ?? null,\n getOptions: () => behaviorRef.options,\n ref: behaviorRef,\n };\n\n // Merge behavior-specific methods if createHandle is provided\n const customMethods = descriptor.createHandle?.(behaviorRef) ?? ({} as H);\n\n return {\n ...baseHandle,\n ...customMethods,\n } as BehaviorHandle<O, H>;\n }\n\n /**\n * Get all behavior references attached to this entity.\n * Used by the stage to auto-register required systems.\n */\n public getBehaviorRefs(): BehaviorRef[] {\n return this.behaviorRefs;\n }\n\n /**\n * Entity-specific setup - runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)\n */\n public _setup(params: SetupContext<this>): void {\n this.behaviorCallbackMap.setup.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n protected async _loaded(_params: LoadedContext<this>): Promise<void> {}\n\n /**\n * Entity-specific update - updates materials and runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)\n */\n public _update(params: UpdateContext<this>): void {\n this.updateMaterials(params);\n this.behaviorCallbackMap.update.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n /**\n * Entity-specific destroy - runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.destroy)\n */\n public _destroy(params: DestroyContext<this>): void {\n this.behaviorCallbackMap.destroy.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n protected async _cleanup(_params: CleanupContext<this>): Promise<void> {}\n\n public _collision(other: GameEntity<O>, globals?: any): void {\n if (this.collisionDelegate.collision?.length) {\n const callbacks = this.collisionDelegate.collision;\n callbacks.forEach((callback) => {\n callback({ entity: this, other, globals });\n });\n }\n this.behaviorCallbackMap.collision.forEach((callback) => {\n callback({ entity: this, other, globals });\n });\n }\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * See `lib/behaviors/thruster/thruster-movement.behavior.ts` for an example.\n */\n public addBehavior(behaviorCallback: {\n type: BehaviorCallbackType;\n handler: any;\n }): this {\n const handler = behaviorCallback.handler as unknown as BehaviorCallback<\n this,\n O\n >;\n if (handler) {\n this.behaviorCallbackMap[behaviorCallback.type].push(handler);\n }\n return this;\n }\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * See `lib/behaviors/thruster/thruster-movement.behavior.ts` for an example.\n */\n public addBehaviors(\n behaviorCallbacks: { type: BehaviorCallbackType; handler: any }[],\n ): this {\n behaviorCallbacks.forEach((callback) => {\n const handler = callback.handler as unknown as BehaviorCallback<this, O>;\n if (handler) {\n this.behaviorCallbackMap[callback.type].push(handler);\n }\n });\n return this;\n }\n\n protected updateMaterials(params: any) {\n if (!this.materials?.length) {\n return;\n }\n for (const material of this.materials) {\n if (material instanceof ShaderMaterial) {\n if (material.uniforms) {\n material.uniforms.iTime &&\n (material.uniforms.iTime.value += params.delta);\n }\n }\n }\n }\n\n public buildInfo(): Record<string, string> {\n const info: Record<string, string> = {};\n info.name = this.name;\n info.uuid = this.uuid;\n info.eid = this.eid.toString();\n return info;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Events API\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Dispatch an event from this entity.\n * Events are emitted both locally and to the global event bus.\n */\n dispatch<K extends keyof EntityEvents>(\n event: K,\n payload: EntityEvents[K],\n ): void {\n this.eventDelegate.dispatch(event, payload);\n (zylemEventBus as any).emit(event, payload);\n }\n\n /**\n * Listen for events on this entity instance.\n * @returns Unsubscribe function\n */\n listen<K extends keyof EntityEvents>(\n event: K,\n handler: (payload: EntityEvents[K]) => void,\n ): () => void {\n return this.eventDelegate.listen(event, handler);\n }\n\n /**\n * Clean up entity event subscriptions.\n */\n disposeEvents(): void {\n this.eventDelegate.dispose();\n }\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 { GameEntityOptions, GameEntity } 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};\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} = 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 builder.build();\n}\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","/**\n * GLTF loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parseAsync\n */\n\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\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\n\tconstructor() {\n\t\tthis.loader = new GLTFLoader();\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: result.object.clone(),\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';\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: result.object.clone(),\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';\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: result.object.clone(),\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) => options?.clone ? this.textureLoader.clone(texture) : texture\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';\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): 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);\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);\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);\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\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\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\tthis._animations = results\n\t\t\t.filter((r): r is AssetLoaderResult => !!r.animation)\n\t\t\t.map(r => r.animation!);\n\n\t\tif (!this._animations.length) return;\n\n\t\tthis._mixer = new AnimationMixer(this.target);\n\t\tthis._animations.forEach((clip, i) => {\n\t\t\tconst key = animations[i].key || i.toString();\n\t\t\tthis._actions[key] = this._mixer!.clipAction(clip);\n\t\t});\n\n\t\tthis.playAnimation({ key: Object.keys(this._actions)[0] });\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\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\tif (prev) prev.stop();\n\n\t\tconst action = this._actions[key];\n\t\tif (!action) return;\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\tif (prev) {\n\t\t\tprev.crossFadeTo(action, fadeDuration, false);\n\t\t}\n\t\taction.reset().play();\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 { 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 { 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}","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 {\n\tColor,\n\tMaterial,\n\tMeshPhongMaterial,\n\tMeshStandardMaterial,\n\tNormalBlending,\n\tRepeatWrapping,\n\tShaderMaterial,\n\tVector2,\n\tVector3\n} from 'three';\nimport { shortHash, sortedStringify } from '../core/utility/strings';\nimport { standardShader } from './shaders/standard.shader';\nimport { assetManager } from '../core/asset-manager';\n\nexport type ZylemShaderObject = { fragment: string, vertex: string };\n\nexport interface MaterialOptions {\n\tpath?: string;\n\trepeat?: Vector2;\n\tshader?: ZylemShaderObject;\n\tcolor?: Color;\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\nexport class MaterialBuilder {\n\tstatic batchMaterialMap: Map<BatchKey, BatchMaterialMapObject> = new Map();\n\n\tmaterials: Material[] = [];\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(\n\t\t\t\tbatchKey, {\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, repeat, color, shader } = options;\n\t\t// If shader is provided, use it; otherwise execute standard logic\n\t\tif (shader) {\n\t\t\tthis.withShader(shader);\n\t\t} else if (path) {\n\t\t\t// If path provided but no shader, standard texture logic applies\n\t\t\tthis.setTexture(path, repeat);\n\t\t}\n\t\t\n\t\tif (color) {\n\t\t\t// standard color material if no custom shader\n\t\t\tthis.withColor(color);\n\t\t}\n\n\t\tif (this.materials.length === 0) {\n\t\t\tthis.setColor(new Color('#ffffff'));\n\t\t}\n\t\tthis.batchMaterial(options, entityType);\n\t}\n\n\twithColor(color: Color): this {\n\t\tthis.setColor(color);\n\t\treturn this;\n\t}\n\n\twithShader(shader: ZylemShaderObject): this {\n\t\tthis.setShader(shader);\n\t\treturn this;\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(texturePath: TexturePath = null, repeat: Vector2 = new Vector2(1, 1)): void {\n\t\tif (!texturePath) {\n\t\t\treturn;\n\t\t}\n\t\t// Create material immediately with null map\n\t\tconst material = new MeshPhongMaterial({\n\t\t\tmap: null,\n\t\t});\n\t\tthis.materials.push(material);\n\n\t\t// Load texture in background and apply when ready\n\t\tassetManager.loadTexture(texturePath as string, { \n\t\t\tclone: true,\n\t\t\trepeat \n\t\t}).then(texture => {\n\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\tmaterial.map = texture;\n\t\t\tmaterial.needsUpdate = true;\n\t\t});\n\t}\n\n\tsetColor(color: Color) {\n\t\tconst material = new MeshStandardMaterial({\n\t\t\tcolor: color,\n\t\t\temissiveIntensity: 0.5,\n\t\t\tlightMapIntensity: 0.5,\n\t\t\tfog: true,\n\t\t});\n\n\t\tthis.materials.push(material);\n\t}\n\n\tsetShader(customShader: ZylemShaderObject) {\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},\n\t\t\tvertexShader: vertex,\n\t\t\tfragmentShader: fragment,\n\t\t\ttransparent: true,\n\t\t\t// blending: NormalBlending\n\t\t});\n\t\tthis.materials.push(shader);\n\t}\n}\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\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}","import { Color, Vector3 } from 'three';\nimport { standardShader } from '../graphics/shaders/standard.shader';\nimport { GameEntityOptions } from './entity';\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","import { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BufferGeometry, Object3D, SkinnedMesh, Mesh, MeshStandardMaterial, Group, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { createEntity } from './create';\nimport { UpdateContext, UpdateFunction } from '../core/base-node-life-cycle';\nimport { 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 } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { commonDefaults } from './common';\nimport { standardShader } from '~/api/main';\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport type CollisionShapeType = 'capsule' | 'model';\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n\tcollisionShape?: CollisionShapeType;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\t...commonDefaults,\n\tcollision: {\n\t\tstatic: false,\n\t\tsize: new Vector3(0.5, 0.5, 0.5),\n\t\tposition: new Vector3(0, 0, 0),\n\t},\n\tmaterial: {\n\t\tshader: standardShader\n\t},\n\tanimations: [],\n\tmodels: [],\n\tcollisionShape: 'capsule',\n};\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate objectModel: Group | null = null;\n\tprivate collisionShape: CollisionShapeType = 'capsule';\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t\tthis.collisionShape = data.collisionShape ?? 'capsule';\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tif (this.collisionShape === 'model') {\n\t\t\treturn this.createColliderFromModel(this.objectModel, options);\n\t\t}\n\t\treturn this.createCapsuleCollider(options);\n\t}\n\n\t/**\n\t * Create a capsule collider based on size options (character controller style).\n\t */\n\tprivate createCapsuleCollider(options: ZylemActorOptions): ColliderDesc {\n\t\tconst size = options.collision?.size ?? options.size ?? { x: 0.5, y: 1, z: 0.5 };\n\t\tconst halfHeight = ((size as any).y || 1);\n\t\tconst radius = Math.max((size as any).x || 0.5, (size as any).z || 0.5);\n\t\tlet colliderDesc = ColliderDesc.capsule(halfHeight, radius);\n\t\tcolliderDesc.setSensor(false);\n\t\tcolliderDesc.setTranslation(0, halfHeight + radius, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n\n\t/**\n\t * Create a collider based on model geometry (works with Mesh and SkinnedMesh).\n\t * If collision.size and collision.position are provided, use those instead of computing from geometry.\n\t */\n\tprivate createColliderFromModel(objectModel: Group | null, options: ZylemActorOptions): ColliderDesc {\n\t\tconst collisionSize = options.collision?.size;\n\t\tconst collisionPosition = options.collision?.position;\n\n\t\t// If user provided explicit size, use that instead of computing from model\n\t\tif (collisionSize) {\n\t\t\tconst halfWidth = (collisionSize as any).x / 2;\n\t\t\tconst halfHeight = (collisionSize as any).y / 2;\n\t\t\tconst halfDepth = (collisionSize as any).z / 2;\n\n\t\t\tlet colliderDesc = ColliderDesc.cuboid(halfWidth, halfHeight, halfDepth);\n\t\t\tcolliderDesc.setSensor(false);\n\n\t\t\t// Use user-provided position or default to center\n\t\t\tconst posX = collisionPosition ? (collisionPosition as any).x : 0;\n\t\t\tconst posY = collisionPosition ? (collisionPosition as any).y : halfHeight;\n\t\t\tconst posZ = collisionPosition ? (collisionPosition as any).z : 0;\n\t\t\tcolliderDesc.setTranslation(posX, posY, posZ);\n\t\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\t\treturn colliderDesc;\n\t\t}\n\n\t\t// Fall back to computing from model geometry\n\t\tif (!objectModel) return this.createCapsuleCollider(options);\n\n\t\t// Find first Mesh (SkinnedMesh or regular Mesh)\n\t\tlet foundGeometry: BufferGeometry | null = null;\n\t\tobjectModel.traverse((child) => {\n\t\t\tif (!foundGeometry && (child as any).isMesh) {\n\t\t\t\tfoundGeometry = (child as Mesh).geometry as BufferGeometry;\n\t\t\t}\n\t\t});\n\n\t\tif (!foundGeometry) return this.createCapsuleCollider(options);\n\n\t\tconst geometry: BufferGeometry = foundGeometry;\n\t\tgeometry.computeBoundingBox();\n\t\tconst box = geometry.boundingBox;\n\t\tif (!box) return this.createCapsuleCollider(options);\n\n\t\tconst height = box.max.y - box.min.y;\n\t\tconst width = box.max.x - box.min.x;\n\t\tconst depth = box.max.z - box.min.z;\n\n\t\t// Create box collider based on mesh bounds\n\t\tlet colliderDesc = ColliderDesc.cuboid(width / 2, height / 2, depth / 2);\n\t\tcolliderDesc.setSensor(false);\n\t\t// Position collider at center of model\n\t\tconst centerY = (box.max.y + box.min.y) / 2;\n\t\tcolliderDesc.setTranslation(0, centerY, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\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 _animationDelegate: AnimationDelegate | null = null;\n\tprivate _modelFileNames: string[] = [];\n\tprivate _assetLoader: EntityAssetLoader = new EntityAssetLoader();\n\n\tcontrolledRotation: boolean = false;\n\n\tconstructor(options?: ZylemActorOptions) {\n\t\tsuper();\n\t\tthis.options = { ...actorDefaults, ...options };\n\t\t// Add actor-specific update to the lifecycle callbacks\n\t\tthis.prependUpdate(this.actorUpdate.bind(this) as UpdateFunction<this>);\n\t\tthis.controlledRotation = true;\n\t}\n\n\t/**\n\t * Initiates model and animation loading in background (deferred).\n\t * Call returns immediately; assets will be ready on subsequent updates.\n\t */\n\tload(): void {\n\t\tthis._modelFileNames = this.options.models || [];\n\t\t// Start async loading in background\n\t\tthis.loadModelsDeferred();\n\t}\n\n\t/**\n\t * Returns current data synchronously.\n\t * May return null values if loading is still in progress.\n\t */\n\tdata(): any {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t\tcollisionShape: this.options.collisionShape,\n\t\t};\n\t}\n\n\tactorUpdate(params: UpdateContext<ZylemActorOptions>): void {\n\t\tthis._animationDelegate?.update(params.delta);\n\t}\n\n\t/**\n\t * Clean up actor resources including animations, models, and groups\n\t */\n\tactorDestroy(): void {\n\t\t// Stop and dispose animation delegate\n\t\tif (this._animationDelegate) {\n\t\t\tthis._animationDelegate.dispose();\n\t\t\tthis._animationDelegate = null;\n\t\t}\n\n\t\t// Dispose geometries and materials from loaded object\n\t\tif (this._object) {\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tconst mesh = child as SkinnedMesh;\n\t\t\t\t\tmesh.geometry?.dispose();\n\t\t\t\t\tif (Array.isArray(mesh.material)) {\n\t\t\t\t\t\tmesh.material.forEach(m => m.dispose());\n\t\t\t\t\t} else if (mesh.material) {\n\t\t\t\t\t\tmesh.material.dispose();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._object = null;\n\t\t}\n\n\t\t// Clear group reference\n\t\tif (this.group) {\n\t\t\tthis.group.clear();\n\t\t\tthis.group = null as any;\n\t\t}\n\n\t\t// Clear file name references\n\t\tthis._modelFileNames = [];\n\t}\n\n\t/**\n\t * Deferred loading - starts async load and updates entity when complete.\n\t * Called by synchronous load() method.\n\t */\n\tprivate loadModelsDeferred(): void {\n\t\tif (this._modelFileNames.length === 0) return;\n\n\t\t// Emit loading started event\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 promises = this._modelFileNames.map(file => this._assetLoader.loadFile(file));\n\t\tPromise.all(promises).then(results => {\n\t\t\tif (results[0]?.object) {\n\t\t\t\tthis._object = results[0].object;\n\t\t\t}\n\t\t\t// Count meshes for the loaded event\n\t\t\tlet meshCount = 0;\n\t\t\tif (this._object) {\n\t\t\t\tthis._object.traverse((child) => {\n\t\t\t\t\tif ((child as any).isMesh) meshCount++;\n\t\t\t\t});\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.attach(this._object);\n\t\t\t\tthis.group.scale.set(\n\t\t\t\t\tthis.options.scale?.x || 1,\n\t\t\t\t\tthis.options.scale?.y || 1,\n\t\t\t\t\tthis.options.scale?.z || 1\n\t\t\t\t);\n\n\t\t\t\t// Apply material overrides if specified\n\t\t\t\tthis.applyMaterialOverrides();\n\n\t\t\t\t// Load animations after model is ready\n\t\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\t\tthis._animationDelegate.loadAnimations(this.options.animations || []).then(() => {\n\t\t\t\t\tthis.dispatch('entity:animation:loaded', {\n\t\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\t\tanimationCount: this.options.animations?.length || 0\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Emit model loaded event\n\t\t\tthis.dispatch('entity:model:loaded', {\n\t\t\t\tentityId: this.uuid,\n\t\t\t\tsuccess: !!this._object,\n\t\t\t\tmeshCount\n\t\t\t});\n\t\t});\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\t/**\n\t * Apply material overrides from options to all meshes in the loaded model.\n\t * Only applies if material options are explicitly specified (not just defaults).\n\t */\n\tprivate applyMaterialOverrides(): void {\n\t\tconst materialOptions = this.options.material;\n\t\t// Only apply if user specified material options beyond defaults\n\t\tif (!materialOptions || (!materialOptions.color && !materialOptions.path)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._object) return;\n\n\t\tthis._object.traverse((child) => {\n\t\t\tif ((child as any).isMesh) {\n\t\t\t\tconst mesh = child as Mesh;\n\t\t\t\tif (materialOptions.color) {\n\t\t\t\t\t// Create new material with the specified color\n\t\t\t\t\tconst newMaterial = new MeshStandardMaterial({\n\t\t\t\t\t\tcolor: materialOptions.color,\n\t\t\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\t\t\tfog: true,\n\t\t\t\t\t});\n\t\t\t\t\tmesh.castShadow = true;\n\t\t\t\t\tmesh.receiveShadow = true;\n\t\t\t\t\tmesh.material = newMaterial;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\t/**\n\t * Provide custom debug information for the actor\n\t * This will be merged with the default debug information\n\t */\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};\n\n\t\t// Add animation info if available\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\t// Add mesh info if model is loaded\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\tmeshCount++;\n\t\t\t\t\tconst geometry = (child as SkinnedMesh).geometry;\n\t\t\t\t\tif (geometry && geometry.attributes.position) {\n\t\t\t\t\t\tvertexCount += geometry.attributes.position.count;\n\t\t\t\t\t}\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\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});\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 { GameEntity } from '../entities/entity';\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 class ZylemWorld implements Entity<ZylemWorld> {\n\ttype = 'World';\n\tworld: World;\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\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\tconstructor(world: World) {\n\t\tthis.world = world;\n\t}\n\n\taddEntity(entity: any) {\n\t\tconst rigidBody = this.world.createRigidBody(entity.bodyDesc);\n\t\tentity.body = rigidBody;\n\t\t// TODO: consider passing in more specific data\n\t\tentity.body.userData = { uuid: entity.uuid, ref: entity };\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\t\tconst collider = this.world.createCollider(entity.colliderDesc, entity.body);\n\t\tentity.collider = collider;\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\tsetForRemoval(entity: any) {\n\t\tif (entity.body) {\n\t\t\tthis._removalMap.set(entity.uuid, entity);\n\t\t}\n\t}\n\n\tdestroyEntity(entity: GameEntity<any>) {\n\t\tif (entity.collider) {\n\t\t\tthis.world.removeCollider(entity.collider, true);\n\t\t}\n\t\tif (entity.body) {\n\t\t\tthis.world.removeRigidBody(entity.body);\n\t\t\tthis.collisionMap.delete(entity.uuid);\n\t\t\tthis._removalMap.delete(entity.uuid);\n\t\t}\n\t}\n\n\tsetup() { }\n\n\tupdate(params: UpdateContext<any>) {\n\t\tconst { delta } = params;\n\t\tif (!this.world) {\n\t\t\treturn;\n\t\t}\n\t\tthis.updateColliders(delta);\n\t\tthis.updatePostCollisionBehaviors(delta);\n\t\tthis.world.step();\n\t}\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\treturn;\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\tupdateColliders(delta: number) {\n\t\tconst dictionaryRef = this.collisionMap;\n\t\tfor (let [id, collider] of dictionaryRef) {\n\t\t\tconst gameEntity = collider as GameEntity<any>;\n\t\t\tif (!gameEntity.body) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this._removalMap.get(gameEntity.uuid)) {\n\t\t\t\tthis.destroyEntity(gameEntity);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.world.contactsWith(gameEntity.body.collider(0), (otherCollider) => {\n\t\t\t\tif (!otherCollider) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst uuid = otherCollider._parent.userData.uuid;\n\t\t\t\tconst entity = dictionaryRef.get(uuid);\n\t\t\t\tif (!entity) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (gameEntity._collision) {\n\t\t\t\t\tgameEntity._collision(entity, state.globals);\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.world.intersectionsWith(gameEntity.body.collider(0), (otherCollider) => {\n\t\t\t\tif (!otherCollider) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst uuid = otherCollider._parent.userData.uuid;\n\t\t\t\tconst entity = dictionaryRef.get(uuid);\n\t\t\t\tif (!entity) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (gameEntity._collision) {\n\t\t\t\t\tgameEntity._collision(entity, state.globals);\n\t\t\t\t}\n\t\t\t\tif (isCollisionHandlerDelegate(entity)) {\n\t\t\t\t\tentity.handleIntersectionEvent({ entity, other: gameEntity, delta });\n\t\t\t\t\tthis.collisionBehaviorMap.set(uuid, entity);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tdestroy() {\n\t\ttry {\n\t\t\tfor (const [, entity] of this.collisionMap) {\n\t\t\t\ttry { this.destroyEntity(entity); } catch { /* noop */ }\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\t// @ts-ignore\n\t\t\tthis.world = undefined as any;\n\t\t} catch { /* noop */ }\n\t}\n\n}","import {\n\tScene,\n\tColor,\n\tAmbientLight,\n\tDirectionalLight,\n\tObject3D,\n\tVector3,\n\tGridHelper,\n\tSphereGeometry,\n\tBoxGeometry,\n\tShaderMaterial,\n\tMesh,\n\tBackSide\n} from 'three';\nimport { Entity, LifecycleFunction } from '../interfaces/entity';\nimport { GameEntity } from '../entities/entity';\nimport { ZylemCamera } from '../camera/zylem-camera';\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 { ZylemShaderObject } from './material';\n\ninterface SceneState {\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | null;\n\tbackgroundShader?: ZylemShaderObject | null;\n}\n\nexport class ZylemScene implements Entity<ZylemScene> {\n\tpublic type = 'Scene';\n\n\t_setup?: SetupFunction<ZylemScene>;\n\tscene!: Scene;\n\tzylemCamera!: ZylemCamera;\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\n\tprivate skyboxMaterial: ShaderMaterial | 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\tthis.setupCamera(scene, camera);\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 * Uses the pos.xyww trick to ensure skybox is always at maximum depth\n\t */\n\tprivate setupBackgroundShader(scene: Scene, shader: ZylemShaderObject) {\n\t\t// Clear the solid color background\n\t\tscene.background = null;\n\n\t\t// Skybox vertex shader with depth trick (pos.xyww ensures depth = 1.0)\n\t\tconst skyboxVertexShader = `\n\t\t\tvarying vec2 vUv;\n\t\t\tvarying vec3 vWorldPosition;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvUv = uv;\n\t\t\t\tvec4 worldPosition = modelMatrix * vec4(position, 1.0);\n\t\t\t\tvWorldPosition = worldPosition.xyz;\n\t\t\t\tvec4 pos = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n\t\t\t\tgl_Position = pos.xyww; // Ensures depth is always 1.0 (farthest)\n\t\t\t}\n\t\t`;\n\n\t\t// Create shader material with skybox-specific settings\n\t\tthis.skyboxMaterial = new ShaderMaterial({\n\t\t\tvertexShader: skyboxVertexShader,\n\t\t\tfragmentShader: shader.fragment,\n\t\t\tuniforms: {\n\t\t\t\tiTime: { value: 0.0 },\n\t\t\t},\n\t\t\tside: BackSide, // Render on inside of geometry\n\t\t\tdepthWrite: false, // Don't write to depth buffer\n\t\t\tdepthTest: true, // But do test depth\n\t\t});\n\n\t\t// Use BoxGeometry for skybox (like the CodePen example)\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\t\n\t\tconsole.log('Skybox created with pos.xyww technique');\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\tif (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\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\tif (Array.isArray(obj.material)) {\n\t\t\t\t\t\tobj.material.forEach((m: any) => m.dispose?.());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tobj.material.dispose?.();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\t/**\n\t * Setup camera with the scene\n\t */\n\tsetupCamera(scene: Scene, camera: ZylemCamera) {\n\t\t// Add camera rig or camera directly to scene\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\t// Camera handles its own setup now\n\t\tcamera.setup(scene);\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\n\t */\n\tupdateRenderer(width: number, height: number) {\n\t\tthis.zylemCamera.resize(width, height);\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\tif (entity.group) {\n\t\t\tthis.add(entity.group, entity.options.position);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.add(entity.mesh, entity.options.position);\n\t\t}\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 position = entity.body\n\t\t\t? new Vector3(\n\t\t\t\tentity.body.translation().x,\n\t\t\t\tentity.body.translation().y,\n\t\t\t\tentity.body.translation().z\n\t\t\t )\n\t\t\t: entity.options.position;\n\n\t\tif (entity.group) {\n\t\t\tthis.add(entity.group, position);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.add(entity.mesh, position);\n\t\t}\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\n\t */\n\tupdateSkybox(delta: number) {\n\t\tif (this.skyboxMaterial?.uniforms?.iTime) {\n\t\t\tthis.skyboxMaterial.uniforms.iTime.value += delta;\n\t\t}\n\t}\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\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 {\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 { ZylemStage } from './zylem-stage';\nimport { debugState, DebugTools, 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\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 disposeFns: Array<() => void> = [];\n\tprivate debugCursor: DebugEntityCursor | null = null;\n\tprivate debugLines: LineSegments | 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\t\tthis.attachDomListeners();\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\t// Initialize visuals if not already created\n\t\tif (!this.debugLines) {\n\t\t\tthis.initDebugVisuals();\n\t\t}\n\n\t\tconst { world, cameraRef } = this.stage;\n\n\t\tif (this.debugLines) {\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\tthis.raycaster.setFromCamera(this.mouseNdc, cameraRef.camera);\n\t\tconst origin = this.raycaster.ray.origin.clone();\n\t\tconst direction = this.raycaster.ray.direction.clone().normalize();\n\n\t\tconst rapierRay = new Ray(\n\t\t\t{ x: origin.x, y: origin.y, z: origin.z },\n\t\t\t{ x: direction.x, y: direction.y, z: direction.z },\n\t\t);\n\t\tconst hit: RayColliderToi | null = world.world.castRay(rapierRay, this.options.maxRayDistance, true);\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._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) {\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._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\tdispose(): void {\n\t\tthis.disposeFns.forEach((fn) => fn());\n\t\tthis.disposeFns = [];\n\t\tthis.disposeDebugVisuals();\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._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.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.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 = (e: MouseEvent) => {\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.disposeFns.push(() => canvas.removeEventListener('mousemove', onMouseMove));\n\t\tthis.disposeFns.push(() => canvas.removeEventListener('mousedown', onMouseDown));\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._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","export const Perspectives = {\n\tFirstPerson: 'first-person',\n\tThirdPerson: 'third-person',\n\tIsometric: 'isometric',\n\tFlat2D: 'flat-2d',\n\tFixed2D: 'fixed-2d',\n} as const;\n\nexport type PerspectiveType = (typeof Perspectives)[keyof typeof Perspectives];","import { Scene, Vector2, Vector3, WebGLRenderer } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\nimport { StageEntity } from '../interfaces/entity';\n\ninterface ThirdPersonCameraOptions {\n\ttarget: StageEntity;\n\tdistance: Vector3;\n\tscreenResolution: Vector2;\n\trenderer: WebGLRenderer;\n\tscene: Scene;\n}\n\nexport class ThirdPersonCamera implements PerspectiveController {\n\tdistance: Vector3;\n\tscreenResolution: Vector2 | null = null;\n\trenderer: WebGLRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\tconstructor() {\n\t\tthis.distance = new Vector3(0, 5, 8);\n\t}\n\n\t/**\n\t * Setup the third person camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: WebGLRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\t}\n\n\t/**\n\t * Update the third person camera\n\t */\n\tupdate(delta: number) {\n\t\tif (!this.cameraRef!.target) {\n\t\t\treturn;\n\t\t}\n\t\t// TODO: Implement third person camera following logic\n\t\tconst desiredCameraPosition = this.cameraRef!.target!.group.position.clone().add(this.distance);\n\t\tthis.cameraRef!.camera.position.lerp(desiredCameraPosition, 0.1);\n\t\tthis.cameraRef!.camera.lookAt(this.cameraRef!.target!.group.position);\n\t}\n\n\t/**\n\t * Handle resize events\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\t\t// TODO: Handle any third-person specific resize logic\n\t}\n\n\t/**\n\t * Set the distance from the target\n\t */\n\tsetDistance(distance: Vector3) {\n\t\tthis.distance = distance;\n\t}\n}","import { Scene, Vector2, WebGLRenderer } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\n\n/**\n * Fixed 2D Camera Controller\n * Maintains a static 2D camera view with no automatic following or movement\n */\nexport class Fixed2DCamera implements PerspectiveController {\n\tscreenResolution: Vector2 | null = null;\n\trenderer: WebGLRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\tconstructor() {\n\t\t// Fixed 2D camera doesn't need any initial setup parameters\n\t}\n\n\t/**\n\t * Setup the fixed 2D camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: WebGLRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\n\t\t// Position camera for 2D view (looking down the Z-axis)\n\t\tthis.cameraRef.camera.position.set(0, 0, 10);\n\t\tthis.cameraRef.camera.lookAt(0, 0, 0);\n\t}\n\n\t/**\n\t * Update the fixed 2D camera\n\t * Fixed cameras don't need to update position/rotation automatically\n\t */\n\tupdate(delta: number) {\n\t\t// Fixed 2D camera maintains its position and orientation\n\t\t// No automatic updates needed for a truly fixed camera\n\t}\n\n\t/**\n\t * Handle resize events for 2D camera\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\n\t\t// For orthographic cameras, we might need to adjust the frustum\n\t\t// This is handled in the main ZylemCamera resize method\n\t}\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 { 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 and debug state for a camera.\n * Orbit controls are only active when debug mode is enabled.\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\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).\n\t */\n\tget isActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled;\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 * 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\tthis.disableOrbitControls();\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 { Vector2, Camera, PerspectiveCamera, Vector3, Object3D, OrthographicCamera, WebGLRenderer, Scene } from 'three';\nimport { PerspectiveType, Perspectives } from './perspective';\nimport { ThirdPersonCamera } from './third-person';\nimport { Fixed2DCamera } from './fixed-2d';\nimport { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';\nimport RenderPass from '../graphics/render-pass';\nimport { StageEntity } from '../interfaces/entity';\nimport { CameraOrbitController, CameraDebugDelegate } from './camera-debug-delegate';\n\n// Re-export for backwards compatibility\nexport type { CameraDebugState, CameraDebugDelegate } from './camera-debug-delegate';\n\n/**\n * Interface for perspective-specific camera controllers\n */\nexport interface PerspectiveController {\n\tsetup(params: { screenResolution: Vector2; renderer: WebGLRenderer; scene: Scene; camera: ZylemCamera }): void;\n\tupdate(delta: number): void;\n\tresize(width: number, height: number): void;\n}\n\nexport class ZylemCamera {\n\tcameraRig: Object3D | null = null;\n\tcamera: Camera;\n\tscreenResolution: Vector2;\n\trenderer: WebGLRenderer;\n\tcomposer: EffectComposer;\n\t_perspective: PerspectiveType;\n\ttarget: StageEntity | null = null;\n\tsceneRef: Scene | null = null;\n\tfrustumSize = 10;\n\n\t// Perspective controller delegation\n\tperspectiveController: PerspectiveController | null = null;\n\n\t// Debug/orbit controls delegation\n\tprivate orbitController: CameraOrbitController | null = null;\n\n\tconstructor(perspective: PerspectiveType, screenResolution: Vector2, frustumSize: number = 10) {\n\t\tthis._perspective = perspective;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.frustumSize = frustumSize;\n\t\t// Initialize renderer\n\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\tthis.renderer.setSize(screenResolution.x, screenResolution.y);\n\t\tthis.renderer.shadowMap.enabled = true;\n\n\t\t// Initialize composer\n\t\tthis.composer = new EffectComposer(this.renderer);\n\n\t\t// Create camera based on perspective\n\t\tconst aspectRatio = screenResolution.x / screenResolution.y;\n\t\tthis.camera = this.createCameraForPerspective(aspectRatio);\n\n\t\t// Setup camera rig only for perspectives that need it (e.g., third-person following)\n\t\tif (this.needsRig()) {\n\t\t\tthis.cameraRig = new Object3D();\n\t\t\tthis.cameraRig.position.set(0, 3, 10);\n\t\t\tthis.cameraRig.add(this.camera);\n\t\t\tthis.camera.lookAt(new Vector3(0, 2, 0));\n\t\t} else {\n\t\t\t// Position camera directly for non-rig perspectives\n\t\t\tthis.camera.position.set(0, 0, 10);\n\t\t\tthis.camera.lookAt(new Vector3(0, 0, 0));\n\t\t}\n\n\t\t// Initialize perspective controller\n\t\tthis.initializePerspectiveController();\n\n\t\t// Initialize orbit controller (handles debug mode orbit controls)\n\t\tthis.orbitController = new CameraOrbitController(this.camera, this.renderer.domElement, this.cameraRig);\n\t}\n\n\t/**\n\t * Setup the camera with a scene\n\t */\n\tasync setup(scene: Scene) {\n\t\tthis.sceneRef = scene;\n\n\t\t// Setup render pass\n\t\tlet renderResolution = this.screenResolution.clone().divideScalar(2);\n\t\trenderResolution.x |= 0;\n\t\trenderResolution.y |= 0;\n\t\tconst pass = new RenderPass(renderResolution, scene, this.camera);\n\t\tthis.composer.addPass(pass);\n\n\t\t// Setup perspective controller\n\t\tif (this.perspectiveController) {\n\t\t\tthis.perspectiveController.setup({\n\t\t\t\tscreenResolution: this.screenResolution,\n\t\t\t\trenderer: this.renderer,\n\t\t\t\tscene: scene,\n\t\t\t\tcamera: this\n\t\t\t});\n\t\t}\n\n\t\t// Set scene reference for orbit controller (needed for camera rig detachment)\n\t\tthis.orbitController?.setScene(scene);\n\n\t\t// Start render loop\n\t\tthis.renderer.setAnimationLoop((delta) => {\n\t\t\tthis.update(delta || 0);\n\t\t});\n\t}\n\n\t/**\n\t * Update camera and render\n\t */\n\tupdate(delta: number) {\n\t\t// Update orbit controls (if debug mode is enabled)\n\t\tthis.orbitController?.update();\n\n\t\t// Skip perspective controller updates when in debug mode\n\t\t// This keeps the debug camera isolated from game camera logic\n\t\tif (this.perspectiveController && !this.isDebugModeActive()) {\n\t\t\tthis.perspectiveController.update(delta);\n\t\t}\n\n\t\t// Render the scene\n\t\tthis.composer.render(delta);\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 * Dispose renderer, composer, controls, and detach from scene\n\t */\n\tdestroy() {\n\t\ttry {\n\t\t\tthis.renderer.setAnimationLoop(null as any);\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.orbitController?.dispose();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.composer?.passes?.forEach((p: any) => p.dispose?.());\n\t\t\t// @ts-ignore dispose exists on EffectComposer but not typed here\n\t\t\tthis.composer?.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}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null) {\n\t\tthis.orbitController?.setDebugDelegate(delegate);\n\t}\n\n\t/**\n\t * Resize camera and renderer\n\t */\n\tresize(width: number, height: number) {\n\t\tthis.screenResolution.set(width, height);\n\t\tthis.renderer.setSize(width, height, false);\n\t\tthis.composer.setSize(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.perspectiveController) {\n\t\t\tthis.perspectiveController.resize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Update renderer pixel ratio (DPR)\n\t */\n\tsetPixelRatio(dpr: number) {\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 * Create 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 this.createThirdPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.FirstPerson:\n\t\t\t\treturn this.createFirstPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.Isometric:\n\t\t\t\treturn this.createIsometricCamera(aspectRatio);\n\t\t\tcase Perspectives.Flat2D:\n\t\t\t\treturn this.createFlat2DCamera(aspectRatio);\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\treturn this.createFixed2DCamera(aspectRatio);\n\t\t\tdefault:\n\t\t\t\treturn this.createThirdPersonCamera(aspectRatio);\n\t\t}\n\t}\n\n\t/**\n\t * Initialize perspective-specific controller\n\t */\n\tprivate initializePerspectiveController() {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t\t\tbreak;\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\tthis.perspectiveController = new Fixed2DCamera();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t}\n\t}\n\n\tprivate createThirdPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createFirstPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createIsometricCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFlat2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFixed2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn this.createFlat2DCamera(aspectRatio);\n\t}\n\n\t// Movement methods\n\tprivate moveCamera(position: Vector3) {\n\t\tif (this._perspective === Perspectives.Flat2D || this._perspective === Perspectives.Fixed2D) {\n\t\t\tthis.frustumSize = position.z;\n\t\t}\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.position.set(position.x, position.y, position.z);\n\t\t} else {\n\t\t\tthis.camera.position.set(position.x, position.y, position.z);\n\t\t}\n\t}\n\n\tmove(position: Vector3) {\n\t\tthis.moveCamera(position);\n\t}\n\n\trotate(pitch: number, yaw: number, roll: number) {\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.rotateX(pitch);\n\t\t\tthis.cameraRig.rotateY(yaw);\n\t\t\tthis.cameraRig.rotateZ(roll);\n\t\t} else {\n\t\t\t(this.camera as Object3D).rotateX(pitch);\n\t\t\t(this.camera as Object3D).rotateY(yaw);\n\t\t\t(this.camera as Object3D).rotateZ(roll);\n\t\t}\n\t}\n\n\t/**\n\t * Check if this perspective type needs a camera rig\n\t */\n\tprivate needsRig(): boolean {\n\t\treturn this._perspective === Perspectives.ThirdPerson;\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}","import { Vector2 } from 'three';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { Perspectives, PerspectiveType } from '../camera/perspective';\nimport { CameraWrapper } from '../camera/camera';\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","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 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): void {\n\t\tthis.scene = scene;\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\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.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.scene = null;\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","import { Color, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { CameraWrapper } from '../camera/camera';\nimport { isBaseNode, isCameraWrapper, isConfigObject, isEntityInput, isThenable } from '../core/utility/options-parser';\nimport { ZylemBlueColor } from '../core/utility/vector';\nimport type { ZylemShaderObject } 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: ZylemShaderObject;\n\tgravity: Vector3;\n\tvariables: Record<string, any>;\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: ZylemShaderObject | null,\n\t\tpublic gravity: Vector3,\n\t\tpublic variables: Record<string, any>,\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);\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\tcamera?: 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\tlet camera: CameraWrapper | undefined;\n\n\tfor (const item of options) {\n\t\tif (isCameraWrapper(item)) {\n\t\t\tcamera = 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);\n\n\treturn { config: resolvedConfig, entities, asyncEntities, camera };\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 { addEntity, createWorld as createECS, removeEntity } from 'bitecs';\nimport { Color, Vector3, Vector2 } from 'three';\n\nimport { ZylemWorld } from '../collision/world';\nimport { ZylemScene } from '../graphics/zylem-scene';\nimport { resetStageVariables, setStageBackgroundColor, setStageBackgroundImage, setStageVariables, clearVariables, initialStageState } from './stage-state';\n\nimport { GameEntityInterface } from '../types/entity-types';\nimport { ZylemBlueColor } from '../core/utility/vector';\nimport { debugState } from '../debug/debug-state';\nimport { subscribe } from 'valtio/vanilla';\nimport { getGlobals } from \"../game/game-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 { StageDebugDelegate } from './stage-debug-delegate';\nimport { StageCameraDebugDelegate } from './stage-camera-debug-delegate';\nimport { StageCameraDelegate } from './stage-camera-delegate';\nimport { StageLoadingDelegate } from './stage-loading-delegate';\nimport { StageEntityModelDelegate } from './stage-entity-model-delegate';\nimport { GameEntity } from '../entities/entity';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { LoadingEvent } from '../core/interfaces';\nimport { parseStageOptions } from './stage-config';\nimport { isBaseNode, isThenable } from '../core/utility/options-parser';\nimport type { BehaviorSystem, BehaviorSystemFactory } from '../behaviors/behavior-system';\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\tstageRef?: Stage;\n}\n\ntype NodeLike = { create: Function };\nexport type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);\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 * - Spawn, track, and remove entities; emit entity-added events\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\n\tchildren: Array<BaseNode> = [];\n\t_childrenMap: Map<number, BaseNode> = new Map();\n\t_removalMap: Map<number, BaseNode> = new Map();\n\n\tprivate pendingEntities: StageEntityInput[] = [];\n\tprivate pendingPromises: Promise<BaseNode>[] = [];\n\tprivate isLoaded: boolean = false;\n\n\t_debugMap: Map<string, BaseNode> = new Map();\n\n\tprivate entityAddedHandlers: Array<(entity: BaseNode) => void> = [];\n\n\tecs = createECS();\n\ttestSystem: any = null;\n\ttransformSystem: ReturnType<typeof createTransformSystem> | null = null;\n\tprivate behaviorSystems: BehaviorSystem[] = [];\n\tprivate registeredSystemKeys: Set<symbol> = new Set();\n\tdebugDelegate: StageDebugDelegate | null = null;\n\tcameraDebugDelegate: StageCameraDebugDelegate | null = null;\n\tprivate debugStateUnsubscribe: (() => void) | null = null;\n\n\tuuid: string;\n\twrapperRef: Stage | null = null;\n\tcamera?: CameraWrapper;\n\tcameraRef?: ZylemCamera | null = null;\n\n\t// Delegates\n\tprivate cameraDelegate: StageCameraDelegate;\n\tprivate loadingDelegate: StageLoadingDelegate;\n\tprivate entityModelDelegate: StageEntityModelDelegate;\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\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.children = parsed.entities;\n\t\tthis.pendingEntities = parsed.asyncEntities;\n\t\t\n\t\t// Update state with resolved config\n\t\tthis.saveState({\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\tentities: [],\n\t\t});\n\n\t\tthis.gravity = parsed.config.gravity ?? new Vector3(0, 0, 0);\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\tprivate saveState(state: StageState) {\n\t\tthis.state = state;\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\t// Initialize reactive stage variables on load\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) {\n\t\tthis.setState();\n\n\t\t// Use camera delegate to resolve camera\n\t\tconst zylemCamera = 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 physicsWorld = await ZylemWorld.loadPhysics(this.gravity ?? new Vector3(0, 0, 0));\n\t\tthis.world = new ZylemWorld(physicsWorld);\n\n\t\tthis.scene.setup();\n\t\tthis.entityModelDelegate.attach(this.scene);\n\n\t\tthis.loadingDelegate.emitStart();\n\n\t\t// Run entity loading with generator pattern for real-time progress\n\t\tawait this.runEntityLoadGenerator();\n\n\t\tthis.transformSystem = createTransformSystem(this as unknown as StageSystem);\n\t\tthis.isLoaded = true;\n\t\tthis.loadingDelegate.emitComplete();\n\t}\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/**\n\t * Runs the entity load generator, yielding to the event loop between loads.\n\t * This allows the browser to process events and update the UI in real-time.\n\t */\n\tprivate async runEntityLoadGenerator(): Promise<void> {\n\t\tconst gen = this.entityLoadGenerator();\n\t\tfor (const progress of gen) {\n\t\t\tthis.loadingDelegate.emitProgress(`Loaded ${progress.name}`, progress.current, progress.total);\n\t\t\t// Yield to event loop so browser can process events and update UI\n\t\t\t// Use setTimeout(0) for more reliable async behavior than RAF\n\t\t\tawait new Promise<void>(resolve => setTimeout(resolve, 0));\n\t\t}\n\t}\n\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// Setup debug delegate based on current state\n\t\tthis.updateDebugDelegate();\n\n\t\t// Subscribe to debugState changes for runtime toggle\n\t\tthis.debugStateUnsubscribe = subscribe(debugState, () => {\n\t\t\tthis.updateDebugDelegate();\n\t\t});\n\t}\n\n\tprivate updateDebugDelegate(): void {\n\t\tif (debugState.enabled && !this.debugDelegate && this.scene && this.world) {\n\t\t\t// Create debug delegate when debug is enabled\n\t\t\tthis.debugDelegate = new StageDebugDelegate(this);\n\t\t\t\n\t\t\t// Create and attach camera debug delegate for orbit controls\n\t\t\tif (this.cameraRef && !this.cameraDebugDelegate) {\n\t\t\t\tthis.cameraDebugDelegate = new StageCameraDebugDelegate(this);\n\t\t\t\tthis.cameraRef.setDebugDelegate(this.cameraDebugDelegate);\n\t\t\t}\n\t\t} else if (!debugState.enabled && this.debugDelegate) {\n\t\t\t// Dispose debug delegate when debug is disabled\n\t\t\tthis.debugDelegate.dispose();\n\t\t\tthis.debugDelegate = null;\n\t\t\t\n\t\t\t// Detach camera debug delegate\n\t\t\tif (this.cameraRef) {\n\t\t\t\tthis.cameraRef.setDebugDelegate(null);\n\t\t\t}\n\t\t\tthis.cameraDebugDelegate = null;\n\t\t}\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\t\tthis.transformSystem?.system(this.ecs);\n\t\t// Run registered ECS behavior systems\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.update(this.ecs, delta);\n\t\t}\n\t\tthis._childrenMap.forEach((child, eid) => {\n\t\t\tchild.nodeUpdate({\n\t\t\t\t...params,\n\t\t\t\tme: child,\n\t\t\t});\n\t\t\tif (child.markedForRemoval) {\n\t\t\t\tthis.removeEntityByUuid(child.uuid);\n\t\t\t}\n\t\t});\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// Cleanup behavior systems\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.destroy?.(this.ecs);\n\t\t}\n\t\tthis.behaviorSystems = [];\n\t\tthis.registeredSystemKeys.clear();\n\t\tthis._childrenMap.forEach((child) => {\n\t\t\ttry { child.nodeDestroy({ me: child, globals: getGlobals() }); } catch { /* noop */ }\n\t\t});\n\t\tthis._childrenMap.clear();\n\t\tthis._removalMap.clear();\n\t\tthis._debugMap.clear();\n\n\t\tthis.world?.destroy();\n\t\tthis.scene?.destroy();\n\n\t\t// Cleanup debug state subscription\n\t\tif (this.debugStateUnsubscribe) {\n\t\t\tthis.debugStateUnsubscribe();\n\t\t\tthis.debugStateUnsubscribe = null;\n\t\t}\n\n\t\tthis.debugDelegate?.dispose();\n\t\tthis.debugDelegate = null;\n\t\tthis.cameraRef?.setDebugDelegate(null);\n\t\tthis.cameraDebugDelegate = null;\n\n\t\tthis.entityModelDelegate.dispose();\n\n\t\tthis.isLoaded = false;\n\t\tthis.world = null as any;\n\t\tthis.scene = null as any;\n\t\tthis.cameraRef = null;\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\t// Clear object-scoped variables for this stage\n\t\tclearVariables(this);\n\t}\n\n\t/**\n\t * Create, register, and add an entity to the scene/world.\n\t * Safe to call only after `load` when scene/world exist.\n\t */\n\tasync spawnEntity(child: BaseNode) {\n\t\tif (!this.scene || !this.world) {\n\t\t\treturn;\n\t\t}\n\t\tconst entity = child.create();\n\t\tconst eid = addEntity(this.ecs);\n\t\tentity.eid = eid;\n\t\tthis.scene.addEntity(entity);\n\n\t\t// Auto-register behavior systems from entity refs\n\t\tif (typeof entity.getBehaviorRefs === 'function') {\n\t\t\tfor (const ref of entity.getBehaviorRefs()) {\n\t\t\t\tconst key = ref.descriptor.key;\n\t\t\t\tif (!this.registeredSystemKeys.has(key)) {\n\t\t\t\t\tconst system = ref.descriptor.systemFactory({ world: this.world, ecs: this.ecs });\n\t\t\t\t\tthis.behaviorSystems.push(system);\n\t\t\t\t\tthis.registeredSystemKeys.add(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (entity.colliderDesc) {\n\t\t\tthis.world.addEntity(entity);\n\t\t}\n\t\tchild.nodeSetup({\n\t\t\tme: child,\n\t\t\tglobals: getGlobals(),\n\t\t\tcamera: this.scene.zylemCamera,\n\t\t});\n\t\tthis.addEntityToStage(entity);\n\t\tthis.entityModelDelegate.observe(entity);\n\t}\n\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/** Add the entity to internal maps and notify listeners. */\n\taddEntityToStage(entity: BaseNode) {\n\t\tthis._childrenMap.set(entity.eid, entity);\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/**\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(callback: (entity: BaseNode) => void, options?: { replayExisting?: boolean }) {\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 { callback(entity); } catch (e) { console.error('onEntityAdded replay failed', e); }\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\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\tlet system: BehaviorSystem;\n\t\tif (typeof systemOrFactory === 'function') {\n\t\t\tsystem = systemOrFactory({ world: this.world, ecs: this.ecs });\n\t\t} else {\n\t\t\tsystem = systemOrFactory;\n\t\t}\n\t\tthis.behaviorSystems.push(system);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Remove an entity and its resources by its UUID.\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) return false;\n\t\t// Try mapping via world collision map first for physics-backed entities\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\n\t\tthis.entityModelDelegate.unobserve(uuid);\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\tlet foundKey: number | null = null;\n\t\tthis._childrenMap.forEach((value, key) => {\n\t\t\tif ((value as any).uuid === uuid) {\n\t\t\t\tfoundKey = key;\n\t\t\t}\n\t\t});\n\t\tif (foundKey !== null) {\n\t\t\tthis._childrenMap.delete(foundKey);\n\t\t}\n\t\tthis._debugMap.delete(uuid);\n\t\treturn true;\n\t}\n\n\t/** Get an entity by its name; returns null if not found. */\n\tgetEntityByName(name: string) {\n\t\tconst arr = Object.entries(Object.fromEntries(this._childrenMap)).map((entry) => entry[1]);\n\t\tconst entity = arr.find((child) => child.name === name);\n\t\tif (!entity) {\n\t\t\tconsole.warn(`Entity ${name} not found`);\n\t\t}\n\t\treturn entity ?? null;\n\t}\n\n\tlogMissingEntities() {\n\t\tconsole.warn('Zylem world or scene is 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\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[]) {\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","import { Vector2, Vector3 } from \"three\";\nimport { PerspectiveType } from \"./perspective\";\nimport { ZylemCamera } from \"./zylem-camera\";\n\nexport interface CameraOptions {\n\tperspective?: PerspectiveType;\n\tposition?: Vector3;\n\ttarget?: Vector3;\n\tzoom?: number;\n\tscreenResolution?: Vector2;\n}\n\nexport class CameraWrapper {\n\tcameraRef: ZylemCamera;\n\n\tconstructor(camera: ZylemCamera) {\n\t\tthis.cameraRef = camera;\n\t}\n}\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(options.perspective || 'third-person', screenResolution, frustumSize);\n\n\t// Set initial position and target\n\tzylemCamera.move(options.position || new Vector3(0, 0, 0));\n\tzylemCamera.camera.lookAt(options.target || new Vector3(0, 0, 0));\n\n\treturn new CameraWrapper(zylemCamera);\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 { stageState } from './stage-state';\nimport { getStageOptions } from './stage-default';\nimport { EntityTypeMap } from '../types/entity-type-map';\nimport { EventEmitterDelegate, zylemEventBus, type StageEvents } from '../events';\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\tconstructor(options: StageOptions) {\n\t\tthis.options = options;\n\t\tthis.wrappedStage = null;\n\t}\n\n\tasync load(id: string, camera?: ZylemCamera | CameraWrapper | 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);\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?.children.find(c => c.name === name);\n\t\treturn entity as any;\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 { 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 { 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 { 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.onDestroy(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});\n}\n\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 { DestroyContext, DestroyFunction, UpdateContext, UpdateFunction } 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.prependUpdate(this.spriteUpdate.bind(this) as any);\n\t\tthis.onDestroy(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\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\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\tspriteUpdate(params: UpdateContext<ZylemSpriteOptions>): void {\n\t\tthis.sprites.forEach(_sprite => {\n\t\t\tif (_sprite.material) {\n\t\t\t\tconst q = this.body?.rotation();\n\t\t\t\tif (q) {\n\t\t\t\t\tconst quat = new Quaternion(q.x, q.y, q.z, q.w);\n\t\t\t\t\tconst euler = new Euler().setFromQuaternion(quat, 'XYZ');\n\t\t\t\t\t_sprite.material.rotation = euler.z;\n\t\t\t\t}\n\t\t\t\t_sprite.scale.set(this.options.size?.x ?? 1, this.options.size?.y ?? 1, this.options.size?.z ?? 1);\n\t\t\t}\n\t\t});\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});\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\t// Clone the template entity using its constructor and options\n\t\t\t\tconst EntityClass = template.constructor as new (options: O) => E;\n\t\t\t\tconst options = { ...template.options } as O;\n\t\t\t\tconst clone = new EntityClass(options).create() as E;\n\t\t\t\t\n\t\t\t\t// Copy behavior refs from template\n\t\t\t\tconst templateRefs = template.getBehaviorRefs();\n\t\t\t\tfor (const ref of templateRefs) {\n\t\t\t\t\tclone.use(ref.descriptor, ref.options);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Copy lifecycle callbacks from template\n\t\t\t\tconst templateCallbacks = (template as any).lifecycleCallbacks;\n\t\t\t\tif (templateCallbacks) {\n\t\t\t\t\tconst cloneCallbacks = (clone as any).lifecycleCallbacks;\n\t\t\t\t\tif (cloneCallbacks) {\n\t\t\t\t\t\tcloneCallbacks.setup.push(...templateCallbacks.setup);\n\t\t\t\t\t\tcloneCallbacks.update.push(...templateCallbacks.update);\n\t\t\t\t\t\tcloneCallbacks.destroy.push(...templateCallbacks.destroy);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tentities.push(clone);\n\t\t\t}\n\t\t\t\n\t\t\treturn entities;\n\t\t}\n\t};\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 { 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 } from './game-interfaces';\nimport { convertNodes, GameOptions, hasStages, extractGlobalsFromOptions } from '../core/utility/nodes';\nimport { resolveGameConfig } from './game-config';\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\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\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\tprivate async load(): Promise<ZylemGame<TGlobals>> {\n\t\tconst options = await convertNodes<TGlobals>(this.options);\n\t\tconst resolved = resolveGameConfig(options as any);\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);\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}\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}","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 { BaseNode } from './base-node';\nimport {\n\tSetupContext,\n\tUpdateContext,\n\tDestroyContext,\n\tLoadedContext,\n\tCleanupContext,\n} from './base-node-life-cycle';\n\nconst VESSEL_TYPE = Symbol('vessel');\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 async _cleanup(_params: CleanupContext<this>): Promise<void> { }\n\n\tpublic create(): this {\n\t\treturn this;\n\t}\n}\n\nexport function vessel(...args: Array<BaseNode>): BaseNode<{}, Vessel> {\n\tconst instance = new Vessel();\n\targs.forEach(arg => instance.add(arg));\n\treturn instance as unknown as BaseNode<{}, Vessel>;\n}\n","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BoxGeometry, Color } from 'three';\nimport { Vector3 } 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';\n\ntype ZylemBoxOptions = GameEntityOptions;\n\nimport { commonDefaults } from './common';\n\nconst boxDefaults: ZylemBoxOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n};\n\nexport class BoxCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: GameEntityOptions): 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\nexport class BoxMeshBuilder extends EntityMeshBuilder {\n\tbuild(options: GameEntityOptions): BoxGeometry {\n\t\tconst size = options.size ?? new Vector3(1, 1, 1);\n\t\treturn new BoxGeometry(size.x, size.y, size.z);\n\t}\n}\n\nexport class BoxBuilder extends EntityBuilder<ZylemBox, ZylemBoxOptions> {\n\tprotected createEntity(options: Partial<ZylemBoxOptions>): ZylemBox {\n\t\treturn new ZylemBox(options);\n\t}\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 | ZylemBoxOptions;\n\nexport function createBox(...args: Array<BoxOptions>): ZylemBox {\n\treturn createEntity<ZylemBox, ZylemBoxOptions>({\n\t\targs,\n\t\tdefaultConfig: boxDefaults,\n\t\tEntityClass: ZylemBox,\n\t\tBuilderClass: BoxBuilder,\n\t\tMeshBuilderClass: BoxMeshBuilder,\n\t\tCollisionBuilderClass: BoxCollisionBuilder,\n\t\tentityType: ZylemBox.type\n\t});\n}","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { Color, SphereGeometry } from 'three';\nimport { Vector3 } 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 { standardShader } from '../graphics/shaders/standard.shader';\nimport { createEntity } from './create';\n\ntype ZylemSphereOptions = GameEntityOptions & {\n\tradius?: number;\n};\n\nimport { commonDefaults } from './common';\n\nconst sphereDefaults: ZylemSphereOptions = {\n\t...commonDefaults,\n\tradius: 1,\n};\n\nexport class SphereCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemSphereOptions): ColliderDesc {\n\t\tconst radius = options.radius ?? 1;\n\t\tlet colliderDesc = ColliderDesc.ball(radius);\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class SphereMeshBuilder extends EntityMeshBuilder {\n\tbuild(options: ZylemSphereOptions): SphereGeometry {\n\t\tconst radius = options.radius ?? 1;\n\t\treturn new SphereGeometry(radius);\n\t}\n}\n\nexport class SphereBuilder extends EntityBuilder<ZylemSphere, ZylemSphereOptions> {\n\tprotected createEntity(options: Partial<ZylemSphereOptions>): ZylemSphere {\n\t\treturn new ZylemSphere(options);\n\t}\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\treturn createEntity<ZylemSphere, ZylemSphereOptions>({\n\t\targs,\n\t\tdefaultConfig: sphereDefaults,\n\t\tEntityClass: ZylemSphere,\n\t\tBuilderClass: SphereBuilder,\n\t\tMeshBuilderClass: SphereMeshBuilder,\n\t\tCollisionBuilderClass: SphereCollisionBuilder,\n\t\tentityType: ZylemSphere.type\n\t});\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 { 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});\n}\n","import { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { Vector3 } 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 { CollisionHandlerDelegate } from '../collision/world';\nimport { state } from '../game/game-state';\nimport { commonDefaults } from './common';\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 class ZoneCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemZoneOptions): 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\tcolliderDesc.setSensor(true);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.KINEMATIC_FIXED;\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class ZoneBuilder extends EntityBuilder<ZylemZone, ZylemZoneOptions> {\n\tprotected createEntity(options: Partial<ZylemZoneOptions>): ZylemZone {\n\t\treturn new ZylemZone(options);\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\treturn createEntity<ZylemZone, ZylemZoneOptions>({\n\t\targs,\n\t\tdefaultConfig: zoneDefaults,\n\t\tEntityClass: ZylemZone,\n\t\tBuilderClass: ZoneBuilder,\n\t\tCollisionBuilderClass: ZoneCollisionBuilder,\n\t\tentityType: ZylemZone.type\n\t});\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\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 dom = this._cameraRef.renderer.domElement;\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 dom = this._cameraRef.renderer.domElement;\n\t\tconst width = dom.clientWidth;\n\t\tconst height = dom.clientHeight;\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 dom = this._cameraRef.renderer.domElement;\n\t\tconst v = point.clone().project(camera);\n\t\tconst x = (v.x + 1) / 2 * dom.clientWidth;\n\t\tconst y = (1 - v.y) / 2 * dom.clientHeight;\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\tconst dom = this._cameraRef.renderer.domElement;\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});\n}\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});\n}\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 * PhysicsStepBehavior\n * \n * Single authoritative place where Rapier advances.\n * Runs after all force-producing behaviors.\n */\n\nimport type { World } from '@dimforge/rapier3d-compat';\nimport type { Behavior } from './thruster/thruster-movement.behavior';\n\n/**\n * PhysicsStepBehavior - Authoritative physics step\n * \n * This behavior is responsible for advancing the Rapier physics simulation.\n * It should run AFTER all force-producing behaviors (like ThrusterMovementBehavior).\n */\nexport class PhysicsStepBehavior implements Behavior {\n\tconstructor(private physicsWorld: World) {}\n\n\tupdate(dt: number): void {\n\t\tthis.physicsWorld.timestep = dt;\n\t\tthis.physicsWorld.step();\n\t}\n}\n","/**\n * PhysicsSyncBehavior\n * \n * Syncs physics state (position, rotation) from Rapier bodies to ECS TransformComponents.\n * This is what keeps Three.js honest - rendering reads from TransformComponent.\n */\n\nimport type { ZylemWorld } from '../collision/world';\nimport type { TransformComponent, PhysicsBodyComponent } from './components';\nimport type { Behavior } from './thruster/thruster-movement.behavior';\n\n/**\n * Entity with physics body and transform components\n */\ninterface PhysicsSyncEntity {\n\tphysics: PhysicsBodyComponent;\n\ttransform: TransformComponent;\n}\n\n/**\n * PhysicsSyncBehavior - Physics → ECS sync\n * \n * Responsibilities:\n * - Query entities with PhysicsBodyComponent and TransformComponent\n * - Copy position from body.translation() to transform.position\n * - Copy rotation from body.rotation() to transform.rotation\n * \n * This runs AFTER PhysicsStepBehavior, before rendering.\n */\nexport class PhysicsSyncBehavior implements Behavior {\n\tconstructor(private world: ZylemWorld) {}\n\n\t/**\n\t * Query entities that have both physics body and transform components\n\t */\n\tprivate queryEntities(): PhysicsSyncEntity[] {\n\t\tconst entities: PhysicsSyncEntity[] = [];\n\t\t\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\t\t\tif (gameEntity.physics?.body && gameEntity.transform) {\n\t\t\t\tentities.push({\n\t\t\t\t\tphysics: gameEntity.physics,\n\t\t\t\t\ttransform: gameEntity.transform,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn entities;\n\t}\n\n\tupdate(_dt: number): void {\n\t\tconst entities = this.queryEntities();\n\n\t\tfor (const e of entities) {\n\t\t\tconst body = e.physics.body;\n\t\t\tconst transform = e.transform;\n\n\t\t\t// Sync position\n\t\t\tconst p = body.translation();\n\t\t\ttransform.position.set(p.x, p.y, p.z);\n\n\t\t\t// Sync rotation\n\t\t\tconst r = body.rotation();\n\t\t\ttransform.rotation.set(r.x, r.y, r.z, r.w);\n\t\t}\n\t}\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}\n\nexport function createThrusterInputComponent(): ThrusterInputComponent {\n\treturn {\n\t\tthrust: 0,\n\t\trotate: 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","/**\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 { StateMachine, t, type ITransition } from 'typescript-fsm';\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}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThrusterFSM Controller\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThrusterFSM {\n\tmachine: StateMachine<ThrusterState, ThrusterEvent, never>;\n\n\tconstructor(private ctx: ThrusterFSMContext) {\n\t\tthis.machine = new StateMachine<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.dispatch(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 = Math.abs(playerInput.thrust) > 0.01 || Math.abs(playerInput.rotate) > 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","/**\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';\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 * Query function - returns entities with required thruster components\n\t */\n\tprivate queryEntities(): ThrusterEntity[] {\n\t\tconst entities: ThrusterEntity[] = [];\n\t\t\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\t\t\tif (\n\t\t\t\tgameEntity.physics?.body &&\n\t\t\t\tgameEntity.thruster &&\n\t\t\t\tgameEntity.$thruster\n\t\t\t) {\n\t\t\t\tentities.push({\n\t\t\t\t\tphysics: gameEntity.physics,\n\t\t\t\t\tthruster: gameEntity.thruster,\n\t\t\t\t\t$thruster: gameEntity.$thruster,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn entities;\n\t}\n\n\tupdate(_dt: number): void {\n\t\tconst entities = this.queryEntities();\n\n\t\tfor (const e of entities) {\n\t\t\tconst body = e.physics.body;\n\t\t\tconst thruster = e.thruster;\n\t\t\tconst input = e.$thruster;\n\n\t\t\t// Get Z rotation from quaternion (for 2D sprites)\n\t\t\tconst q = body.rotation();\n\t\t\tconst rotationZ = Math.atan2(2 * (q.w * q.z + q.x * q.y), 1 - 2 * (q.y * q.y + q.z * q.z));\n\n\t\t\t// --- Linear thrust (Asteroids-style: adds velocity in forward direction) ---\n\t\t\tif (input.thrust !== 0) {\n\t\t\t\tconst currentVel = body.linvel();\n\t\t\t\t\n\t\t\t\tif (input.thrust > 0) {\n\t\t\t\t\t// Forward thrust: add velocity in facing direction\n\t\t\t\t\tconst forwardX = Math.sin(-rotationZ);\n\t\t\t\t\tconst forwardY = Math.cos(-rotationZ);\n\t\t\t\t\tconst thrustAmount = thruster.linearThrust * input.thrust * 0.1;\n\t\t\t\t\tbody.setLinvel({\n\t\t\t\t\t\tx: currentVel.x + forwardX * thrustAmount,\n\t\t\t\t\t\ty: currentVel.y + forwardY * thrustAmount,\n\t\t\t\t\t\tz: currentVel.z\n\t\t\t\t\t}, true);\n\t\t\t\t} else {\n\t\t\t\t\t// Brake: reduce current velocity (slow down)\n\t\t\t\t\tconst brakeAmount = 0.9; // 10% reduction per frame\n\t\t\t\t\tbody.setLinvel({\n\t\t\t\t\t\tx: currentVel.x * brakeAmount,\n\t\t\t\t\t\ty: currentVel.y * brakeAmount,\n\t\t\t\t\t\tz: currentVel.z\n\t\t\t\t\t}, true);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// --- Angular thrust (Z-axis for 2D) ---\n\t\t\tif (input.rotate !== 0) {\n\t\t\t\tbody.setAngvel({ x: 0, y: 0, z: -thruster.angularThrust * input.rotate }, true);\n\t\t\t} else {\n\t\t\t\t// Stop rotation when no input\n\t\t\t\tconst angVel = body.angvel();\n\t\t\t\tbody.setAngvel({ x: angVel.x, y: angVel.y, z: 0 }, true);\n\t\t\t}\n\t\t}\n\t}\n}\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 { BehaviorSystem } from '../behavior-system';\nimport { ThrusterMovementBehavior, ThrusterEntity } from './thruster-movement.behavior';\nimport { ThrusterFSM } from './thruster-fsm';\nimport type { ThrusterMovementComponent, ThrusterInputComponent } 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}\n\nconst defaultOptions: ThrusterBehaviorOptions = {\n\tlinearThrust: 10,\n\tangularThrust: 5,\n};\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(private world: any) {\n\t\tthis.movementBehavior = new ThrusterMovementBehavior(world);\n\t}\n\n\tupdate(ecs: IWorld, delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\t// Initialize ECS components on entities with thruster behavior refs\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\t\t\t\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\t\t\t\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst thrusterRef = refs.find((r: any) => \n\t\t\t\tr.descriptor.key === Symbol.for('zylem:behavior:thruster')\n\t\t\t);\n\t\t\t\n\t\t\tif (!thrusterRef || !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 = {\n\t\t\t\t\tlinearThrust: options.linearThrust,\n\t\t\t\t\tangularThrust: options.angularThrust,\n\t\t\t\t} as ThrusterMovementComponent;\n\t\t\t}\n\n\t\t\tif (!gameEntity.$thruster) {\n\t\t\t\tgameEntity.$thruster = {\n\t\t\t\t\tthrust: 0,\n\t\t\t\t\trotate: 0,\n\t\t\t\t} 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});\n\t\t\t}\n\t\t}\n\n\t\t// Delegate to the existing movement behavior\n\t\tthis.movementBehavior.update(delta);\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) => new ThrusterBehaviorSystem(ctx.world),\n});\n","/**\n * Thruster Behavior Module Index\n * \n * Re-exports all thruster-related components and behaviors.\n */\n\n// Components\nexport {\n\ttype ThrusterMovementComponent,\n\ttype ThrusterInputComponent,\n\ttype ThrusterStateComponent,\n\tcreateThrusterMovementComponent,\n\tcreateThrusterInputComponent,\n\tcreateThrusterStateComponent,\n} from './components';\n\n// FSM\nexport {\n\tThrusterState,\n\tThrusterEvent,\n\tThrusterFSM,\n\ttype ThrusterFSMContext,\n\ttype PlayerInput,\n} from './thruster-fsm';\n\n// Behaviors\nexport {\n\tThrusterMovementBehavior,\n\ttype Behavior,\n\ttype ThrusterEntity,\n} from './thruster-movement.behavior';\n\n// Typed Descriptor (new entity.use() API)\nexport { ThrusterBehavior, type ThrusterBehaviorOptions } from './thruster.descriptor';\n","/**\n * ScreenWrapFSM\n * \n * State machine for screen wrap behavior.\n * Reports position relative to bounds edges.\n */\n\nimport { StateMachine, t } from 'typescript-fsm';\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: StateMachine<ScreenWrapState, ScreenWrapEvent, never>;\n\n\tconstructor() {\n\t\tthis.machine = new StateMachine<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.dispatch(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","/**\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 { BehaviorSystem } from '../behavior-system';\nimport { ScreenWrapFSM } from './screen-wrap-fsm';\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\n/**\n * ScreenWrapSystem - Wraps entities around 2D bounds\n */\nclass ScreenWrapSystem implements BehaviorSystem {\n\tconstructor(private world: any) {}\n\n\tupdate(ecs: IWorld, delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\t\t\t\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\t\t\t\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst wrapRef = refs.find((r: any) => \n\t\t\t\tr.descriptor.key === Symbol.for('zylem:behavior:screen-wrap')\n\t\t\t);\n\t\t\t\n\t\t\tif (!wrapRef || !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 { width, height, centerX, centerY, edgeThreshold } = options;\n\t\t\tconst halfWidth = width / 2;\n\t\t\tconst halfHeight = height / 2;\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: centerX - halfWidth,\n\t\t\t\t\tmaxX: centerX + halfWidth,\n\t\t\t\t\tminY: centerY - halfHeight,\n\t\t\t\t\tmaxY: centerY + halfHeight,\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 { width, height, centerX, centerY } = options;\n\t\tconst halfWidth = width / 2;\n\t\tconst halfHeight = height / 2;\n\n\t\tconst minX = centerX - halfWidth;\n\t\tconst maxX = centerX + halfWidth;\n\t\tconst minY = centerY - halfHeight;\n\t\tconst maxY = centerY + halfHeight;\n\n\t\tconst pos = body.translation();\n\t\tlet newX = pos.x;\n\t\tlet newY = pos.y;\n\t\tlet wrapped = false;\n\n\t\t// Wrap X\n\t\tif (pos.x < minX) {\n\t\t\tnewX = maxX - (minX - pos.x);\n\t\t\twrapped = true;\n\t\t} else if (pos.x > maxX) {\n\t\t\tnewX = minX + (pos.x - maxX);\n\t\t\twrapped = true;\n\t\t}\n\n\t\t// Wrap Y\n\t\tif (pos.y < minY) {\n\t\t\tnewY = maxY - (minY - pos.y);\n\t\t\twrapped = true;\n\t\t} else if (pos.y > maxY) {\n\t\t\tnewY = minY + (pos.y - maxY);\n\t\t\twrapped = true;\n\t\t}\n\n\t\tif (wrapped) {\n\t\t\tbody.setTranslation({ x: newX, y: newY, z: pos.z }, true);\n\t\t}\n\n\t\treturn 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) => new ScreenWrapSystem(ctx.world),\n});\n\n","/**\n * Screen Wrap Behavior Module\n */\n\nexport { ScreenWrapBehavior, type ScreenWrapOptions } from './screen-wrap.descriptor';\nexport { ScreenWrapFSM, ScreenWrapState, ScreenWrapEvent } from './screen-wrap-fsm';\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 { StateMachine, t } from 'typescript-fsm';\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\tconst hits: WorldBoundary2DHits = {\n\t\ttop: false,\n\t\tbottom: false,\n\t\tleft: false,\n\t\tright: false,\n\t};\n\n\tif (position.x <= bounds.left) hits.left = true;\n\telse if (position.x >= bounds.right) hits.right = true;\n\n\tif (position.y <= bounds.bottom) hits.bottom = true;\n\telse if (position.y >= bounds.top) hits.top = true;\n\n\treturn hits;\n}\n\nexport function hasAnyWorldBoundary2DHit(hits: WorldBoundary2DHits): boolean {\n\treturn !!(hits.left || hits.right || hits.top || hits.bottom);\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: StateMachine<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 StateMachine<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\tconst hits = this.lastHits;\n\n\t\tlet adjustedX = moveX;\n\t\tlet adjustedY = moveY;\n\n\t\t// If moving left and hitting left, or moving right and hitting right, zero X\n\t\tif ((hits.left && moveX < 0) || (hits.right && moveX > 0)) {\n\t\t\tadjustedX = 0;\n\t\t}\n\n\t\t// If moving down and hitting bottom, or moving up and hitting top, zero Y\n\t\tif ((hits.bottom && moveY < 0) || (hits.top && moveY > 0)) {\n\t\t\tadjustedY = 0;\n\t\t}\n\n\t\treturn { moveX: adjustedX, moveY: adjustedY };\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.dispatch(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 { 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\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(private world: any) {}\n\n\tupdate(_ecs: IWorld, _delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst boundaryRef = refs.find(\n\t\t\t\t(r: any) => r.descriptor.key === Symbol.for('zylem:behavior:world-boundary-2d')\n\t\t\t);\n\n\t\t\tif (!boundaryRef || !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) => new WorldBoundary2DSystem(ctx.world),\n\tcreateHandle: createWorldBoundary2DHandle,\n});\n","/**\n * World Boundary 2D Module\n *\n * Barrel exports for the `world-boundary-2d` behavior and its FSM helpers.\n */\nexport { WorldBoundary2DBehavior } from './world-boundary-2d.descriptor';\n\nexport {\n\tWorldBoundary2DFSM,\n\tcomputeWorldBoundary2DHits,\n\thasAnyWorldBoundary2DHit,\n\ttype WorldBoundary2DHit,\n\ttype WorldBoundary2DHits,\n\ttype WorldBoundary2DPosition,\n\ttype WorldBoundary2DBounds,\n\tWorldBoundary2DState,\n\tWorldBoundary2DEvent,\n} from './world-boundary-2d-fsm';\n\nexport type {\n\tWorldBoundary2DOptions,\n\tWorldBoundary2DHandle,\n} from './world-boundary-2d.descriptor';\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 { StateMachine, t } from 'typescript-fsm';\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 * FSM wrapper with extended state (lastResult).\n * Systems or consumers call `computeRicochet(...)` when a collision occurs.\n */\nexport class Ricochet2DFSM {\n\tpublic readonly machine: StateMachine<Ricochet2DState, Ricochet2DEvent, never>;\n\n\tprivate lastResult: Ricochet2DResult | null = null;\n\tprivate lastUpdatedAtMs: number | null = null;\n\n\tconstructor() {\n\t\tthis.machine = new StateMachine<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\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 * 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 = Date.now();\n\t\tthis.dispatch(Ricochet2DEvent.StartRicochet);\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.dispatch(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 { BehaviorSystem } from '../behavior-system';\nimport { Ricochet2DFSM, type Ricochet2DResult, type Ricochet2DCollisionContext } 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 * Get the last computed ricochet result, or null if none.\n\t */\n\tgetLastResult(): Ricochet2DResult | null;\n}\n\nconst defaultOptions: Ricochet2DOptions = {\n\tminSpeed: 2,\n\tmaxSpeed: 20,\n\tspeedMultiplier: 1.05,\n\treflectionMode: 'angled',\n\tmaxAngleDeg: 60,\n};\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\tgetLastResult: () => {\n\t\t\tconst fsm = ref.fsm as Ricochet2DFSM | undefined;\n\t\t\treturn fsm?.getLastResult() ?? null;\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\tconstructor(private world: any) {}\n\n\tupdate(_ecs: IWorld, _delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst ricochetRef = refs.find(\n\t\t\t\t(r: any) => r.descriptor.key === Symbol.for('zylem:behavior:ricochet-2d')\n\t\t\t);\n\n\t\t\tif (!ricochetRef) continue;\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}\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 * 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) => new Ricochet2DSystem(ctx.world),\n\tcreateHandle: createRicochet2DHandle,\n});\n","/**\n * Ricochet 2D Behavior Module\n *\n * Exports FSM, types, and behavior descriptor for 2D ricochet/reflection.\n */\n\n// FSM and types\nexport {\n\tRicochet2DFSM,\n\tRicochet2DState,\n\tRicochet2DEvent,\n\ttype Ricochet2DResult,\n\ttype Ricochet2DCollisionContext,\n} from './ricochet-2d-fsm';\n\n// Behavior descriptor, options, and handle\nexport {\n\tRicochet2DBehavior,\n\ttype Ricochet2DOptions,\n\ttype Ricochet2DHandle,\n} from './ricochet-2d.descriptor';\n\n","/**\n * MovementSequence2DFSM\n *\n * FSM + extended state to manage timed movement sequences.\n * Tracks current step, time remaining, and computes movement for consumer.\n */\n\nimport { StateMachine, t } from 'typescript-fsm';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MovementSequence2DStep {\n\t/** Identifier for this step */\n\tname: string;\n\t/** X velocity for this step */\n\tmoveX?: number;\n\t/** Y velocity for this step */\n\tmoveY?: number;\n\t/** Duration in seconds */\n\ttimeInSeconds: number;\n}\n\nexport interface MovementSequence2DMovement {\n\tmoveX: number;\n\tmoveY: number;\n}\n\nexport interface MovementSequence2DProgress {\n\tstepIndex: number;\n\ttotalSteps: number;\n\tstepTimeRemaining: number;\n\tdone: boolean;\n}\n\nexport interface MovementSequence2DCurrentStep {\n\tname: string;\n\tindex: number;\n\tmoveX: number;\n\tmoveY: number;\n\ttimeRemaining: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM State Model\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum MovementSequence2DState {\n\tIdle = 'idle',\n\tRunning = 'running',\n\tPaused = 'paused',\n\tCompleted = 'completed',\n}\n\nexport enum MovementSequence2DEvent {\n\tStart = 'start',\n\tPause = 'pause',\n\tResume = 'resume',\n\tComplete = 'complete',\n\tReset = 'reset',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM Implementation\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class MovementSequence2DFSM {\n\tpublic readonly machine: StateMachine<MovementSequence2DState, MovementSequence2DEvent, never>;\n\n\tprivate sequence: MovementSequence2DStep[] = [];\n\tprivate loop: boolean = true;\n\tprivate currentIndex: number = 0;\n\tprivate timeRemaining: number = 0;\n\n\tconstructor() {\n\t\tthis.machine = new StateMachine<MovementSequence2DState, MovementSequence2DEvent, never>(\n\t\t\tMovementSequence2DState.Idle,\n\t\t\t[\n\t\t\t\t// From Idle\n\t\t\t\tt(MovementSequence2DState.Idle, MovementSequence2DEvent.Start, MovementSequence2DState.Running),\n\n\t\t\t\t// From Running\n\t\t\t\tt(MovementSequence2DState.Running, MovementSequence2DEvent.Pause, MovementSequence2DState.Paused),\n\t\t\t\tt(MovementSequence2DState.Running, MovementSequence2DEvent.Complete, MovementSequence2DState.Completed),\n\t\t\t\tt(MovementSequence2DState.Running, MovementSequence2DEvent.Reset, MovementSequence2DState.Idle),\n\n\t\t\t\t// From Paused\n\t\t\t\tt(MovementSequence2DState.Paused, MovementSequence2DEvent.Resume, MovementSequence2DState.Running),\n\t\t\t\tt(MovementSequence2DState.Paused, MovementSequence2DEvent.Reset, MovementSequence2DState.Idle),\n\n\t\t\t\t// From Completed\n\t\t\t\tt(MovementSequence2DState.Completed, MovementSequence2DEvent.Reset, MovementSequence2DState.Idle),\n\t\t\t\tt(MovementSequence2DState.Completed, MovementSequence2DEvent.Start, MovementSequence2DState.Running),\n\n\t\t\t\t// Self-transitions (no-ops)\n\t\t\t\tt(MovementSequence2DState.Idle, MovementSequence2DEvent.Pause, MovementSequence2DState.Idle),\n\t\t\t\tt(MovementSequence2DState.Idle, MovementSequence2DEvent.Resume, MovementSequence2DState.Idle),\n\t\t\t\tt(MovementSequence2DState.Running, MovementSequence2DEvent.Start, MovementSequence2DState.Running),\n\t\t\t\tt(MovementSequence2DState.Running, MovementSequence2DEvent.Resume, MovementSequence2DState.Running),\n\t\t\t\tt(MovementSequence2DState.Paused, MovementSequence2DEvent.Pause, MovementSequence2DState.Paused),\n\t\t\t\tt(MovementSequence2DState.Completed, MovementSequence2DEvent.Complete, MovementSequence2DState.Completed),\n\t\t\t]\n\t\t);\n\t}\n\n\t/**\n\t * Initialize the sequence. Call this once with options.\n\t */\n\tinit(sequence: MovementSequence2DStep[], loop: boolean): void {\n\t\tthis.sequence = sequence;\n\t\tthis.loop = loop;\n\t\tthis.currentIndex = 0;\n\t\tthis.timeRemaining = sequence.length > 0 ? sequence[0].timeInSeconds : 0;\n\t}\n\n\tgetState(): MovementSequence2DState {\n\t\treturn this.machine.getState();\n\t}\n\n\t/**\n\t * Start the sequence (from Idle or Completed).\n\t */\n\tstart(): void {\n\t\tif (this.machine.getState() === MovementSequence2DState.Idle ||\n\t\t this.machine.getState() === MovementSequence2DState.Completed) {\n\t\t\tthis.currentIndex = 0;\n\t\t\tthis.timeRemaining = this.sequence.length > 0 ? this.sequence[0].timeInSeconds : 0;\n\t\t}\n\t\tthis.dispatch(MovementSequence2DEvent.Start);\n\t}\n\n\t/**\n\t * Pause the sequence.\n\t */\n\tpause(): void {\n\t\tthis.dispatch(MovementSequence2DEvent.Pause);\n\t}\n\n\t/**\n\t * Resume a paused sequence.\n\t */\n\tresume(): void {\n\t\tthis.dispatch(MovementSequence2DEvent.Resume);\n\t}\n\n\t/**\n\t * Reset to Idle state.\n\t */\n\treset(): void {\n\t\tthis.dispatch(MovementSequence2DEvent.Reset);\n\t\tthis.currentIndex = 0;\n\t\tthis.timeRemaining = this.sequence.length > 0 ? this.sequence[0].timeInSeconds : 0;\n\t}\n\n\t/**\n\t * Update the sequence with delta time.\n\t * Returns the current movement to apply.\n\t * Automatically starts if in Idle state.\n\t */\n\tupdate(delta: number): MovementSequence2DMovement {\n\t\tif (this.sequence.length === 0) {\n\t\t\treturn { moveX: 0, moveY: 0 };\n\t\t}\n\n\t\t// Auto-start if idle\n\t\tif (this.machine.getState() === MovementSequence2DState.Idle) {\n\t\t\tthis.start();\n\t\t}\n\n\t\t// Don't advance if paused or completed\n\t\tif (this.machine.getState() !== MovementSequence2DState.Running) {\n\t\t\tif (this.machine.getState() === MovementSequence2DState.Completed) {\n\t\t\t\treturn { moveX: 0, moveY: 0 };\n\t\t\t}\n\t\t\t// Paused - return current step's movement (but don't advance time)\n\t\t\tconst step = this.sequence[this.currentIndex];\n\t\t\treturn { moveX: step?.moveX ?? 0, moveY: step?.moveY ?? 0 };\n\t\t}\n\n\t\t// Advance time\n\t\tlet timeLeft = this.timeRemaining - delta;\n\n\t\t// Handle step transitions\n\t\twhile (timeLeft <= 0) {\n\t\t\tconst overflow = -timeLeft;\n\t\t\tthis.currentIndex += 1;\n\n\t\t\tif (this.currentIndex >= this.sequence.length) {\n\t\t\t\tif (!this.loop) {\n\t\t\t\t\tthis.dispatch(MovementSequence2DEvent.Complete);\n\t\t\t\t\treturn { moveX: 0, moveY: 0 };\n\t\t\t\t}\n\t\t\t\tthis.currentIndex = 0;\n\t\t\t}\n\n\t\t\ttimeLeft = this.sequence[this.currentIndex].timeInSeconds - overflow;\n\t\t}\n\n\t\tthis.timeRemaining = timeLeft;\n\n\t\tconst step = this.sequence[this.currentIndex];\n\t\treturn { moveX: step?.moveX ?? 0, moveY: step?.moveY ?? 0 };\n\t}\n\n\t/**\n\t * Get the current movement without advancing time.\n\t */\n\tgetMovement(): MovementSequence2DMovement {\n\t\tif (this.sequence.length === 0 ||\n\t\t this.machine.getState() === MovementSequence2DState.Completed) {\n\t\t\treturn { moveX: 0, moveY: 0 };\n\t\t}\n\t\tconst step = this.sequence[this.currentIndex];\n\t\treturn { moveX: step?.moveX ?? 0, moveY: step?.moveY ?? 0 };\n\t}\n\n\t/**\n\t * Get current step info.\n\t */\n\tgetCurrentStep(): MovementSequence2DCurrentStep | null {\n\t\tif (this.sequence.length === 0) return null;\n\t\tconst step = this.sequence[this.currentIndex];\n\t\tif (!step) return null;\n\t\treturn {\n\t\t\tname: step.name,\n\t\t\tindex: this.currentIndex,\n\t\t\tmoveX: step.moveX ?? 0,\n\t\t\tmoveY: step.moveY ?? 0,\n\t\t\ttimeRemaining: this.timeRemaining,\n\t\t};\n\t}\n\n\t/**\n\t * Get sequence progress.\n\t */\n\tgetProgress(): MovementSequence2DProgress {\n\t\treturn {\n\t\t\tstepIndex: this.currentIndex,\n\t\t\ttotalSteps: this.sequence.length,\n\t\t\tstepTimeRemaining: this.timeRemaining,\n\t\t\tdone: this.machine.getState() === MovementSequence2DState.Completed,\n\t\t};\n\t}\n\n\tprivate dispatch(event: MovementSequence2DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.dispatch(event);\n\t\t}\n\t}\n}\n","/**\n * MovementSequence2DBehavior\n *\n * Sequences 2D movements over time. Each step defines velocity and duration.\n * The behavior computes movement; the consumer applies it.\n */\n\nimport type { IWorld } from 'bitecs';\nimport { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorSystem } from '../behavior-system';\nimport {\n\tMovementSequence2DFSM,\n\ttype MovementSequence2DStep,\n\ttype MovementSequence2DMovement,\n\ttype MovementSequence2DCurrentStep,\n\ttype MovementSequence2DProgress,\n} from './movement-sequence-2d-fsm';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Options\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface MovementSequence2DOptions {\n\t/**\n\t * The sequence of movement steps.\n\t * Each step has name, moveX, moveY, and timeInSeconds.\n\t */\n\tsequence: MovementSequence2DStep[];\n\n\t/**\n\t * Whether to loop when the sequence ends.\n\t * Default: true\n\t */\n\tloop: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Handle\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Handle methods provided by MovementSequence2DBehavior\n */\nexport interface MovementSequence2DHandle {\n\t/**\n\t * Get the current movement velocity.\n\t * Returns { moveX: 0, moveY: 0 } if sequence is empty or completed.\n\t */\n\tgetMovement(): MovementSequence2DMovement;\n\n\t/**\n\t * Get the current step info.\n\t * Returns null if sequence is empty.\n\t */\n\tgetCurrentStep(): MovementSequence2DCurrentStep | null;\n\n\t/**\n\t * Get sequence progress.\n\t */\n\tgetProgress(): MovementSequence2DProgress;\n\n\t/**\n\t * Pause the sequence. Movement values remain but time doesn't advance.\n\t */\n\tpause(): void;\n\n\t/**\n\t * Resume a paused sequence.\n\t */\n\tresume(): void;\n\n\t/**\n\t * Reset the sequence to the beginning.\n\t */\n\treset(): void;\n}\n\nconst defaultOptions: MovementSequence2DOptions = {\n\tsequence: [],\n\tloop: true,\n};\n\n/**\n * Creates behavior-specific handle methods for MovementSequence2DBehavior.\n */\nfunction createMovementSequence2DHandle(\n\tref: BehaviorRef<MovementSequence2DOptions>\n): MovementSequence2DHandle {\n\treturn {\n\t\tgetMovement: () => {\n\t\t\tconst fsm = ref.fsm as MovementSequence2DFSM | undefined;\n\t\t\treturn fsm?.getMovement() ?? { moveX: 0, moveY: 0 };\n\t\t},\n\t\tgetCurrentStep: () => {\n\t\t\tconst fsm = ref.fsm as MovementSequence2DFSM | undefined;\n\t\t\treturn fsm?.getCurrentStep() ?? null;\n\t\t},\n\t\tgetProgress: () => {\n\t\t\tconst fsm = ref.fsm as MovementSequence2DFSM | undefined;\n\t\t\treturn fsm?.getProgress() ?? { stepIndex: 0, totalSteps: 0, stepTimeRemaining: 0, done: true };\n\t\t},\n\t\tpause: () => {\n\t\t\tconst fsm = ref.fsm as MovementSequence2DFSM | undefined;\n\t\t\tfsm?.pause();\n\t\t},\n\t\tresume: () => {\n\t\t\tconst fsm = ref.fsm as MovementSequence2DFSM | undefined;\n\t\t\tfsm?.resume();\n\t\t},\n\t\treset: () => {\n\t\t\tconst fsm = ref.fsm as MovementSequence2DFSM | undefined;\n\t\t\tfsm?.reset();\n\t\t},\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// System\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * MovementSequence2DSystem\n *\n * Stage-level system that:\n * - Finds entities with this behavior attached\n * - Updates FSM with delta time each frame\n * - Consumers read getMovement() to get current velocity\n */\nclass MovementSequence2DSystem implements BehaviorSystem {\n\tconstructor(private world: any) {}\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst sequenceRef = refs.find(\n\t\t\t\t(r: any) => r.descriptor.key === Symbol.for('zylem:behavior:movement-sequence-2d')\n\t\t\t);\n\n\t\t\tif (!sequenceRef) continue;\n\n\t\t\tconst options = sequenceRef.options as MovementSequence2DOptions;\n\n\t\t\t// Create and init FSM lazily on first update\n\t\t\tif (!sequenceRef.fsm) {\n\t\t\t\tsequenceRef.fsm = new MovementSequence2DFSM();\n\t\t\t\tsequenceRef.fsm.init(options.sequence, options.loop);\n\t\t\t}\n\n\t\t\t// Update FSM - advances time and handles step transitions\n\t\t\tsequenceRef.fsm.update(delta);\n\t\t}\n\t}\n\n\tdestroy(_ecs: IWorld): void {}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Behavior Definition\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * MovementSequence2DBehavior\n *\n * @example\n * ```ts\n * import { MovementSequence2DBehavior } from \"@zylem/game-lib\";\n *\n * const enemy = makeMoveable(createSprite({ ... }));\n * const sequence = enemy.use(MovementSequence2DBehavior, {\n * sequence: [\n * { name: 'right', moveX: 3, moveY: 0, timeInSeconds: 2 },\n * { name: 'left', moveX: -3, moveY: 0, timeInSeconds: 2 },\n * ],\n * loop: true,\n * });\n *\n * enemy.onUpdate(({ me }) => {\n * const { moveX, moveY } = sequence.getMovement();\n * me.moveXY(moveX, moveY);\n * });\n * ```\n */\nexport const MovementSequence2DBehavior = defineBehavior({\n\tname: 'movement-sequence-2d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) => new MovementSequence2DSystem(ctx.world),\n\tcreateHandle: createMovementSequence2DHandle,\n});\n","/**\n * Movement Sequence 2D Behavior Module\n *\n * Exports FSM, types, and behavior descriptor for 2D movement sequencing.\n */\n\n// FSM and types\nexport {\n\tMovementSequence2DFSM,\n\tMovementSequence2DState,\n\tMovementSequence2DEvent,\n\ttype MovementSequence2DStep,\n\ttype MovementSequence2DMovement,\n\ttype MovementSequence2DProgress,\n\ttype MovementSequence2DCurrentStep,\n} from './movement-sequence-2d-fsm';\n\n// Behavior descriptor, options, and handle\nexport {\n\tMovementSequence2DBehavior,\n\ttype MovementSequence2DOptions,\n\ttype MovementSequence2DHandle,\n} from './movement-sequence-2d.descriptor';\n","import { GameEntity } from '../entities/entity';\nimport { Ricochet2DHandle, Ricochet2DResult } from '../behaviors/ricochet-2d/ricochet-2d.descriptor';\nimport { WorldBoundary2DHandle } from '../behaviors/world-boundary-2d/world-boundary-2d.descriptor';\nimport { MoveableEntity } from '../actions/capabilities/moveable';\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 */\n public update(): Ricochet2DResult | null {\n const hits = this.boundary.getLastHits();\n if (!hits) return null;\n\n const anyHit = hits.left || hits.right || hits.top || hits.bottom;\n if (!anyHit) return null;\n\n // Compute collision normal from boundary hits\n let normalX = 0;\n let normalY = 0;\n if (hits.left) normalX = 1;\n if (hits.right) normalX = -1;\n if (hits.bottom) normalY = 1;\n if (hits.top) normalY = -1;\n\n // Compute ricochet result\n return this.ricochet.getRicochet({\n entity: this.entity,\n contact: { normal: { x: normalX, y: normalY } },\n });\n }\n}\n","/**\n * Behaviors Module Index\n *\n * Re-exports all ECS components and behaviors.\n */\n\n// Core Behavior System Interface\nexport type { BehaviorSystem, BehaviorSystemFactory } from './behavior-system';\n\n// Behavior Descriptor Pattern\nexport { defineBehavior } from './behavior-descriptor';\nexport type {\n BehaviorDescriptor,\n BehaviorRef,\n BehaviorHandle,\n DefineBehaviorConfig,\n} from './behavior-descriptor';\n\nexport { useBehavior } from './use-behavior';\n\n// Core ECS Components\nexport {\n type TransformComponent,\n type PhysicsBodyComponent,\n createTransformComponent,\n createPhysicsBodyComponent,\n} from './components';\n\n// Physics Behaviors\nexport { PhysicsStepBehavior } from './physics-step.behavior';\nexport { PhysicsSyncBehavior } from './physics-sync.behavior';\n\n// Thruster Module (components, FSM, and behaviors)\nexport * from './thruster';\n\n// Screen Wrap Module\nexport * from './screen-wrap';\n\n// World Boundary 2D Module\nexport * from './world-boundary-2d';\n\n// Ricochet 2D Module\nexport * from './ricochet-2d';\n\n// Movement Sequence 2D Module\nexport * from './movement-sequence-2d';\n\n// Coordinators\nexport * from '../coordinators/boundary-ricochet.coordinator';\n","import { Vector3 } from 'three';\nimport { RigidBody, Vector } from '@dimforge/rapier3d-compat';\n\nexport interface EntityWithBody {\n\tbody: RigidBody | null;\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.body) return;\n\tconst currentVelocity = entity.body.linvel();\n\tconst newVelocity = new Vector3(delta, currentVelocity.y, currentVelocity.z);\n\tentity.body.setLinvel(newVelocity, true);\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.body) return;\n\tconst currentVelocity = entity.body.linvel();\n\tconst newVelocity = new Vector3(currentVelocity.x, delta, currentVelocity.z);\n\tentity.body.setLinvel(newVelocity, true);\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.body) return;\n\tconst currentVelocity = entity.body.linvel();\n\tconst newVelocity = new Vector3(currentVelocity.x, currentVelocity.y, delta);\n\tentity.body.setLinvel(newVelocity, true);\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.body) return;\n\tconst currentVelocity = entity.body.linvel();\n\tconst newVelocity = new Vector3(deltaX, deltaY, currentVelocity.z);\n\tentity.body.setLinvel(newVelocity, true);\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.body) return;\n\tconst currentVelocity = entity.body.linvel();\n\tconst newVelocity = new Vector3(deltaX, currentVelocity.y, deltaZ);\n\tentity.body.setLinvel(newVelocity, true);\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.body) return;\n\tconst currentVelocity = entity.body.linvel();\n\tconst newVelocity = new Vector3(\n\t\tcurrentVelocity.x + vector.x,\n\t\tcurrentVelocity.y + vector.y,\n\t\tcurrentVelocity.z + vector.z\n\t);\n\tentity.body.setLinvel(newVelocity, true);\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 * Class decorator to enhance an entity with additive movement methods\n */\nexport function moveable<T extends { new(...args: any[]): EntityWithBody }>(constructor: T) {\n\treturn class extends constructor implements MoveableEntity {\n\t\tmoveX(delta: number): void {\n\t\t\tmoveX(this, delta);\n\t\t}\n\t\tmoveY(delta: number): void {\n\t\t\tmoveY(this, delta);\n\t\t}\n\t\tmoveZ(delta: number): void {\n\t\t\tmoveZ(this, delta);\n\t\t}\n\t\tmoveXY(deltaX: number, deltaY: number): void {\n\t\t\tmoveXY(this, deltaX, deltaY);\n\t\t}\n\t\tmoveXZ(deltaX: number, deltaZ: number): void {\n\t\t\tmoveXZ(this, deltaX, deltaZ);\n\t\t}\n\t\tmove(vector: Vector3): void {\n\t\t\tmove(this, vector);\n\t\t}\n\t\tresetVelocity(): void {\n\t\t\tresetVelocity(this);\n\t\t}\n\t\tmoveForwardXY(delta: number, rotation2DAngle: number): void {\n\t\t\tmoveForwardXY(this, delta, rotation2DAngle);\n\t\t}\n\t\tgetPosition(): Vector | null {\n\t\t\treturn getPosition(this);\n\t\t}\n\t\tgetVelocity(): Vector | null {\n\t\t\treturn getVelocity(this);\n\t\t}\n\t\tsetPosition(x: number, y: number, z: number): void {\n\t\t\tsetPosition(this, x, y, z);\n\t\t}\n\t\tsetPositionX(x: number): void {\n\t\t\tsetPositionX(this, x);\n\t\t}\n\t\tsetPositionY(y: number): void {\n\t\t\tsetPositionY(this, y);\n\t\t}\n\t\tsetPositionZ(z: number): void {\n\t\t\tsetPositionZ(this, z);\n\t\t}\n\t\twrapAroundXY(boundsX: number, boundsY: number): void {\n\t\t\twrapAroundXY(this, boundsX, boundsY);\n\t\t}\n\t\twrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void {\n\t\t\twrapAround3D(this, boundsX, boundsY, boundsZ);\n\t\t}\n\t};\n}\n\n/**\n * Enhance an entity with additive movement methods (retained for compatibility)\n */\nexport function makeMoveable<T extends EntityWithBody>(entity: T): T & MoveableEntity {\n\tconst moveable = entity as T & MoveableEntity;\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}\n\n/**\n * Wrap a standalone function with movement capabilities\n */\nexport function withMovement<T extends (...args: any[]) => any>(\n\tfn: T,\n\tentity: EntityWithBody\n): (...args: Parameters<T>) => ReturnType<T> & MoveableEntity {\n\tconst wrapped = (...args: Parameters<T>) => {\n\t\tconst result = fn(...args);\n\t\tconst moveableEntity = makeMoveable(entity);\n\t\treturn Object.assign(result, moveableEntity);\n\t};\n\treturn wrapped as (...args: Parameters<T>) => ReturnType<T> & MoveableEntity;\n}","import { Euler, Vector3, MathUtils, Quaternion } from 'three';\nimport { RigidBody } from '@dimforge/rapier3d-compat';\n\nexport interface RotatableEntity {\n\tbody: RigidBody | null;\n\tgroup: any;\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.group) return;\n\tconst euler = new Euler(rotation.x, rotation.y, rotation.z);\n\tentity.group.setRotationFromEuler(euler);\n}\n\n/**\n * Rotate an entity around the Y axis\n */\nexport function rotateY(entity: RotatableEntity, delta: number): void {\n\tsetRotationY(entity, delta);\n}\n\n/**\n * Rotate an entity around the Z axis\n */\nexport function rotateZ(entity: RotatableEntity, delta: number): void {\n\tsetRotationZ(entity, delta);\n}\n\n/**\n * Set rotation around Y axis\n */\nexport function setRotationY(entity: RotatableEntity, y: number): void {\n\tif (!entity.body) return;\n\tconst halfAngle = y / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst yComponent = Math.sin(halfAngle);\n\tentity.body.setRotation({ w: w, x: 0, y: yComponent, z: 0 }, true);\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.body) return;\n\tconst halfAngle = x / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst xComponent = Math.sin(halfAngle);\n\tentity.body.setRotation({ w: w, x: xComponent, y: 0, z: 0 }, true);\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.body) return;\n\tconst halfAngle = z / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst zComponent = Math.sin(halfAngle);\n\tentity.body.setRotation({ w: w, x: 0, y: 0, z: zComponent }, true);\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.body) return;\n\tconst quat = new Quaternion().setFromEuler(new Euler(x, y, z));\n\tentity.body.setRotation({ w: quat.w, x: quat.x, y: quat.y, z: quat.z }, true);\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\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 * Class decorator to enhance an entity with rotatable methods\n */\nexport function rotatable<T extends { new(...args: any[]): RotatableEntity }>(constructor: T) {\n\treturn class extends constructor implements RotatableEntityAPI {\n\t\trotateInDirection(moveVector: Vector3): void {\n\t\t\trotateInDirection(this, moveVector);\n\t\t}\n\t\trotateYEuler(amount: number): void {\n\t\t\trotateYEuler(this, amount);\n\t\t}\n\t\trotateEuler(rotation: Vector3): void {\n\t\t\trotateEuler(this, rotation);\n\t\t}\n\t\trotateY(delta: number): void {\n\t\t\trotateY(this, delta);\n\t\t}\n\t\trotateZ(delta: number): void {\n\t\t\trotateZ(this, delta);\n\t\t}\n\t\tsetRotationY(y: number): void {\n\t\t\tsetRotationY(this, y);\n\t\t}\n\t\tsetRotationX(x: number): void {\n\t\t\tsetRotationX(this, x);\n\t\t}\n\t\tsetRotationZ(z: number): void {\n\t\t\tsetRotationZ(this, z);\n\t\t}\n\t\tsetRotationDegrees(x: number, y: number, z: number): void {\n\t\t\tsetRotationDegrees(this, x, y, z);\n\t\t}\n\t\tsetRotationDegreesY(y: number): void {\n\t\t\tsetRotationDegreesY(this, y);\n\t\t}\n\t\tsetRotationDegreesX(x: number): void {\n\t\t\tsetRotationDegreesX(this, x);\n\t\t}\n\t\tsetRotationDegreesZ(z: number): void {\n\t\t\tsetRotationDegreesZ(this, z);\n\t\t}\n\t\tsetRotation(x: number, y: number, z: number): void {\n\t\t\tsetRotation(this, x, y, z);\n\t\t}\n\t\tgetRotation(): any {\n\t\t\treturn getRotation(this);\n\t\t}\n\t};\n}\n\n/**\n * Enhance an entity instance with rotatable methods\n */\nexport function makeRotatable<T extends RotatableEntity>(entity: T): T & RotatableEntityAPI {\n\tconst rotatableEntity = entity as T & RotatableEntityAPI;\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.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}","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 */\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\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} ","export { ricochetSound } from \"./ricochet-sound\";\nexport { pingPongBeep } from \"./ping-pong-sound\"; ","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 { debugState, setDebugTool, setPaused, type DebugTools } from '../lib/debug/debug-state';\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\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\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!.appendChild(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 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 game.options.push({ container: this.container });\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 /**\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 if (this._game) {\n this._game.dispose();\n this._game = null;\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 { 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}\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};\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","// 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';\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 { PerspectiveType } from '../lib/camera/perspective';\nexport { Perspectives } from '../lib/camera/perspective';\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 { createEntityFactory, type TemplateFactory } from '../lib/entities/entity-factory';\nexport { ZylemBox } from '../lib/entities/box';\n\n// ECS Components & Behaviors (new thruster system)\nexport * from '../lib/behaviors';\n\n// Capabilities\nexport { makeMoveable } from '../lib/actions/capabilities/moveable';\nexport { makeRotatable } from '../lib/actions/capabilities/rotatable';\nexport { makeTransformable } from '../lib/actions/capabilities/transformable';\nexport { rotatable } from '../lib/actions/capabilities/rotatable';\nexport { moveable } from '../lib/actions/capabilities/moveable';\nexport { rotateInDirection } from '../lib/actions/capabilities/rotatable';\nexport { move } from '../lib/actions/capabilities/moveable';\nexport { resetVelocity } from '../lib/actions/capabilities/moveable';\n\n\n// Destruction utilities\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// 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} 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 } from '../lib/graphics/material';\n"],"mappings":"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","names":["proxy","state","document","subscribe","all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map","state","position","rotation","scale","destroy","Mesh","Color","RepeatWrapping","ShaderMaterial","Vector2","Vector3","fragment","BufferGeometry","Mesh","Color","Color","Vector3","ActiveCollisionTypes","ColliderDesc","MeshStandardMaterial","Group","Vector3","colliderDesc","Color","Vector3","ShaderMaterial","Mesh","state","position","Color","Vector3","Color","Vector3","proxy","subscribe","BoxGeometry","Color","Group","Mesh","Vector3","BufferGeometry","LineBasicMaterial","LineSegments","Vector2","hoveredUuid","subscribe","Vector3","Vector3","state","Vector3","Object3D","WebGLRenderer","position","Vector2","Vector3","Color","Vector3","subscribe","nanoid","state","Vector2","Vector3","proxy","Vector3","proxy","initialDefaults","getGameDefaultConfig","proxy","stageState","MeshStandardMaterial","MeshBasicMaterial","MeshPhongMaterial","x","y","z","toDeg","Color","Group","Vector2","ColliderDesc","Group","Quaternion","Vector3","TextureLoader","SpriteMaterial","ThreeSprite","stageState","Euler","Quaternion","Vector2","ColliderDesc","BoxGeometry","Vector3","ColliderDesc","SphereGeometry","BufferGeometry","ColliderDesc","Vector2","Vector3","scale","ActiveCollisionTypes","ColliderDesc","Vector3","Color","Group","ThreeSprite","SpriteMaterial","CanvasTexture","LinearFilter","Vector2","ClampToEdgeWrapping","ShaderMaterial","Mesh","PlaneGeometry","Vector3","ColliderDesc","Group","Vector3","Quaternion","init_components","ThrusterState","ThrusterEvent","state","init_components","StateMachine","t","ScreenWrapState","ScreenWrapEvent","position","defaultOptions","StateMachine","t","position","WorldBoundary2DState","WorldBoundary2DEvent","moveX","moveY","moveX","moveY","defaultOptions","StateMachine","t","Ricochet2DState","Ricochet2DEvent","scale","defaultOptions","StateMachine","t","MovementSequence2DState","MovementSequence2DEvent","step","defaultOptions","Vector3","position","moveable","Euler","Vector3","Quaternion","rotation","init_zylem_game","fragment","fragment","fragment","init_debug_shader","THREE","RAPIER","init_zylem_game","init_debug_shader"]}
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/systems/transformable.system.ts","../src/lib/actions/capabilities/transform-store.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/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/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/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/debug-entity-cursor.ts","../src/lib/stage/stage-debug-delegate.ts","../src/lib/stage/stage-camera-debug-delegate.ts","../src/lib/camera/perspective.ts","../src/lib/camera/third-person.ts","../src/lib/camera/fixed-2d.ts","../src/lib/camera/camera-debug-delegate.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/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/input-manager.ts","../src/lib/core/three-addons/Timer.ts","../src/lib/device/aspect-ratio.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/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/behaviors/thruster/thruster-fsm.ts","../src/lib/behaviors/thruster/thruster-movement.behavior.ts","../src/lib/behaviors/thruster/thruster.descriptor.ts","../src/lib/behaviors/screen-wrap/screen-wrap-fsm.ts","../src/lib/behaviors/screen-wrap/screen-wrap.descriptor.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/ricochet-2d/ricochet-2d-fsm.ts","../src/lib/behaviors/ricochet-2d/ricochet-2d.descriptor.ts","../src/lib/behaviors/platformer-3d/components.ts","../src/lib/behaviors/platformer-3d/platformer-3d-fsm.ts","../src/lib/behaviors/platformer-3d/platformer-3d.behavior.ts","../src/lib/behaviors/platformer-3d/platformer-3d.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/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 } 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 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\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\tresult[player] = {\n\t\t\t\tkey: { ...target.key, ...source.key },\n\t\t\t\tmouse: { ...target.mouse, ...source.mouse },\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\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.renderer.setAnimationLoop((delta: number) => {\n\t\t\tonFrame(delta || 0);\n\t\t});\n\t}\n\n\t/**\n\t * Stop the render loop.\n\t */\n\tstopRenderLoop(): void {\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 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>;\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\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\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\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\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\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\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\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\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\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}","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 RAPIER from '@dimforge/rapier3d-compat';\n\nexport type StageSystem = {\n\t_childrenMap: Map<number, StageEntity & { body: RAPIER.RigidBody }>;\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\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\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) {\n\t\t\t\ttarget.position.set(translation.x, translation.y, translation.z);\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) {\n\t\t\t\t_tempQuaternion.set(rot.x, rot.y, rot.z, rot.w);\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}","import { proxy } from 'valtio';\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\t\n\t/** Dirty flags to track what needs to be applied */\n\tdirty: {\n\t\tposition: boolean;\n\t\trotation: boolean;\n\t\tvelocity: 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\tdirty: {\n\t\t\tposition: false,\n\t\t\trotation: false,\n\t\t\tvelocity: 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// Clear all dirty flags\n\tstore.dirty.position = false;\n\tstore.dirty.rotation = false;\n\tstore.dirty.velocity = false;\n\tstore.dirty.angularVelocity = false;\n}\n","import { Vector3 } from 'three';\nimport { RigidBody, Vector } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\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\tentity.transformStore.velocity.x = delta;\n\tentity.transformStore.dirty.velocity = true;\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\tentity.transformStore.velocity.y = delta;\n\tentity.transformStore.dirty.velocity = true;\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\tentity.transformStore.velocity.z = delta;\n\tentity.transformStore.dirty.velocity = true;\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\tentity.transformStore.velocity.x = deltaX;\n\tentity.transformStore.velocity.y = deltaY;\n\tentity.transformStore.dirty.velocity = true;\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\tentity.transformStore.velocity.x = deltaX;\n\tentity.transformStore.velocity.z = deltaZ;\n\tentity.transformStore.dirty.velocity = true;\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\tentity.transformStore.velocity.x += vector.x;\n\tentity.transformStore.velocity.y += vector.y;\n\tentity.transformStore.velocity.z += vector.z;\n\tentity.transformStore.dirty.velocity = true;\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\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.group) return;\n\tconst euler = new Euler(rotation.x, rotation.y, rotation.z);\n\tentity.group.setRotationFromEuler(euler);\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}\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}\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}\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}\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}\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}\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}\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}","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 {\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';\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}\n\n/**\n * Type guard for CollisionComponent.\n */\nexport function isCollisionComponent(obj: any): obj is CollisionComponent {\n\treturn obj && obj.__kind === 'collision';\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): CollisionComponent {\n\tapplyCollisionOptions(colliderDesc, opts);\n\treturn {\n\t\t__kind: 'collision',\n\t\tbodyDesc: buildBodyDesc(opts.static ?? false),\n\t\tcolliderDesc,\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\treturn makeComponent(desc, opts);\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\treturn makeComponent(desc, opts);\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\treturn makeComponent(desc, opts);\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\treturn makeComponent(desc, opts);\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\treturn makeComponent(desc, opts);\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\treturn makeComponent(desc, opts);\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\treturn makeComponent(desc, { ...opts, static: opts.static ?? true });\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\treturn makeComponent(desc, { ...opts, static: opts.static ?? true, sensor: true });\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 type { MoveableEntity } from '../actions/capabilities/moveable';\nimport type { RotatableEntityAPI } from '../actions/capabilities/rotatable';\nimport { isCollisionComponent, type CollisionComponent } from './parts/collision-factories';\nimport type { NodeInterface } from '../core/node-interface';\nimport { commonDefaults } from './common';\nimport type { Action } from '../actions/action';\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 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?: ((params: CollisionContext<any, any>) => void)[];\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\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 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};\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\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} else if (isCollisionComponent(component)) {\n\t\t\t\tthis.addCollisionComponent(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\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\tstore.dirty.velocity = false;\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\t// If every non-persistent action finished this frame, zero out\n\t\t// any velocity they wrote so the entity doesn't drift.\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\tstore.dirty.velocity = false;\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\t/**\n\t * Add collision callbacks\n\t */\n\tpublic onCollision(\n\t\t...callbacks: ((params: CollisionContext<this, O>) => void)[]\n\t): this {\n\t\tconst existing = this.collisionDelegate.collision ?? [];\n\t\tthis.collisionDelegate.collision = [...existing, ...callbacks];\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\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(other: GameEntity<O>, globals?: any): void {\n\t\tif (this.collisionDelegate.collision?.length) {\n\t\t\tconst callbacks = this.collisionDelegate.collision;\n\t\t\tcallbacks.forEach((callback) => {\n\t\t\t\tcallback({ entity: this, other, globals });\n\t\t\t});\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 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 { GameEntityOptions, GameEntity } 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};\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} = 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 builder.build();\n}\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","/**\n * GLTF loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parseAsync\n */\n\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\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\n\tconstructor() {\n\t\tthis.loader = new GLTFLoader();\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: result.object.clone(),\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';\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: result.object.clone(),\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';\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: result.object.clone(),\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';\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): 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);\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);\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);\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\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\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\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: result.animation\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/**\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\nexport class MaterialBuilder {\n\tstatic batchMaterialMap: Map<BatchKey, BatchMaterialMapObject> = new Map();\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, 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);\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);\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);\n\t\t}\n\n\t\tif (color) {\n\t\t\tthis.withColor(color, shouldUseTSL);\n\t\t}\n\n\t\tif (this.materials.length === 0) {\n\t\t\tthis.setColor(new Color('#ffffff'), shouldUseTSL);\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): this {\n\t\tthis.setColor(color, useTSL);\n\t\treturn this;\n\t}\n\n\twithShader(shader: ZylemShaderObject): this {\n\t\tthis.setShader(shader);\n\t\treturn this;\n\t}\n\n\twithTSLShader(shader: ZylemTSLShader): this {\n\t\tthis.setTSLShader(shader);\n\t\treturn this;\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(texturePath: TexturePath = null, repeat: Vector2 = new Vector2(1, 1), useTSL: boolean = false): 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.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});\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) {\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.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});\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) {\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});\n\t\tthis.materials.push(shader);\n\t}\n\n\t/**\n\t * Set TSL shader (WebGPU compatible)\n\t */\n\tsetTSLShader(tslShader: ZylemTSLShader) {\n\t\tconst material = new MeshBasicNodeMaterial();\n\t\tmaterial.colorNode = tslShader.colorNode;\n\t\tif (tslShader.transparent) {\n\t\t\tmaterial.transparent = true;\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 { BufferGeometry, Object3D, SkinnedMesh, Mesh, MeshStandardMaterial, Group, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { createEntity } from './create';\nimport { UpdateContext, UpdateFunction } from '../core/base-node-life-cycle';\nimport { 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 } from './builder';\nimport { 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' | 'model';\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n\tcollisionShape?: CollisionShapeType;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\t...commonDefaults,\n\tcollision: {\n\t\tstatic: false,\n\t\tsize: new Vector3(0.5, 0.5, 0.5),\n\t\tposition: new Vector3(0, 0, 0),\n\t},\n\tmaterial: {\n\t\tshader: standardShader\n\t},\n\tanimations: [],\n\tmodels: [],\n\tcollisionShape: 'capsule',\n};\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate objectModel: Group | null = null;\n\tprivate collisionShape: CollisionShapeType = 'capsule';\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t\tthis.collisionShape = data.collisionShape ?? 'capsule';\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tif (this.collisionShape === 'model') {\n\t\t\treturn this.createColliderFromModel(this.objectModel, options);\n\t\t}\n\t\treturn this.createCapsuleCollider(options);\n\t}\n\n\t/**\n\t * Create a capsule collider based on size options (character controller style).\n\t */\n\tprivate createCapsuleCollider(options: ZylemActorOptions): ColliderDesc {\n\t\tconst size = options.collision?.size ?? options.size ?? { x: 0.5, y: 1, z: 0.5 };\n\t\tconst halfHeight = ((size as any).y || 1);\n\t\tconst radius = Math.max((size as any).x || 0.5, (size as any).z || 0.5);\n\t\tlet colliderDesc = ColliderDesc.capsule(halfHeight, radius);\n\t\tcolliderDesc.setSensor(false);\n\t\tcolliderDesc.setTranslation(0, halfHeight + radius, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n\n\t/**\n\t * Create a collider based on model geometry (works with Mesh and SkinnedMesh).\n\t * If collision.size and collision.position are provided, use those instead of computing from geometry.\n\t */\n\tprivate createColliderFromModel(objectModel: Group | null, options: ZylemActorOptions): ColliderDesc {\n\t\tconst collisionSize = options.collision?.size;\n\t\tconst collisionPosition = options.collision?.position;\n\n\t\t// If user provided explicit size, use that instead of computing from model\n\t\tif (collisionSize) {\n\t\t\tconst halfWidth = (collisionSize as any).x / 2;\n\t\t\tconst halfHeight = (collisionSize as any).y / 2;\n\t\t\tconst halfDepth = (collisionSize as any).z / 2;\n\n\t\t\tlet colliderDesc = ColliderDesc.cuboid(halfWidth, halfHeight, halfDepth);\n\t\t\tcolliderDesc.setSensor(false);\n\n\t\t\t// Use user-provided position or default to center\n\t\t\tconst posX = collisionPosition ? (collisionPosition as any).x : 0;\n\t\t\tconst posY = collisionPosition ? (collisionPosition as any).y : halfHeight;\n\t\t\tconst posZ = collisionPosition ? (collisionPosition as any).z : 0;\n\t\t\tcolliderDesc.setTranslation(posX, posY, posZ);\n\t\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\t\treturn colliderDesc;\n\t\t}\n\n\t\t// Fall back to computing from model geometry\n\t\tif (!objectModel) return this.createCapsuleCollider(options);\n\n\t\t// Find first Mesh (SkinnedMesh or regular Mesh)\n\t\tlet foundGeometry: BufferGeometry | null = null;\n\t\tobjectModel.traverse((child) => {\n\t\t\tif (!foundGeometry && (child as any).isMesh) {\n\t\t\t\tfoundGeometry = (child as Mesh).geometry as BufferGeometry;\n\t\t\t}\n\t\t});\n\n\t\tif (!foundGeometry) return this.createCapsuleCollider(options);\n\n\t\tconst geometry: BufferGeometry = foundGeometry;\n\t\tgeometry.computeBoundingBox();\n\t\tconst box = geometry.boundingBox;\n\t\tif (!box) return this.createCapsuleCollider(options);\n\n\t\tconst height = box.max.y - box.min.y;\n\t\tconst width = box.max.x - box.min.x;\n\t\tconst depth = box.max.z - box.min.z;\n\n\t\t// Create box collider based on mesh bounds\n\t\tlet colliderDesc = ColliderDesc.cuboid(width / 2, height / 2, depth / 2);\n\t\tcolliderDesc.setSensor(false);\n\t\t// Position collider at center of model\n\t\tconst centerY = (box.max.y + box.min.y) / 2;\n\t\tcolliderDesc.setTranslation(0, centerY, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\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 _animationDelegate: AnimationDelegate | null = null;\n\tprivate _modelFileNames: string[] = [];\n\tprivate _assetLoader: EntityAssetLoader = new EntityAssetLoader();\n\n\tcontrolledRotation: boolean = false;\n\n\tconstructor(options?: ZylemActorOptions) {\n\t\tsuper();\n\t\tthis.options = { ...actorDefaults, ...options };\n\t\t// Add actor-specific update to the lifecycle callbacks\n\t\tthis.prependUpdate(this.actorUpdate.bind(this) as UpdateFunction<this>);\n\t\tthis.controlledRotation = true;\n\t}\n\n\t/**\n\t * Initiates model and animation loading in background (deferred).\n\t * Call returns immediately; assets will be ready on subsequent updates.\n\t */\n\tload(): void {\n\t\tthis._modelFileNames = this.options.models || [];\n\t\t// Start async loading in background\n\t\tthis.loadModelsDeferred();\n\t}\n\n\t/**\n\t * Returns current data synchronously.\n\t * May return null values if loading is still in progress.\n\t */\n\tdata(): any {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t\tcollisionShape: this.options.collisionShape,\n\t\t};\n\t}\n\n\tactorUpdate(params: UpdateContext<ZylemActorOptions>): void {\n\t\tthis._animationDelegate?.update(params.delta);\n\t}\n\n\t/**\n\t * Clean up actor resources including animations, models, and groups\n\t */\n\tactorDestroy(): void {\n\t\t// Stop and dispose animation delegate\n\t\tif (this._animationDelegate) {\n\t\t\tthis._animationDelegate.dispose();\n\t\t\tthis._animationDelegate = null;\n\t\t}\n\n\t\t// Dispose geometries and materials from loaded object\n\t\tif (this._object) {\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tconst mesh = child as SkinnedMesh;\n\t\t\t\t\tmesh.geometry?.dispose();\n\t\t\t\t\tif (Array.isArray(mesh.material)) {\n\t\t\t\t\t\tmesh.material.forEach(m => m.dispose());\n\t\t\t\t\t} else if (mesh.material) {\n\t\t\t\t\t\tmesh.material.dispose();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._object = null;\n\t\t}\n\n\t\t// Clear group reference\n\t\tif (this.group) {\n\t\t\tthis.group.clear();\n\t\t\tthis.group = null as any;\n\t\t}\n\n\t\t// Clear file name references\n\t\tthis._modelFileNames = [];\n\t}\n\n\t/**\n\t * Deferred loading - starts async load and updates entity when complete.\n\t * Called by synchronous load() method.\n\t */\n\tprivate loadModelsDeferred(): void {\n\t\tif (this._modelFileNames.length === 0) return;\n\n\t\t// Emit loading started event\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 promises = this._modelFileNames.map(file => this._assetLoader.loadFile(file));\n\t\tPromise.all(promises).then(results => {\n\t\t\tif (results[0]?.object) {\n\t\t\t\tthis._object = results[0].object;\n\t\t\t}\n\t\t\t// Count meshes for the loaded event\n\t\t\tlet meshCount = 0;\n\t\t\tif (this._object) {\n\t\t\t\tthis._object.traverse((child) => {\n\t\t\t\t\tif ((child as any).isMesh) meshCount++;\n\t\t\t\t});\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.attach(this._object);\n\t\t\t\tthis.group.scale.set(\n\t\t\t\t\tthis.options.scale?.x || 1,\n\t\t\t\t\tthis.options.scale?.y || 1,\n\t\t\t\t\tthis.options.scale?.z || 1\n\t\t\t\t);\n\n\t\t\t\t// Apply material overrides if specified\n\t\t\t\tthis.applyMaterialOverrides();\n\n\t\t\t\t// Load animations after model is ready\n\t\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\t\tthis._animationDelegate.loadAnimations(this.options.animations || []).then(() => {\n\t\t\t\t\tthis.dispatch('entity:animation:loaded', {\n\t\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\t\tanimationCount: this.options.animations?.length || 0\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Emit model loaded event\n\t\t\tthis.dispatch('entity:model:loaded', {\n\t\t\t\tentityId: this.uuid,\n\t\t\t\tsuccess: !!this._object,\n\t\t\t\tmeshCount\n\t\t\t});\n\t\t});\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\t/**\n\t * Apply material overrides from options to all meshes in the loaded model.\n\t * Only applies if material options are explicitly specified (not just defaults).\n\t */\n\tprivate applyMaterialOverrides(): void {\n\t\tconst materialOptions = this.options.material;\n\t\t// Only apply if user specified material options beyond defaults\n\t\tif (!materialOptions || (!materialOptions.color && !materialOptions.path)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._object) return;\n\n\t\tthis._object.traverse((child) => {\n\t\t\tif ((child as any).isMesh) {\n\t\t\t\tconst mesh = child as Mesh;\n\t\t\t\tif (materialOptions.color) {\n\t\t\t\t\t// Create new material with the specified color\n\t\t\t\t\tconst newMaterial = new MeshStandardMaterial({\n\t\t\t\t\t\tcolor: materialOptions.color,\n\t\t\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\t\t\tfog: true,\n\t\t\t\t\t});\n\t\t\t\t\tmesh.castShadow = true;\n\t\t\t\t\tmesh.receiveShadow = true;\n\t\t\t\t\tmesh.material = newMaterial;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\t/**\n\t * Provide custom debug information for the actor\n\t * This will be merged with the default debug information\n\t */\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};\n\n\t\t// Add animation info if available\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\t// Add mesh info if model is loaded\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\tmeshCount++;\n\t\t\t\t\tconst geometry = (child as SkinnedMesh).geometry;\n\t\t\t\t\tif (geometry && geometry.attributes.position) {\n\t\t\t\t\t\tvertexCount += geometry.attributes.position.count;\n\t\t\t\t\t}\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\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});\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 { GameEntity } from '../entities/entity';\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 class ZylemWorld implements Entity<ZylemWorld> {\n\ttype = 'World';\n\tworld: World;\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\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\tconstructor(world: World) {\n\t\tthis.world = world;\n\t}\n\n\taddEntity(entity: any) {\n\t\tconst rigidBody = this.world.createRigidBody(entity.bodyDesc);\n\t\tentity.body = rigidBody;\n\t\t// TODO: consider passing in more specific data\n\t\tentity.body.userData = { uuid: entity.uuid, ref: entity };\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\t// Create primary collider\n\t\tconst collider = this.world.createCollider(entity.colliderDesc, entity.body);\n\t\tentity.collider = collider;\n\t\tentity.colliders = [collider];\n\n\t\t// Create additional compound colliders (if any)\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\tsetForRemoval(entity: any) {\n\t\tif (entity.body) {\n\t\t\tthis._removalMap.set(entity.uuid, entity);\n\t\t}\n\t}\n\n\tdestroyEntity(entity: GameEntity<any>) {\n\t\t// Free character controller WASM resource if present\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\t// Remove all colliders (compound support)\n\t\tif (entity.colliders?.length) {\n\t\t\tfor (const collider of entity.colliders) {\n\t\t\t\tthis.world.removeCollider(collider, true);\n\t\t\t}\n\t\t} else if (entity.collider) {\n\t\t\tthis.world.removeCollider(entity.collider, true);\n\t\t}\n\t\tif (entity.body) {\n\t\t\tthis.world.removeRigidBody(entity.body);\n\t\t\tthis.collisionMap.delete(entity.uuid);\n\t\t\tthis._removalMap.delete(entity.uuid);\n\t\t}\n\t}\n\n\tsetup() { }\n\n\tupdate(params: UpdateContext<any>) {\n\t\tconst { delta } = params;\n\t\tif (!this.world) {\n\t\t\treturn;\n\t\t}\n\t\tthis.updateColliders(delta);\n\t\tthis.updatePostCollisionBehaviors(delta);\n\t\tthis.world.step();\n\t}\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\treturn;\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\tupdateColliders(delta: number) {\n\t\tconst dictionaryRef = this.collisionMap;\n\t\tfor (let [id, collider] of dictionaryRef) {\n\t\t\tconst gameEntity = collider as GameEntity<any>;\n\t\t\tif (!gameEntity.body) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (this._removalMap.get(gameEntity.uuid)) {\n\t\t\t\tthis.destroyEntity(gameEntity);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\tthis.world.contactsWith(gameEntity.body.collider(0), (otherCollider) => {\n\t\t\tif (!otherCollider) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// @ts-ignore\n\t\t\tconst uuid = otherCollider._parent.userData.uuid;\n\t\t\tconst entity = dictionaryRef.get(uuid);\n\t\t\tif (!entity) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (gameEntity._collision) {\n\t\t\t\tgameEntity._collision(entity, state.globals);\n\t\t\t}\n\t\t});\n\t\t// Body may have been invalidated by a destroy() call inside a collision callback\n\t\tif (!gameEntity.body || gameEntity.markedForRemoval) {\n\t\t\tcontinue;\n\t\t}\n\t\tthis.world.intersectionsWith(gameEntity.body.collider(0), (otherCollider) => {\n\t\t\t\tif (!otherCollider) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst uuid = otherCollider._parent.userData.uuid;\n\t\t\t\tconst entity = dictionaryRef.get(uuid);\n\t\t\t\tif (!entity) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (gameEntity._collision) {\n\t\t\t\t\tgameEntity._collision(entity, state.globals);\n\t\t\t\t}\n\t\t\t\tif (isCollisionHandlerDelegate(entity)) {\n\t\t\t\t\tentity.handleIntersectionEvent({ entity, other: gameEntity, delta });\n\t\t\t\t\tthis.collisionBehaviorMap.set(uuid, entity);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tdestroy() {\n\t\ttry {\n\t\t\tfor (const [, entity] of this.collisionMap) {\n\t\t\t\ttry { this.destroyEntity(entity); } catch { /* noop */ }\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\t// Free WASM-backed Rapier world before dropping the reference\n\t\t\ttry { this.world?.free(); } catch { /* noop */ }\n\t\t\t// @ts-ignore\n\t\t\tthis.world = undefined as any;\n\t\t} catch { /* noop */ }\n\t}\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\tif (entity.group) {\n\t\t\tthis.add(entity.group, entity.options.position);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.add(entity.mesh, entity.options.position);\n\t\t}\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 position = entity.body\n\t\t\t? new Vector3(\n\t\t\t\tentity.body.translation().x,\n\t\t\t\tentity.body.translation().y,\n\t\t\t\tentity.body.translation().z\n\t\t\t )\n\t\t\t: entity.options.position;\n\n\t\tif (entity.group) {\n\t\t\tthis.add(entity.group, position);\n\t\t} else if (entity.mesh) {\n\t\t\tthis.add(entity.mesh, position);\n\t\t}\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\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 {\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 { ZylemStage } from './zylem-stage';\nimport { debugState, DebugTools, 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\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 disposeFns: Array<() => void> = [];\n\tprivate debugCursor: DebugEntityCursor | null = null;\n\tprivate debugLines: LineSegments | 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\t\tthis.attachDomListeners();\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\t// Initialize visuals if not already created\n\t\tif (!this.debugLines) {\n\t\t\tthis.initDebugVisuals();\n\t\t}\n\n\t\tconst { world, cameraRef } = this.stage;\n\n\t\tif (this.debugLines) {\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\tthis.raycaster.setFromCamera(this.mouseNdc, cameraRef.camera);\n\t\tconst origin = this.raycaster.ray.origin.clone();\n\t\tconst direction = this.raycaster.ray.direction.clone().normalize();\n\n\t\tconst rapierRay = new Ray(\n\t\t\t{ x: origin.x, y: origin.y, z: origin.z },\n\t\t\t{ x: direction.x, y: direction.y, z: direction.z },\n\t\t);\n\t\tconst hit: RayColliderToi | null = world.world.castRay(rapierRay, this.options.maxRayDistance, true);\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._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) {\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._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\tdispose(): void {\n\t\tthis.disposeFns.forEach((fn) => fn());\n\t\tthis.disposeFns = [];\n\t\tthis.disposeDebugVisuals();\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._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.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.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 = (e: MouseEvent) => {\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.disposeFns.push(() => canvas.removeEventListener('mousemove', onMouseMove));\n\t\tthis.disposeFns.push(() => canvas.removeEventListener('mousedown', onMouseDown));\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._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","export const Perspectives = {\n\tFirstPerson: 'first-person',\n\tThirdPerson: 'third-person',\n\tIsometric: 'isometric',\n\tFlat2D: 'flat-2d',\n\tFixed2D: 'fixed-2d',\n} as const;\n\nexport type PerspectiveType = (typeof Perspectives)[keyof typeof Perspectives];","import { Scene, Vector2, Vector3 } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\nimport { ZylemRenderer } from './renderer-manager';\n\n/**\n * Third-person camera controller that supports multiple targets.\n *\n * - 0 targets: stays at configured position, looks at world origin\n * - 1 target: classic third-person follow (lerp to target + offset)\n * - 2+ targets: weighted-center framing -- computes centroid of all targets,\n * zooms out based on max distance between them, and looks at centroid\n */\nexport class ThirdPersonCamera implements PerspectiveController {\n\tdistance: Vector3;\n\tscreenResolution: Vector2 | null = null;\n\trenderer: ZylemRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\t/** Padding multiplier when framing multiple targets. Higher = more zoom out. */\n\tpaddingFactor = 1.5;\n\n\t/** Minimum camera distance when multi-framing (prevents extreme zoom-in). */\n\tminDistance = 5;\n\n\t/** Lerp factor for camera position smoothing. */\n\tlerpFactor = 0.1;\n\n\tconstructor() {\n\t\tthis.distance = new Vector3(0, 5, 8);\n\t}\n\n\t/**\n\t * Setup the third person camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\t}\n\n\t/**\n\t * Update the third person camera.\n\t * Handles 0, 1, and multi-target scenarios.\n\t */\n\tupdate(delta: number) {\n\t\tif (!this.cameraRef) return;\n\n\t\tconst targets = this.cameraRef.targets;\n\n\t\tif (targets.length === 0) {\n\t\t\t// No targets: look at world origin, stay at current position\n\t\t\tthis.cameraRef.camera.lookAt(new Vector3(0, 0, 0));\n\t\t\treturn;\n\t\t}\n\n\t\tif (targets.length === 1) {\n\t\t\t// Single target: classic third-person follow\n\t\t\tthis.updateSingleTarget(targets[0]);\n\t\t\treturn;\n\t\t}\n\n\t\t// Multiple targets: weighted-center framing\n\t\tthis.updateMultiTarget(targets);\n\t}\n\n\t/**\n\t * Classic single-target follow: lerp to target position + offset, lookAt target.\n\t */\n\tprivate updateSingleTarget(target: { group: { position: Vector3 } }) {\n\t\tconst useTarget = target.group?.position || new Vector3(0, 0, 0);\n\t\tconst desiredCameraPosition = useTarget.clone().add(this.distance);\n\t\tthis.cameraRef!.camera.position.lerp(desiredCameraPosition, this.lerpFactor);\n\t\tthis.cameraRef!.camera.lookAt(useTarget);\n\t}\n\n\t/**\n\t * Multi-target framing: compute centroid, measure spread, zoom out to fit all.\n\t */\n\tprivate updateMultiTarget(targets: Array<{ group: { position: Vector3 } }>) {\n\t\t// Compute centroid (average position of all targets)\n\t\tconst centroid = new Vector3();\n\t\tfor (const t of targets) {\n\t\t\tcentroid.add(t.group.position);\n\t\t}\n\t\tcentroid.divideScalar(targets.length);\n\n\t\t// Compute max distance from centroid to any target\n\t\tlet maxDistFromCentroid = 0;\n\t\tfor (const t of targets) {\n\t\t\tconst dist = centroid.distanceTo(t.group.position);\n\t\t\tif (dist > maxDistFromCentroid) {\n\t\t\t\tmaxDistFromCentroid = dist;\n\t\t\t}\n\t\t}\n\n\t\t// Scale the camera distance based on the spread of targets\n\t\tconst dynamicDistance = Math.max(maxDistFromCentroid * this.paddingFactor, this.minDistance);\n\n\t\t// Compute desired camera position: centroid + offset direction scaled by dynamic distance\n\t\tconst offsetDirection = this.distance.clone().normalize();\n\t\tconst desiredCameraPosition = centroid.clone().add(\n\t\t\toffsetDirection.multiplyScalar(dynamicDistance)\n\t\t);\n\n\t\t// Preserve the vertical offset proportionally\n\t\tconst baseLen = this.distance.length();\n\t\tif (baseLen > 0) {\n\t\t\tconst heightRatio = this.distance.y / baseLen;\n\t\t\tdesiredCameraPosition.y = centroid.y + dynamicDistance * heightRatio;\n\t\t}\n\n\t\t// Smooth camera movement\n\t\tthis.cameraRef!.camera.position.lerp(desiredCameraPosition, this.lerpFactor);\n\t\tthis.cameraRef!.camera.lookAt(centroid);\n\t}\n\n\t/**\n\t * Handle resize events\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Set the distance offset from the target\n\t */\n\tsetDistance(distance: Vector3) {\n\t\tthis.distance = distance;\n\t}\n}\n","import { Scene, Vector2 } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\nimport { ZylemRenderer } from './renderer-manager';\n\n/**\n * Fixed 2D Camera Controller\n * Maintains a static 2D camera view with no automatic following or movement\n */\nexport class Fixed2DCamera implements PerspectiveController {\n\tscreenResolution: Vector2 | null = null;\n\trenderer: ZylemRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\tconstructor() {\n\t\t// Fixed 2D camera doesn't need any initial setup parameters\n\t}\n\n\t/**\n\t * Setup the fixed 2D camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\n\t\t// Position camera for 2D view (looking down the Z-axis)\n\t\tthis.cameraRef.camera.position.set(0, 0, 10);\n\t\tthis.cameraRef.camera.lookAt(0, 0, 0);\n\t}\n\n\t/**\n\t * Update the fixed 2D camera\n\t * Fixed cameras don't need to update position/rotation automatically\n\t */\n\tupdate(delta: number) {\n\t\t// Fixed 2D camera maintains its position and orientation\n\t\t// No automatic updates needed for a truly fixed camera\n\t}\n\n\t/**\n\t * Handle resize events for 2D camera\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\n\t\t// For orthographic cameras, we might need to adjust the frustum\n\t\t// This is handled in the main ZylemCamera resize method\n\t}\n}\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 { Vector2, Camera, PerspectiveCamera, Vector3, Object3D, OrthographicCamera, Scene } from 'three';\nimport { PerspectiveType, Perspectives } from './perspective';\nimport { ThirdPersonCamera } from './third-person';\nimport { Fixed2DCamera } from './fixed-2d';\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';\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 * Interface for perspective-specific camera controllers\n */\nexport interface PerspectiveController {\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }): void;\n\tupdate(delta: number): void;\n\tresize(width: number, height: number): void;\n}\n\n/**\n * ZylemCamera is a lightweight camera wrapper that manages the Three.js camera,\n * perspective controller, and viewport configuration. It no longer owns a renderer;\n * rendering is handled by RendererManager.\n */\nexport class ZylemCamera {\n\tcameraRig: Object3D | null = null;\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 * Replaces the old single `target` property.\n\t */\n\ttargets: StageEntity[] = [];\n\n\t/**\n\t * @deprecated Use `targets` array instead. This getter/setter is 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// Perspective controller delegation\n\tperspectiveController: PerspectiveController | null = null;\n\n\t// Orbit controls\n\tprivate orbitController: CameraOrbitController | null = null;\n\tprivate _useOrbitalControls = false;\n\n\t/** Reference to the shared renderer manager (set during setup) */\n\tprivate _rendererManager: RendererManager | null = null;\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 camera based on perspective\n\t\tconst aspectRatio = screenResolution.x / screenResolution.y;\n\t\tthis.camera = this.createCameraForPerspective(aspectRatio);\n\n\t\t// Setup camera rig only for perspectives that need it (e.g., third-person following)\n\t\tif (this.needsRig()) {\n\t\t\tthis.cameraRig = new Object3D();\n\t\t\tthis.cameraRig.position.set(0, 3, 10);\n\t\t\tthis.cameraRig.add(this.camera);\n\t\t\tthis.camera.lookAt(new Vector3(0, 2, 0));\n\t\t} else {\n\t\t\t// Position camera directly for non-rig perspectives\n\t\t\tthis.camera.position.set(0, 0, 10);\n\t\t\tthis.camera.lookAt(new Vector3(0, 0, 0));\n\t\t}\n\n\t\t// Initialize perspective controller\n\t\tthis.initializePerspectiveController();\n\t}\n\n\t/**\n\t * Setup the camera with a scene and renderer manager.\n\t * The renderer manager provides shared rendering infrastructure.\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// Setup perspective controller\n\t\tif (this.perspectiveController && this._rendererManager) {\n\t\t\tthis.perspectiveController.setup({\n\t\t\t\tscreenResolution: this.screenResolution,\n\t\t\t\trenderer: this._rendererManager.renderer,\n\t\t\t\tscene: scene,\n\t\t\t\tcamera: this\n\t\t\t});\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\tthis.cameraRig\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 camera controllers (called each frame).\n\t * Does NOT render -- rendering is handled by RendererManager.\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 perspective controller updates when orbit controls are active\n\t\tif (this.perspectiveController && !this.isDebugModeActive() && !this._useOrbitalControls) {\n\t\t\tthis.perspectiveController.update(delta);\n\t\t}\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/**\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/**\n\t * Dispose camera resources (not the renderer -- that's managed by RendererManager).\n\t */\n\tdestroy(): void {\n\t\ttry {\n\t\t\tthis.orbitController?.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis.sceneRef = null;\n\t\tthis.targets = [];\n\t\tthis._rendererManager = null;\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null): void {\n\t\tthis.orbitController?.setDebugDelegate(delegate);\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.perspectiveController) {\n\t\t\tthis.perspectiveController.resize(width, height);\n\t\t}\n\t}\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 * Create 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 this.createThirdPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.FirstPerson:\n\t\t\t\treturn this.createFirstPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.Isometric:\n\t\t\t\treturn this.createIsometricCamera(aspectRatio);\n\t\t\tcase Perspectives.Flat2D:\n\t\t\t\treturn this.createFlat2DCamera(aspectRatio);\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\treturn this.createFixed2DCamera(aspectRatio);\n\t\t\tdefault:\n\t\t\t\treturn this.createThirdPersonCamera(aspectRatio);\n\t\t}\n\t}\n\n\t/**\n\t * Initialize perspective-specific controller\n\t */\n\tprivate initializePerspectiveController(): void {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t\t\tbreak;\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\tthis.perspectiveController = new Fixed2DCamera();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t}\n\t}\n\n\tprivate createThirdPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createFirstPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createIsometricCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFlat2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFixed2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn this.createFlat2DCamera(aspectRatio);\n\t}\n\n\t// Movement methods\n\tprivate moveCamera(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\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.position.set(position.x, position.y, position.z);\n\t\t} else {\n\t\t\tthis.camera.position.set(position.x, position.y, position.z);\n\t\t}\n\t}\n\n\tmove(position: Vector3): void {\n\t\tthis.moveCamera(position);\n\t}\n\n\trotate(pitch: number, yaw: number, roll: number): void {\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.rotateX(pitch);\n\t\t\tthis.cameraRig.rotateY(yaw);\n\t\t\tthis.cameraRig.rotateZ(roll);\n\t\t} else {\n\t\t\t(this.camera as Object3D).rotateX(pitch);\n\t\t\t(this.camera as Object3D).rotateY(yaw);\n\t\t\t(this.camera as Object3D).rotateZ(roll);\n\t\t}\n\t}\n\n\t/**\n\t * Check if this perspective type needs a camera rig\n\t */\n\tprivate needsRig(): boolean {\n\t\treturn this._perspective === Perspectives.ThirdPerson;\n\t}\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/**\n\t * @deprecated Renderer is now owned by RendererManager\n\t */\n\tget renderer(): any {\n\t\treturn this._rendererManager?.renderer;\n\t}\n\n\t/**\n\t * @deprecated Composer is now owned by RendererManager\n\t */\n\tget composer(): any {\n\t\treturn this._rendererManager?.composer;\n\t}\n\n\t/**\n\t * @deprecated Use RendererManager.setPixelRatio() instead\n\t */\n\tsetPixelRatio(dpr: number): void {\n\t\tthis._rendererManager?.setPixelRatio(dpr);\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 */\n\trender(scene: Scene): void {\n\t\tif (!this._rendererManager || this._activeCameras.length === 0) return;\n\t\tthis._rendererManager.renderCameras(scene, this._activeCameras as ZylemCamera[]);\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} 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 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): void {\n\t\tthis.scene = scene;\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\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.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.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}>;\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) { }\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);\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);\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\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\t// Apply velocity if dirty\n\tif (store.dirty.velocity) {\n\t\tentity.body.setLinvel(store.velocity, true);\n\t}\n\n\t// Apply rotation if dirty\n\tif (store.dirty.rotation) {\n\t\tentity.body.setRotation(store.rotation, true);\n\t}\n\n\t// Apply angular velocity if dirty\n\tif (store.dirty.angularVelocity) {\n\t\tentity.body.setAngvel(store.angularVelocity, true);\n\t}\n\n\t// Apply position deltas if dirty\n\tif (store.dirty.position) {\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","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\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\treturn instance;\n}\n","import { addEntity, createWorld as createECS, removeEntity } from 'bitecs';\nimport { Color, Vector3, Vector2 } 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';\nimport { subscribe } from 'valtio/vanilla';\nimport { getGlobals } from \"../game/game-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 { StageCameraDebugDelegate } from './stage-camera-debug-delegate';\nimport { StageCameraDelegate } from './stage-camera-delegate';\nimport { StageLoadingDelegate } from './stage-loading-delegate';\nimport { StageEntityModelDelegate } from './stage-entity-model-delegate';\nimport { GameEntity } from '../entities/entity';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { LoadingEvent } from '../core/interfaces';\nimport { parseStageOptions } from './stage-config';\nimport { isBaseNode, isThenable } from '../core/utility/options-parser';\nimport type { BehaviorSystem, BehaviorSystemFactory } from '../behaviors/behavior-system';\nimport { applyTransformChanges } from '../actions/capabilities/apply-transform';\nimport { Vessel } from '../core/vessel';\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\tstageRef?: Stage;\n}\n\ntype NodeLike = { create: Function };\nexport type StageEntityInput = NodeLike | Promise<any> | (() => NodeLike | Promise<any>);\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 * - Spawn, track, and remove entities; emit entity-added events\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\tchildren: Array<BaseNode> = [];\n\t_childrenMap: Map<number, BaseNode> = new Map();\n\t_removalMap: Map<number, BaseNode> = new Map();\n\n\tprivate pendingEntities: StageEntityInput[] = [];\n\tprivate pendingPromises: Promise<BaseNode>[] = [];\n\tprivate isLoaded: boolean = false;\n\n\t_debugMap: Map<string, BaseNode> = new Map();\n\n\tprivate entityAddedHandlers: Array<(entity: BaseNode) => void> = [];\n\n\tecs = createECS();\n\ttestSystem: any = null;\n\ttransformSystem: ReturnType<typeof createTransformSystem> | null = null;\n\tprivate behaviorSystems: BehaviorSystem[] = [];\n\tprivate registeredSystemKeys: Set<symbol> = new Set();\n\tdebugDelegate: StageDebugDelegate | null = null;\n\tcameraDebugDelegate: StageCameraDebugDelegate | null = null;\n\tprivate debugStateUnsubscribe: (() => void) | 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\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\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.children = parsed.entities;\n\t\tthis.pendingEntities = parsed.asyncEntities;\n\t\t\n\t\t// Update state with resolved config\n\t\tthis.saveState({\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\tentities: [],\n\t\t});\n\n\t\tthis.gravity = parsed.config.gravity ?? new Vector3(0, 0, 0);\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\tprivate saveState(state: StageState) {\n\t\tthis.state = state;\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\t// Initialize reactive stage variables on load\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. This avoids creating two separate default\n\t\t// camera instances (one for the scene and a different one in the manager).\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 physicsWorld = await ZylemWorld.loadPhysics(this.gravity ?? new Vector3(0, 0, 0));\n\t\tthis.world = new ZylemWorld(physicsWorld);\n\n\t\t// Setup scene (lighting, etc.)\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\t// Setup render pass for the primary camera (WebGL post-processing)\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\t// Start the render loop via the renderer manager\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\t// Legacy path: single camera manages its own renderer\n\t\t\tthis.scene.setupCamera(this.scene.scene, zylemCamera);\n\t\t}\n\n\t\tthis.entityModelDelegate.attach(this.scene);\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\tthis.loadingDelegate.emitStart();\n\n\t\t// Run entity loading with generator pattern for real-time progress\n\t\tawait this.runEntityLoadGenerator();\n\n\t\tthis.transformSystem = createTransformSystem(this as unknown as StageSystem);\n\t\tthis.isLoaded = true;\n\t\tthis.loadingDelegate.emitComplete();\n\t}\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/**\n\t * Runs the entity load generator, yielding to the event loop between loads.\n\t * This allows the browser to process events and update the UI in real-time.\n\t */\n\tprivate runEntityLoadGenerator(): void {\n\t\tconst gen = this.entityLoadGenerator();\n\t\tfor (const progress of gen) {\n\t\t\tthis.loadingDelegate.emitProgress(`Loaded ${progress.name}`, progress.current, progress.total);\n\t\t\t// Yield to event loop so browser can process events and update UI\n\t\t\t// Use setTimeout(0) for more reliable async behavior than RAF\n\t\t\tnew Promise<void>(resolve => setTimeout(resolve, 0));\n\t\t}\n\t}\n\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// Setup debug delegate based on current state\n\t\tthis.updateDebugDelegate();\n\n\t\t// Subscribe to debugState changes for runtime toggle\n\t\tthis.debugStateUnsubscribe = subscribe(debugState, () => {\n\t\t\tthis.updateDebugDelegate();\n\t\t});\n\t}\n\n\tprivate updateDebugDelegate(): void {\n\t\tif (debugState.enabled && !this.debugDelegate && this.scene && this.world) {\n\t\t\t// Create debug delegate when debug is enabled\n\t\t\tthis.debugDelegate = new StageDebugDelegate(this);\n\t\t\t\n\t\t\t// Create and attach camera debug delegate for orbit controls\n\t\t\tif (this.cameraRef && !this.cameraDebugDelegate) {\n\t\t\t\tthis.cameraDebugDelegate = new StageCameraDebugDelegate(this);\n\t\t\t\tthis.cameraRef.setDebugDelegate(this.cameraDebugDelegate);\n\t\t\t}\n\t\t} else if (!debugState.enabled && this.debugDelegate) {\n\t\t\t// Dispose debug delegate when debug is disabled\n\t\t\tthis.debugDelegate.dispose();\n\t\t\tthis.debugDelegate = null;\n\t\t\t\n\t\t\t// Detach camera debug delegate\n\t\t\tif (this.cameraRef) {\n\t\t\t\tthis.cameraRef.setDebugDelegate(null);\n\t\t\t}\n\t\t\tthis.cameraDebugDelegate = null;\n\t\t}\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\t\t// Run registered ECS behavior systems\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.update(this.ecs, delta);\n\t\t}\n\t\tthis._childrenMap.forEach((child, eid) => {\n\t\t\tchild.nodeUpdate({\n\t\t\t\t...params,\n\t\t\t\tme: child,\n\t\t\t});\n\t\t\t\n\t\t\t// Apply pending transformations after update callbacks\n\t\t\tif ((child as any).transformStore) {\n\t\t\t\tapplyTransformChanges(child as any, (child as any).transformStore);\n\t\t\t}\n\t\t\t\n\t\t\tif (child.markedForRemoval) {\n\t\t\t\tthis.removeEntityByUuid(child.uuid);\n\t\t\t}\n\t\t});\n\t\t\n\t\t// Sync physics to rendering AFTER transforms are applied\n\t\tthis.transformSystem?.system(this.ecs);\n\t\t\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// Cleanup behavior systems\n\t\tfor (const system of this.behaviorSystems) {\n\t\t\tsystem.destroy?.(this.ecs);\n\t\t}\n\t\tthis.behaviorSystems = [];\n\t\tthis.registeredSystemKeys.clear();\n\t\tthis._childrenMap.forEach((child) => {\n\t\t\ttry { child.nodeDestroy({ me: child, globals: getGlobals() }); } catch { /* noop */ }\n\t\t\t// Clear entity-scoped variable proxy store entries\n\t\t\tclearVariables(child);\n\t\t});\n\t\tthis._childrenMap.clear();\n\t\tthis._removalMap.clear();\n\t\tthis._debugMap.clear();\n\n\t\tthis.world?.destroy();\n\t\tthis.scene?.destroy();\n\n\t\t// Cleanup debug state subscription\n\t\tif (this.debugStateUnsubscribe) {\n\t\t\tthis.debugStateUnsubscribe();\n\t\t\tthis.debugStateUnsubscribe = null;\n\t\t}\n\n\t\tthis.debugDelegate?.dispose();\n\t\tthis.debugDelegate = null;\n\t\tthis.cameraRef?.setDebugDelegate(null);\n\t\tthis.cameraDebugDelegate = 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.isLoaded = false;\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\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\t// Clear object-scoped variables for this stage\n\t\tclearVariables(this);\n\t}\n\n\t/**\n\t * Create, register, and add an entity to the scene/world.\n\t * Safe to call only after `load` when scene/world exist.\n\t */\n\tasync spawnEntity(child: BaseNode) {\n\t\tif (!this.scene || !this.world) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If the child is a Vessel, spawn each of its children individually\n\t\t// then register the Vessel itself so it participates in the update loop.\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\t// Assign an ECS eid so the Vessel can be tracked in _childrenMap\n\t\t\tconst vesselEid = addEntity(this.ecs);\n\t\t\tchild.eid = vesselEid;\n\n\t\t\t// Run vessel lifecycle after children are spawned\n\t\t\tchild.nodeSetup({\n\t\t\t\tme: child,\n\t\t\t\tglobals: getGlobals(),\n\t\t\t\tcamera: this.scene.zylemCamera,\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\t\tthis.scene.addEntity(entity);\n\n\t\t// Auto-register behavior systems from entity refs\n\t\tif (typeof entity.getBehaviorRefs === 'function') {\n\t\t\tfor (const ref of entity.getBehaviorRefs()) {\n\t\t\t\tconst key = ref.descriptor.key;\n\t\t\t\tif (!this.registeredSystemKeys.has(key)) {\n\t\t\t\t\tconst system = ref.descriptor.systemFactory({ world: this.world, ecs: this.ecs, scene: this.scene });\n\t\t\t\t\tthis.behaviorSystems.push(system);\n\t\t\t\t\tthis.registeredSystemKeys.add(key);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (entity.colliderDesc) {\n\t\t\tthis.world.addEntity(entity);\n\t\t}\n\n\t\t// Recursively spawn any BaseNode children (for nested entities)\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.scene.zylemCamera,\n\t\t});\n\n\t\t// Register for instanced rendering if opted in\n\t\tthis.tryRegisterInstance(entity);\n\n\t\tthis.addEntityToStage(entity);\n\t\tthis.entityModelDelegate.observe(entity);\n\t}\n\n\t/**\n\t * Try to register an entity for instanced rendering.\n\t * Batching is enabled by default unless explicitly disabled with batched: false.\n\t */\n\tprivate tryRegisterInstance(entity: GameEntity<any>): void {\n\t\tif (!this.instanceManager) return;\n\n\t\t// Batching is disabled by default, must be explicitly enabled\n\t\tconst options = entity.options as any;\n\t\tif (options?.batched !== true) return;\n\n\t\t// Need mesh with geometry and material\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\t// Generate batch key based on entity type and options\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\t// Register with instance manager\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\t// Hide the individual mesh since it's now part of an instanced batch\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\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/** Add the entity to internal maps and notify listeners. */\n\taddEntityToStage(entity: BaseNode) {\n\t\tthis._childrenMap.set(entity.eid, entity);\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/**\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(callback: (entity: BaseNode) => void, options?: { replayExisting?: boolean }) {\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 { callback(entity); } catch (e) { console.error('onEntityAdded replay failed', e); }\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\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\tlet system: BehaviorSystem;\n\t\tif (typeof systemOrFactory === 'function') {\n\t\tsystem = systemOrFactory({ world: this.world, ecs: this.ecs, scene: this.scene });\n\t\t} else {\n\t\t\tsystem = systemOrFactory;\n\t\t}\n\t\tthis.behaviorSystems.push(system);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Remove an entity and its resources by its UUID.\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) return false;\n\t\t// Try mapping via world collision map first for physics-backed entities\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\n\t\tthis.entityModelDelegate.unobserve(uuid);\n\n\t\t// Unregister from instance manager if instanced\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\tlet foundKey: number | null = null;\n\t\tthis._childrenMap.forEach((value, key) => {\n\t\t\tif ((value as any).uuid === uuid) {\n\t\t\t\tfoundKey = key;\n\t\t\t}\n\t\t});\n\t\tif (foundKey !== null) {\n\t\t\tthis._childrenMap.delete(foundKey);\n\t\t}\n\t\tthis._debugMap.delete(uuid);\n\t\treturn true;\n\t}\n\n\t/** Get an entity by its name; returns null if not found. */\n\tgetEntityByName(name: string) {\n\t\tconst arr = Object.entries(Object.fromEntries(this._childrenMap)).map((entry) => entry[1]);\n\t\tconst entity = arr.find((child) => child.name === name);\n\t\tif (!entity) {\n\t\t\tconsole.warn(`Entity ${name} not found`);\n\t\t}\n\t\treturn entity ?? null;\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/**\n\t * Add a camera to this stage's camera manager.\n\t */\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/**\n\t * Remove a camera from this stage's camera manager.\n\t */\n\tremoveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\treturn this.cameraManagerRef?.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): boolean {\n\t\treturn this.cameraManagerRef?.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.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\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[]) {\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","import { Vector2, Vector3 } from \"three\";\nimport { PerspectiveType } from \"./perspective\";\nimport { ZylemCamera } from \"./zylem-camera\";\nimport { RendererType, Viewport, DEFAULT_VIEWPORT } from \"./renderer-manager\";\nimport { StageEntity } from \"../interfaces/entity\";\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}\n\n/**\n * CameraWrapper is the user-facing camera handle returned by createCamera().\n * It provides convenience methods for target management, orbital controls, and viewport configuration.\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\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// 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// Mark for enablement -- actual OrbitControls are created during setup()\n\t\t// when the renderer DOM element is available\n\t\t(zylemCamera as any)._useOrbitalControls = true;\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?.children.find(c => c.name === 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 { GameConfig, resolveGameConfig } 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\nexport class ZylemGame<TGlobals extends BaseGlobals> {\n\tid: string;\n\tinitialGlobals = {} as TGlobals;\n\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\n\tstatic FRAME_LIMIT = 120;\n\tstatic FRAME_DURATION = 1000 / ZylemGame.FRAME_LIMIT;\n\tstatic MAX_DELTA_SECONDS = 1 / 30;\n\n\tconstructor(options: ZylemGameOptions<TGlobals>, wrapperRef: Game<TGlobals>) {\n\t\tthis.wrapperRef = wrapperRef;\n\t\tthis.timer = new Timer();\n\t\tthis.timer.connect(document);\n\n\t\tconst config = resolveGameConfig(options as any);\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\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\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\t\treturn {\n\t\t\tdelta,\n\t\t\tinputs,\n\t\t\tglobals: getGlobals<TGlobals>(),\n\t\t\tme: this,\n\t\t\tcamera: camera!,\n\t\t};\n\t}\n\n\tstart() {\n\t\tconst stage = this.currentStage();\n\t\tconst params = this.params();\n\t\tstage!.start({ ...params, me: stage!.wrappedStage as ZylemStage });\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\tconst clampedParams = { ...params, delta: clampedDelta };\n\n\t\tif (this.customUpdate) {\n\t\t\tthis.customUpdate(clampedParams);\n\t\t}\n\n\t\tstage.wrappedStage?.nodeUpdate({ ...clampedParams, me: stage.wrappedStage as ZylemStage });\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.loop.bind(this));\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\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._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\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},\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\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};\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}\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\t\taxes: {\n\t\t\t\tHorizontal: this.handleAnalogState(0, gamepad, delta),\n\t\t\t\tVertical: this.handleAnalogState(1, gamepad, delta),\n\t\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, InputGamepad, InputPlayerNumber, Inputs } from './input';\nimport { KeyboardProvider } from './keyboard-provider';\nimport { GamepadProvider } from './gamepad-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\tthis.addInputProvider(player, new GamepadProvider(gamepadIndex));\n\t\t}\n\t}\n\n\t/**\n\t * Reconfigure keyboard providers at runtime without affecting gamepad providers.\n\t * Disposes existing keyboard 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 providers\n\t\t\tconst remaining = providers.filter(p => {\n\t\t\t\tif (p instanceof KeyboardProvider) {\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\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},\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};\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\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\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\tthis.apply();\n\t}\n\n\t/** Detach window resize listener. */\n\tdetach() {\n\t\twindow.removeEventListener('resize', this.handleResizeBound);\n\t}\n\n\t/** Compute the largest size that fits container while preserving aspect. */\n\tmeasure(): { width: number; height: number } {\n\t\tconst containerWidth = this.container.clientWidth || window.innerWidth;\n\t\tconst containerHeight = this.container.clientHeight || window.innerHeight;\n\n\t\tconst containerRatio = containerWidth / containerHeight;\n\t\tif (containerRatio > this.aspectRatio) {\n\t\t\t// container is wider than target; limit by height\n\t\t\tconst height = containerHeight;\n\t\t\tconst width = Math.round(height * this.aspectRatio);\n\t\t\treturn { width, height };\n\t\t} else {\n\t\t\t// container is taller/narrower; limit by width\n\t\t\tconst width = containerWidth;\n\t\t\tconst height = Math.round(width / this.aspectRatio);\n\t\t\treturn { width, height };\n\t\t}\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}","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 and console 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};\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\n","import { StageInterface } from \"../types\";\nimport { GameInputConfig } from \"./game-interfaces\";\nimport { AspectRatio, AspectRatioValue } from \"../device/aspect-ratio\";\nimport { getDisplayAspect, getPresetResolution, parseResolution, RetroPresetKey } from \"./game-retro-resolutions\";\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 resolution (e.g., '256x240' or { width, height }) */\n\tresolution: string | { width: number; height: number };\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 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\nexport function resolveGameConfig(user?: GameConfigLike): 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\n\t// Derive aspect ratio: explicit numeric -> preset -> default\n\tconst explicitAspect = user?.aspectRatio as any;\n\tlet aspectRatio = defaults.aspectRatio;\n\tif (typeof explicitAspect === 'number' || (explicitAspect && typeof explicitAspect === 'string')) {\n\t\taspectRatio = typeof explicitAspect === 'number' ? explicitAspect : (AspectRatio as any)[explicitAspect] ?? defaults.aspectRatio;\n\t} else if (user?.preset) {\n\t\ttry {\n\t\t\taspectRatio = getDisplayAspect(user.preset as RetroPresetKey) || defaults.aspectRatio;\n\t\t} catch {\n\t\t\taspectRatio = defaults.aspectRatio;\n\t\t}\n\t}\n\n\tconst fullscreen = (user?.fullscreen as boolean) ?? defaults.fullscreen;\n\tconst bodyBackground = (user?.bodyBackground as string) ?? defaults.bodyBackground;\n\n\t// Normalize internal resolution lock\n\tlet internalResolution: { width: number; height: number } | undefined;\n\tif (user?.resolution) {\n\t\tif (typeof user.resolution === 'string') {\n\t\t\tconst parsed = parseResolution(user.resolution);\n\t\t\tif (parsed) internalResolution = parsed;\n\t\t\t// fallback: allow preset resolution keys like '256x240' under a preset\n\t\t\tif (!internalResolution && user.preset) {\n\t\t\t\tconst res = getPresetResolution(user.preset as RetroPresetKey, user.resolution);\n\t\t\t\tif (res) internalResolution = { width: res.width, height: res.height };\n\t\t\t}\n\t\t} else if (typeof user.resolution === 'object') {\n\t\t\tconst w = (user.resolution as any).width;\n\t\t\tconst h = (user.resolution as any).height;\n\t\t\tif (Number.isFinite(w) && Number.isFinite(h)) {\n\t\t\t\tinternalResolution = { width: w, height: h };\n\t\t\t}\n\t\t}\n\t}\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}","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\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';\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 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\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\t\tconst internal = this.config?.internalResolution;\n\n\t\tthis.gameCanvas.mountRenderer(dom, (cssW, cssH) => {\n\t\t\tif (!this.rendererManager) return;\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} 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}\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\tconst internal = this.config?.internalResolution;\n\t\t\n\t\tthis.gameCanvas.mountRenderer(dom, (cssW, cssH) => {\n\t\t\tif (!this.camera) return;\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.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.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 { resolveGameConfig } 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\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\tprivate async load(): Promise<ZylemGame<TGlobals>> {\n\t\tconst options = await convertNodes<TGlobals>(this.options);\n\t\tconst resolved = resolveGameConfig(options as any);\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);\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}\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}","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});\n}\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 { DestroyContext, DestroyFunction, UpdateContext, UpdateFunction } 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.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\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\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\tspriteUpdate(params: UpdateContext<ZylemSpriteOptions>): void {\n\t\tthis.sprites.forEach(_sprite => {\n\t\t\tif (_sprite.material) {\n\t\t\t\tconst q = this.body?.rotation();\n\t\t\t\tif (q) {\n\t\t\t\t\tconst quat = new Quaternion(q.x, q.y, q.z, q.w);\n\t\t\t\t\tconst euler = new Euler().setFromQuaternion(quat, 'XYZ');\n\t\t\t\t\t_sprite.material.rotation = euler.z;\n\t\t\t\t}\n\t\t\t\t_sprite.scale.set(this.options.size?.x ?? 1, this.options.size?.y ?? 1, this.options.size?.z ?? 1);\n\t\t\t}\n\t\t});\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});\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\t// Clone the template entity using its constructor and options\n\t\t\t\tconst EntityClass = template.constructor as new (options: O) => E;\n\t\t\t\tconst options = { ...template.options } as O;\n\t\t\t\tconst clone = new EntityClass(options).create() as E;\n\t\t\t\t\n\t\t\t\t// Copy behavior refs from template\n\t\t\t\tconst templateRefs = template.getBehaviorRefs();\n\t\t\t\tfor (const ref of templateRefs) {\n\t\t\t\t\tclone.use(ref.descriptor, ref.options);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Copy lifecycle callbacks from template\n\t\t\t\tconst templateCallbacks = (template as any).lifecycleCallbacks;\n\t\t\t\tif (templateCallbacks) {\n\t\t\t\t\tconst cloneCallbacks = (clone as any).lifecycleCallbacks;\n\t\t\t\t\tif (cloneCallbacks) {\n\t\t\t\t\t\tcloneCallbacks.setup.push(...templateCallbacks.setup);\n\t\t\t\t\t\tcloneCallbacks.update.push(...templateCallbacks.update);\n\t\t\t\t\t\tcloneCallbacks.destroy.push(...templateCallbacks.destroy);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tentities.push(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';\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// 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\tuseArrowsForDirections,\n\tuseWASDForDirections,\n\tuseWASDForAxes,\n\tuseIJKLForAxes,\n\tuseIJKLForDirections,\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 { BaseNode } from '../core/base-node';\nimport { 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 entity;\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 { 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 entity;\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});\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 { 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 entity;\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});\n}\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});\n}\n","import { BaseNode } from '../core/base-node';\nimport { 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 entity;\n}\n","import { BaseNode } from '../core/base-node';\nimport { 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 entity;\n}\n","import { BaseNode } from '../core/base-node';\nimport { 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 entity;\n}\n","import { BaseNode } from '../core/base-node';\nimport { 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 entity;\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}\n\nexport function createThrusterInputComponent(): ThrusterInputComponent {\n\treturn {\n\t\tthrust: 0,\n\t\trotate: 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","/**\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 { StateMachine, t, type ITransition } from 'typescript-fsm';\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}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThrusterFSM Controller\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThrusterFSM {\n\tmachine: StateMachine<ThrusterState, ThrusterEvent, never>;\n\n\tconstructor(private ctx: ThrusterFSMContext) {\n\t\tthis.machine = new StateMachine<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.dispatch(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 = Math.abs(playerInput.thrust) > 0.01 || Math.abs(playerInput.rotate) > 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","/**\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';\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 * Query function - returns entities with required thruster components\n\t */\n\tprivate queryEntities(): ThrusterEntity[] {\n\t\tconst entities: ThrusterEntity[] = [];\n\t\t\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\t\t\tif (\n\t\t\t\tgameEntity.physics?.body &&\n\t\t\t\tgameEntity.thruster &&\n\t\t\t\tgameEntity.$thruster\n\t\t\t) {\n\t\t\t\tentities.push({\n\t\t\t\t\tphysics: gameEntity.physics,\n\t\t\t\t\tthruster: gameEntity.thruster,\n\t\t\t\t\t$thruster: gameEntity.$thruster,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn entities;\n\t}\n\n\tupdate(_dt: number): void {\n\t\tconst entities = this.queryEntities();\n\n\t\tfor (const e of entities) {\n\t\t\tconst body = e.physics.body;\n\t\t\tconst thruster = e.thruster;\n\t\t\tconst input = e.$thruster;\n\n\t\t\t// Get Z rotation from quaternion (for 2D sprites)\n\t\t\tconst q = body.rotation();\n\t\t\tconst rotationZ = Math.atan2(2 * (q.w * q.z + q.x * q.y), 1 - 2 * (q.y * q.y + q.z * q.z));\n\n\t\t\t// --- Linear thrust (Asteroids-style: adds velocity in forward direction) ---\n\t\t\tif (input.thrust !== 0) {\n\t\t\t\tconst currentVel = body.linvel();\n\t\t\t\t\n\t\t\t\tif (input.thrust > 0) {\n\t\t\t\t\t// Forward thrust: add velocity in facing direction\n\t\t\t\t\tconst forwardX = Math.sin(-rotationZ);\n\t\t\t\t\tconst forwardY = Math.cos(-rotationZ);\n\t\t\t\t\tconst thrustAmount = thruster.linearThrust * input.thrust * 0.1;\n\t\t\t\t\tbody.setLinvel({\n\t\t\t\t\t\tx: currentVel.x + forwardX * thrustAmount,\n\t\t\t\t\t\ty: currentVel.y + forwardY * thrustAmount,\n\t\t\t\t\t\tz: currentVel.z\n\t\t\t\t\t}, true);\n\t\t\t\t} else {\n\t\t\t\t\t// Brake: reduce current velocity (slow down)\n\t\t\t\t\tconst brakeAmount = 0.9; // 10% reduction per frame\n\t\t\t\t\tbody.setLinvel({\n\t\t\t\t\t\tx: currentVel.x * brakeAmount,\n\t\t\t\t\t\ty: currentVel.y * brakeAmount,\n\t\t\t\t\t\tz: currentVel.z\n\t\t\t\t\t}, true);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// --- Angular thrust (Z-axis for 2D) ---\n\t\t\tif (input.rotate !== 0) {\n\t\t\t\tbody.setAngvel({ x: 0, y: 0, z: -thruster.angularThrust * input.rotate }, true);\n\t\t\t} else {\n\t\t\t\t// Stop rotation when no input\n\t\t\t\tconst angVel = body.angvel();\n\t\t\t\tbody.setAngvel({ x: angVel.x, y: angVel.y, z: 0 }, true);\n\t\t\t}\n\t\t}\n\t}\n}\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 { BehaviorSystem } from '../behavior-system';\nimport { ThrusterMovementBehavior, ThrusterEntity } from './thruster-movement.behavior';\nimport { ThrusterFSM } from './thruster-fsm';\nimport type { ThrusterMovementComponent, ThrusterInputComponent } 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}\n\nconst defaultOptions: ThrusterBehaviorOptions = {\n\tlinearThrust: 10,\n\tangularThrust: 5,\n};\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(private world: any) {\n\t\tthis.movementBehavior = new ThrusterMovementBehavior(world);\n\t}\n\n\tupdate(ecs: IWorld, delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\t// Initialize ECS components on entities with thruster behavior refs\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\t\t\t\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\t\t\t\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst thrusterRef = refs.find((r: any) => \n\t\t\t\tr.descriptor.key === Symbol.for('zylem:behavior:thruster')\n\t\t\t);\n\t\t\t\n\t\t\tif (!thrusterRef || !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 = {\n\t\t\t\t\tlinearThrust: options.linearThrust,\n\t\t\t\t\tangularThrust: options.angularThrust,\n\t\t\t\t} as ThrusterMovementComponent;\n\t\t\t}\n\n\t\t\tif (!gameEntity.$thruster) {\n\t\t\t\tgameEntity.$thruster = {\n\t\t\t\t\tthrust: 0,\n\t\t\t\t\trotate: 0,\n\t\t\t\t} 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});\n\t\t\t}\n\t\t}\n\n\t\t// Delegate to the existing movement behavior\n\t\tthis.movementBehavior.update(delta);\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) => new ThrusterBehaviorSystem(ctx.world),\n});\n","/**\n * ScreenWrapFSM\n * \n * State machine for screen wrap behavior.\n * Reports position relative to bounds edges.\n */\n\nimport { StateMachine, t } from 'typescript-fsm';\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: StateMachine<ScreenWrapState, ScreenWrapEvent, never>;\n\n\tconstructor() {\n\t\tthis.machine = new StateMachine<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.dispatch(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","/**\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 { BehaviorSystem } from '../behavior-system';\nimport { ScreenWrapFSM } from './screen-wrap-fsm';\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\n/**\n * ScreenWrapSystem - Wraps entities around 2D bounds\n */\nclass ScreenWrapSystem implements BehaviorSystem {\n\tconstructor(private world: any) {}\n\n\tupdate(ecs: IWorld, delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\t\t\t\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\t\t\t\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst wrapRef = refs.find((r: any) => \n\t\t\t\tr.descriptor.key === Symbol.for('zylem:behavior:screen-wrap')\n\t\t\t);\n\t\t\t\n\t\t\tif (!wrapRef || !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 { width, height, centerX, centerY, edgeThreshold } = options;\n\t\t\tconst halfWidth = width / 2;\n\t\t\tconst halfHeight = height / 2;\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: centerX - halfWidth,\n\t\t\t\t\tmaxX: centerX + halfWidth,\n\t\t\t\t\tminY: centerY - halfHeight,\n\t\t\t\t\tmaxY: centerY + halfHeight,\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 { width, height, centerX, centerY } = options;\n\t\tconst halfWidth = width / 2;\n\t\tconst halfHeight = height / 2;\n\n\t\tconst minX = centerX - halfWidth;\n\t\tconst maxX = centerX + halfWidth;\n\t\tconst minY = centerY - halfHeight;\n\t\tconst maxY = centerY + halfHeight;\n\n\t\tconst pos = body.translation();\n\t\tlet newX = pos.x;\n\t\tlet newY = pos.y;\n\t\tlet wrapped = false;\n\n\t\t// Wrap X\n\t\tif (pos.x < minX) {\n\t\t\tnewX = maxX - (minX - pos.x);\n\t\t\twrapped = true;\n\t\t} else if (pos.x > maxX) {\n\t\t\tnewX = minX + (pos.x - maxX);\n\t\t\twrapped = true;\n\t\t}\n\n\t\t// Wrap Y\n\t\tif (pos.y < minY) {\n\t\t\tnewY = maxY - (minY - pos.y);\n\t\t\twrapped = true;\n\t\t} else if (pos.y > maxY) {\n\t\t\tnewY = minY + (pos.y - maxY);\n\t\t\twrapped = true;\n\t\t}\n\n\t\tif (wrapped) {\n\t\t\tbody.setTranslation({ x: newX, y: newY, z: pos.z }, true);\n\t\t}\n\n\t\treturn 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) => new ScreenWrapSystem(ctx.world),\n});\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 { StateMachine, t } from 'typescript-fsm';\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\tconst hits: WorldBoundary2DHits = {\n\t\ttop: false,\n\t\tbottom: false,\n\t\tleft: false,\n\t\tright: false,\n\t};\n\n\tif (position.x <= bounds.left) hits.left = true;\n\telse if (position.x >= bounds.right) hits.right = true;\n\n\tif (position.y <= bounds.bottom) hits.bottom = true;\n\telse if (position.y >= bounds.top) hits.top = true;\n\n\treturn hits;\n}\n\nexport function hasAnyWorldBoundary2DHit(hits: WorldBoundary2DHits): boolean {\n\treturn !!(hits.left || hits.right || hits.top || hits.bottom);\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: StateMachine<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 StateMachine<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\tconst hits = this.lastHits;\n\n\t\tlet adjustedX = moveX;\n\t\tlet adjustedY = moveY;\n\n\t\t// If moving left and hitting left, or moving right and hitting right, zero X\n\t\tif ((hits.left && moveX < 0) || (hits.right && moveX > 0)) {\n\t\t\tadjustedX = 0;\n\t\t}\n\n\t\t// If moving down and hitting bottom, or moving up and hitting top, zero Y\n\t\tif ((hits.bottom && moveY < 0) || (hits.top && moveY > 0)) {\n\t\t\tadjustedY = 0;\n\t\t}\n\n\t\treturn { moveX: adjustedX, moveY: adjustedY };\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.dispatch(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 { 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\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(private world: any) {}\n\n\tupdate(_ecs: IWorld, _delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst boundaryRef = refs.find(\n\t\t\t\t(r: any) => r.descriptor.key === Symbol.for('zylem:behavior:world-boundary-2d')\n\t\t\t);\n\n\t\t\tif (!boundaryRef || !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) => new WorldBoundary2DSystem(ctx.world),\n\tcreateHandle: createWorldBoundary2DHandle,\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 { StateMachine, t } from 'typescript-fsm';\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: StateMachine<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 StateMachine<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.dispatch(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 { 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\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(private world: any) {}\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\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst ricochetRef = refs.find(\n\t\t\t\t(r: any) => r.descriptor.key === Symbol.for('zylem:behavior:ricochet-2d')\n\t\t\t);\n\n\t\t\tif (!ricochetRef) continue;\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\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst ricochetRef = refs.find(\n\t\t\t\t(r: any) => r.descriptor.key === Symbol.for('zylem:behavior:ricochet-2d')\n\t\t\t);\n\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) => new Ricochet2DSystem(ctx.world),\n\tcreateHandle: createRicochet2DHandle,\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}\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};\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 { StateMachine, t } from 'typescript-fsm';\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: StateMachine<Platformer3DState, Platformer3DEvent, never>;\n\n\tconstructor(private ctx: Platformer3DContext) {\n\t\tthis.machine = new StateMachine<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.dispatch(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","/**\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 { Vector3, BufferGeometry, LineBasicMaterial, Line } from 'three';\nimport { Ray } from '@dimforge/rapier3d-compat';\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 rays: Map<string, Ray[]> = new Map();\n\tprivate debugLines: Map<string, any[]> = new Map(); // Store Line objects for debug visualization\n\n\tconstructor(world: any, scene: any) {\n\t\tthis.world = world;\n\t\tthis.scene = scene;\n\t}\n\n\t/**\n\t * Detect if entity is on the ground using raycasting\n\t */\n\t/**\n\t * Detect if entity is on the ground using raycasting (multi-sample: center + 4 corners)\n\t */\n\tprivate detectGround(entity: Platformer3DEntity): boolean {\n\t\tif (!this.world?.world || !entity.body) return false;\n\n\t\tconst translation = entity.body.translation();\n\t\tconst rayLength = entity.platformer.groundRayLength;\n\t\tconst radius = 0.4; // Sample radius (approx 80% of typical character collider radius)\n\n\t\t// Define ray offsets (center + 4 corners)\n\t\tconst offsets = [\n\t\t\t{ x: 0, z: 0 },\n\t\t\t{ x: radius, z: radius },\n\t\t\t{ x: -radius, z: radius },\n\t\t\t{ x: radius, z: -radius },\n\t\t\t{ x: -radius, z: -radius },\n\t\t];\n\n\t\t// Get or create rays for this entity\n\t\tlet entityRays = this.rays.get(entity.uuid);\n\t\tif (!entityRays) {\n\t\t\tentityRays = offsets.map(() => new Ray({ x: 0, y: 0, z: 0 }, { x: 0, y: -1, z: 0 }));\n\t\t\tthis.rays.set(entity.uuid, entityRays);\n\t\t}\n\n\t\tlet grounded = false;\n\t\t\n\t\t// Cast all rays\n\t\toffsets.forEach((offset, i) => {\n\t\t\tif (grounded) return; // Optimization: stop if already grounded (comment out for full debug viz)\n\n\t\t\tconst ray = entityRays![i];\n\t\t\tray.origin = { \n\t\t\t\tx: translation.x + offset.x, \n\t\t\t\ty: translation.y, \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\trayLength,\n\t\t\t\ttrue,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\t(collider: any) => {\n\t\t\t\t\tconst ref = collider._parent?.userData?.uuid;\n\t\t\t\t\tif (ref === entity.uuid) return false;\n\t\t\t\t\tgrounded = true;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t);\n\t\t});\n\n\t\t// Visualization logic omitted for brevity/performance (restore if needed)\n\t\tif (this.scene) {\n\t\t\tthis.updateDebugLines(entity, entityRays, grounded, rayLength);\n\t\t}\n\n\t\treturn grounded;\n\t}\n\n\tprivate updateDebugLines(entity: Platformer3DEntity, rays: Ray[], hasGround: boolean, length: number) {\n\t\tlet lines = this.debugLines.get(entity.uuid);\n\t\tif (!lines) {\n\t\t\tlines = rays.map(() => {\n\t\t\t\tconst geometry = new BufferGeometry().setFromPoints([new Vector3(), new Vector3()]);\n\t\t\t\tconst material = new LineBasicMaterial({ color: 0xff0000 });\n\t\t\t\tconst line = new Line(geometry, material);\n\t\t\t\tthis.scene.add(line);\n\t\t\t\treturn line;\n\t\t\t});\n\t\t\tthis.debugLines.set(entity.uuid, lines);\n\t\t}\n\n\t\trays.forEach((ray, i) => {\n\t\t\tconst line = lines![i];\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.geometry.setFromPoints([start, end]);\n\t\t\tline.material.color.setHex(hasGround ? 0x00ff00 : 0xff0000);\n\t\t});\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\t\t\n\t\t// DEBUG: Log jump attempt\n\t\tconsole.log('[JUMP DEBUG] Attempting jump:', {\n\t\t\tgrounded: state.grounded,\n\t\t\tjumpCount: state.jumpCount,\n\t\t\tmaxJumps: movement.maxJumps,\n\t\t\tisFirstJump,\n\t\t\tcanMultiJump,\n\t\t\t'--- Multi-jump conditions ---': '',\n\t\t\t'!grounded': !state.grounded,\n\t\t\thasJumpsRemaining,\n\t\t\tbuttonReleased,\n\t\t\tinMultiJumpWindow,\n\t\t\ttimeSinceJump: state.timeSinceJump.toFixed(3),\n\t\t\tmultiJumpWindowTime: movement.multiJumpWindowTime,\n\t\t});\n\t\t\n\t\tif (isFirstJump || canMultiJump) {\n\t\t\tconsole.log('[JUMP DEBUG] ✅ EXECUTING JUMP #' + (state.jumpCount + 1));\n\t\t\t\n\t\t\t// Consume buffered input\n\t\t\tstate.jumpBuffered = false;\n\t\t\t\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} else {\n\t\t\tconsole.log('[JUMP DEBUG] ❌ JUMP BLOCKED - conditions not met');\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 nearGround = this.detectGround(entity);\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 nearGround = this.detectGround(entity);\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 all platformer entities\n\t */\n\tupdate(delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst platformerEntity = entity as any;\n\n\t\t\t// Check if entity has platformer components\n\t\t\tif (!platformerEntity.platformer || !platformerEntity.$platformer || !platformerEntity.platformerState) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Update state first\n\t\t\tthis.updateState(platformerEntity, delta);\n\n\t\t\t// Apply movement\n\t\t\tthis.applyMovement(platformerEntity, delta);\n\n\t\t\t// Handle jumping\n\t\t\tthis.handleJump(platformerEntity, delta);\n\n\t\t\t// Apply gravity\n\t\t\tthis.applyGravity(platformerEntity, delta);\n\t\t}\n\t}\n\n\t/**\n\t * Cleanup\n\t */\n\tdestroy(): void {\n\t\tthis.rays.clear();\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 { 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}\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};\n\n/**\n * Adapter that wraps Platformer3DBehavior as a BehaviorSystem\n */\nclass Platformer3DBehaviorSystem implements BehaviorSystem {\n\tprivate movementBehavior: Platformer3DMovementBehavior;\n\n\tconstructor(private world: any, private scene: any) {\n\t\tthis.movementBehavior = new Platformer3DMovementBehavior(world, scene);\n\t}\n\n\tupdate(ecs: IWorld, delta: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\n\t\t// Initialize ECS components on entities with platformer behavior refs\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tconst gameEntity = entity as any;\n\n\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\n\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\tconst platformerRef = refs.find((r: any) =>\n\t\t\t\tr.descriptor.key === Symbol.for('zylem:behavior:platformer-3d')\n\t\t\t);\n\n\t\t\tif (!platformerRef || !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\t\t}\n\n\t\t// Delegate to the movement behavior\n\t\tthis.movementBehavior.update(delta);\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) => new Platformer3DBehaviorSystem(ctx.world, ctx.scene),\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","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 { 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\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\tprivate initialized = false;\n\n\tconstructor(private world: any) { }\n\n\tupdate(_ecs: IWorld, delta: number): void {\n\t\t// Register cooldowns from entities on first update\n\t\tif (!this.initialized && this.world?.collisionMap) {\n\t\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\t\tconst gameEntity = entity as any;\n\t\t\t\tif (typeof gameEntity.getBehaviorRefs !== 'function') continue;\n\n\t\t\t\tconst refs = gameEntity.getBehaviorRefs();\n\t\t\t\tconst cdRef = refs.find(\n\t\t\t\t\t(r: any) => r.descriptor.key === Symbol.for('zylem:behavior:cooldown'),\n\t\t\t\t);\n\t\t\t\tif (!cdRef) continue;\n\n\t\t\t\tconst options = cdRef.options as CooldownOptions;\n\t\t\t\tfor (const [name, config] of Object.entries(options.cooldowns)) {\n\t\t\t\t\tregisterCooldown(name, config.duration, config.immediate ?? true);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.initialized = true;\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\t// Also register cooldowns eagerly so the handle works before the system initializes\n\tconst options = ref.options;\n\tfor (const [name, config] of Object.entries(options.cooldowns)) {\n\t\tregisterCooldown(name, config.duration, config.immediate ?? true);\n\t}\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\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) => new CooldownSystem(ctx.world),\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';\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 // Compute collision normal from boundary hits\n let normalX = 0;\n let normalY = 0;\n if (hits.left) normalX = 1;\n if (hits.right) normalX = -1;\n if (hits.bottom) normalY = 1;\n if (hits.top) normalY = -1;\n\n // Apply ricochet (also emits to listeners)\n return this.ricochet.applyRicochet({\n entity: this.entity,\n contact: { normal: { x: normalX, y: normalY } },\n });\n }\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';\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\tstore.velocity.x += vx;\n\t\tstore.velocity.y += vy;\n\t\tstore.velocity.z += vz;\n\t\tstore.dirty.velocity = true;\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\tstore.velocity.x += vx;\n\t\tstore.velocity.y += vy;\n\t\tstore.velocity.z += vz;\n\t\tstore.dirty.velocity = true;\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 { 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 new ZylemCooldownIcon(options as ZylemCooldownIconOptions);\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 { debugState, setDebugTool, setPaused, type DebugTools } from '../lib/debug/debug-state';\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\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\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!.appendChild(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 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 game.options.push({ container: this.container });\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 /**\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 if (this._game) {\n this._game.dispose();\n this._game = null;\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","destroy","proxy","position","Vector3","Quaternion","rotation","Vector3","ActiveCollisionTypes","ColliderDesc","RigidBodyDesc","RigidBodyType","Vector3","Vector3","ShaderMaterial","Mesh","Color","Vector2","Vector3","RepeatWrapping","ShaderMaterial","repeat","fragment","BufferGeometry","Mesh","Color","ActiveCollisionTypes","ColliderDesc","MeshStandardMaterial","Group","Vector3","colliderDesc","Scene","Color","Vector3","ShaderMaterial","Mesh","Texture","MeshBasicNodeMaterial","state","position","Vector3","Quaternion","scale","rotation","Color","Vector3","Color","Vector3","proxy","subscribe","BoxGeometry","Color","Group","Mesh","Vector3","BufferGeometry","LineBasicMaterial","LineSegments","Vector2","hoveredUuid","subscribe","Vector3","t","Vector3","state","PerspectiveCamera","Vector3","Object3D","position","Vector2","Vector2","Vector3","Color","Vector3","subscribe","nanoid","state","Vector2","Vector3","position","proxy","Vector3","proxy","initialDefaults","state","state","document","time","subscribe","state","position","rotation","scale","getGameDefaultConfig","proxy","stageState","Color","Group","Vector2","MeshStandardMaterial","MeshBasicMaterial","MeshPhongMaterial","x","y","z","toDeg","Vector2","Group","Color","ColliderDesc","Euler","Group","Quaternion","Vector3","TextureLoader","SpriteMaterial","ThreeSprite","Vector3","ColliderDesc","TextureLoader","SpriteMaterial","ThreeSprite","Group","Quaternion","Euler","stageState","Euler","Quaternion","Vector2","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","StateMachine","t","ScreenWrapState","ScreenWrapEvent","position","defaultOptions","StateMachine","t","WorldBoundary2DState","WorldBoundary2DEvent","position","moveX","moveY","defaultOptions","moveX","moveY","StateMachine","t","Ricochet2DState","Ricochet2DEvent","scale","defaultOptions","StateMachine","t","Platformer3DState","Platformer3DEvent","state","Vector3","BufferGeometry","LineBasicMaterial","Ray","state","moveX","moveZ","defaultOptions","Platformer3DBehavior","proxy","Group","ThreeSprite","SpriteMaterial","CanvasTexture","LinearFilter","Vector2","Color","ClampToEdgeWrapping","Group","CanvasTexture","LinearFilter","ClampToEdgeWrapping","SpriteMaterial","ThreeSprite","Color","Vector2","THREE","RAPIER","fragment","fragment","fragment"]}