@zylem/game-lib 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/stage.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/stage/zylem-stage.ts","../src/lib/collision/world.ts","../src/lib/game/game-state.ts","../src/lib/entities/actor.ts","../src/lib/entities/entity.ts","../src/lib/systems/transformable.system.ts","../src/lib/core/flags.ts","../src/lib/core/base-node.ts","../src/lib/core/entity-asset-loader.ts","../src/lib/entities/delegates/animation.ts","../src/lib/graphics/shaders/fragment/standard.glsl","../src/lib/collision/collision-delegate.ts","../src/lib/graphics/zylem-scene.ts","../src/lib/debug/debug-state.ts","../src/lib/stage/stage-state.ts","../src/lib/core/utility/vector.ts","../src/lib/core/lifecycle-base.ts","../src/lib/camera/perspective.ts","../src/lib/camera/camera.ts","../src/lib/camera/zylem-camera.ts","../src/lib/camera/third-person.ts","../src/lib/camera/fixed-2d.ts","../src/lib/graphics/render-pass.ts","../src/lib/graphics/shaders/vertex/standard.glsl","../src/lib/stage/stage-debug-delegate.ts","../src/lib/stage/debug-entity-cursor.ts","../src/lib/stage/stage-default.ts","../src/lib/stage/stage.ts","../src/lib/stage/entity-spawner.ts"],"sourcesContent":["import { addComponent, 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 } from './stage-state';\n\nimport { GameEntityInterface } from '../types/entity-types';\nimport { ZylemBlueColor } from '../core/utility/vector';\nimport { debugState } from '../debug/debug-state';\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 { Perspectives } from '../camera/perspective';\nimport { CameraWrapper } from '../camera/camera';\nimport { StageDebugDelegate } from './stage-debug-delegate';\nimport { StageCameraDebugDelegate } from './stage-camera-debug-delegate';\nimport { GameEntity } from '../entities/entity';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { LoadingEvent } from '../core/interfaces';\nexport type { LoadingEvent };\n\nexport interface ZylemStageConfig {\n\tinputs: Record<string, string[]>;\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | 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 = {\n\t\tbackgroundColor: ZylemBlueColor,\n\t\tbackgroundImage: null,\n\t\tinputs: {\n\t\t\tp1: ['gamepad-1', 'keyboard'],\n\t\t\tp2: ['gamepad-2', 'keyboard'],\n\t\t},\n\t\tgravity: new Vector3(0, 0, 0),\n\t\tvariables: {},\n\t\tentities: [],\n\t};\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\tprivate loadingHandlers: Array<(event: LoadingEvent) => void> = [];\n\n\n\tecs = createECS();\n\ttestSystem: any = null;\n\ttransformSystem: any = null;\n\tdebugDelegate: StageDebugDelegate | null = null;\n\tcameraDebugDelegate: StageCameraDebugDelegate | null = null;\n\n\tuuid: string;\n\twrapperRef: Stage | null = null;\n\tcamera?: CameraWrapper;\n\tcameraRef?: ZylemCamera | null = null;\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// Parse the options array to extract different types of items\n\t\tconst { config, entities, asyncEntities, camera } = this.parseOptions(options);\n\t\tthis.camera = camera;\n\t\tthis.children = entities;\n\t\tthis.pendingEntities = asyncEntities;\n\t\tthis.saveState({ ...this.state, ...config, entities: [] });\n\n\t\tthis.gravity = config.gravity ?? new Vector3(0, 0, 0);\n\n\t}\n\n\tprivate parseOptions(options: StageOptions): {\n\t\tconfig: Partial<ZylemStageConfig>;\n\t\tentities: BaseNode[];\n\t\tasyncEntities: StageEntityInput[];\n\t\tcamera?: CameraWrapper;\n\t} {\n\t\tlet config: Partial<ZylemStageConfig> = {};\n\t\tconst entities: BaseNode[] = [];\n\t\tconst asyncEntities: StageEntityInput[] = [];\n\t\tlet camera: CameraWrapper | undefined;\n\t\tfor (const item of options) {\n\t\t\tif (this.isCameraWrapper(item)) {\n\t\t\t\tcamera = item;\n\t\t\t} else if (this.isBaseNode(item)) {\n\t\t\t\tentities.push(item);\n\t\t\t} else if (this.isEntityInput(item)) {\n\t\t\t\tasyncEntities.push(item as StageEntityInput);\n\t\t\t} else if (this.isZylemStageConfig(item)) {\n\t\t\t\tconfig = { ...config, ...item };\n\t\t\t}\n\t\t}\n\n\t\treturn { config, entities, asyncEntities, camera };\n\t}\n\n\tprivate isZylemStageConfig(item: any): item is ZylemStageConfig {\n\t\treturn item && typeof item === 'object' && !(item instanceof BaseNode) && !(item instanceof CameraWrapper);\n\t}\n\n\tprivate isBaseNode(item: any): item is BaseNode {\n\t\treturn item && typeof item === 'object' && typeof item.create === 'function';\n\t}\n\n\tprivate isCameraWrapper(item: any): item is CameraWrapper {\n\t\treturn item && typeof item === 'object' && item.constructor.name === 'CameraWrapper';\n\t}\n\n\tprivate isEntityInput(item: any): item is StageEntityInput {\n\t\tif (!item) return false;\n\t\tif (this.isBaseNode(item)) return true;\n\t\tif (typeof item === 'function') return true;\n\t\tif (typeof item === 'object' && typeof (item as any).then === 'function') return true;\n\t\treturn false;\n\t}\n\n\tprivate isThenable(value: any): value is Promise<any> {\n\t\treturn !!value && typeof (value as any).then === 'function';\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 * @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\tconst zylemCamera = camera || (this.camera ? this.camera.cameraRef : this.createDefaultCamera());\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\n\t\tthis.emitLoading({ type: 'start', message: 'Loading stage...', progress: 0 });\n\n\t\tconst total = this.children.length + this.pendingEntities.length + this.pendingPromises.length;\n\t\tlet current = 0;\n\n\t\tfor (let child of this.children) {\n\t\t\tthis.spawnEntity(child);\n\t\t\tcurrent++;\n\t\t\tthis.emitLoading({\n\t\t\t\ttype: 'progress',\n\t\t\t\tmessage: `Loaded entity ${child.name || 'unknown'}`,\n\t\t\t\tprogress: current / total,\n\t\t\t\tcurrent,\n\t\t\t\ttotal\n\t\t\t});\n\t\t}\n\t\tif (this.pendingEntities.length) {\n\t\t\tthis.enqueue(...this.pendingEntities);\n\t\t\t// enqueue handles spawning, but we might want to track progress here if we could\n\t\t\t// For now, let's just assume they are processed\n\t\t\tcurrent += this.pendingEntities.length;\n\t\t\tthis.pendingEntities = [];\n\t\t}\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\t// Note: this progress update might happen after 'complete' if we don't await, \n\t\t\t\t\t// but load is async so we should probably await if we want accurate progress?\n\t\t\t\t\t// The original code didn't await.\n\t\t\t\t}).catch((e) => console.error('Failed to resolve pending stage entity', e));\n\t\t\t}\n\t\t\t// We are not awaiting promises here in original code, so we can't accurately track their completion for \"progress\" \n\t\t\t// in a linear synchronous way. \n\t\t\t// For now, let's just increment current count as if they are \"scheduled\"\n\t\t\tcurrent += this.pendingPromises.length;\n\t\t\tthis.pendingPromises = [];\n\t\t}\n\t\tthis.transformSystem = createTransformSystem(this as unknown as StageSystem);\n\t\tthis.isLoaded = true;\n\t\tthis.emitLoading({ type: 'complete', message: 'Stage loaded', progress: 1 });\n\t}\n\n\tprivate createDefaultCamera(): 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\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\tif (debugState.enabled) {\n\t\t\tthis.debugDelegate = new StageDebugDelegate(this);\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(this.ecs);\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}\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\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\t\tthis.debugDelegate?.dispose();\n\t\tthis.cameraRef?.setDebugDelegate(null);\n\t\tthis.cameraDebugDelegate = null;\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// 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\t\t// @ts-ignore\n\t\tif (child.behaviors) {\n\t\t\t// @ts-ignore\n\t\t\tfor (let behavior of child.behaviors) {\n\t\t\t\taddComponent(this.ecs, behavior.component, entity.eid);\n\t\t\t\tconst keys = Object.keys(behavior.values);\n\t\t\t\tfor (const key of keys) {\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tbehavior.component[key][entity.eid] = behavior.values[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\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}\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\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\tprivate emitLoading(event: LoadingEvent) {\n\t\tthis.loadingHandlers.forEach((h) => h(event));\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.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 (this.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 (this.isBaseNode(result)) {\n\t\t\t\t\t\tthis.handleEntityImmediatelyOrQueue(result);\n\t\t\t\t\t} else if (this.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 (this.isThenable(item)) {\n\t\t\t\tthis.handlePromiseWithSpawnOnResolve(item as Promise<any>);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { Vector3 } from 'three';\nimport RAPIER, { World } from '@dimforge/rapier3d-compat';\n\nimport { Entity } from '../interfaces/entity';\nimport { state } from '../game/game-state';\nimport { UpdateContext } from '../core/base-node-life-cycle';\nimport { ZylemActor } from '../entities/actor';\nimport { isCollisionHandlerDelegate } from './collision-delegate';\nimport { GameEntity } from '../entities/entity';\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\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\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 { proxy, subscribe } from 'valtio/vanilla';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\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 * Set a global value by path.\n * @example setGlobal('score', 100)\n * @example setGlobal('player.health', 50)\n */\nexport function setGlobal(path: string, value: unknown): void {\n\tsetByPath(state.globals, path, value);\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.\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\treturn 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}\n\n/**\n * Subscribe to changes on multiple global paths.\n * Callback fires when any of the paths change, receiving all current values.\n * Returns an unsubscribe function.\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\treturn 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}\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\nexport { state };","import { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BufferGeometry, Object3D, SkinnedMesh, 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';\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\tposition: { x: 0, y: 0, z: 0 },\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: 'standard',\n\t},\n\tanimations: [],\n\tmodels: []\n};\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate height: number = 1;\n\tprivate objectModel: Group | null = null;\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t}\n\n\tcreateColliderFromObjectModel(objectModel: Group | null): ColliderDesc {\n\t\tif (!objectModel) return ColliderDesc.capsule(1, 1);\n\n\t\tconst skinnedMesh = objectModel.children.find(child => child instanceof SkinnedMesh) as SkinnedMesh;\n\t\tconst geometry = skinnedMesh.geometry as BufferGeometry;\n\n\t\tif (geometry) {\n\t\t\tgeometry.computeBoundingBox();\n\t\t\tif (geometry.boundingBox) {\n\t\t\t\tconst maxY = geometry.boundingBox.max.y;\n\t\t\t\tconst minY = geometry.boundingBox.min.y;\n\t\t\t\tthis.height = maxY - minY;\n\t\t\t}\n\t\t}\n\t\tthis.height = 1;\n\t\tlet colliderDesc = ColliderDesc.capsule(this.height / 2, 1);\n\t\tcolliderDesc.setSensor(false);\n\t\tcolliderDesc.setTranslation(0, this.height + 0.5, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\n\t\treturn colliderDesc;\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tlet colliderDesc = this.createColliderFromObjectModel(this.objectModel);\n\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\nconst 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\tthis.lifeCycleDelegate = {\n\t\t\tupdate: [this.actorUpdate.bind(this) as UpdateFunction<ZylemActorOptions>],\n\t\t};\n\t\tthis.controlledRotation = true;\n\t}\n\n\tasync load(): Promise<void> {\n\t\tthis._modelFileNames = this.options.models || [];\n\t\tawait this.loadModels();\n\t\tif (this._object) {\n\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\tawait this._animationDelegate.loadAnimations(this.options.animations || []);\n\t\t}\n\t}\n\n\tasync data(): Promise<any> {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t};\n\t}\n\n\tasync actorUpdate(params: UpdateContext<ZylemActorOptions>): Promise<void> {\n\t\tthis._animationDelegate?.update(params.delta);\n\t}\n\n\tprivate async loadModels(): Promise<void> {\n\t\tif (this._modelFileNames.length === 0) return;\n\t\tconst promises = this._modelFileNames.map(file => this._assetLoader.loadFile(file));\n\t\tconst results = await Promise.all(promises);\n\t\tif (results[0]?.object) {\n\t\t\tthis._object = results[0].object;\n\t\t}\n\t\tif (this._object) {\n\t\t\tthis.group = new Group();\n\t\t\tthis.group.attach(this._object);\n\t\t\tthis.group.scale.set(\n\t\t\t\tthis.options.scale?.x || 1,\n\t\t\t\tthis.options.scale?.y || 1,\n\t\t\t\tthis.options.scale?.z || 1\n\t\t\t);\n\t\t}\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\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 async function actor(...args: Array<ActorOptions>): Promise<ZylemActor> {\n\treturn await 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 { Mesh, Material, ShaderMaterial, Group, Color } from \"three\";\nimport { Collider, ColliderDesc, RigidBody, RigidBodyDesc } 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\";\nimport { BaseNode } from \"../core/base-node\";\nimport { DestroyContext, SetupContext, UpdateContext, LoadedContext, CleanupContext } from \"../core/base-node-life-cycle\";\nimport type { EntityMeshBuilder, EntityCollisionBuilder } from \"./builder\";\nimport { Behavior } from \"../actions/behaviors/behavior\";\n\nexport interface LifeCycleDelegate<U> {\n\tsetup?: ((params: SetupContext<U>) => void)[];\n\tupdate?: ((params: UpdateContext<U>) => void)[];\n\tdestroy?: ((params: DestroyContext<U>) => void)[];\n}\n\nexport interface CollisionContext<T, O extends GameEntityOptions, TGlobals extends Record<string, unknown> = any> {\n\tentity: T;\n\tother: GameEntity<O>;\n\tglobals: TGlobals;\n}\n\nexport type BehaviorContext<T, O extends GameEntityOptions> =\n\tSetupContext<T, O> |\n\tUpdateContext<T, O> |\n\tCollisionContext<T, O> |\n\tDestroyContext<T, O>;\n\nexport type BehaviorCallback<T, O extends GameEntityOptions> = (params: BehaviorContext<T, O>) => void;\n\nexport interface CollisionDelegate<T, O extends GameEntityOptions> {\n\tcollision?: ((params: CollisionContext<T, O>) => 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 type BehaviorCallbackType = 'setup' | 'update' | 'destroy' | 'collision';\n\nexport class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implements\n\tGameEntityLifeCycle,\n\tEntityDebugInfo {\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\tpublic debugInfo: Record<string, any> = {};\n\tpublic debugMaterial: ShaderMaterial | undefined;\n\n\tpublic lifeCycleDelegate: LifeCycleDelegate<O> = {\n\t\tsetup: [],\n\t\tupdate: [],\n\t\tdestroy: [],\n\t};\n\tpublic collisionDelegate: CollisionDelegate<this, O> = {\n\t\tcollision: [],\n\t};\n\tpublic collisionType?: string;\n\n\tpublic behaviorCallbackMap: Record<BehaviorCallbackType, BehaviorCallback<this, O>[]> = {\n\t\tsetup: [],\n\t\tupdate: [],\n\t\tdestroy: [],\n\t\tcollision: [],\n\t};\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tpublic create(): this {\n\t\tconst { position: setupPosition } = this.options;\n\t\tconst { x, y, z } = setupPosition || { x: 0, y: 0, z: 0 };\n\t\tthis.behaviors = [\n\t\t\t{ component: position, values: { x, y, z } },\n\t\t\t{ component: scale, values: { x: 0, y: 0, z: 0 } },\n\t\t\t{ component: rotation, values: { x: 0, y: 0, z: 0, w: 0 } },\n\t\t];\n\t\tthis.name = this.options.name || '';\n\t\treturn this;\n\t}\n\n\tpublic onSetup(...callbacks: ((params: SetupContext<this>) => void)[]): this {\n\t\tconst combineCallbacks = [...(this.lifeCycleDelegate.setup ?? []), ...callbacks];\n\t\tthis.lifeCycleDelegate = {\n\t\t\t...this.lifeCycleDelegate,\n\t\t\tsetup: combineCallbacks as unknown as ((params: SetupContext<O>) => void)[]\n\t\t};\n\t\treturn this;\n\t}\n\n\tpublic onUpdate(...callbacks: ((params: UpdateContext<this>) => void)[]): this {\n\t\tconst combineCallbacks = [...(this.lifeCycleDelegate.update ?? []), ...callbacks];\n\t\tthis.lifeCycleDelegate = {\n\t\t\t...this.lifeCycleDelegate,\n\t\t\tupdate: combineCallbacks as unknown as ((params: UpdateContext<O>) => void)[]\n\t\t};\n\t\treturn this;\n\t}\n\n\tpublic onDestroy(...callbacks: ((params: DestroyContext<this>) => void)[]): this {\n\t\tthis.lifeCycleDelegate = {\n\t\t\t...this.lifeCycleDelegate,\n\t\t\tdestroy: callbacks.length > 0 ? callbacks as unknown as ((params: DestroyContext<O>) => void)[] : undefined\n\t\t};\n\t\treturn this;\n\t}\n\n\tpublic onCollision(...callbacks: ((params: CollisionContext<this, O>) => void)[]): this {\n\t\tthis.collisionDelegate = {\n\t\t\tcollision: callbacks.length > 0 ? callbacks : undefined\n\t\t};\n\t\treturn this;\n\t}\n\n\tpublic _setup(params: SetupContext<this>): void {\n\t\tthis.behaviorCallbackMap.setup.forEach(callback => {\n\t\t\tcallback({ ...params, me: this });\n\t\t});\n\t\tif (this.lifeCycleDelegate.setup?.length) {\n\t\t\tconst callbacks = this.lifeCycleDelegate.setup;\n\t\t\tcallbacks.forEach(callback => {\n\t\t\t\tcallback({ ...params, me: this as unknown as O });\n\t\t\t});\n\t\t}\n\t}\n\n\tprotected async _loaded(_params: LoadedContext<this>): Promise<void> { }\n\n\tpublic _update(params: UpdateContext<this>): void {\n\t\tthis.updateMaterials(params);\n\t\tif (this.lifeCycleDelegate.update?.length) {\n\t\t\tconst callbacks = this.lifeCycleDelegate.update;\n\t\t\tcallbacks.forEach(callback => {\n\t\t\t\tcallback({ ...params, me: this as unknown as O });\n\t\t\t});\n\t\t}\n\t\tthis.behaviorCallbackMap.update.forEach(callback => {\n\t\t\tcallback({ ...params, me: this });\n\t\t});\n\t}\n\n\tpublic _destroy(params: DestroyContext<this>): void {\n\t\tif (this.lifeCycleDelegate.destroy?.length) {\n\t\t\tconst callbacks = this.lifeCycleDelegate.destroy;\n\t\t\tcallbacks.forEach(callback => {\n\t\t\t\tcallback({ ...params, me: this as unknown as O });\n\t\t\t});\n\t\t}\n\t\tthis.behaviorCallbackMap.destroy.forEach(callback => {\n\t\t\tcallback({ ...params, me: this });\n\t\t});\n\t}\n\n\tprotected async _cleanup(_params: CleanupContext<this>): Promise<void> { }\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\tthis.behaviorCallbackMap.collision.forEach(callback => {\n\t\t\tcallback({ entity: this, other, globals });\n\t\t});\n\t}\n\n\tpublic addBehavior(\n\t\tbehaviorCallback: ({ type: BehaviorCallbackType, handler: any })\n\t): this {\n\t\tconst handler = behaviorCallback.handler as unknown as BehaviorCallback<this, O>;\n\t\tif (handler) {\n\t\t\tthis.behaviorCallbackMap[behaviorCallback.type].push(handler);\n\t\t}\n\t\treturn this;\n\t}\n\n\tpublic addBehaviors(\n\t\tbehaviorCallbacks: ({ type: BehaviorCallbackType, handler: any })[]\n\t): this {\n\t\tbehaviorCallbacks.forEach(callback => {\n\t\t\tconst handler = callback.handler as unknown as BehaviorCallback<this, O>;\n\t\t\tif (handler) {\n\t\t\t\tthis.behaviorCallbackMap[callback.type].push(handler);\n\t\t\t}\n\t\t});\n\t\treturn this;\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 && (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","import {\n\tdefineSystem,\n\tdefineQuery,\n\tdefineComponent,\n\tTypes,\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\nexport default function createTransformSystem(stage: StageSystem) {\n\tconst transformQuery = defineQuery([position, rotation]);\n\tconst stageEntities = stage._childrenMap;\n\treturn defineSystem((world) => {\n\t\tconst entities = transformQuery(world);\n\t\tif (stageEntities === undefined) {\n\t\t\treturn world;\n\t\t};\n\t\tfor (const [key, value] of stageEntities) {\n\t\t\tconst id = entities[key];\n\t\t\tconst stageEntity = value;\n\t\t\tif (stageEntity === undefined || !stageEntity?.body || stageEntity.markedForRemoval) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst { x, y, z } = stageEntity.body.translation();\n\t\t\tposition.x[id] = x;\n\t\t\tposition.y[id] = y;\n\t\t\tposition.z[id] = z;\n\t\t\tif (stageEntity.group) {\n\t\t\t\tstageEntity.group.position.set(position.x[id], position.y[id], position.z[id]);\n\t\t\t} else if (stageEntity.mesh) {\n\t\t\t\tstageEntity.mesh.position.set(position.x[id], position.y[id], position.z[id]);\n\t\t\t}\n\t\t\tif (stageEntity.controlledRotation) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst { x: rx, y: ry, z: rz, w: rw } = stageEntity.body.rotation();\n\t\t\trotation.x[id] = rx;\n\t\t\trotation.y[id] = ry;\n\t\t\trotation.z[id] = rz;\n\t\t\trotation.w[id] = rw;\n\t\t\tconst newRotation = new Quaternion(\n\t\t\t\trotation.x[id],\n\t\t\t\trotation.y[id],\n\t\t\t\trotation.z[id],\n\t\t\t\trotation.w[id]\n\t\t\t);\n\t\t\tif (stageEntity.group) {\n\t\t\t\tstageEntity.group.setRotationFromQuaternion(newRotation);\n\t\t\t} else if (stageEntity.mesh) {\n\t\t\t\tstageEntity.mesh.setRotationFromQuaternion(newRotation);\n\t\t\t}\n\t\t}\n\n\t\treturn world;\n\t});\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\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\tsetup: SetupFunction<this> = () => { };\n\tloaded: LoadedFunction<this> = () => { };\n\tupdate: UpdateFunction<this> = () => { };\n\tdestroy: DestroyFunction<this> = () => { };\n\tcleanup: CleanupFunction<this> = () => { };\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\tpublic setParent(parent: NodeInterface | null): void {\n\t\tthis.parent = parent;\n\t}\n\n\tpublic getParent(): NodeInterface | null {\n\t\treturn this.parent;\n\t}\n\n\tpublic add(baseNode: NodeInterface): void {\n\t\tthis.children.push(baseNode);\n\t\tbaseNode.setParent(this);\n\t}\n\n\tpublic remove(baseNode: NodeInterface): void {\n\t\tconst index = this.children.indexOf(baseNode);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tbaseNode.setParent(null);\n\t\t}\n\t}\n\n\tpublic getChildren(): NodeInterface[] {\n\t\treturn this.children;\n\t}\n\n\tpublic isComposite(): boolean {\n\t\treturn this.children.length > 0;\n\t}\n\n\tpublic 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\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\tif (this.setup) {\n\t\t\tthis.setup(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\tif (this.update) {\n\t\t\tthis.update(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\tthis.children.forEach(child => child.nodeDestroy(params));\n\t\tif (this.destroy) {\n\t\t\tthis.destroy(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\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 { AnimationClip, Object3D } from 'three';\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js';\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\n\nenum FileExtensionTypes {\n\tFBX = 'fbx',\n\tGLTF = 'gltf'\n}\n\nexport interface AssetLoaderResult {\n\tobject?: Object3D;\n\tanimation?: AnimationClip;\n\tgltf?: GLTF;\n}\n\nexport interface IAssetLoader {\n\tload(file: string): Promise<AssetLoaderResult>;\n\tisSupported(file: string): boolean;\n}\n\nclass FBXAssetLoader implements IAssetLoader {\n\tprivate loader: FBXLoader = new FBXLoader();\n\n\tisSupported(file: string): boolean {\n\t\treturn file.toLowerCase().endsWith(FileExtensionTypes.FBX);\n\t}\n\n\tasync load(file: string): Promise<AssetLoaderResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\tfile,\n\t\t\t\t(object: Object3D) => {\n\t\t\t\t\tconst animation = object.animations[0];\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimation\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\treject\n\t\t\t);\n\t\t});\n\t}\n}\n\nclass GLTFAssetLoader implements IAssetLoader {\n\tprivate loader: GLTFLoader = new GLTFLoader();\n\n\tisSupported(file: string): boolean {\n\t\treturn file.toLowerCase().endsWith(FileExtensionTypes.GLTF);\n\t}\n\n\tasync load(file: string): Promise<AssetLoaderResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\tfile,\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\tgltf\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\treject\n\t\t\t);\n\t\t});\n\t}\n}\n\nexport class EntityAssetLoader {\n\tprivate loaders: IAssetLoader[] = [\n\t\tnew FBXAssetLoader(),\n\t\tnew GLTFAssetLoader()\n\t];\n\n\tasync loadFile(file: string): Promise<AssetLoaderResult> {\n\t\tconst loader = this.loaders.find(l => l.isSupported(file));\n\n\t\tif (!loader) {\n\t\t\tthrow new Error(`Unsupported file type: ${file}`);\n\t\t}\n\n\t\treturn loader.load(file);\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\tget currentAnimationKey() { return this._currentKey; }\n\tget animations() { return this._animations; }\n}\n","export default \"uniform sampler2D tDiffuse;\\nvarying vec2 vUv;\\n\\nvoid main() {\\n\\tvec4 texel = texture2D( tDiffuse, vUv );\\n\\n\\tgl_FragColor = texel;\\n}\"","\nexport function isCollisionHandlerDelegate(obj: any): obj is CollisionHandlerDelegate {\n\treturn typeof obj?.handlePostCollision === \"function\" && typeof obj?.handleIntersectionEvent === \"function\";\n}\n\nexport interface CollisionHandlerDelegate {\n\thandlePostCollision(params: any): boolean;\n\thandleIntersectionEvent(params: any): void;\n}\n\nclass CollisionHandler {\n\tentityReference: CollisionHandlerDelegate;\n\n\tconstructor(entity: CollisionHandlerDelegate) {\n\t\tthis.entityReference = entity;\n\t}\n\n\thandlePostCollision(params: any): boolean {\n\t\treturn this.entityReference.handlePostCollision(params);\n\t}\n\n\thandleIntersectionEvent(params: any) {\n\t\tthis.entityReference.handleIntersectionEvent(params);\n\t}\n}\n","import {\n\tScene,\n\tColor,\n\tAmbientLight,\n\tDirectionalLight,\n\tObject3D,\n\tVector3,\n\tTextureLoader,\n\tGridHelper\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';\n\ninterface SceneState {\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | 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\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\tif (state.backgroundImage) {\n\t\t\tconst loader = new TextureLoader();\n\t\t\tconst texture = loader.load(state.backgroundImage);\n\t\t\tscene.background = texture;\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\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.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\tscene.add(camera.cameraRig);\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 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}","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 { Color, Vector3 } from 'three';\nimport { proxy, subscribe } from 'valtio/vanilla';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { StageStateInterface } from '../types/stage-types';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\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 { 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');\nconst ZylemBlue = '#0333EC';\nconst ZylemBlueTransparent = '#0333ECA0';\nconst ZylemGoldText = '#DAA420';\n\ntype SizeVector = Vect3 | null;\n\nconst Vec0 = new Vector3(0, 0, 0);\nconst Vec1 = new Vector3(1, 1, 1);","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","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 { 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 camera(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 { Vector2, Camera, PerspectiveCamera, Vector3, Object3D, OrthographicCamera, WebGLRenderer, Scene } from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\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';\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 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\nexport class ZylemCamera {\n\tcameraRig: Object3D;\n\tcamera: Camera;\n\tscreenResolution: Vector2;\n\trenderer: WebGLRenderer;\n\tcomposer: EffectComposer;\n\t_perspective: PerspectiveType;\n\torbitControls: OrbitControls | null = null;\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\tdebugDelegate: CameraDebugDelegate | null = null;\n\tprivate debugUnsubscribe: (() => void) | null = null;\n\tprivate debugStateSnapshot: CameraDebugState = { enabled: false, selected: [] };\n\tprivate orbitTarget: Object3D | null = null;\n\tprivate orbitTargetWorldPos: Vector3 = new Vector3();\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\n\t\tthis.cameraRig = new Object3D();\n\t\tthis.cameraRig.position.set(0, 3, 10);\n\t\tthis.cameraRig.add(this.camera);\n\t\tthis.camera.lookAt(new Vector3(0, 2, 0));\n\n\t\t// Initialize perspective controller\n\t\tthis.initializePerspectiveController();\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 orbit controls\n\t\tif (this.orbitControls === null) {\n\t\t\tthis.orbitControls = new OrbitControls(this.camera, this.renderer.domElement);\n\t\t\tthis.orbitControls.enableDamping = true;\n\t\t\tthis.orbitControls.dampingFactor = 0.05;\n\t\t\tthis.orbitControls.screenSpacePanning = false;\n\t\t\tthis.orbitControls.minDistance = 1;\n\t\t\tthis.orbitControls.maxDistance = 500;\n\t\t\tthis.orbitControls.maxPolarAngle = Math.PI / 2;\n\t\t}\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// 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\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\n\t\t// Delegate to perspective controller\n\t\tif (this.perspectiveController) {\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 * 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.disableOrbitControls();\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.detachDebugDelegate();\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\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 * 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\tthis.cameraRig.position.set(position.x, position.y, position.z);\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\tthis.cameraRig.rotateX(pitch);\n\t\tthis.cameraRig.rotateY(yaw);\n\t\tthis.cameraRig.rotateZ(roll);\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\tprivate applyDebugState(state: CameraDebugState) {\n\t\tthis.debugStateSnapshot = {\n\t\t\tenabled: state.enabled,\n\t\t\tselected: [...state.selected],\n\t\t};\n\t\tif (state.enabled) {\n\t\t\tthis.enableOrbitControls();\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t} else {\n\t\t\tthis.orbitTarget = null;\n\t\t\tthis.disableOrbitControls();\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.renderer.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}\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\tif (!this.debugDelegate || selected.length === 0) {\n\t\t\tthis.orbitTarget = null;\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}","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 fragmentShader from './shaders/fragment/standard.glsl';\nimport vertexShader from './shaders/vertex/standard.glsl';\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: vertexShader,\n\t\t\tfragmentShader: fragmentShader\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","export default \"varying vec2 vUv;\\n\\nvoid main() {\\n\\tvUv = uv;\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\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\tif (this.stage.scene) {\n\t\t\tthis.debugLines = new LineSegments(\n\t\t\t\tnew BufferGeometry(),\n\t\t\t\tnew LineBasicMaterial({ vertexColors: true })\n\t\t\t);\n\t\t\tthis.stage.scene.scene.add(this.debugLines);\n\t\t\tthis.debugLines.visible = true;\n\n\t\t\tthis.debugCursor = new DebugEntityCursor(this.stage.scene.scene);\n\t\t}\n\t\tthis.attachDomListeners();\n\t}\n\n\tupdate(): void {\n\t\tif (!debugState.enabled) return;\n\t\tif (!this.stage.scene || !this.stage.world || !this.stage.cameraRef) return;\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.debugCursor?.dispose();\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}\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 {\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 { 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';\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\n\t// TODO: these shouldn't be here maybe more like nextFrame(stageInstance, () => {})\n\tupdate: UpdateFunction<ZylemStage> = () => { };\n\tsetup: SetupFunction<ZylemStage> = () => { };\n\tdestroy: DestroyFunction<ZylemStage> = () => { };\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\tthis.wrappedStage = new ZylemStage(this.options as StageOptions);\n\t\tthis.wrappedStage.wrapperRef = this;\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\t}\n\n\tasync addEntities(entities: BaseNode[]) {\n\t\tthis.options.push(...(entities as unknown as StageOptionItem[]));\n\t\t// TODO: this check is unnecessary\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\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\tonUpdate(...callbacks: UpdateFunction<ZylemStage>[]) {\n\t\t// TODO: this check is unnecessary\n\t\tif (!this.wrappedStage) { return; }\n\t\tthis.wrappedStage!.update = (params) => {\n\t\t\tconst extended = { ...params, stage: this } as any;\n\t\t\tcallbacks.forEach((cb) => cb(extended));\n\t\t};\n\t}\n\n\tonSetup(callback: SetupFunction<ZylemStage>) {\n\t\tthis.wrappedStage!.setup = callback;\n\t}\n\n\tonDestroy(callback: DestroyFunction<ZylemStage>) {\n\t\tthis.wrappedStage!.destroy = callback;\n\t}\n\n\tonLoading(callback: (event: LoadingEvent) => void) {\n\t\tif (!this.wrappedStage) { return () => { }; }\n\t\treturn this.wrappedStage.onLoading(callback);\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 { 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}"],"mappings":"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","names":["Color","Vector3","Vector2","Group","Group","Color","Vector3","proxy","state","Color","position","Vector3","Color","Vector3","proxy","subscribe","proxy","Color","Vector3","Color","Vector3","Vector3","nanoid","Vector2","Vector3","Vector3","Object3D","WebGLRenderer","Vector3","standard_default","standard_default","Vector3","WebGLRenderer","Object3D","state","position","BufferGeometry","LineBasicMaterial","LineSegments","Vector2","Color","Group","Mesh","Vector3","Vector2","LineSegments","BufferGeometry","LineBasicMaterial","hoveredUuid","Vector3","nanoid","state","Color","Vector2","proxy","Vector3","Vector3","proxy","Quaternion","Vector2"]}
1
+ {"version":3,"sources":["../src/lib/stage/zylem-stage.ts","../src/lib/collision/world.ts","../src/lib/game/game-state.ts","../src/lib/game/game-event-bus.ts","../src/lib/entities/actor.ts","../src/lib/entities/entity.ts","../src/lib/systems/transformable.system.ts","../src/lib/core/flags.ts","../src/lib/core/base-node.ts","../src/lib/core/entity-asset-loader.ts","../src/lib/entities/delegates/animation.ts","../src/lib/graphics/shaders/fragment/standard.glsl","../src/lib/graphics/zylem-scene.ts","../src/lib/debug/debug-state.ts","../src/lib/stage/stage-state.ts","../src/lib/core/utility/vector.ts","../src/lib/core/lifecycle-base.ts","../src/lib/stage/stage-debug-delegate.ts","../src/lib/stage/debug-entity-cursor.ts","../src/lib/stage/stage-camera-debug-delegate.ts","../src/lib/stage/stage-camera-delegate.ts","../src/lib/camera/zylem-camera.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/graphics/shaders/vertex/standard.glsl","../src/lib/camera/camera-debug-delegate.ts","../src/lib/stage/stage-loading-delegate.ts","../src/lib/stage/stage-config.ts","../src/lib/core/utility/options-parser.ts","../src/lib/camera/camera.ts","../src/lib/stage/stage-default.ts","../src/lib/stage/stage.ts","../src/lib/stage/entity-spawner.ts","../src/lib/stage/stage-events.ts"],"sourcesContent":["import { addComponent, 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 } 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 { 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';\nexport type { LoadingEvent };\n\nexport interface ZylemStageConfig {\n\tinputs: Record<string, string[]>;\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | 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 = {\n\t\tbackgroundColor: ZylemBlueColor,\n\t\tbackgroundImage: null,\n\t\tinputs: {\n\t\t\tp1: ['gamepad-1', 'keyboard'],\n\t\t\tp2: ['gamepad-2', 'keyboard'],\n\t\t},\n\t\tgravity: new Vector3(0, 0, 0),\n\t\tvariables: {},\n\t\tentities: [],\n\t};\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\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\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\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\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\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\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}\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\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.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\t\t// @ts-ignore\n\t\tif (child.behaviors) {\n\t\t\t// @ts-ignore\n\t\t\tfor (let behavior of child.behaviors) {\n\t\t\t\taddComponent(this.ecs, behavior.component, entity.eid);\n\t\t\t\tconst keys = Object.keys(behavior.values);\n\t\t\t\tfor (const key of keys) {\n\t\t\t\t\t// @ts-ignore\n\t\t\t\t\tbehavior.component[key][entity.eid] = behavior.values[key];\n\t\t\t\t}\n\t\t\t}\n\t\t}\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}\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 * 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.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 { 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\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\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 { 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 { 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 { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BufferGeometry, Object3D, SkinnedMesh, 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';\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\tposition: { x: 0, y: 0, z: 0 },\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: 'standard',\n\t},\n\tanimations: [],\n\tmodels: []\n};\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate height: number = 1;\n\tprivate objectModel: Group | null = null;\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t}\n\n\tcreateColliderFromObjectModel(objectModel: Group | null): ColliderDesc {\n\t\tif (!objectModel) return ColliderDesc.capsule(1, 1);\n\n\t\tconst skinnedMesh = objectModel.children.find(child => child instanceof SkinnedMesh) as SkinnedMesh;\n\t\tconst geometry = skinnedMesh.geometry as BufferGeometry;\n\n\t\tif (geometry) {\n\t\t\tgeometry.computeBoundingBox();\n\t\t\tif (geometry.boundingBox) {\n\t\t\t\tconst maxY = geometry.boundingBox.max.y;\n\t\t\t\tconst minY = geometry.boundingBox.min.y;\n\t\t\t\tthis.height = maxY - minY;\n\t\t\t}\n\t\t}\n\t\tthis.height = 1;\n\t\tlet colliderDesc = ColliderDesc.capsule(this.height / 2, 1);\n\t\tcolliderDesc.setSensor(false);\n\t\tcolliderDesc.setTranslation(0, this.height + 0.5, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\n\t\treturn colliderDesc;\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tlet colliderDesc = this.createColliderFromObjectModel(this.objectModel);\n\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\tasync load(): Promise<void> {\n\t\tthis._modelFileNames = this.options.models || [];\n\t\tawait this.loadModels();\n\t\tif (this._object) {\n\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\tawait this._animationDelegate.loadAnimations(this.options.animations || []);\n\t\t}\n\t}\n\n\tasync data(): Promise<any> {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t};\n\t}\n\n\tasync actorUpdate(params: UpdateContext<ZylemActorOptions>): Promise<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\tprivate async loadModels(): Promise<void> {\n\t\tif (this._modelFileNames.length === 0) return;\n\t\tconst promises = this._modelFileNames.map(file => this._assetLoader.loadFile(file));\n\t\tconst results = await Promise.all(promises);\n\t\tif (results[0]?.object) {\n\t\t\tthis._object = results[0].object;\n\t\t}\n\t\tif (this._object) {\n\t\t\tthis.group = new Group();\n\t\t\tthis.group.attach(this._object);\n\t\t\tthis.group.scale.set(\n\t\t\t\tthis.options.scale?.x || 1,\n\t\t\t\tthis.options.scale?.y || 1,\n\t\t\t\tthis.options.scale?.z || 1\n\t\t\t);\n\t\t}\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\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 async function actor(...args: Array<ActorOptions>): Promise<ZylemActor> {\n\treturn await 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 { Mesh, Material, ShaderMaterial, Group, Color } from \"three\";\nimport { Collider, ColliderDesc, RigidBody, RigidBodyDesc } 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 { DestroyContext, SetupContext, UpdateContext, LoadedContext, CleanupContext } from \"../core/base-node-life-cycle\";\nimport type { EntityMeshBuilder, EntityCollisionBuilder } from \"./builder\";\nimport { Behavior } from \"../actions/behaviors/behavior\";\n\nexport interface CollisionContext<T, O extends GameEntityOptions, TGlobals extends Record<string, unknown> = any> {\n\tentity: T;\n\tother: GameEntity<O>;\n\tglobals: TGlobals;\n}\n\nexport type BehaviorContext<T, O extends GameEntityOptions> =\n\tSetupContext<T, O> |\n\tUpdateContext<T, O> |\n\tCollisionContext<T, O> |\n\tDestroyContext<T, O>;\n\nexport type BehaviorCallback<T, O extends GameEntityOptions> = (params: BehaviorContext<T, O>) => void;\n\nexport interface CollisionDelegate<T, O extends GameEntityOptions> {\n\tcollision?: ((params: CollisionContext<T, O>) => 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 type BehaviorCallbackType = 'setup' | 'update' | 'destroy' | 'collision';\n\nexport class GameEntity<O extends GameEntityOptions> extends BaseNode<O> implements\n\tGameEntityLifeCycle,\n\tEntityDebugInfo {\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\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\tpublic behaviorCallbackMap: Record<BehaviorCallbackType, BehaviorCallback<this, O>[]> = {\n\t\tsetup: [],\n\t\tupdate: [],\n\t\tdestroy: [],\n\t\tcollision: [],\n\t};\n\n\tconstructor() {\n\t\tsuper();\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(...callbacks: ((params: CollisionContext<this, O>) => void)[]): 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 * Entity-specific setup - runs behavior callbacks\n\t * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)\n\t */\n\tpublic _setup(params: SetupContext<this>): void {\n\t\tthis.behaviorCallbackMap.setup.forEach(callback => {\n\t\t\tcallback({ ...params, me: this });\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 and runs behavior callbacks\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\tthis.behaviorCallbackMap.update.forEach(callback => {\n\t\t\tcallback({ ...params, me: this });\n\t\t});\n\t}\n\n\t/**\n\t * Entity-specific destroy - runs behavior callbacks\n\t * (User callbacks are handled by BaseNode's lifecycleCallbacks.destroy)\n\t */\n\tpublic _destroy(params: DestroyContext<this>): void {\n\t\tthis.behaviorCallbackMap.destroy.forEach(callback => {\n\t\t\tcallback({ ...params, me: this });\n\t\t});\n\t}\n\n\tprotected async _cleanup(_params: CleanupContext<this>): Promise<void> { }\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\tthis.behaviorCallbackMap.collision.forEach(callback => {\n\t\t\tcallback({ entity: this, other, globals });\n\t\t});\n\t}\n\n\tpublic addBehavior(\n\t\tbehaviorCallback: ({ type: BehaviorCallbackType, handler: any })\n\t): this {\n\t\tconst handler = behaviorCallback.handler as unknown as BehaviorCallback<this, O>;\n\t\tif (handler) {\n\t\t\tthis.behaviorCallbackMap[behaviorCallback.type].push(handler);\n\t\t}\n\t\treturn this;\n\t}\n\n\tpublic addBehaviors(\n\t\tbehaviorCallbacks: ({ type: BehaviorCallbackType, handler: any })[]\n\t): this {\n\t\tbehaviorCallbacks.forEach(callback => {\n\t\t\tconst handler = callback.handler as unknown as BehaviorCallback<this, O>;\n\t\t\tif (handler) {\n\t\t\t\tthis.behaviorCallbackMap[callback.type].push(handler);\n\t\t\t}\n\t\t});\n\t\treturn this;\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 && (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\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}","/** 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 { AnimationClip, Object3D } from 'three';\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js';\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\n\nenum FileExtensionTypes {\n\tFBX = 'fbx',\n\tGLTF = 'gltf'\n}\n\nexport interface AssetLoaderResult {\n\tobject?: Object3D;\n\tanimation?: AnimationClip;\n\tgltf?: GLTF;\n}\n\nexport interface IAssetLoader {\n\tload(file: string): Promise<AssetLoaderResult>;\n\tisSupported(file: string): boolean;\n}\n\nclass FBXAssetLoader implements IAssetLoader {\n\tprivate loader: FBXLoader = new FBXLoader();\n\n\tisSupported(file: string): boolean {\n\t\treturn file.toLowerCase().endsWith(FileExtensionTypes.FBX);\n\t}\n\n\tasync load(file: string): Promise<AssetLoaderResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\tfile,\n\t\t\t\t(object: Object3D) => {\n\t\t\t\t\tconst animation = object.animations[0];\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimation\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\treject\n\t\t\t);\n\t\t});\n\t}\n}\n\nclass GLTFAssetLoader implements IAssetLoader {\n\tprivate loader: GLTFLoader = new GLTFLoader();\n\n\tisSupported(file: string): boolean {\n\t\treturn file.toLowerCase().endsWith(FileExtensionTypes.GLTF);\n\t}\n\n\tasync load(file: string): Promise<AssetLoaderResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\tfile,\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\tgltf\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\treject\n\t\t\t);\n\t\t});\n\t}\n}\n\nexport class EntityAssetLoader {\n\tprivate loaders: IAssetLoader[] = [\n\t\tnew FBXAssetLoader(),\n\t\tnew GLTFAssetLoader()\n\t];\n\n\tasync loadFile(file: string): Promise<AssetLoaderResult> {\n\t\tconst loader = this.loaders.find(l => l.isSupported(file));\n\n\t\tif (!loader) {\n\t\t\tthrow new Error(`Unsupported file type: ${file}`);\n\t\t}\n\n\t\treturn loader.load(file);\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","export default \"uniform sampler2D tDiffuse;\\nvarying vec2 vUv;\\n\\nvoid main() {\\n\\tvec4 texel = texture2D( tDiffuse, vUv );\\n\\n\\tgl_FragColor = texel;\\n}\"","import {\n\tScene,\n\tColor,\n\tAmbientLight,\n\tDirectionalLight,\n\tObject3D,\n\tVector3,\n\tTextureLoader,\n\tGridHelper\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';\n\ninterface SceneState {\n\tbackgroundColor: Color | string;\n\tbackgroundImage: string | 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\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\tif (state.backgroundImage) {\n\t\t\tconst loader = new TextureLoader();\n\t\t\tconst texture = loader.load(state.backgroundImage);\n\t\t\tscene.background = texture;\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\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.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 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}","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 { Color, Vector3 } from 'three';\nimport { proxy, subscribe } from 'valtio/vanilla';\nimport { BaseEntityInterface } from '../types/entity-types';\nimport { StageStateInterface } from '../types/stage-types';\nimport { getByPath, setByPath } from '../core/utility/path-utils';\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 { 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');\nconst ZylemBlue = '#0333EC';\nconst ZylemBlueTransparent = '#0333ECA0';\nconst ZylemGoldText = '#DAA420';\n\ntype SizeVector = Vect3 | null;\n\nconst Vec0 = new Vector3(0, 0, 0);\nconst Vec1 = new Vector3(1, 1, 1);","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 { 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\tif (this.stage.scene) {\n\t\t\tthis.debugLines = new LineSegments(\n\t\t\t\tnew BufferGeometry(),\n\t\t\t\tnew LineBasicMaterial({ vertexColors: true })\n\t\t\t);\n\t\t\tthis.stage.scene.scene.add(this.debugLines);\n\t\t\tthis.debugLines.visible = true;\n\n\t\t\tthis.debugCursor = new DebugEntityCursor(this.stage.scene.scene);\n\t\t}\n\t\tthis.attachDomListeners();\n\t}\n\n\tupdate(): void {\n\t\tif (!debugState.enabled) return;\n\t\tif (!this.stage.scene || !this.stage.world || !this.stage.cameraRef) return;\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.debugCursor?.dispose();\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}\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 {\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 { 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","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 { 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);\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// 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}","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 fragmentShader from './shaders/fragment/standard.glsl';\nimport vertexShader from './shaders/vertex/standard.glsl';\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: vertexShader,\n\t\t\tfragmentShader: fragmentShader\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","export default \"varying vec2 vUv;\\n\\nvoid main() {\\n\\tvUv = uv;\\n\\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\\n}\"","import { Object3D, Vector3, Quaternion, Camera } 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\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\n\tconstructor(camera: Camera, domElement: HTMLElement) {\n\t\tthis.camera = camera;\n\t\tthis.domElement = domElement;\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\t\n\t\tif (state.enabled && !wasEnabled) {\n\t\t\t// Entering debug mode: save camera state\n\t\t\tthis.saveCameraState();\n\t\t\tthis.enableOrbitControls();\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t} else if (!state.enabled && wasEnabled) {\n\t\t\t// Exiting debug mode: restore camera state\n\t\t\tthis.orbitTarget = null;\n\t\t\tthis.disableOrbitControls();\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","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 { 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';\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\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 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\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.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 { 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 { 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 camera(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';\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\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\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 { 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 { subscribe } from 'valtio/vanilla';\nimport { stageState } from './stage-state';\nimport type { StageStateInterface } from '../types/stage-types';\n\n/**\n * Event name for stage state changes.\n * Dispatched when the stage state proxy is updated.\n */\nexport const STAGE_STATE_CHANGE = 'STAGE_STATE_CHANGE';\n\n/**\n * Event detail payload for STAGE_STATE_CHANGE events.\n */\nexport interface StageStateChangeEvent {\n\tentities: StageStateInterface['entities'];\n\tvariables: StageStateInterface['variables'];\n}\n\n/**\n * Initialize the stage state dispatcher.\n * Subscribes to stageState changes and dispatches STAGE_STATE_CHANGE events to the window.\n * \n * @returns Unsubscribe function to stop dispatching events.\n * \n * @example\n * // Start dispatching stage state changes\n * const unsubscribe = initStageStateDispatcher();\n * \n * // Later, stop dispatching\n * unsubscribe();\n */\nexport function initStageStateDispatcher(): () => void {\n\treturn subscribe(stageState, () => {\n\t\tconst detail: StageStateChangeEvent = {\n\t\t\tentities: stageState.entities,\n\t\t\tvariables: stageState.variables,\n\t\t};\n\t\twindow.dispatchEvent(new CustomEvent(STAGE_STATE_CHANGE, { detail }));\n\t});\n}\n\n/**\n * Manually dispatch the current stage state.\n * Useful for initial sync when a listener is added.\n */\nexport function dispatchStageState(): void {\n\tconst detail: StageStateChangeEvent = {\n\t\tentities: stageState.entities,\n\t\tvariables: stageState.variables,\n\t};\n\twindow.dispatchEvent(new CustomEvent(STAGE_STATE_CHANGE, { detail }));\n}\n"],"mappings":"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","names":["Color","Vector3","Group","Group","Color","Vector3","proxy","state","Color","position","Vector3","Color","Vector3","proxy","subscribe","proxy","Color","Vector3","Color","Vector3","Vector3","subscribe","nanoid","BufferGeometry","LineBasicMaterial","LineSegments","Color","Group","Mesh","Vector3","LineSegments","BufferGeometry","LineBasicMaterial","hoveredUuid","subscribe","subscribe","Vector2","Vector3","Object3D","WebGLRenderer","Vector3","standard_default","standard_default","Vector3","state","WebGLRenderer","Object3D","Vector3","position","Vector2","Vector3","Vector3","Vector3","nanoid","state","Color","subscribe","Vector2","Vector3","proxy","Vector3","Vector3","proxy","Quaternion","Vector2","subscribe","subscribe"]}