@zylem/game-lib 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +9 -16
- package/dist/actions.d.ts +30 -21
- package/dist/actions.js +628 -145
- package/dist/actions.js.map +1 -1
- package/dist/behavior/platformer-3d.d.ts +296 -0
- package/dist/behavior/platformer-3d.js +518 -0
- package/dist/behavior/platformer-3d.js.map +1 -0
- package/dist/behavior/ricochet-2d.d.ts +274 -0
- package/dist/behavior/ricochet-2d.js +394 -0
- package/dist/behavior/ricochet-2d.js.map +1 -0
- package/dist/behavior/screen-wrap.d.ts +86 -0
- package/dist/behavior/screen-wrap.js +195 -0
- package/dist/behavior/screen-wrap.js.map +1 -0
- package/dist/behavior/thruster.d.ts +10 -0
- package/dist/behavior/thruster.js +234 -0
- package/dist/behavior/thruster.js.map +1 -0
- package/dist/behavior/world-boundary-2d.d.ts +141 -0
- package/dist/behavior/world-boundary-2d.js +181 -0
- package/dist/behavior/world-boundary-2d.js.map +1 -0
- package/dist/behavior-descriptor-BWNWmIjv.d.ts +142 -0
- package/dist/{blueprints-Cq3Ko6_G.d.ts → blueprints-BWGz8fII.d.ts} +2 -2
- package/dist/camera-B5e4c78l.d.ts +468 -0
- package/dist/camera.d.ts +3 -2
- package/dist/camera.js +900 -211
- package/dist/camera.js.map +1 -1
- package/dist/composition-DrzFrbqI.d.ts +218 -0
- package/dist/{core-bO8TzV7u.d.ts → core-DAkskq6Y.d.ts} +60 -62
- package/dist/core.d.ts +10 -6
- package/dist/core.js +6896 -5020
- package/dist/core.js.map +1 -1
- package/dist/{entities-DvByhMGU.d.ts → entities-DC9ce_vx.d.ts} +113 -3
- package/dist/entities.d.ts +5 -3
- package/dist/entities.js +3727 -3167
- package/dist/entities.js.map +1 -1
- package/dist/entity-BpbZqg19.d.ts +1100 -0
- package/dist/global-change-Dc8uCKi2.d.ts +25 -0
- package/dist/main.d.ts +418 -15
- package/dist/main.js +11384 -8515
- package/dist/main.js.map +1 -1
- package/dist/{stage-types-Bd-KtcYT.d.ts → stage-types-BFsm3qsZ.d.ts} +205 -13
- package/dist/stage.d.ts +10 -7
- package/dist/stage.js +5311 -3880
- package/dist/stage.js.map +1 -1
- package/dist/thruster-DhRaJnoL.d.ts +172 -0
- package/dist/world-Be5m1XC1.d.ts +31 -0
- package/package.json +29 -13
- package/dist/behaviors.d.ts +0 -854
- package/dist/behaviors.js +0 -1209
- package/dist/behaviors.js.map +0 -1
- package/dist/camera-CeJPAgGg.d.ts +0 -116
- package/dist/moveable-B_vyA6cw.d.ts +0 -67
- package/dist/transformable-CUhvyuYO.d.ts +0 -67
- package/dist/world-C8tQ7Plj.d.ts +0 -774
package/dist/entities.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/systems/transformable.system.ts","../src/lib/core/flags.ts","../src/lib/core/base-node.ts","../../../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/src/index.ts","../src/lib/events/event-emitter-delegate.ts","../src/lib/events/zylem-events.ts","../src/lib/events/index.ts","../src/lib/entities/entity.ts","../src/lib/collision/collision-builder.ts","../src/lib/graphics/mesh.ts","../src/lib/core/utility/strings.ts","../src/lib/graphics/shaders/vertex/object.shader.ts","../src/lib/graphics/shaders/standard.shader.ts","../src/lib/core/loaders/texture-loader.ts","../src/lib/core/loaders/gltf-loader.ts","../src/lib/core/loaders/fbx-loader.ts","../src/lib/core/loaders/obj-loader.ts","../src/lib/core/loaders/audio-loader.ts","../src/lib/core/loaders/file-loader.ts","../src/lib/core/loaders/index.ts","../src/lib/core/asset-manager.ts","../src/lib/graphics/material.ts","../src/lib/entities/builder.ts","../src/lib/entities/delegates/debug.ts","../src/lib/entities/delegates/loader.ts","../src/lib/entities/create.ts","../src/lib/entities/common.ts","../src/lib/entities/box.ts","../src/lib/entities/sphere.ts","../src/lib/entities/sprite.ts","../src/lib/graphics/geometries/XZPlaneGeometry.ts","../src/lib/entities/plane.ts","../src/lib/game/game-state.ts","../src/lib/entities/zone.ts","../src/lib/core/entity-asset-loader.ts","../src/lib/entities/delegates/animation.ts","../src/lib/entities/text.ts","../src/lib/entities/rect.ts","../src/lib/behaviors/thruster/index.ts","../src/lib/behaviors/screen-wrap/index.ts","../src/lib/behaviors/world-boundary-2d/index.ts","../src/lib/behaviors/ricochet-2d/index.ts","../src/lib/behaviors/movement-sequence-2d/index.ts","../src/lib/coordinators/boundary-ricochet.coordinator.ts","../src/lib/behaviors/index.ts","../src/api/main.ts","../src/lib/entities/actor.ts","../src/api/entities.ts"],"sourcesContent":["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}","export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<\n\tWildcardHandler<T>\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n\tall: EventHandlerMap<Events>;\n\n\ton<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n\ton(type: '*', handler: WildcardHandler<Events>): void;\n\n\toff<Key extends keyof Events>(\n\t\ttype: Key,\n\t\thandler?: Handler<Events[Key]>\n\t): void;\n\toff(type: '*', handler: WildcardHandler<Events>): void;\n\n\temit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n\temit<Key extends keyof Events>(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt<Events extends Record<EventType, unknown>>(\n\tall?: EventHandlerMap<Events>\n): Emitter<Events> {\n\ttype GenericEventHandler =\n\t\t| Handler<Events[keyof Events]>\n\t\t| WildcardHandler<Events>;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList<Events[keyof Events]>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList<Events>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n","import mitt, { Emitter } from 'mitt';\n\n/**\n * Event scope identifier for routing events.\n */\nexport type EventScope = 'game' | 'stage' | 'entity';\n\n/**\n * Reusable delegate for event emission and subscription.\n * Use via composition in Game, Stage, and Entity classes.\n * \n * @example\n * class Game {\n * private eventDelegate = new EventEmitterDelegate<GameEvents>();\n * \n * dispatch<K extends keyof GameEvents>(event: K, payload: GameEvents[K]) {\n * this.eventDelegate.dispatch(event, payload);\n * }\n * }\n */\nexport class EventEmitterDelegate<TEvents extends Record<string, unknown>> {\n\tprivate emitter: Emitter<TEvents>;\n\tprivate unsubscribes: (() => void)[] = [];\n\n\tconstructor() {\n\t\tthis.emitter = mitt<TEvents>();\n\t}\n\n\t/**\n\t * Dispatch an event to all listeners.\n\t */\n\tdispatch<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n\t\tthis.emitter.emit(event, payload);\n\t}\n\n\t/**\n\t * Subscribe to an event. Returns an unsubscribe function.\n\t */\n\tlisten<K extends keyof TEvents>(\n\t\tevent: K,\n\t\thandler: (payload: TEvents[K]) => void\n\t): () => void {\n\t\tthis.emitter.on(event, handler);\n\t\tconst unsub = () => this.emitter.off(event, handler);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Subscribe to all events.\n\t */\n\tlistenAll(handler: (type: keyof TEvents, payload: TEvents[keyof TEvents]) => void): () => void {\n\t\tthis.emitter.on('*', handler as any);\n\t\tconst unsub = () => this.emitter.off('*', handler as any);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Clean up all subscriptions.\n\t */\n\tdispose(): void {\n\t\tthis.unsubscribes.forEach(fn => fn());\n\t\tthis.unsubscribes = [];\n\t\tthis.emitter.all.clear();\n\t}\n}\n","import mitt from 'mitt';\nimport type { LoadingEvent } from '../core/interfaces';\n\n/**\n * Payload for game loading events with stage context.\n */\nexport interface GameLoadingPayload extends LoadingEvent {\n\tstageName?: string;\n\tstageIndex?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Game Events\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Payload for stage configuration sent to editor. */\nexport interface StageConfigPayload {\n\tid: string;\n\tbackgroundColor: string;\n\tbackgroundImage: string | null;\n\tgravity: { x: number; y: number; z: number };\n\tinputs: Record<string, string[]>;\n\tvariables: Record<string, unknown>;\n}\n\n/** Payload for entity configuration sent to editor. */\nexport interface EntityConfigPayload {\n\tuuid: string;\n\tname: string;\n\ttype: string;\n\tposition: { x: number; y: number; z: number };\n\trotation: { x: number; y: number; z: number };\n\tscale: { x: number; y: number; z: number };\n}\n\n/** Payload for state dispatch events from game to editor. */\nexport interface StateDispatchPayload {\n\tscope: 'game' | 'stage' | 'entity';\n\tpath: string;\n\tvalue: unknown;\n\tpreviousValue?: unknown;\n\tconfig?: {\n\t\tid: string;\n\t\taspectRatio: number;\n\t\tfullscreen: boolean;\n\t\tbodyBackground: string | undefined;\n\t\tinternalResolution: { width: number; height: number } | undefined;\n\t\tdebug: boolean;\n\t} | null;\n\tstageConfig?: StageConfigPayload | null;\n\tentities?: EntityConfigPayload[] | null;\n}\n\nexport type GameEvents = {\n\t'loading:start': GameLoadingPayload;\n\t'loading:progress': GameLoadingPayload;\n\t'loading:complete': GameLoadingPayload;\n\t'paused': { paused: boolean };\n\t'debug': { enabled: boolean };\n\t'state:dispatch': StateDispatchPayload;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Stage Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type StageEvents = {\n\t'stage:loaded': { stageId: string };\n\t'stage:unloaded': { stageId: string };\n\t'stage:variable:changed': { key: string; value: unknown };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Entity Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type EntityEvents = {\n\t'entity:spawned': { entityId: string; name: string };\n\t'entity:destroyed': { entityId: string };\n\t'entity:collision': { entityId: string; otherId: string };\n\t'entity:model:loading': { entityId: string; files: string[] };\n\t'entity:model:loaded': { entityId: string; success: boolean; meshCount?: number };\n\t'entity:animation:loaded': { entityId: string; animationCount: number };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Combined Event Map\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type ZylemEvents = GameEvents & StageEvents & EntityEvents;\n\n/**\n * Global event bus for cross-package communication.\n * \n * Usage:\n * ```ts\n * import { zylemEventBus } from '@zylem/game-lib';\n * \n * // Subscribe\n * const unsub = zylemEventBus.on('loading:progress', (e) => console.log(e));\n * \n * // Emit\n * zylemEventBus.emit('loading:progress', { type: 'progress', progress: 0.5 });\n * \n * // Cleanup\n * unsub();\n * ```\n */\nexport const zylemEventBus = mitt<ZylemEvents>();\n","export { EventEmitterDelegate, type EventScope } from './event-emitter-delegate';\nexport {\n\tzylemEventBus,\n\ttype ZylemEvents,\n\ttype GameEvents,\n\ttype StageEvents,\n\ttype EntityEvents,\n\ttype GameLoadingPayload,\n\ttype StateDispatchPayload,\n\ttype StageConfigPayload,\n\ttype EntityConfigPayload,\n} from './zylem-events';\n","import { Mesh, Material, ShaderMaterial, Group, Color } from 'three';\nimport {\n Collider,\n ColliderDesc,\n RigidBody,\n RigidBodyDesc,\n} from '@dimforge/rapier3d-compat';\nimport { position, rotation, scale } from '../systems/transformable.system';\nimport { Vec3 } from '../core/vector';\nimport { MaterialBuilder, MaterialOptions } from '../graphics/material';\nimport { CollisionOptions } from '../collision/collision-builder';\nimport { BaseNode } from '../core/base-node';\nimport {\n DestroyContext,\n SetupContext,\n UpdateContext,\n LoadedContext,\n CleanupContext,\n} from '../core/base-node-life-cycle';\nimport type { EntityMeshBuilder, EntityCollisionBuilder } from './builder';\nimport { Behavior } from '../actions/behaviors/behavior';\nimport {\n EventEmitterDelegate,\n zylemEventBus,\n type EntityEvents,\n} from '../events';\nimport type {\n BehaviorDescriptor,\n BehaviorRef,\n BehaviorHandle,\n} from '../behaviors/behavior-descriptor';\n\nexport interface CollisionContext<\n T,\n O extends GameEntityOptions,\n TGlobals extends Record<string, unknown> = any,\n> {\n entity: T;\n // Use 'any' for other's options type to break recursive type variance issues\n other: GameEntity<O | any>;\n globals: TGlobals;\n}\n\nexport type BehaviorContext<T, O extends GameEntityOptions> =\n | SetupContext<T, O>\n | UpdateContext<T, O>\n | CollisionContext<T, O>\n | DestroyContext<T, O>;\n\nexport type BehaviorCallback<T, O extends GameEntityOptions> = (\n params: BehaviorContext<T, O>,\n) => void;\n\nexport interface CollisionDelegate<T, O extends GameEntityOptions> {\n // Use 'any' for entity and options types to avoid contravariance issues\n // with function parameters. Type safety is still enforced at the call site via onCollision()\n collision?: ((params: CollisionContext<any, any>) => void)[];\n}\n\nexport type IBuilder<BuilderOptions = any> = {\n preBuild: (options: BuilderOptions) => BuilderOptions;\n build: (options: BuilderOptions) => BuilderOptions;\n postBuild: (options: BuilderOptions) => BuilderOptions;\n};\n\nexport type GameEntityOptions = {\n name?: string;\n color?: Color;\n size?: Vec3;\n position?: Vec3;\n batched?: boolean;\n collision?: Partial<CollisionOptions>;\n material?: Partial<MaterialOptions>;\n custom?: { [key: string]: any };\n collisionType?: string;\n collisionGroup?: string;\n collisionFilter?: string[];\n _builders?: {\n meshBuilder?: IBuilder | EntityMeshBuilder | null;\n collisionBuilder?: IBuilder | EntityCollisionBuilder | null;\n materialBuilder?: MaterialBuilder | null;\n };\n};\n\nexport abstract class GameEntityLifeCycle {\n abstract _setup(params: SetupContext<this>): void;\n abstract _update(params: UpdateContext<this>): void;\n abstract _destroy(params: DestroyContext<this>): void;\n}\n\nexport interface EntityDebugInfo {\n buildInfo: () => Record<string, string>;\n}\n\nexport type BehaviorCallbackType = 'setup' | 'update' | 'destroy' | 'collision';\n\nexport class GameEntity<O extends GameEntityOptions>\n extends BaseNode<O>\n implements GameEntityLifeCycle, EntityDebugInfo\n{\n public behaviors: Behavior[] = [];\n public group: Group | undefined;\n public mesh: Mesh | undefined;\n public materials: Material[] | undefined;\n public bodyDesc: RigidBodyDesc | null = null;\n public body: RigidBody | null = null;\n public colliderDesc: ColliderDesc | undefined;\n public collider: Collider | undefined;\n public custom: Record<string, any> = {};\n\n public debugInfo: Record<string, any> = {};\n public debugMaterial: ShaderMaterial | undefined;\n\n public collisionDelegate: CollisionDelegate<this, O> = {\n collision: [],\n };\n public collisionType?: string;\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * Use 'any' for callback types to avoid contravariance issues\n * with function parameters. Type safety is enforced where callbacks are registered.\n */\n public behaviorCallbackMap: Record<\n BehaviorCallbackType,\n BehaviorCallback<any, any>[]\n > = {\n setup: [],\n update: [],\n destroy: [],\n collision: [],\n };\n\n // Event delegate for dispatch/listen API\n protected eventDelegate = new EventEmitterDelegate<EntityEvents>();\n\n // Behavior references (new ECS pattern)\n private behaviorRefs: BehaviorRef[] = [];\n\n constructor() {\n super();\n }\n\n public create(): this {\n const { position: setupPosition } = this.options;\n const { x, y, z } = setupPosition || { x: 0, y: 0, z: 0 };\n this.behaviors = [\n { component: position, values: { x, y, z } },\n { component: scale, values: { x: 0, y: 0, z: 0 } },\n { component: rotation, values: { x: 0, y: 0, z: 0, w: 0 } },\n ];\n this.name = this.options.name || '';\n return this;\n }\n\n /**\n * Add collision callbacks\n */\n public onCollision(\n ...callbacks: ((params: CollisionContext<this, O>) => void)[]\n ): this {\n const existing = this.collisionDelegate.collision ?? [];\n this.collisionDelegate.collision = [...existing, ...callbacks];\n return this;\n }\n\n /**\n * Use a behavior on this entity via typed descriptor.\n * Behaviors will be auto-registered as systems when the entity is spawned.\n * @param descriptor The behavior descriptor (import from behaviors module)\n * @param options Optional overrides for the behavior's default options\n * @returns BehaviorHandle with behavior-specific methods for lazy FSM access\n */\n public use<\n O extends Record<string, any>,\n H extends Record<string, any> = Record<string, never>,\n >(\n descriptor: BehaviorDescriptor<O, H>,\n options?: Partial<O>,\n ): BehaviorHandle<O, H> {\n const behaviorRef: BehaviorRef<O> = {\n descriptor: descriptor as BehaviorDescriptor<O, any>,\n options: { ...descriptor.defaultOptions, ...options } as O,\n };\n this.behaviorRefs.push(behaviorRef as BehaviorRef<any>);\n\n // Create base handle\n const baseHandle = {\n getFSM: () => behaviorRef.fsm ?? null,\n getOptions: () => behaviorRef.options,\n ref: behaviorRef,\n };\n\n // Merge behavior-specific methods if createHandle is provided\n const customMethods = descriptor.createHandle?.(behaviorRef) ?? ({} as H);\n\n return {\n ...baseHandle,\n ...customMethods,\n } as BehaviorHandle<O, H>;\n }\n\n /**\n * Get all behavior references attached to this entity.\n * Used by the stage to auto-register required systems.\n */\n public getBehaviorRefs(): BehaviorRef[] {\n return this.behaviorRefs;\n }\n\n /**\n * Entity-specific setup - runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)\n */\n public _setup(params: SetupContext<this>): void {\n this.behaviorCallbackMap.setup.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n protected async _loaded(_params: LoadedContext<this>): Promise<void> {}\n\n /**\n * Entity-specific update - updates materials and runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)\n */\n public _update(params: UpdateContext<this>): void {\n this.updateMaterials(params);\n this.behaviorCallbackMap.update.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n /**\n * Entity-specific destroy - runs behavior callbacks\n * (User callbacks are handled by BaseNode's lifecycleCallbacks.destroy)\n */\n public _destroy(params: DestroyContext<this>): void {\n this.behaviorCallbackMap.destroy.forEach((callback) => {\n callback({ ...params, me: this });\n });\n }\n\n protected async _cleanup(_params: CleanupContext<this>): Promise<void> {}\n\n public _collision(other: GameEntity<O>, globals?: any): void {\n if (this.collisionDelegate.collision?.length) {\n const callbacks = this.collisionDelegate.collision;\n callbacks.forEach((callback) => {\n callback({ entity: this, other, globals });\n });\n }\n this.behaviorCallbackMap.collision.forEach((callback) => {\n callback({ entity: this, other, globals });\n });\n }\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * See `lib/behaviors/thruster/thruster-movement.behavior.ts` for an example.\n */\n public addBehavior(behaviorCallback: {\n type: BehaviorCallbackType;\n handler: any;\n }): this {\n const handler = behaviorCallback.handler as unknown as BehaviorCallback<\n this,\n O\n >;\n if (handler) {\n this.behaviorCallbackMap[behaviorCallback.type].push(handler);\n }\n return this;\n }\n\n /**\n * @deprecated Use the new ECS-based behavior system instead.\n * See `lib/behaviors/thruster/thruster-movement.behavior.ts` for an example.\n */\n public addBehaviors(\n behaviorCallbacks: { type: BehaviorCallbackType; handler: any }[],\n ): this {\n behaviorCallbacks.forEach((callback) => {\n const handler = callback.handler as unknown as BehaviorCallback<this, O>;\n if (handler) {\n this.behaviorCallbackMap[callback.type].push(handler);\n }\n });\n return this;\n }\n\n protected updateMaterials(params: any) {\n if (!this.materials?.length) {\n return;\n }\n for (const material of this.materials) {\n if (material instanceof ShaderMaterial) {\n if (material.uniforms) {\n material.uniforms.iTime &&\n (material.uniforms.iTime.value += params.delta);\n }\n }\n }\n }\n\n public buildInfo(): Record<string, string> {\n const info: Record<string, string> = {};\n info.name = this.name;\n info.uuid = this.uuid;\n info.eid = this.eid.toString();\n return info;\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Events API\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Dispatch an event from this entity.\n * Events are emitted both locally and to the global event bus.\n */\n dispatch<K extends keyof EntityEvents>(\n event: K,\n payload: EntityEvents[K],\n ): void {\n this.eventDelegate.dispatch(event, payload);\n (zylemEventBus as any).emit(event, payload);\n }\n\n /**\n * Listen for events on this entity instance.\n * @returns Unsubscribe function\n */\n listen<K extends keyof EntityEvents>(\n event: K,\n handler: (payload: EntityEvents[K]) => void,\n ): () => void {\n return this.eventDelegate.listen(event, handler);\n }\n\n /**\n * Clean up entity event subscriptions.\n */\n disposeEvents(): void {\n this.eventDelegate.dispose();\n }\n}\n","import { ActiveCollisionTypes, ColliderDesc, RigidBodyDesc, RigidBodyType, Vector3 } from \"@dimforge/rapier3d-compat\";\nimport { Vec3 } from \"../core/vector\";\n\n/**\n * Options for configuring entity collision behavior.\n */\nexport interface CollisionOptions {\n\tstatic?: boolean;\n\tsensor?: boolean;\n\tsize?: Vector3;\n\tposition?: Vector3;\n\tcollisionType?: string;\n\tcollisionFilter?: string[];\n}\n\nconst typeToGroup = new Map<string, number>();\nlet nextGroupId = 0;\n\nexport function getOrCreateCollisionGroupId(type: string): number {\n\tlet groupId = typeToGroup.get(type);\n\tif (groupId === undefined) {\n\t\tgroupId = nextGroupId++ % 16;\n\t\ttypeToGroup.set(type, groupId);\n\t}\n\treturn groupId;\n}\n\nexport function createCollisionFilter(allowedTypes: string[]): number {\n\tlet filter = 0;\n\tallowedTypes.forEach(type => {\n\t\tconst groupId = getOrCreateCollisionGroupId(type);\n\t\tfilter |= (1 << groupId);\n\t});\n\treturn filter;\n}\n\nexport class CollisionBuilder {\n\tstatic: boolean = false;\n\tsensor: boolean = false;\n\tgravity: Vec3 = new Vector3(0, 0, 0);\n\n\tbuild(options: Partial<CollisionOptions>): [RigidBodyDesc, ColliderDesc] {\n\t\tconst bodyDesc = this.bodyDesc({\n\t\t\tisDynamicBody: !this.static\n\t\t});\n\t\tconst collider = this.collider(options);\n\t\tconst type = options.collisionType;\n\t\tif (type) {\n\t\t\tlet groupId = getOrCreateCollisionGroupId(type);\n\t\t\tlet filter = 0b1111111111111111;\n\t\t\tif (options.collisionFilter) {\n\t\t\t\tfilter = createCollisionFilter(options.collisionFilter);\n\t\t\t}\n\t\t\tcollider.setCollisionGroups((groupId << 16) | filter);\n\t\t}\n\t\tconst { KINEMATIC_FIXED, DEFAULT } = ActiveCollisionTypes;\n\t\tcollider.activeCollisionTypes = (this.sensor) ? KINEMATIC_FIXED : DEFAULT;\n\t\treturn [bodyDesc, collider];\n\t}\n\n\twithCollision(collisionOptions: Partial<CollisionOptions>): this {\n\t\tthis.sensor = collisionOptions?.sensor ?? this.sensor;\n\t\tthis.static = collisionOptions?.static ?? this.static;\n\t\treturn this;\n\t}\n\n\tcollider(options: CollisionOptions): ColliderDesc {\n\t\tconst size = options.size ?? new Vector3(1, 1, 1);\n\t\tconst half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };\n\t\tlet colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);\n\t\treturn colliderDesc;\n\t}\n\n\tbodyDesc({ isDynamicBody = true }): RigidBodyDesc {\n\t\tconst type = isDynamicBody ? RigidBodyType.Dynamic : RigidBodyType.Fixed;\n\t\tconst bodyDesc = new RigidBodyDesc(type)\n\t\t\t.setTranslation(0, 0, 0)\n\t\t\t.setGravityScale(1.0)\n\t\t\t.setCanSleep(false)\n\t\t\t.setCcdEnabled(true);\n\t\treturn bodyDesc;\n\t}\n}","import { BufferGeometry, Material, Mesh } from 'three';\nimport { GameEntityOptions } from '../entities/entity';\n\n/**\n * TODO: allow for multiple materials requires geometry groups\n * TODO: allow for instanced uniforms\n * TODO: allow for geometry groups\n * TODO: allow for batched meshes\n * import { InstancedUniformsMesh } from 'three-instanced-uniforms-mesh';\n * may not need geometry groups for shaders though\n * setGeometry<T extends BufferGeometry>(geometry: T) {\n * MeshBuilder.bachedMesh = new BatchedMesh(10, 5000, 10000, material);\n * }\n */\n\nexport type MeshBuilderOptions = Partial<Pick<GameEntityOptions, 'batched' | 'material'>>;\n\nexport class MeshBuilder {\n\n\t_build(meshOptions: MeshBuilderOptions, geometry: BufferGeometry, materials: Material[]): Mesh {\n\t\tconst { batched, material } = meshOptions;\n\t\tif (batched) {\n\t\t\tconsole.warn('warning: mesh batching is not implemented');\n\t\t}\n\t\tconst mesh = new Mesh(geometry, materials.at(-1));\n\t\tmesh.position.set(0, 0, 0);\n\t\tmesh.castShadow = true;\n\t\tmesh.receiveShadow = true;\n\t\treturn mesh;\n\t}\n\n\t_postBuild(): void {\n\t\treturn;\n\t}\n}","export function sortedStringify(obj: Record<string, any>) {\n\tconst sortedObj = Object.keys(obj)\n\t\t.sort()\n\t\t.reduce((acc: Record<string, any>, key: string) => {\n\t\t\tacc[key] = obj[key];\n\t\t\treturn acc;\n\t\t}, {} as Record<string, any>);\n\n\treturn JSON.stringify(sortedObj);\n}\n\nexport function shortHash(objString: string) {\n\tlet hash = 0;\n\tfor (let i = 0; i < objString.length; i++) {\n\t\thash = Math.imul(31, hash) + objString.charCodeAt(i) | 0;\n\t}\n\treturn hash.toString(36);\n}","export const objectVertexShader = `\nuniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n\tvUv = uv;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n}\n`;\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\nuniform sampler2D tDiffuse;\nvarying vec2 vUv;\n\nvoid main() {\n\tvec4 texel = texture2D( tDiffuse, vUv );\n\n\tgl_FragColor = texel;\n}\n`;\n\nexport const standardShader = {\n vertex: objectVertexShader,\n fragment\n};\n","/**\n * Texture loader adapter for the Asset Manager\n */\n\nimport { TextureLoader, Texture, RepeatWrapping, Vector2, Wrapping } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface TextureOptions extends AssetLoadOptions {\n\trepeat?: Vector2;\n\twrapS?: Wrapping;\n\twrapT?: Wrapping;\n}\n\nexport class TextureLoaderAdapter implements LoaderAdapter<Texture> {\n\tprivate loader: TextureLoader;\n\n\tconstructor() {\n\t\tthis.loader = new TextureLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'tga'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: TextureOptions): Promise<Texture> {\n\t\tconst texture = await this.loader.loadAsync(url, (event) => {\n\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t}\n\t\t});\n\n\t\t// Apply texture options\n\t\tif (options?.repeat) {\n\t\t\ttexture.repeat.copy(options.repeat);\n\t\t}\n\t\ttexture.wrapS = options?.wrapS ?? RepeatWrapping;\n\t\ttexture.wrapT = options?.wrapT ?? RepeatWrapping;\n\n\t\treturn texture;\n\t}\n\n\t/**\n\t * Clone a texture for independent usage\n\t */\n\tclone(texture: Texture): Texture {\n\t\tconst cloned = texture.clone();\n\t\tcloned.needsUpdate = true;\n\t\treturn cloned;\n\t}\n}\n","/**\n * GLTF loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parseAsync\n */\n\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface GLTFLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parseAsync pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers, so this mainly\n\t * provides a cleaner async/await pattern rather than performance gains\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class GLTFLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: GLTFLoader;\n\n\tconstructor() {\n\t\tthis.loader = new GLTFLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['gltf', 'glb'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parseAsync\n\t * Both fetch and parsing are async, keeping the main thread responsive\n\t */\n\tprivate async loadWithAsyncFetch(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using GLTFLoader.parseAsync\n\t\t\t// The url is passed as the path for resolving relative resources\n\t\t\tconst gltf = await this.loader.parseAsync(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject: gltf.scene,\n\t\t\t\tanimations: gltf.animations,\n\t\t\t\tgltf\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch GLTF load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(gltf: GLTF) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject: gltf.scene,\n\t\t\t\t\t\tanimations: gltf.animations,\n\t\t\t\t\t\tgltf\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded GLTF scene for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: result.animations?.map(anim => anim.clone()),\n\t\t\tgltf: result.gltf\n\t\t};\n\t}\n}\n","/**\n * FBX loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parse\n */\n\nimport { Object3D } from 'three';\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface FBXLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parse pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class FBXLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: FBXLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FBXLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'fbx';\n\t}\n\n\tasync load(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parse\n\t */\n\tprivate async loadWithAsyncFetch(url: string, _options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using FBXLoader.parse\n\t\t\tconst object = this.loader.parse(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject,\n\t\t\t\tanimations: (object as any).animations || []\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch FBX load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, _options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Object3D) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: (object as any).animations || []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded FBX object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: result.animations?.map(anim => anim.clone())\n\t\t};\n\t}\n}\n","/**\n * OBJ loader adapter for the Asset Manager\n * Supports optional MTL (material) file loading\n */\n\nimport { Object3D, Group } from 'three';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { MTLLoader } from 'three/addons/loaders/MTLLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface OBJLoadOptions extends AssetLoadOptions {\n\t/** Path to MTL material file */\n\tmtlPath?: string;\n}\n\nexport class OBJLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: OBJLoader;\n\tprivate mtlLoader: MTLLoader;\n\n\tconstructor() {\n\t\tthis.loader = new OBJLoader();\n\t\tthis.mtlLoader = new MTLLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'obj';\n\t}\n\n\tasync load(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Load MTL first if provided\n\t\tif (options?.mtlPath) {\n\t\t\tawait this.loadMTL(options.mtlPath);\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Group) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate async loadMTL(url: string): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.mtlLoader.load(\n\t\t\t\turl,\n\t\t\t\t(materials) => {\n\t\t\t\t\tmaterials.preload();\n\t\t\t\t\tthis.loader.setMaterials(materials);\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded OBJ object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: []\n\t\t};\n\t}\n}\n","/**\n * Audio loader adapter for the Asset Manager\n */\n\nimport { AudioLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport class AudioLoaderAdapter implements LoaderAdapter<AudioBuffer> {\n\tprivate loader: AudioLoader;\n\n\tconstructor() {\n\t\tthis.loader = new AudioLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['mp3', 'ogg', 'wav', 'flac', 'aac', 'm4a'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(buffer) => resolve(buffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n","/**\n * File loader adapter for the Asset Manager\n */\n\nimport { FileLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface FileLoadOptions extends AssetLoadOptions {\n\tresponseType?: 'text' | 'arraybuffer' | 'blob' | 'json';\n}\n\nexport class FileLoaderAdapter implements LoaderAdapter<string | ArrayBuffer> {\n\tprivate loader: FileLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FileLoader();\n\t}\n\n\tisSupported(_url: string): boolean {\n\t\t// FileLoader can handle any file type\n\t\treturn true;\n\t}\n\n\tasync load(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst responseType = options?.responseType ?? 'text';\n\t\tthis.loader.setResponseType(responseType as any);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(data) => resolve(data as string | ArrayBuffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n\n/**\n * JSON loader using FileLoader\n */\nexport class JsonLoaderAdapter implements LoaderAdapter<unknown> {\n\tprivate fileLoader: FileLoaderAdapter;\n\n\tconstructor() {\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'json';\n\t}\n\n\tasync load<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\tconst data = await this.fileLoader.load(url, { ...options, responseType: 'json' });\n\t\treturn data as T;\n\t}\n}\n","/**\n * Loader adapters barrel export\n */\n\nexport { TextureLoaderAdapter, type TextureOptions } from './texture-loader';\nexport { GLTFLoaderAdapter, type GLTFLoadOptions } from './gltf-loader';\nexport { FBXLoaderAdapter, type FBXLoadOptions } from './fbx-loader';\nexport { OBJLoaderAdapter, type OBJLoadOptions } from './obj-loader';\nexport { AudioLoaderAdapter } from './audio-loader';\nexport { FileLoaderAdapter, JsonLoaderAdapter, type FileLoadOptions } from './file-loader';\n","/**\n * Centralized Asset Manager for Zylem\n * \n * Provides caching, parallel loading, and unified access to all asset types.\n * All asset loading should funnel through this manager.\n */\n\nimport { Texture, Object3D, LoadingManager, Cache } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport mitt, { Emitter } from 'mitt';\n\nimport {\n\tAssetType,\n\tAssetLoadOptions,\n\tAssetManagerEvents,\n\tBatchLoadItem,\n\tModelLoadResult\n} from './asset-types';\n\nimport {\n\tTextureLoaderAdapter,\n\tGLTFLoaderAdapter,\n\tFBXLoaderAdapter,\n\tOBJLoaderAdapter,\n\tAudioLoaderAdapter,\n\tFileLoaderAdapter,\n\tJsonLoaderAdapter,\n\tTextureOptions,\n\tGLTFLoadOptions,\n\tFBXLoadOptions,\n\tOBJLoadOptions,\n\tFileLoadOptions\n} from './loaders';\n\n/**\n * Asset cache entry\n */\ninterface CacheEntry<T> {\n\tpromise: Promise<T>;\n\tresult?: T;\n\tloadedAt: number;\n}\n\n/**\n * AssetManager - Singleton for all asset loading\n * \n * Features:\n * - URL-based caching with deduplication\n * - Typed load methods for each asset type\n * - Batch loading with Promise.all() for parallelism\n * - Progress events via LoadingManager\n * - Clone support for shared assets (textures, models)\n */\nexport class AssetManager {\n\tprivate static instance: AssetManager | null = null;\n\n\t// Caches for different asset types\n\tprivate textureCache: Map<string, CacheEntry<Texture>> = new Map();\n\tprivate modelCache: Map<string, CacheEntry<ModelLoadResult>> = new Map();\n\tprivate audioCache: Map<string, CacheEntry<AudioBuffer>> = new Map();\n\tprivate fileCache: Map<string, CacheEntry<string | ArrayBuffer>> = new Map();\n\tprivate jsonCache: Map<string, CacheEntry<unknown>> = new Map();\n\n\t// Loaders\n\tprivate textureLoader: TextureLoaderAdapter;\n\tprivate gltfLoader: GLTFLoaderAdapter;\n\tprivate fbxLoader: FBXLoaderAdapter;\n\tprivate objLoader: OBJLoaderAdapter;\n\tprivate audioLoader: AudioLoaderAdapter;\n\tprivate fileLoader: FileLoaderAdapter;\n\tprivate jsonLoader: JsonLoaderAdapter;\n\n\t// Loading manager for progress tracking\n\tprivate loadingManager: LoadingManager;\n\n\t// Event emitter\n\tprivate events: Emitter<AssetManagerEvents>;\n\n\t// Stats\n\tprivate stats = {\n\t\ttexturesLoaded: 0,\n\t\tmodelsLoaded: 0,\n\t\taudioLoaded: 0,\n\t\tfilesLoaded: 0,\n\t\tcacheHits: 0,\n\t\tcacheMisses: 0\n\t};\n\n\tprivate constructor() {\n\t\t// Initialize loaders\n\t\tthis.textureLoader = new TextureLoaderAdapter();\n\t\tthis.gltfLoader = new GLTFLoaderAdapter();\n\t\tthis.fbxLoader = new FBXLoaderAdapter();\n\t\tthis.objLoader = new OBJLoaderAdapter();\n\t\tthis.audioLoader = new AudioLoaderAdapter();\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t\tthis.jsonLoader = new JsonLoaderAdapter();\n\n\t\t// Initialize loading manager\n\t\tthis.loadingManager = new LoadingManager();\n\t\tthis.loadingManager.onProgress = (url, loaded, total) => {\n\t\t\tthis.events.emit('batch:progress', { loaded, total });\n\t\t};\n\n\t\t// Initialize event emitter\n\t\tthis.events = mitt<AssetManagerEvents>();\n\n\t\t// Enable Three.js built-in cache\n\t\tCache.enabled = true;\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tstatic getInstance(): AssetManager {\n\t\tif (!AssetManager.instance) {\n\t\t\tAssetManager.instance = new AssetManager();\n\t\t}\n\t\treturn AssetManager.instance;\n\t}\n\n\t/**\n\t * Reset the singleton (useful for testing)\n\t */\n\tstatic resetInstance(): void {\n\t\tif (AssetManager.instance) {\n\t\t\tAssetManager.instance.clearCache();\n\t\t\tAssetManager.instance = null;\n\t\t}\n\t}\n\n\t// ==================== TEXTURE LOADING ====================\n\n\t/**\n\t * Load a texture with caching\n\t */\n\tasync loadTexture(url: string, options?: TextureOptions): Promise<Texture> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.TEXTURE,\n\t\t\tthis.textureCache,\n\t\t\t() => this.textureLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(texture) => options?.clone ? this.textureLoader.clone(texture) : texture\n\t\t);\n\t}\n\n\t// ==================== MODEL LOADING ====================\n\n\t/**\n\t * Load a GLTF/GLB model with caching\n\t */\n\tasync loadGLTF(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.GLTF,\n\t\t\tthis.modelCache,\n\t\t\t() => this.gltfLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.gltfLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an FBX model with caching\n\t */\n\tasync loadFBX(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.FBX,\n\t\t\tthis.modelCache,\n\t\t\t() => this.fbxLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.fbxLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an OBJ model with caching\n\t */\n\tasync loadOBJ(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Include mtlPath in cache key for OBJ files\n\t\tconst cacheKey = options?.mtlPath ? `${url}:${options.mtlPath}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.OBJ,\n\t\t\tthis.modelCache,\n\t\t\t() => this.objLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.objLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Auto-detect model type and load\n\t */\n\tasync loadModel(url: string, options?: AssetLoadOptions): Promise<ModelLoadResult> {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\t\n\t\tswitch (ext) {\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb':\n\t\t\t\treturn this.loadGLTF(url, options);\n\t\t\tcase 'fbx':\n\t\t\t\treturn this.loadFBX(url, options);\n\t\t\tcase 'obj':\n\t\t\t\treturn this.loadOBJ(url, options);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported model format: ${ext}`);\n\t\t}\n\t}\n\n\t// ==================== AUDIO LOADING ====================\n\n\t/**\n\t * Load an audio buffer with caching\n\t */\n\tasync loadAudio(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.AUDIO,\n\t\t\tthis.audioCache,\n\t\t\t() => this.audioLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t// ==================== FILE LOADING ====================\n\n\t/**\n\t * Load a raw file with caching\n\t */\n\tasync loadFile(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst cacheKey = options?.responseType ? `${url}:${options.responseType}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.FILE,\n\t\t\tthis.fileCache,\n\t\t\t() => this.fileLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Load a JSON file with caching\n\t */\n\tasync loadJSON<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.JSON,\n\t\t\tthis.jsonCache,\n\t\t\t() => this.jsonLoader.load<T>(url, options),\n\t\t\toptions\n\t\t) as Promise<T>;\n\t}\n\n\t// ==================== BATCH LOADING ====================\n\n\t/**\n\t * Load multiple assets in parallel\n\t */\n\tasync loadBatch(items: BatchLoadItem[]): Promise<Map<string, any>> {\n\t\tconst results = new Map<string, any>();\n\t\t\n\t\tconst promises = items.map(async (item) => {\n\t\t\ttry {\n\t\t\t\tlet result: any;\n\t\t\t\t\n\t\t\t\tswitch (item.type) {\n\t\t\t\t\tcase AssetType.TEXTURE:\n\t\t\t\t\t\tresult = await this.loadTexture(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.GLTF:\n\t\t\t\t\t\tresult = await this.loadGLTF(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FBX:\n\t\t\t\t\t\tresult = await this.loadFBX(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.OBJ:\n\t\t\t\t\t\tresult = await this.loadOBJ(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.AUDIO:\n\t\t\t\t\t\tresult = await this.loadAudio(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FILE:\n\t\t\t\t\t\tresult = await this.loadFile(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.JSON:\n\t\t\t\t\t\tresult = await this.loadJSON(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`Unknown asset type: ${item.type}`);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tresults.set(item.url, result);\n\t\t\t} catch (error) {\n\t\t\t\tthis.events.emit('asset:error', {\n\t\t\t\t\turl: item.url,\n\t\t\t\t\ttype: item.type,\n\t\t\t\t\terror: error as Error\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.all(promises);\n\t\t\n\t\tthis.events.emit('batch:complete', { urls: items.map(i => i.url) });\n\t\t\n\t\treturn results;\n\t}\n\n\t/**\n\t * Preload assets without returning results\n\t */\n\tasync preload(items: BatchLoadItem[]): Promise<void> {\n\t\tawait this.loadBatch(items);\n\t}\n\n\t// ==================== CACHE MANAGEMENT ====================\n\n\t/**\n\t * Check if an asset is cached\n\t */\n\tisCached(url: string): boolean {\n\t\treturn this.textureCache.has(url) ||\n\t\t\tthis.modelCache.has(url) ||\n\t\t\tthis.audioCache.has(url) ||\n\t\t\tthis.fileCache.has(url) ||\n\t\t\tthis.jsonCache.has(url);\n\t}\n\n\t/**\n\t * Clear all caches or a specific URL\n\t */\n\tclearCache(url?: string): void {\n\t\tif (url) {\n\t\t\tthis.textureCache.delete(url);\n\t\t\tthis.modelCache.delete(url);\n\t\t\tthis.audioCache.delete(url);\n\t\t\tthis.fileCache.delete(url);\n\t\t\tthis.jsonCache.delete(url);\n\t\t} else {\n\t\t\tthis.textureCache.clear();\n\t\t\tthis.modelCache.clear();\n\t\t\tthis.audioCache.clear();\n\t\t\tthis.fileCache.clear();\n\t\t\tthis.jsonCache.clear();\n\t\t\tCache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetStats(): typeof this.stats {\n\t\treturn { ...this.stats };\n\t}\n\n\t// ==================== EVENTS ====================\n\n\t/**\n\t * Subscribe to asset manager events\n\t */\n\ton<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.on(event, handler);\n\t}\n\n\t/**\n\t * Unsubscribe from asset manager events\n\t */\n\toff<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.off(event, handler);\n\t}\n\n\t// ==================== PRIVATE HELPERS ====================\n\n\t/**\n\t * Generic cache wrapper for loading assets\n\t */\n\tprivate async loadWithCache<T>(\n\t\turl: string,\n\t\ttype: AssetType,\n\t\tcache: Map<string, CacheEntry<T>>,\n\t\tloader: () => Promise<T>,\n\t\toptions?: AssetLoadOptions,\n\t\tcloner?: (result: T) => T\n\t): Promise<T> {\n\t\t// Check for force reload\n\t\tif (options?.forceReload) {\n\t\t\tcache.delete(url);\n\t\t}\n\n\t\t// Check cache\n\t\tconst cached = cache.get(url);\n\t\tif (cached) {\n\t\t\tthis.stats.cacheHits++;\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: true });\n\t\t\t\n\t\t\tconst result = await cached.promise;\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t}\n\n\t\t// Cache miss - start loading\n\t\tthis.stats.cacheMisses++;\n\t\tthis.events.emit('asset:loading', { url, type });\n\n\t\tconst promise = loader();\n\t\tconst entry: CacheEntry<T> = {\n\t\t\tpromise,\n\t\t\tloadedAt: Date.now()\n\t\t};\n\t\tcache.set(url, entry);\n\n\t\ttry {\n\t\t\tconst result = await promise;\n\t\t\tentry.result = result;\n\t\t\t\n\t\t\t// Update stats\n\t\t\tthis.updateStats(type);\n\t\t\t\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: false });\n\t\t\t\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t} catch (error) {\n\t\t\t// Remove failed entry from cache\n\t\t\tcache.delete(url);\n\t\t\tthis.events.emit('asset:error', { url, type, error: error as Error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate updateStats(type: AssetType): void {\n\t\tswitch (type) {\n\t\t\tcase AssetType.TEXTURE:\n\t\t\t\tthis.stats.texturesLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.GLTF:\n\t\t\tcase AssetType.FBX:\n\t\t\tcase AssetType.OBJ:\n\t\t\t\tthis.stats.modelsLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.AUDIO:\n\t\t\t\tthis.stats.audioLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.FILE:\n\t\t\tcase AssetType.JSON:\n\t\t\t\tthis.stats.filesLoaded++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Singleton instance export for convenience\n */\nexport const assetManager = AssetManager.getInstance();","import {\n\tColor,\n\tMaterial,\n\tMeshPhongMaterial,\n\tMeshStandardMaterial,\n\tNormalBlending,\n\tRepeatWrapping,\n\tShaderMaterial,\n\tVector2,\n\tVector3\n} from 'three';\nimport { shortHash, sortedStringify } from '../core/utility/strings';\nimport { standardShader } from './shaders/standard.shader';\nimport { assetManager } from '../core/asset-manager';\n\nexport type ZylemShaderObject = { fragment: string, vertex: string };\n\nexport interface MaterialOptions {\n\tpath?: string;\n\trepeat?: Vector2;\n\tshader?: ZylemShaderObject;\n\tcolor?: Color;\n}\n\ntype BatchGeometryMap = Map<symbol, number>;\n\ninterface BatchMaterialMapObject {\n\tgeometryMap: BatchGeometryMap;\n\tmaterial: Material;\n};\n\ntype BatchKey = ReturnType<typeof shortHash>;\n\nexport type TexturePath = string | null;\n\nexport class MaterialBuilder {\n\tstatic batchMaterialMap: Map<BatchKey, BatchMaterialMapObject> = new Map();\n\n\tmaterials: Material[] = [];\n\n\tbatchMaterial(options: Partial<MaterialOptions>, entityType: symbol) {\n\t\tconst batchKey = shortHash(sortedStringify(options));\n\t\tconst mappedObject = MaterialBuilder.batchMaterialMap.get(batchKey);\n\t\tif (mappedObject) {\n\t\t\tconst count = mappedObject.geometryMap.get(entityType);\n\t\t\tif (count) {\n\t\t\t\tmappedObject.geometryMap.set(entityType, count + 1);\n\t\t\t} else {\n\t\t\t\tmappedObject.geometryMap.set(entityType, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tMaterialBuilder.batchMaterialMap.set(\n\t\t\t\tbatchKey, {\n\t\t\t\tgeometryMap: new Map([[entityType, 1]]),\n\t\t\t\tmaterial: this.materials[0]\n\t\t\t});\n\t\t}\n\t}\n\n\tbuild(options: Partial<MaterialOptions>, entityType: symbol): void {\n\t\tconst { path, repeat, color, shader } = options;\n\t\t// If shader is provided, use it; otherwise execute standard logic\n\t\tif (shader) {\n\t\t\tthis.withShader(shader);\n\t\t} else if (path) {\n\t\t\t// If path provided but no shader, standard texture logic applies\n\t\t\tthis.setTexture(path, repeat);\n\t\t}\n\t\t\n\t\tif (color) {\n\t\t\t// standard color material if no custom shader\n\t\t\tthis.withColor(color);\n\t\t}\n\n\t\tif (this.materials.length === 0) {\n\t\t\tthis.setColor(new Color('#ffffff'));\n\t\t}\n\t\tthis.batchMaterial(options, entityType);\n\t}\n\n\twithColor(color: Color): this {\n\t\tthis.setColor(color);\n\t\treturn this;\n\t}\n\n\twithShader(shader: ZylemShaderObject): this {\n\t\tthis.setShader(shader);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set texture - loads in background (deferred).\n\t * Material is created immediately with null map, texture applies when loaded.\n\t */\n\tsetTexture(texturePath: TexturePath = null, repeat: Vector2 = new Vector2(1, 1)): void {\n\t\tif (!texturePath) {\n\t\t\treturn;\n\t\t}\n\t\t// Create material immediately with null map\n\t\tconst material = new MeshPhongMaterial({\n\t\t\tmap: null,\n\t\t});\n\t\tthis.materials.push(material);\n\n\t\t// Load texture in background and apply when ready\n\t\tassetManager.loadTexture(texturePath as string, { \n\t\t\tclone: true,\n\t\t\trepeat \n\t\t}).then(texture => {\n\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\tmaterial.map = texture;\n\t\t\tmaterial.needsUpdate = true;\n\t\t});\n\t}\n\n\tsetColor(color: Color) {\n\t\tconst material = new MeshStandardMaterial({\n\t\t\tcolor: color,\n\t\t\temissiveIntensity: 0.5,\n\t\t\tlightMapIntensity: 0.5,\n\t\t\tfog: true,\n\t\t});\n\n\t\tthis.materials.push(material);\n\t}\n\n\tsetShader(customShader: ZylemShaderObject) {\n\t\tconst { fragment, vertex } = customShader ?? standardShader;\n\n\t\tconst shader = new ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiResolution: { value: new Vector3(1, 1, 1) },\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null }\n\t\t\t},\n\t\t\tvertexShader: vertex,\n\t\t\tfragmentShader: fragment,\n\t\t\ttransparent: true,\n\t\t\t// blending: NormalBlending\n\t\t});\n\t\tthis.materials.push(shader);\n\t}\n}\n","import { ColliderDesc } from \"@dimforge/rapier3d-compat\";\nimport { GameEntity, GameEntityOptions } from \"./entity\";\nimport { BufferGeometry, Group, Material, Mesh, Color } from \"three\";\nimport { CollisionBuilder } from \"../collision/collision-builder\";\nimport { MeshBuilder } from \"../graphics/mesh\";\nimport { MaterialBuilder, MaterialOptions } from \"../graphics/material\";\nimport { Vec3 } from \"../core/vector\";\n\nexport abstract class EntityCollisionBuilder extends CollisionBuilder {\n\tabstract collider(options: GameEntityOptions): ColliderDesc;\n}\n\nexport abstract class EntityMeshBuilder extends MeshBuilder {\n\tbuild(options: GameEntityOptions): BufferGeometry {\n\t\treturn new BufferGeometry();\n\t}\n\n\tpostBuild(): void {\n\t\treturn;\n\t}\n}\n\nexport abstract class EntityBuilder<T extends GameEntity<U> & P, U extends GameEntityOptions, P = any> {\n\tprotected meshBuilder: EntityMeshBuilder | null;\n\tprotected collisionBuilder: EntityCollisionBuilder | null;\n\tprotected materialBuilder: MaterialBuilder | null;\n\tprotected options: Partial<U>;\n\tprotected entity: T;\n\n\tconstructor(\n\t\toptions: Partial<U>,\n\t\tentity: T,\n\t\tmeshBuilder: EntityMeshBuilder | null,\n\t\tcollisionBuilder: EntityCollisionBuilder | null,\n\t) {\n\t\tthis.options = options;\n\t\tthis.entity = entity;\n\t\tthis.meshBuilder = meshBuilder;\n\t\tthis.collisionBuilder = collisionBuilder;\n\t\tthis.materialBuilder = new MaterialBuilder();\n\t\tconst builders: NonNullable<GameEntityOptions[\"_builders\"]> = {\n\t\t\tmeshBuilder: this.meshBuilder,\n\t\t\tcollisionBuilder: this.collisionBuilder,\n\t\t\tmaterialBuilder: this.materialBuilder,\n\t\t};\n\t\t(this.options as Partial<GameEntityOptions>)._builders = builders;\n\t}\n\n\twithPosition(setupPosition: Vec3): this {\n\t\tthis.options.position = setupPosition;\n\t\treturn this;\n\t}\n\n\twithMaterial(options: Partial<MaterialOptions>, entityType: symbol): this {\n\t\tif (this.materialBuilder) {\n\t\t\tthis.materialBuilder.build(options, entityType);\n\t\t}\n\t\treturn this;\n\t}\n\n\tapplyMaterialToGroup(group: Group, materials: Material[]): void {\n\t\tgroup.traverse((child) => {\n\t\t\tif (child instanceof Mesh) {\n\t\t\t\tif (child.type === 'SkinnedMesh' && materials[0] && !child.material.map) {\n\t\t\t\t\tchild.material = materials[0];\n\t\t\t\t}\n\t\t\t}\n\t\t\tchild.castShadow = true;\n\t\t\tchild.receiveShadow = true;\n\t\t});\n\t}\n\n\tbuild(): T {\n\t\tconst entity = this.entity;\n\t\tif (this.materialBuilder) {\n\t\t\tentity.materials = this.materialBuilder.materials;\n\t\t}\n\t\tif (this.meshBuilder && entity.materials) {\n\t\t\tconst geometry = this.meshBuilder.build(this.options);\n\t\t\tentity.mesh = this.meshBuilder._build(this.options, geometry, entity.materials);\n\t\t\tthis.meshBuilder.postBuild();\n\t\t}\n\n\t\tif (entity.group && entity.materials) {\n\t\t\tthis.applyMaterialToGroup(entity.group, entity.materials);\n\t\t}\n\n\t\tif (this.collisionBuilder) {\n\t\t\tthis.collisionBuilder.withCollision(this.options?.collision || {});\n\t\t\tconst [bodyDesc, colliderDesc] = this.collisionBuilder.build(this.options as any);\n\t\t\tentity.bodyDesc = bodyDesc;\n\t\t\tentity.colliderDesc = colliderDesc;\n\n\t\t\tconst { x, y, z } = this.options.position || { x: 0, y: 0, z: 0 };\n\t\t\tentity.bodyDesc.setTranslation(x, y, z);\n\t\t}\n\t\tif (this.options.collisionType) {\n\t\t\tentity.collisionType = this.options.collisionType;\n\t\t}\n\n\t\tif (this.options.color instanceof Color) {\n\t\t\tconst applyColor = (material: Material) => {\n\t\t\t\tconst anyMat = material as any;\n\t\t\t\tif (anyMat && anyMat.color && anyMat.color.set) {\n\t\t\t\t\tanyMat.color.set(this.options.color as Color);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (entity.materials?.length) {\n\t\t\t\tfor (const mat of entity.materials) applyColor(mat);\n\t\t\t}\n\t\t\tif (entity.mesh && entity.mesh.material) {\n\t\t\t\tconst mat = entity.mesh.material as any;\n\t\t\t\tif (Array.isArray(mat)) mat.forEach(applyColor); else applyColor(mat);\n\t\t\t}\n\t\t\tif (entity.group) {\n\t\t\t\tentity.group.traverse((child) => {\n\t\t\t\t\tif (child instanceof Mesh && child.material) {\n\t\t\t\t\t\tconst mat = child.material as any;\n\t\t\t\t\t\tif (Array.isArray(mat)) mat.forEach(applyColor); else applyColor(mat);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn entity;\n\t}\n\n\tprotected abstract createEntity(options: Partial<U>): T;\n}","import { GameEntity, GameEntityOptions } from '../entity';\nimport { MeshStandardMaterial, MeshBasicMaterial, MeshPhongMaterial } from 'three';\n\n/**\n * Interface for entities that provide custom debug information\n */\nexport interface DebugInfoProvider {\n\tgetDebugInfo(): Record<string, any>;\n}\n\n/**\n * Helper to check if an object implements DebugInfoProvider\n */\nfunction hasDebugInfo(obj: any): obj is DebugInfoProvider {\n\treturn obj && typeof obj.getDebugInfo === 'function';\n}\n\n/**\n * Debug delegate that provides debug information for entities\n */\nexport class DebugDelegate {\n\tprivate entity: GameEntity<any>;\n\n\tconstructor(entity: GameEntity<any>) {\n\t\tthis.entity = entity;\n\t}\n\n\t/**\n\t * Get formatted position string\n\t */\n\tprivate getPositionString(): string {\n\t\tif (this.entity.mesh) {\n\t\t\tconst { x, y, z } = this.entity.mesh.position;\n\t\t\treturn `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`;\n\t\t}\n\t\tconst { x, y, z } = this.entity.options.position || { x: 0, y: 0, z: 0 };\n\t\treturn `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`;\n\t}\n\n\t/**\n\t * Get formatted rotation string (in degrees)\n\t */\n\tprivate getRotationString(): string {\n\t\tif (this.entity.mesh) {\n\t\t\tconst { x, y, z } = this.entity.mesh.rotation;\n\t\t\tconst toDeg = (rad: number) => (rad * 180 / Math.PI).toFixed(1);\n\t\t\treturn `${toDeg(x)}°, ${toDeg(y)}°, ${toDeg(z)}°`;\n\t\t}\n\t\tconst { x, y, z } = this.entity.options.rotation || { x: 0, y: 0, z: 0 };\n\t\tconst toDeg = (rad: number) => (rad * 180 / Math.PI).toFixed(1);\n\t\treturn `${toDeg(x)}°, ${toDeg(y)}°, ${toDeg(z)}°`;\n\t}\n\n\t/**\n\t * Get material information\n\t */\n\tprivate getMaterialInfo(): Record<string, any> {\n\t\tif (!this.entity.mesh || !this.entity.mesh.material) {\n\t\t\treturn { type: 'none' };\n\t\t}\n\n\t\tconst material = Array.isArray(this.entity.mesh.material)\n\t\t\t? this.entity.mesh.material[0]\n\t\t\t: this.entity.mesh.material;\n\n\t\tconst info: Record<string, any> = {\n\t\t\ttype: material.type\n\t\t};\n\n\t\tif (material instanceof MeshStandardMaterial ||\n\t\t\tmaterial instanceof MeshBasicMaterial ||\n\t\t\tmaterial instanceof MeshPhongMaterial) {\n\t\t\tinfo.color = `#${material.color.getHexString()}`;\n\t\t\tinfo.opacity = material.opacity;\n\t\t\tinfo.transparent = material.transparent;\n\t\t}\n\n\t\tif ('roughness' in material) {\n\t\t\tinfo.roughness = material.roughness;\n\t\t}\n\n\t\tif ('metalness' in material) {\n\t\t\tinfo.metalness = material.metalness;\n\t\t}\n\n\t\treturn info;\n\t}\n\n\tprivate getPhysicsInfo(): Record<string, any> | null {\n\t\tif (!this.entity.body) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst info: Record<string, any> = {\n\t\t\ttype: this.entity.body.bodyType(),\n\t\t\tmass: this.entity.body.mass(),\n\t\t\tisEnabled: this.entity.body.isEnabled(),\n\t\t\tisSleeping: this.entity.body.isSleeping()\n\t\t};\n\n\t\tconst velocity = this.entity.body.linvel();\n\t\tinfo.velocity = `${velocity.x.toFixed(2)}, ${velocity.y.toFixed(2)}, ${velocity.z.toFixed(2)}`;\n\n\t\treturn info;\n\t}\n\n\tpublic buildDebugInfo(): Record<string, any> {\n\t\tconst defaultInfo: Record<string, any> = {\n\t\t\tname: this.entity.name || this.entity.uuid,\n\t\t\tuuid: this.entity.uuid,\n\t\t\tposition: this.getPositionString(),\n\t\t\trotation: this.getRotationString(),\n\t\t\tmaterial: this.getMaterialInfo()\n\t\t};\n\n\t\tconst physicsInfo = this.getPhysicsInfo();\n\t\tif (physicsInfo) {\n\t\t\tdefaultInfo.physics = physicsInfo;\n\t\t}\n\n\t\tif (this.entity.behaviors.length > 0) {\n\t\t\tdefaultInfo.behaviors = this.entity.behaviors.map(b => b.constructor.name);\n\t\t}\n\n\t\tif (hasDebugInfo(this.entity)) {\n\t\t\tconst customInfo = this.entity.getDebugInfo();\n\t\t\treturn { ...defaultInfo, ...customInfo };\n\t\t}\n\n\t\treturn defaultInfo;\n\t}\n}\n\nclass EnhancedDebugInfoBuilder {\n\tprivate customBuilder?: (options: GameEntityOptions) => Record<string, any>;\n\n\tconstructor(customBuilder?: (options: GameEntityOptions) => Record<string, any>) {\n\t\tthis.customBuilder = customBuilder;\n\t}\n\n\tbuildInfo(options: GameEntityOptions, entity?: GameEntity<any>): Record<string, any> {\n\t\tif (this.customBuilder) {\n\t\t\treturn this.customBuilder(options);\n\t\t}\n\n\t\tif (entity) {\n\t\t\tconst delegate = new DebugDelegate(entity);\n\t\t\treturn delegate.buildDebugInfo();\n\t\t}\n\n\t\tconst { x, y, z } = options.position || { x: 0, y: 0, z: 0 };\n\t\treturn {\n\t\t\tname: (options as any).name || 'unnamed',\n\t\t\tposition: `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`\n\t\t};\n\t}\n}\n","// this class is not for asset loading, it is for loading entity specific data\n// this is to keep the entity class focused purely on entity logic\n\nexport function isLoadable(obj: any): obj is EntityLoaderDelegate {\n\treturn typeof obj?.load === \"function\" && typeof obj?.data === \"function\";\n}\n\nexport interface EntityLoaderDelegate {\n\t/** Initiates loading (may be async internally, but call returns immediately) */\n\tload(): void;\n\t/** Returns data synchronously (may be null if still loading) */\n\tdata(): any;\n}\n\nexport class EntityLoader {\n\tentityReference: EntityLoaderDelegate;\n\n\tconstructor(entity: EntityLoaderDelegate) {\n\t\tthis.entityReference = entity;\n\t}\n\n\tload(): void {\n\t\tif (this.entityReference.load) {\n\t\t\tthis.entityReference.load();\n\t\t}\n\t}\n\n\tdata(): any {\n\t\tif (this.entityReference.data) {\n\t\t\treturn this.entityReference.data();\n\t\t}\n\t\treturn null;\n\t}\n}","import { GameEntityOptions, GameEntity } from \"./entity\";\nimport { BaseNode } from \"../core/base-node\";\nimport { EntityBuilder } from \"./builder\";\nimport { EntityCollisionBuilder } from \"./builder\";\nimport { EntityMeshBuilder } from \"./builder\";\nimport { EntityLoader, isLoadable } from \"./delegates/loader\";\n\nexport interface CreateGameEntityOptions<T extends GameEntity<any>, CreateOptions extends GameEntityOptions> {\n\targs: Array<any>;\n\tdefaultConfig: GameEntityOptions;\n\tEntityClass: new (options: any) => T;\n\tBuilderClass: new (options: any, entity: T, meshBuilder: any, collisionBuilder: any) => EntityBuilder<T, CreateOptions>;\n\tMeshBuilderClass?: new (data: any) => EntityMeshBuilder;\n\tCollisionBuilderClass?: new (data: any) => EntityCollisionBuilder;\n\tentityType: symbol;\n};\n\nexport function createEntity<T extends GameEntity<any>, CreateOptions extends GameEntityOptions>(params: CreateGameEntityOptions<T, CreateOptions>): T {\n\tconst {\n\t\targs,\n\t\tdefaultConfig,\n\t\tEntityClass,\n\t\tBuilderClass,\n\t\tentityType,\n\t\tMeshBuilderClass,\n\t\tCollisionBuilderClass,\n\t} = params;\n\n\tlet builder: EntityBuilder<T, CreateOptions> | null = null;\n\tlet configuration;\n\n\tconst configurationIndex = args.findIndex(node => !(node instanceof BaseNode));\n\tif (configurationIndex !== -1) {\n\t\tconst subArgs = args.splice(configurationIndex, 1);\n\t\tconfiguration = subArgs.find(node => !(node instanceof BaseNode));\n\t}\n\n\tconst mergedConfiguration = configuration ? { ...defaultConfig, ...configuration } : defaultConfig;\n\targs.push(mergedConfiguration);\n\n\tfor (const arg of args) {\n\t\tif (arg instanceof BaseNode) {\n\t\t\tcontinue;\n\t\t}\n\t\tlet entityData = null;\n\t\tconst entity = new EntityClass(arg);\n\t\ttry {\n\t\t\tif (isLoadable(entity)) {\n\t\t\t\tconst loader = new EntityLoader(entity);\n\t\t\t\tloader.load();\n\t\t\t\tentityData = loader.data();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error creating entity with loader:\", error);\n\t\t}\n\t\tbuilder = new BuilderClass(\n\t\t\targ,\n\t\t\tentity,\n\t\t\tMeshBuilderClass ? new MeshBuilderClass(entityData) : null,\n\t\t\tCollisionBuilderClass ? new CollisionBuilderClass(entityData) : null,\n\t\t);\n\t\tif (arg.material) {\n\t\t\tbuilder.withMaterial(arg.material, entityType);\n\t\t}\n\t}\n\n\tif (!builder) {\n\t\tthrow new Error(`missing options for ${String(entityType)}, builder is not initialized.`);\n\t}\n\n\treturn builder.build();\n}\n\n","import { Color, Vector3 } from 'three';\nimport { standardShader } from '../graphics/shaders/standard.shader';\nimport { GameEntityOptions } from './entity';\n\nexport const commonDefaults: Partial<GameEntityOptions> = {\n position: new Vector3(0, 0, 0),\n material: {\n color: new Color('#ffffff'),\n shader: standardShader\n },\n collision: {\n static: false,\n },\n};\n","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BoxGeometry, Color } from 'three';\nimport { Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { EntityMeshBuilder } from './builder';\nimport { DebugDelegate } from './delegates/debug';\nimport { createEntity } from './create';\n\ntype ZylemBoxOptions = GameEntityOptions;\n\nimport { commonDefaults } from './common';\n\nconst boxDefaults: ZylemBoxOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n};\n\nexport class BoxCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: GameEntityOptions): ColliderDesc {\n\t\tconst size = options.size || new Vector3(1, 1, 1);\n\t\tconst half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };\n\t\tlet colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class BoxMeshBuilder extends EntityMeshBuilder {\n\tbuild(options: GameEntityOptions): BoxGeometry {\n\t\tconst size = options.size ?? new Vector3(1, 1, 1);\n\t\treturn new BoxGeometry(size.x, size.y, size.z);\n\t}\n}\n\nexport class BoxBuilder extends EntityBuilder<ZylemBox, ZylemBoxOptions> {\n\tprotected createEntity(options: Partial<ZylemBoxOptions>): ZylemBox {\n\t\treturn new ZylemBox(options);\n\t}\n}\n\nexport const BOX_TYPE = Symbol('Box');\n\nexport class ZylemBox extends GameEntity<ZylemBoxOptions> {\n\tstatic type = BOX_TYPE;\n\n\tconstructor(options?: ZylemBoxOptions) {\n\t\tsuper();\n\t\tthis.options = { ...boxDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\tconst { x: sizeX, y: sizeY, z: sizeZ } = this.options.size ?? { x: 1, y: 1, z: 1 };\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemBox.type),\n\t\t\tsize: `${sizeX}, ${sizeY}, ${sizeZ}`,\n\t\t};\n\t}\n}\n\ntype BoxOptions = BaseNode | ZylemBoxOptions;\n\nexport function createBox(...args: Array<BoxOptions>): ZylemBox {\n\treturn createEntity<ZylemBox, ZylemBoxOptions>({\n\t\targs,\n\t\tdefaultConfig: boxDefaults,\n\t\tEntityClass: ZylemBox,\n\t\tBuilderClass: BoxBuilder,\n\t\tMeshBuilderClass: BoxMeshBuilder,\n\t\tCollisionBuilderClass: BoxCollisionBuilder,\n\t\tentityType: ZylemBox.type\n\t});\n}","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { Color, SphereGeometry } from 'three';\nimport { Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { EntityMeshBuilder } from './builder';\nimport { DebugDelegate } from './delegates/debug';\nimport { standardShader } from '../graphics/shaders/standard.shader';\nimport { createEntity } from './create';\n\ntype ZylemSphereOptions = GameEntityOptions & {\n\tradius?: number;\n};\n\nimport { commonDefaults } from './common';\n\nconst sphereDefaults: ZylemSphereOptions = {\n\t...commonDefaults,\n\tradius: 1,\n};\n\nexport class SphereCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemSphereOptions): ColliderDesc {\n\t\tconst radius = options.radius ?? 1;\n\t\tlet colliderDesc = ColliderDesc.ball(radius);\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class SphereMeshBuilder extends EntityMeshBuilder {\n\tbuild(options: ZylemSphereOptions): SphereGeometry {\n\t\tconst radius = options.radius ?? 1;\n\t\treturn new SphereGeometry(radius);\n\t}\n}\n\nexport class SphereBuilder extends EntityBuilder<ZylemSphere, ZylemSphereOptions> {\n\tprotected createEntity(options: Partial<ZylemSphereOptions>): ZylemSphere {\n\t\treturn new ZylemSphere(options);\n\t}\n}\n\nexport const SPHERE_TYPE = Symbol('Sphere');\n\nexport class ZylemSphere extends GameEntity<ZylemSphereOptions> {\n\tstatic type = SPHERE_TYPE;\n\n\tconstructor(options?: ZylemSphereOptions) {\n\t\tsuper();\n\t\tthis.options = { ...sphereDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 1;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemSphere.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t};\n\t}\n}\n\ntype SphereOptions = BaseNode | Partial<ZylemSphereOptions>;\n\nexport function createSphere(...args: Array<SphereOptions>): ZylemSphere {\n\treturn createEntity<ZylemSphere, ZylemSphereOptions>({\n\t\targs,\n\t\tdefaultConfig: sphereDefaults,\n\t\tEntityClass: ZylemSphere,\n\t\tBuilderClass: SphereBuilder,\n\t\tMeshBuilderClass: SphereMeshBuilder,\n\t\tCollisionBuilderClass: SphereCollisionBuilder,\n\t\tentityType: ZylemSphere.type\n\t});\n}","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { Color, Euler, Group, Quaternion, Vector3 } from 'three';\nimport {\n\tTextureLoader,\n\tSpriteMaterial,\n\tSprite as ThreeSprite,\n} from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { createEntity } from './create';\nimport { DestroyContext, DestroyFunction, UpdateContext, UpdateFunction } from '../core/base-node-life-cycle';\nimport { DebugDelegate } from './delegates/debug';\nimport { standardShader } from '../graphics/shaders/standard.shader';\n\nexport type SpriteImage = { name: string; file: string };\nexport type SpriteAnimation = {\n\tname: string;\n\tframes: string[];\n\tspeed: number | number[];\n\tloop: boolean;\n};\n\ntype ZylemSpriteOptions = GameEntityOptions & {\n\timages?: SpriteImage[];\n\tanimations?: SpriteAnimation[];\n\tsize?: Vector3;\n\tcollisionSize?: Vector3;\n};\n\nimport { commonDefaults } from './common';\n\nconst spriteDefaults: ZylemSpriteOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n\timages: [],\n\tanimations: [],\n};\n\nexport class SpriteCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemSpriteOptions): ColliderDesc {\n\t\tconst size = options.collisionSize || options.size || new Vector3(1, 1, 1);\n\t\tconst half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };\n\t\tlet colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class SpriteBuilder extends EntityBuilder<ZylemSprite, ZylemSpriteOptions> {\n\tprotected createEntity(options: Partial<ZylemSpriteOptions>): ZylemSprite {\n\t\treturn new ZylemSprite(options);\n\t}\n}\n\nexport const SPRITE_TYPE = Symbol('Sprite');\n\nexport class ZylemSprite extends GameEntity<ZylemSpriteOptions> {\n\tstatic type = SPRITE_TYPE;\n\n\tprotected sprites: ThreeSprite[] = [];\n\tprotected spriteMap: Map<string, number> = new Map();\n\tprotected currentSpriteIndex: number = 0;\n\tprotected animations: Map<string, any> = new Map();\n\tprotected currentAnimation: any = null;\n\tprotected currentAnimationFrame: string = '';\n\tprotected currentAnimationIndex: number = 0;\n\tprotected currentAnimationTime: number = 0;\n\n\tconstructor(options?: ZylemSpriteOptions) {\n\t\tsuper();\n\t\tthis.options = { ...spriteDefaults, ...options };\n\t\t// Add sprite-specific lifecycle callbacks (only registered once)\n\t\tthis.prependUpdate(this.spriteUpdate.bind(this) as any);\n\t\tthis.onDestroy(this.spriteDestroy.bind(this) as any);\n\t}\n\n\tpublic create(): this {\n\t\t// Clear previous state to prevent accumulation on reload\n\t\tthis.sprites = [];\n\t\tthis.spriteMap.clear();\n\t\tthis.animations.clear();\n\t\tthis.currentAnimation = null;\n\t\tthis.currentAnimationFrame = '';\n\t\tthis.currentAnimationIndex = 0;\n\t\tthis.currentAnimationTime = 0;\n\t\tthis.group = undefined;\n\t\t\n\t\t// Recreate sprites and animations\n\t\tthis.createSpritesFromImages(this.options?.images || []);\n\t\tthis.createAnimations(this.options?.animations || []);\n\t\t\n\t\t// Call parent create\n\t\treturn super.create();\n\t}\n\n\tprotected createSpritesFromImages(images: SpriteImage[]) {\n\t\t// Use synchronous load() which returns a texture that updates when ready\n\t\t// This maintains compatibility with the synchronous create() method\n\t\tconst textureLoader = new TextureLoader();\n\t\timages.forEach((image, index) => {\n\t\t\tconst spriteMap = textureLoader.load(image.file);\n\t\t\tconst material = new SpriteMaterial({\n\t\t\t\tmap: spriteMap,\n\t\t\t\ttransparent: true,\n\t\t\t});\n\t\t\tconst _sprite = new ThreeSprite(material);\n\t\t\t_sprite.position.normalize();\n\t\t\tthis.sprites.push(_sprite);\n\t\t\tthis.spriteMap.set(image.name, index);\n\t\t});\n\t\tthis.group = new Group();\n\t\tthis.group.add(...this.sprites);\n\t}\n\n\tprotected createAnimations(animations: SpriteAnimation[]) {\n\t\tanimations.forEach(animation => {\n\t\t\tconst { name, frames, loop = false, speed = 1 } = animation;\n\t\t\tconst internalAnimation = {\n\t\t\t\tframes: frames.map((frame, index) => ({\n\t\t\t\t\tkey: frame,\n\t\t\t\t\tindex,\n\t\t\t\t\ttime: (typeof speed === 'number' ? speed : speed[index]) * (index + 1),\n\t\t\t\t\tduration: typeof speed === 'number' ? speed : speed[index]\n\t\t\t\t})),\n\t\t\t\tloop,\n\t\t\t};\n\t\t\tthis.animations.set(name, internalAnimation);\n\t\t});\n\t}\n\n\tsetSprite(key: string) {\n\t\tconst spriteIndex = this.spriteMap.get(key);\n\t\tconst useIndex = spriteIndex ?? 0;\n\t\tthis.currentSpriteIndex = useIndex;\n\t\tthis.sprites.forEach((_sprite, i) => {\n\t\t\t_sprite.visible = this.currentSpriteIndex === i;\n\t\t});\n\t}\n\n\tsetAnimation(name: string, delta: number) {\n\t\tconst animation = this.animations.get(name);\n\t\tif (!animation) return;\n\n\t\tconst { loop, frames } = animation;\n\t\tconst frame = frames[this.currentAnimationIndex];\n\n\t\tif (name === this.currentAnimation) {\n\t\t\tthis.currentAnimationFrame = frame.key;\n\t\t\tthis.currentAnimationTime += delta;\n\t\t\tthis.setSprite(this.currentAnimationFrame);\n\t\t} else {\n\t\t\tthis.currentAnimation = name;\n\t\t}\n\n\t\tif (this.currentAnimationTime > frame.time) {\n\t\t\tthis.currentAnimationIndex++;\n\t\t}\n\n\t\tif (this.currentAnimationIndex >= frames.length) {\n\t\t\tif (loop) {\n\t\t\t\tthis.currentAnimationIndex = 0;\n\t\t\t\tthis.currentAnimationTime = 0;\n\t\t\t} else {\n\t\t\t\tthis.currentAnimationTime = frames[this.currentAnimationIndex].time;\n\t\t\t}\n\t\t}\n\t}\n\n\tspriteUpdate(params: UpdateContext<ZylemSpriteOptions>): void {\n\t\tthis.sprites.forEach(_sprite => {\n\t\t\tif (_sprite.material) {\n\t\t\t\tconst q = this.body?.rotation();\n\t\t\t\tif (q) {\n\t\t\t\t\tconst quat = new Quaternion(q.x, q.y, q.z, q.w);\n\t\t\t\t\tconst euler = new Euler().setFromQuaternion(quat, 'XYZ');\n\t\t\t\t\t_sprite.material.rotation = euler.z;\n\t\t\t\t}\n\t\t\t\t_sprite.scale.set(this.options.size?.x ?? 1, this.options.size?.y ?? 1, this.options.size?.z ?? 1);\n\t\t\t}\n\t\t});\n\t}\n\n\tspriteDestroy(params: DestroyContext<ZylemSpriteOptions>): void {\n\t\tthis.sprites.forEach(_sprite => {\n\t\t\t_sprite.removeFromParent();\n\t\t});\n\t\tthis.group?.remove(...this.sprites);\n\t\tthis.group?.removeFromParent();\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemSprite.type),\n\t\t};\n\t}\n}\n\ntype SpriteOptions = BaseNode | Partial<ZylemSpriteOptions>;\n\nexport function createSprite(...args: Array<SpriteOptions>): ZylemSprite {\n\treturn createEntity<ZylemSprite, ZylemSpriteOptions>({\n\t\targs,\n\t\tdefaultConfig: spriteDefaults,\n\t\tEntityClass: ZylemSprite,\n\t\tBuilderClass: SpriteBuilder,\n\t\tCollisionBuilderClass: SpriteCollisionBuilder,\n\t\tentityType: ZylemSprite.type\n\t});\n}","// @ts-nocheck\nimport { BufferGeometry, Float32BufferAttribute } from 'three';\n\nclass XZPlaneGeometry extends BufferGeometry {\n\n\tconstructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) {\n\n\t\tsuper();\n\n\t\tthis.type = 'XZPlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tconst width_half = width / 2;\n\t\tconst height_half = height / 2;\n\n\t\tconst gridX = Math.floor(widthSegments);\n\t\tconst gridY = Math.floor(heightSegments);\n\n\t\tconst gridX1 = gridX + 1;\n\t\tconst gridY1 = gridY + 1;\n\n\t\tconst segment_width = width / gridX;\n\t\tconst segment_height = height / gridY;\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\tfor (let iy = 0; iy < gridY1; iy++) {\n\n\t\t\tconst z = iy * segment_height - height_half;\n\n\t\t\tfor (let ix = 0; ix < gridX1; ix++) {\n\n\t\t\t\tconst x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push(x, 0, z);\n\n\t\t\t\tnormals.push(0, 1, 0);\n\n\t\t\t\tuvs.push(ix / gridX);\n\t\t\t\tuvs.push(1 - (iy / gridY));\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor (let iy = 0; iy < gridY; iy++) {\n\n\t\t\tfor (let ix = 0; ix < gridX; ix++) {\n\n\t\t\t\tconst a = ix + gridX1 * iy;\n\t\t\t\tconst b = ix + gridX1 * (iy + 1);\n\t\t\t\tconst c = (ix + 1) + gridX1 * (iy + 1);\n\t\t\t\tconst d = (ix + 1) + gridX1 * iy;\n\n\t\t\t\tindices.push(a, b, d);\n\t\t\t\tindices.push(b, c, d);\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex(indices);\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\tthis.setAttribute('normal', new Float32BufferAttribute(normals, 3));\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvs, 2));\n\n\t}\n\n\tcopy(source) {\n\n\t\tsuper.copy(source);\n\n\t\tthis.parameters = Object.assign({}, source.parameters);\n\n\t\treturn this;\n\t}\n\n\tstatic fromJSON(data) {\n\t\treturn new XZPlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments);\n\t}\n\n}\n\nexport { XZPlaneGeometry };","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { PlaneGeometry, Vector2, Vector3 } from 'three';\nimport { TexturePath } from '../graphics/material';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { EntityMeshBuilder } from './builder';\nimport { XZPlaneGeometry } from '../graphics/geometries/XZPlaneGeometry';\nimport { createEntity } from './create';\n\ntype ZylemPlaneOptions = GameEntityOptions & {\n\ttile?: Vector2;\n\trepeat?: Vector2;\n\ttexture?: TexturePath;\n\tsubdivisions?: number;\n\trandomizeHeight?: boolean;\n\theightMap?: number[];\n\theightScale?: number;\n};\n\nconst DEFAULT_SUBDIVISIONS = 4;\n\nimport { commonDefaults } from './common';\n\nconst planeDefaults: ZylemPlaneOptions = {\n\t...commonDefaults,\n\ttile: new Vector2(10, 10),\n\trepeat: new Vector2(1, 1),\n\tcollision: {\n\t\tstatic: true,\n\t},\n\tsubdivisions: DEFAULT_SUBDIVISIONS,\n\trandomizeHeight: false,\n\theightScale: 1,\n};\n\nexport class PlaneCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemPlaneOptions): ColliderDesc {\n\t\tconst tile = options.tile ?? new Vector2(1, 1);\n\t\tconst subdivisions = options.subdivisions ?? DEFAULT_SUBDIVISIONS;\n\t\tconst size = new Vector3(tile.x, 1, tile.y);\n\n\t\tconst heightData = (options._builders?.meshBuilder as unknown as PlaneMeshBuilder)?.heightData;\n\t\tconst scale = new Vector3(size.x, 1, size.z);\n\t\tlet colliderDesc = ColliderDesc.heightfield(\n\t\t\tsubdivisions,\n\t\t\tsubdivisions,\n\t\t\theightData,\n\t\t\tscale\n\t\t);\n\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class PlaneMeshBuilder extends EntityMeshBuilder {\n\theightData: Float32Array = new Float32Array();\n\tcolumnsRows = new Map();\n\tprivate subdivisions: number = DEFAULT_SUBDIVISIONS;\n\n\tbuild(options: ZylemPlaneOptions): XZPlaneGeometry {\n\t\tconst tile = options.tile ?? new Vector2(1, 1);\n\t\tconst subdivisions = options.subdivisions ?? DEFAULT_SUBDIVISIONS;\n\t\tthis.subdivisions = subdivisions;\n\t\tconst size = new Vector3(tile.x, 1, tile.y);\n\t\tconst heightScale = options.heightScale ?? 1;\n\n\t\tconst geometry = new XZPlaneGeometry(size.x, size.z, subdivisions, subdivisions);\n\t\tconst vertexGeometry = new PlaneGeometry(size.x, size.z, subdivisions, subdivisions);\n\t\tconst dx = size.x / subdivisions;\n\t\tconst dy = size.z / subdivisions;\n\t\tconst originalVertices = geometry.attributes.position.array;\n\t\tconst vertices = vertexGeometry.attributes.position.array;\n\t\tconst columsRows = new Map();\n\n\t\t// Get height data source\n\t\tconst heightMapData = options.heightMap;\n\t\tconst useRandomHeight = options.randomizeHeight ?? false;\n\n\t\tfor (let i = 0; i < vertices.length; i += 3) {\n\t\t\tconst vertexIndex = i / 3;\n\t\t\tlet row = Math.floor(Math.abs((vertices as any)[i] + (size.x / 2)) / dx);\n\t\t\tlet column = Math.floor(Math.abs((vertices as any)[i + 1] - (size.z / 2)) / dy);\n\n\t\t\tlet height = 0;\n\t\t\tif (heightMapData && heightMapData.length > 0) {\n\t\t\t\t// Loop the height map data if it doesn't cover all vertices\n\t\t\t\tconst heightIndex = vertexIndex % heightMapData.length;\n\t\t\t\theight = heightMapData[heightIndex] * heightScale;\n\t\t\t} else if (useRandomHeight) {\n\t\t\t\theight = Math.random() * 4 * heightScale;\n\t\t\t}\n\n\t\t\t(vertices as any)[i + 2] = height;\n\t\t\toriginalVertices[i + 1] = height;\n\t\t\tif (!columsRows.get(column)) {\n\t\t\t\tcolumsRows.set(column, new Map());\n\t\t\t}\n\t\t\tcolumsRows.get(column).set(row, height);\n\t\t}\n\t\tthis.columnsRows = columsRows;\n\t\treturn geometry;\n\t}\n\n\tpostBuild(): void {\n\t\tconst heights = [];\n\t\tfor (let i = 0; i <= this.subdivisions; ++i) {\n\t\t\tfor (let j = 0; j <= this.subdivisions; ++j) {\n\t\t\t\tconst row = this.columnsRows.get(j);\n\t\t\t\tif (!row) {\n\t\t\t\t\theights.push(0);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst data = row.get(i);\n\t\t\t\theights.push(data ?? 0);\n\t\t\t}\n\t\t}\n\t\tthis.heightData = new Float32Array(heights as unknown as number[]);\n\t}\n}\n\nexport class PlaneBuilder extends EntityBuilder<ZylemPlane, ZylemPlaneOptions> {\n\tprotected createEntity(options: Partial<ZylemPlaneOptions>): ZylemPlane {\n\t\treturn new ZylemPlane(options);\n\t}\n}\n\nexport const PLANE_TYPE = Symbol('Plane');\n\nexport class ZylemPlane extends GameEntity<ZylemPlaneOptions> {\n\tstatic type = PLANE_TYPE;\n\n\tconstructor(options?: ZylemPlaneOptions) {\n\t\tsuper();\n\t\tthis.options = { ...planeDefaults, ...options };\n\t}\n}\n\ntype PlaneOptions = BaseNode | Partial<ZylemPlaneOptions>;\n\nexport function createPlane(...args: Array<PlaneOptions>): ZylemPlane {\n\treturn createEntity<ZylemPlane, ZylemPlaneOptions>({\n\t\targs,\n\t\tdefaultConfig: planeDefaults,\n\t\tEntityClass: ZylemPlane,\n\t\tBuilderClass: PlaneBuilder,\n\t\tMeshBuilderClass: PlaneMeshBuilder,\n\t\tCollisionBuilderClass: PlaneCollisionBuilder,\n\t\tentityType: ZylemPlane.type\n\t});\n}\n","import { 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 { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { createEntity } from './create';\nimport { CollisionHandlerDelegate } from '../collision/world';\nimport { state } from '../game/game-state';\nimport { commonDefaults } from './common';\n\nexport type OnHeldParams = {\n\tdelta: number;\n\tself: ZylemZone;\n\tvisitor: GameEntity<any>;\n\theldTime: number;\n\tglobals: any;\n}\n\nexport type OnEnterParams = Pick<OnHeldParams, 'self' | 'visitor' | 'globals'>;\nexport type OnExitParams = Pick<OnHeldParams, 'self' | 'visitor' | 'globals'>;\n\ntype ZylemZoneOptions = GameEntityOptions & {\n\tsize?: Vector3;\n\tstatic?: boolean;\n\tonEnter?: (params: OnEnterParams) => void;\n\tonHeld?: (params: OnHeldParams) => void;\n\tonExit?: (params: OnExitParams) => void;\n};\n\nconst zoneDefaults: ZylemZoneOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n\tcollision: {\n\t\tstatic: true,\n\t},\n};\n\nexport class ZoneCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemZoneOptions): ColliderDesc {\n\t\tconst size = options.size || new Vector3(1, 1, 1);\n\t\tconst half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };\n\t\tlet colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);\n\t\tcolliderDesc.setSensor(true);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.KINEMATIC_FIXED;\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class ZoneBuilder extends EntityBuilder<ZylemZone, ZylemZoneOptions> {\n\tprotected createEntity(options: Partial<ZylemZoneOptions>): ZylemZone {\n\t\treturn new ZylemZone(options);\n\t}\n}\n\nexport const ZONE_TYPE = Symbol('Zone');\n\nexport class ZylemZone extends GameEntity<ZylemZoneOptions> implements CollisionHandlerDelegate {\n\tstatic type = ZONE_TYPE;\n\n\tprivate _enteredZone: Map<string, number> = new Map();\n\tprivate _exitedZone: Map<string, number> = new Map();\n\tprivate _zoneEntities: Map<string, any> = new Map();\n\n\tconstructor(options?: ZylemZoneOptions) {\n\t\tsuper();\n\t\tthis.options = { ...zoneDefaults, ...options };\n\t}\n\n\tpublic handlePostCollision({ delta }: { delta: number }): boolean {\n\t\tthis._enteredZone.forEach((val, key) => {\n\t\t\tthis.exited(delta, key);\n\t\t});\n\t\treturn this._enteredZone.size > 0;\n\t}\n\n\tpublic handleIntersectionEvent({ other, delta }: { other: any, delta: number }) {\n\t\tconst hasEntered = this._enteredZone.get(other.uuid);\n\t\tif (!hasEntered) {\n\t\t\tthis.entered(other);\n\t\t\tthis._zoneEntities.set(other.uuid, other);\n\t\t} else {\n\t\t\tthis.held(delta, other);\n\t\t}\n\t}\n\n\tonEnter(callback: (params: OnEnterParams) => void) {\n\t\tthis.options.onEnter = callback;\n\t\treturn this;\n\t}\n\n\tonHeld(callback: (params: OnHeldParams) => void) {\n\t\tthis.options.onHeld = callback;\n\t\treturn this;\n\t}\n\n\tonExit(callback: (params: OnExitParams) => void) {\n\t\tthis.options.onExit = callback;\n\t\treturn this;\n\t}\n\n\tentered(other: any) {\n\t\tthis._enteredZone.set(other.uuid, 1);\n\t\tif (this.options.onEnter) {\n\t\t\tthis.options.onEnter({\n\t\t\t\tself: this,\n\t\t\t\tvisitor: other,\n\t\t\t\tglobals: state.globals\n\t\t\t});\n\t\t}\n\t}\n\n\texited(delta: number, key: string) {\n\t\tconst hasExited = this._exitedZone.get(key);\n\t\tif (hasExited && hasExited > 1 + delta) {\n\t\t\tthis._exitedZone.delete(key);\n\t\t\tthis._enteredZone.delete(key);\n\t\t\tconst other = this._zoneEntities.get(key);\n\t\t\tif (this.options.onExit) {\n\t\t\t\tthis.options.onExit({\n\t\t\t\t\tself: this,\n\t\t\t\t\tvisitor: other,\n\t\t\t\t\tglobals: state.globals\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._exitedZone.set(key, 1 + delta);\n\t}\n\n\theld(delta: number, other: any) {\n\t\tconst heldTime = this._enteredZone.get(other.uuid) ?? 0;\n\t\tthis._enteredZone.set(other.uuid, heldTime + delta);\n\t\tthis._exitedZone.set(other.uuid, 1);\n\t\tif (this.options.onHeld) {\n\t\t\tthis.options.onHeld({\n\t\t\t\tdelta,\n\t\t\t\tself: this,\n\t\t\t\tvisitor: other,\n\t\t\t\tglobals: state.globals,\n\t\t\t\theldTime\n\t\t\t});\n\t\t}\n\t}\n}\n\ntype ZoneOptions = BaseNode | Partial<ZylemZoneOptions>;\n\nexport function createZone(...args: Array<ZoneOptions>): ZylemZone {\n\treturn createEntity<ZylemZone, ZylemZoneOptions>({\n\t\targs,\n\t\tdefaultConfig: zoneDefaults,\n\t\tEntityClass: ZylemZone,\n\t\tBuilderClass: ZoneBuilder,\n\t\tCollisionBuilderClass: ZoneCollisionBuilder,\n\t\tentityType: ZylemZone.type\n\t});\n}","/**\n * Entity Asset Loader - Refactored to use AssetManager\n * \n * This module provides a compatibility layer for existing code that uses EntityAssetLoader.\n * All loading now goes through the centralized AssetManager for caching.\n */\n\nimport { AnimationClip, Object3D } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport { assetManager } from './asset-manager';\n\nexport interface AssetLoaderResult {\n\tobject?: Object3D;\n\tanimation?: AnimationClip;\n\tgltf?: GLTF;\n}\n\n/**\n * EntityAssetLoader - Uses AssetManager for all model loading\n * \n * This class is now a thin wrapper around AssetManager, providing backward\n * compatibility for existing code while benefiting from centralized caching.\n */\nexport class EntityAssetLoader {\n\t/**\n\t * Load a model file (FBX, GLTF, GLB, OBJ) using the asset manager\n\t */\n\tasync loadFile(file: string): Promise<AssetLoaderResult> {\n\t\tconst ext = file.split('.').pop()?.toLowerCase();\n\n\t\tswitch (ext) {\n\t\t\tcase 'fbx': {\n\t\t\t\tconst result = await assetManager.loadFBX(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tanimation: result.animations?.[0]\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb': {\n\t\t\t\tconst result = await assetManager.loadGLTF(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tgltf: result.gltf\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'obj': {\n\t\t\t\tconst result = await assetManager.loadOBJ(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported file type: ${file}`);\n\t\t}\n\t}\n}\n","import {\n\tAnimationAction,\n\tAnimationClip,\n\tAnimationMixer,\n\tLoopOnce,\n\tLoopRepeat,\n\tObject3D,\n} from 'three';\nimport { EntityAssetLoader, AssetLoaderResult } from '../../core/entity-asset-loader';\n\nexport type AnimationOptions = {\n\tkey: string;\n\tpauseAtEnd?: boolean;\n\tpauseAtPercentage?: number;\n\tfadeToKey?: string;\n\tfadeDuration?: number;\n};\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport class AnimationDelegate {\n\tprivate _mixer: AnimationMixer | null = null;\n\tprivate _actions: Record<string, AnimationAction> = {};\n\tprivate _animations: AnimationClip[] = [];\n\tprivate _currentAction: AnimationAction | null = null;\n\n\tprivate _pauseAtPercentage = 0;\n\tprivate _isPaused = false;\n\tprivate _queuedKey: string | null = null;\n\tprivate _fadeDuration = 0.5;\n\n\tprivate _currentKey: string = '';\n\tprivate _assetLoader = new EntityAssetLoader();\n\n\tconstructor(private target: Object3D) { }\n\n\tasync loadAnimations(animations: AnimationObject[]): Promise<void> {\n\t\tif (!animations.length) return;\n\n\t\tconst results = await Promise.all(animations.map(a => this._assetLoader.loadFile(a.path)));\n\t\tthis._animations = results\n\t\t\t.filter((r): r is AssetLoaderResult => !!r.animation)\n\t\t\t.map(r => r.animation!);\n\n\t\tif (!this._animations.length) return;\n\n\t\tthis._mixer = new AnimationMixer(this.target);\n\t\tthis._animations.forEach((clip, i) => {\n\t\t\tconst key = animations[i].key || i.toString();\n\t\t\tthis._actions[key] = this._mixer!.clipAction(clip);\n\t\t});\n\n\t\tthis.playAnimation({ key: Object.keys(this._actions)[0] });\n\t}\n\n\tupdate(delta: number): void {\n\t\tif (!this._mixer || !this._currentAction) return;\n\n\t\tthis._mixer.update(delta);\n\n\t\tconst pauseAtTime = this._currentAction.getClip().duration * (this._pauseAtPercentage / 100);\n\t\tif (\n\t\t\t!this._isPaused &&\n\t\t\tthis._pauseAtPercentage > 0 &&\n\t\t\tthis._currentAction.time >= pauseAtTime\n\t\t) {\n\t\t\tthis._currentAction.time = pauseAtTime;\n\t\t\tthis._currentAction.paused = true;\n\t\t\tthis._isPaused = true;\n\n\t\t\tif (this._queuedKey !== null) {\n\t\t\t\tconst next = this._actions[this._queuedKey];\n\t\t\t\tnext.reset().play();\n\t\t\t\tthis._currentAction.crossFadeTo(next, this._fadeDuration, false);\n\t\t\t\tthis._currentAction = next;\n\t\t\t\tthis._currentKey = this._queuedKey;\n\t\t\t\tthis._queuedKey = null;\n\t\t\t}\n\t\t}\n\t}\n\n\tplayAnimation(opts: AnimationOptions): void {\n\t\tif (!this._mixer) return;\n\t\tconst { key, pauseAtPercentage = 0, pauseAtEnd = false, fadeToKey, fadeDuration = 0.5 } = opts;\n\t\tif (key === this._currentKey) return;\n\n\t\tthis._queuedKey = fadeToKey || null;\n\t\tthis._fadeDuration = fadeDuration;\n\n\t\tthis._pauseAtPercentage = pauseAtEnd ? 100 : pauseAtPercentage;\n\t\tthis._isPaused = false;\n\n\t\tconst prev = this._currentAction;\n\t\tif (prev) prev.stop();\n\n\t\tconst action = this._actions[key];\n\t\tif (!action) return;\n\n\t\tif (this._pauseAtPercentage > 0) {\n\t\t\taction.setLoop(LoopOnce, Infinity);\n\t\t\taction.clampWhenFinished = true;\n\t\t} else {\n\t\t\taction.setLoop(LoopRepeat, Infinity);\n\t\t\taction.clampWhenFinished = false;\n\t\t}\n\n\t\tif (prev) {\n\t\t\tprev.crossFadeTo(action, fadeDuration, false);\n\t\t}\n\t\taction.reset().play();\n\n\t\tthis._currentAction = action;\n\t\tthis._currentKey = key;\n\t}\n\n\t/**\n\t * Dispose of all animation resources\n\t */\n\tdispose(): void {\n\t\t// Stop all actions\n\t\tObject.values(this._actions).forEach(action => {\n\t\t\taction.stop();\n\t\t});\n\n\t\t// Stop and uncache mixer\n\t\tif (this._mixer) {\n\t\t\tthis._mixer.stopAllAction();\n\t\t\tthis._mixer.uncacheRoot(this.target);\n\t\t\tthis._mixer = null;\n\t\t}\n\n\t\t// Clear references\n\t\tthis._actions = {};\n\t\tthis._animations = [];\n\t\tthis._currentAction = null;\n\t\tthis._currentKey = '';\n\t}\n\n\tget currentAnimationKey() { return this._currentKey; }\n\tget animations() { return this._animations; }\n}\n","import { Color, Group, Sprite as ThreeSprite, SpriteMaterial, CanvasTexture, LinearFilter, Vector2, PerspectiveCamera, OrthographicCamera, ClampToEdgeWrapping } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { createEntity } from './create';\nimport { UpdateContext, SetupContext } from '../core/base-node-life-cycle';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { DebugDelegate } from './delegates/debug';\n\ntype ZylemTextOptions = GameEntityOptions & {\n\ttext?: string;\n\tfontFamily?: string;\n\tfontSize?: number;\n\tfontColor?: Color | string;\n\tbackgroundColor?: Color | string | null;\n\tpadding?: number;\n\tstickToViewport?: boolean;\n\tscreenPosition?: Vector2;\n\tzDistance?: number;\n};\n\nconst textDefaults: ZylemTextOptions = {\n\tposition: undefined,\n\ttext: '',\n\tfontFamily: 'Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n\tfontSize: 18,\n\tfontColor: '#FFFFFF',\n\tbackgroundColor: null,\n\tpadding: 4,\n\tstickToViewport: true,\n\tscreenPosition: new Vector2(24, 24),\n\tzDistance: 1,\n};\n\nexport class TextBuilder extends EntityBuilder<ZylemText, ZylemTextOptions> {\n\tprotected createEntity(options: Partial<ZylemTextOptions>): ZylemText {\n\t\treturn new ZylemText(options);\n\t}\n}\n\nexport const TEXT_TYPE = Symbol('Text');\n\nexport class ZylemText extends GameEntity<ZylemTextOptions> {\n\tstatic type = TEXT_TYPE;\n\n\tprivate _sprite: ThreeSprite | null = null;\n\tprivate _texture: CanvasTexture | null = null;\n\tprivate _canvas: HTMLCanvasElement | null = null;\n\tprivate _ctx: CanvasRenderingContext2D | null = null;\n\tprivate _cameraRef: ZylemCamera | null = null;\n\tprivate _lastCanvasW: number = 0;\n\tprivate _lastCanvasH: number = 0;\n\n\tconstructor(options?: ZylemTextOptions) {\n\t\tsuper();\n\t\tthis.options = { ...textDefaults, ...options } as ZylemTextOptions;\n\t\t// Add text-specific lifecycle callbacks (only registered once)\n\t\tthis.prependSetup(this.textSetup.bind(this) as any);\n\t\tthis.prependUpdate(this.textUpdate.bind(this) as any);\n\t\tthis.onDestroy(this.textDestroy.bind(this) as any);\n\t}\n\n\tpublic create(): this {\n\t\t// Clear previous state to prevent issues on reload\n\t\tthis._sprite = null;\n\t\tthis._texture = null;\n\t\tthis._canvas = null;\n\t\tthis._ctx = null;\n\t\tthis._lastCanvasW = 0;\n\t\tthis._lastCanvasH = 0;\n\t\tthis.group = new Group();\n\t\t\n\t\t// Recreate the sprite\n\t\tthis.createSprite();\n\t\t\n\t\t// Call parent create\n\t\treturn super.create();\n\t}\n\n\tprivate createSprite() {\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._ctx = this._canvas.getContext('2d');\n\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\tthis._texture.minFilter = LinearFilter;\n\t\tthis._texture.magFilter = LinearFilter;\n\t\tconst material = new SpriteMaterial({\n\t\t\tmap: this._texture,\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\talphaTest: 0.5,\n\t\t});\n\t\tthis._sprite = new ThreeSprite(material);\n\t\tthis.group?.add(this._sprite);\n\t\tthis.redrawText(this.options.text ?? '');\n\t}\n\n\tprivate measureAndResizeCanvas(text: string, fontSize: number, fontFamily: string, padding: number) {\n\t\tif (!this._canvas || !this._ctx) return { sizeChanged: false };\n\t\tthis._ctx.font = `${fontSize}px ${fontFamily}`;\n\t\tconst metrics = this._ctx.measureText(text);\n\t\tconst textWidth = Math.ceil(metrics.width);\n\t\tconst textHeight = Math.ceil(fontSize * 1.4);\n\t\tconst nextW = Math.max(2, textWidth + padding * 2);\n\t\tconst nextH = Math.max(2, textHeight + padding * 2);\n\t\tconst sizeChanged = nextW !== this._lastCanvasW || nextH !== this._lastCanvasH;\n\t\tthis._canvas.width = nextW;\n\t\tthis._canvas.height = nextH;\n\t\tthis._lastCanvasW = nextW;\n\t\tthis._lastCanvasH = nextH;\n\t\treturn { sizeChanged };\n\t}\n\n\tprivate drawCenteredText(text: string, fontSize: number, fontFamily: string) {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tthis._ctx.font = `${fontSize}px ${fontFamily}`;\n\t\tthis._ctx.textAlign = 'center';\n\t\tthis._ctx.textBaseline = 'middle';\n\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\t\tif (this.options.backgroundColor) {\n\t\t\tthis._ctx.fillStyle = this.toCssColor(this.options.backgroundColor);\n\t\t\tthis._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t}\n\t\tthis._ctx.fillStyle = this.toCssColor(this.options.fontColor ?? '#FFFFFF');\n\t\tthis._ctx.fillText(text, this._canvas.width / 2, this._canvas.height / 2);\n\t}\n\n\tprivate updateTexture(sizeChanged: boolean) {\n\t\tif (!this._texture || !this._canvas) return;\n\t\tif (sizeChanged) {\n\t\t\tthis._texture.dispose();\n\t\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\t\tthis._texture.minFilter = LinearFilter;\n\t\t\tthis._texture.magFilter = LinearFilter;\n\t\t\tthis._texture.wrapS = ClampToEdgeWrapping;\n\t\t\tthis._texture.wrapT = ClampToEdgeWrapping;\n\t\t}\n\t\tthis._texture.image = this._canvas;\n\t\tthis._texture.needsUpdate = true;\n\t\tif (this._sprite && this._sprite.material) {\n\t\t\t(this._sprite.material as any).map = this._texture;\n\t\t\tthis._sprite.material.needsUpdate = true;\n\t\t}\n\t}\n\n\tprivate redrawText(_text: string) {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tconst fontSize = this.options.fontSize ?? 18;\n\t\tconst fontFamily = this.options.fontFamily ?? (textDefaults.fontFamily as string);\n\t\tconst padding = this.options.padding ?? 4;\n\n\t\tconst { sizeChanged } = this.measureAndResizeCanvas(_text, fontSize, fontFamily, padding);\n\t\tthis.drawCenteredText(_text, fontSize, fontFamily);\n\t\tthis.updateTexture(Boolean(sizeChanged));\n\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate toCssColor(color: Color | string): string {\n\t\tif (typeof color === 'string') return color;\n\t\tconst c = color instanceof Color ? color : new Color(color as any);\n\t\treturn `#${c.getHexString()}`;\n\t}\n\n\tprivate textSetup(params: SetupContext<ZylemTextOptions>) {\n\t\tthis._cameraRef = (params.camera as unknown) as ZylemCamera | null;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\t(this._cameraRef.camera as any).add(this.group);\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate textUpdate(params: UpdateContext<ZylemTextOptions>) {\n\t\tif (!this._sprite) return;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate getResolution() {\n\t\treturn {\n\t\t\twidth: this._cameraRef?.screenResolution.x ?? 1,\n\t\t\theight: this._cameraRef?.screenResolution.y ?? 1,\n\t\t};\n\t}\n\n\tprivate getScreenPixels(sp: Vector2, width: number, height: number) {\n\t\tconst isPercentX = sp.x >= 0 && sp.x <= 1;\n\t\tconst isPercentY = sp.y >= 0 && sp.y <= 1;\n\t\treturn {\n\t\t\tpx: isPercentX ? sp.x * width : sp.x,\n\t\t\tpy: isPercentY ? sp.y * height : sp.y,\n\t\t};\n\t}\n\n\tprivate computeWorldExtents(camera: PerspectiveCamera | OrthographicCamera, zDist: number) {\n\t\tlet worldHalfW = 1;\n\t\tlet worldHalfH = 1;\n\t\tif ((camera as PerspectiveCamera).isPerspectiveCamera) {\n\t\t\tconst pc = camera as PerspectiveCamera;\n\t\t\tconst halfH = Math.tan((pc.fov * Math.PI) / 180 / 2) * zDist;\n\t\t\tconst halfW = halfH * pc.aspect;\n\t\t\tworldHalfW = halfW;\n\t\t\tworldHalfH = halfH;\n\t\t} else if ((camera as OrthographicCamera).isOrthographicCamera) {\n\t\t\tconst oc = camera as OrthographicCamera;\n\t\t\tworldHalfW = (oc.right - oc.left) / 2;\n\t\t\tworldHalfH = (oc.top - oc.bottom) / 2;\n\t\t}\n\t\treturn { worldHalfW, worldHalfH };\n\t}\n\n\tprivate updateSpriteScale(worldHalfH: number, viewportHeight: number) {\n\t\tif (!this._canvas || !this._sprite) return;\n\t\tconst planeH = worldHalfH * 2;\n\t\tconst unitsPerPixel = planeH / viewportHeight;\n\t\tconst pixelH = this._canvas.height;\n\t\tconst scaleY = Math.max(0.0001, pixelH * unitsPerPixel);\n\t\tconst aspect = this._canvas.width / this._canvas.height;\n\t\tconst scaleX = scaleY * aspect;\n\t\tthis._sprite.scale.set(scaleX, scaleY, 1);\n\t}\n\n\tprivate updateStickyTransform() {\n\t\tif (!this._sprite || !this._cameraRef) return;\n\t\tconst camera = this._cameraRef.camera as PerspectiveCamera | OrthographicCamera;\n\t\tconst { width, height } = this.getResolution();\n\t\tconst sp = this.options.screenPosition ?? new Vector2(24, 24);\n\t\tconst { px, py } = this.getScreenPixels(sp, width, height);\n\t\tconst zDist = Math.max(0.001, this.options.zDistance ?? 1);\n\t\tconst { worldHalfW, worldHalfH } = this.computeWorldExtents(camera, zDist);\n\n\t\tconst ndcX = (px / width) * 2 - 1;\n\t\tconst ndcY = 1 - (py / height) * 2;\n\t\tconst localX = ndcX * worldHalfW;\n\t\tconst localY = ndcY * worldHalfH;\n\t\tthis.group?.position.set(localX, localY, -zDist);\n\t\tthis.updateSpriteScale(worldHalfH, height);\n\t}\n\n\tupdateText(_text: string) {\n\t\tthis.options.text = _text;\n\t\tthis.redrawText(_text);\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemText.type),\n\t\t\ttext: this.options.text ?? '',\n\t\t\tsticky: this.options.stickToViewport,\n\t\t};\n\t}\n\n\t/**\n\t * Dispose of Three.js resources when the entity is destroyed.\n\t */\n\tprivate textDestroy(): void {\n\t\t// Dispose texture\n\t\tthis._texture?.dispose();\n\t\t\n\t\t// Dispose sprite material\n\t\tif (this._sprite?.material) {\n\t\t\t(this._sprite.material as SpriteMaterial).dispose();\n\t\t}\n\t\t\n\t\t// Remove sprite from group\n\t\tif (this._sprite) {\n\t\t\tthis._sprite.removeFromParent();\n\t\t}\n\t\t\n\t\t// Remove group from parent (camera or scene)\n\t\tthis.group?.removeFromParent();\n\t\t\n\t\t// Clear references\n\t\tthis._sprite = null;\n\t\tthis._texture = null;\n\t\tthis._canvas = null;\n\t\tthis._ctx = null;\n\t\tthis._cameraRef = null;\n\t}\n}\n\ntype TextOptions = BaseNode | Partial<ZylemTextOptions>;\n\nexport function createText(...args: Array<TextOptions>): ZylemText {\n\treturn createEntity<ZylemText, ZylemTextOptions>({\n\t\targs,\n\t\tdefaultConfig: { ...textDefaults },\n\t\tEntityClass: ZylemText,\n\t\tBuilderClass: TextBuilder,\n\t\tentityType: ZylemText.type,\n\t});\n}\n\n\n","import { Color, Group, Sprite as ThreeSprite, SpriteMaterial, CanvasTexture, LinearFilter, Vector2, PerspectiveCamera, OrthographicCamera, ClampToEdgeWrapping, ShaderMaterial, Mesh, PlaneGeometry, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { createEntity } from './create';\nimport { UpdateContext, SetupContext } from '../core/base-node-life-cycle';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { DebugDelegate } from './delegates/debug';\n\ntype ZylemRectOptions = GameEntityOptions & {\n\twidth?: number;\n\theight?: number;\n\tfillColor?: Color | string | null;\n\tstrokeColor?: Color | string | null;\n\tstrokeWidth?: number;\n\tradius?: number;\n\tpadding?: number;\n\tstickToViewport?: boolean;\n\tscreenPosition?: Vector2;\n\tzDistance?: number;\n\tanchor?: Vector2; // 0-100 per axis, default top-left (0,0)\n\tbounds?: {\n\t\tscreen?: { x: number; y: number; width: number; height: number };\n\t\tworld?: { left: number; right: number; top: number; bottom: number; z?: number };\n\t};\n};\n\nconst rectDefaults: ZylemRectOptions = {\n\tposition: undefined,\n\twidth: 120,\n\theight: 48,\n\tfillColor: '#FFFFFF',\n\tstrokeColor: null,\n\tstrokeWidth: 0,\n\tradius: 0,\n\tpadding: 0,\n\tstickToViewport: true,\n\tscreenPosition: new Vector2(24, 24),\n\tzDistance: 1,\n\tanchor: new Vector2(0, 0),\n};\n\nexport class RectBuilder extends EntityBuilder<ZylemRect, ZylemRectOptions> {\n\tprotected createEntity(options: Partial<ZylemRectOptions>): ZylemRect {\n\t\treturn new ZylemRect(options);\n\t}\n}\n\nexport const RECT_TYPE = Symbol('Rect');\n\nexport class ZylemRect extends GameEntity<ZylemRectOptions> {\n\tstatic type = RECT_TYPE;\n\n\tprivate _sprite: ThreeSprite | null = null;\n\tprivate _mesh: Mesh | null = null;\n\tprivate _texture: CanvasTexture | null = null;\n\tprivate _canvas: HTMLCanvasElement | null = null;\n\tprivate _ctx: CanvasRenderingContext2D | null = null;\n\tprivate _cameraRef: ZylemCamera | null = null;\n\tprivate _lastCanvasW: number = 0;\n\tprivate _lastCanvasH: number = 0;\n\n\tconstructor(options?: ZylemRectOptions) {\n\t\tsuper();\n\t\tthis.options = { ...rectDefaults, ...options } as ZylemRectOptions;\n\t\tthis.group = new Group();\n\t\tthis.createSprite();\n\t\t// Add rect-specific lifecycle callbacks\n\t\tthis.prependSetup(this.rectSetup.bind(this) as any);\n\t\tthis.prependUpdate(this.rectUpdate.bind(this) as any);\n\t}\n\n\tprivate createSprite() {\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._ctx = this._canvas.getContext('2d');\n\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\tthis._texture.minFilter = LinearFilter;\n\t\tthis._texture.magFilter = LinearFilter;\n\t\tconst material = new SpriteMaterial({\n\t\t\tmap: this._texture,\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\talphaTest: 0.5,\n\t\t});\n\t\tthis._sprite = new ThreeSprite(material);\n\t\tthis.group?.add(this._sprite);\n\t\tthis.redrawRect();\n\t}\n\n\tprivate redrawRect() {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tconst width = Math.max(2, Math.floor((this.options.width ?? 120)));\n\t\tconst height = Math.max(2, Math.floor((this.options.height ?? 48)));\n\t\tconst padding = this.options.padding ?? 0;\n\t\tconst strokeWidth = this.options.strokeWidth ?? 0;\n\t\tconst totalW = width + padding * 2 + strokeWidth;\n\t\tconst totalH = height + padding * 2 + strokeWidth;\n\t\tconst nextW = Math.max(2, totalW);\n\t\tconst nextH = Math.max(2, totalH);\n\t\tconst sizeChanged = nextW !== this._lastCanvasW || nextH !== this._lastCanvasH;\n\t\tthis._canvas.width = nextW;\n\t\tthis._canvas.height = nextH;\n\t\tthis._lastCanvasW = nextW;\n\t\tthis._lastCanvasH = nextH;\n\n\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\n\t\tconst radius = Math.max(0, this.options.radius ?? 0);\n\t\tconst rectX = Math.floor(padding + strokeWidth / 2);\n\t\tconst rectY = Math.floor(padding + strokeWidth / 2);\n\t\tconst rectW = Math.floor(width);\n\t\tconst rectH = Math.floor(height);\n\n\t\tthis._ctx.beginPath();\n\t\tif (radius > 0) {\n\t\t\tthis.roundedRectPath(this._ctx, rectX, rectY, rectW, rectH, radius);\n\t\t} else {\n\t\t\tthis._ctx.rect(rectX, rectY, rectW, rectH);\n\t\t}\n\n\t\tif (this.options.fillColor) {\n\t\t\tthis._ctx.fillStyle = this.toCssColor(this.options.fillColor);\n\t\t\tthis._ctx.fill();\n\t\t}\n\n\t\tif ((this.options.strokeColor && (strokeWidth > 0))) {\n\t\t\tthis._ctx.lineWidth = strokeWidth;\n\t\t\tthis._ctx.strokeStyle = this.toCssColor(this.options.strokeColor);\n\t\t\tthis._ctx.stroke();\n\t\t}\n\n\t\tif (this._texture) {\n\t\t\tif (sizeChanged) {\n\t\t\t\tthis._texture.dispose();\n\t\t\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\t\t\tthis._texture.minFilter = LinearFilter;\n\t\t\t\tthis._texture.magFilter = LinearFilter;\n\t\t\t\tthis._texture.wrapS = ClampToEdgeWrapping;\n\t\t\t\tthis._texture.wrapT = ClampToEdgeWrapping;\n\t\t\t\tif (this._sprite && this._sprite.material instanceof ShaderMaterial) {\n\t\t\t\t\tconst shader = this._sprite.material as ShaderMaterial;\n\t\t\t\t\tif (shader.uniforms?.tDiffuse) shader.uniforms.tDiffuse.value = this._texture;\n\t\t\t\t\tif (shader.uniforms?.iResolution) shader.uniforms.iResolution.value.set(this._canvas.width, this._canvas.height, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._texture.image = this._canvas;\n\t\t\tthis._texture.needsUpdate = true;\n\t\t\tif (this._sprite && this._sprite.material) {\n\t\t\t\t(this._sprite.material as any).map = this._texture;\n\t\t\t\tthis._sprite.material.needsUpdate = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tgetWidth() {\n\t\treturn this.options.width ?? 0;\n\t}\n\n\tgetHeight() {\n\t\treturn this.options.height ?? 0;\n\t}\n\n\tprivate roundedRectPath(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number) {\n\t\tconst radius = Math.min(r, Math.floor(Math.min(w, h) / 2));\n\t\tctx.moveTo(x + radius, y);\n\t\tctx.lineTo(x + w - radius, y);\n\t\tctx.quadraticCurveTo(x + w, y, x + w, y + radius);\n\t\tctx.lineTo(x + w, y + h - radius);\n\t\tctx.quadraticCurveTo(x + w, y + h, x + w - radius, y + h);\n\t\tctx.lineTo(x + radius, y + h);\n\t\tctx.quadraticCurveTo(x, y + h, x, y + h - radius);\n\t\tctx.lineTo(x, y + radius);\n\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t}\n\n\tprivate toCssColor(color: Color | string): string {\n\t\tif (typeof color === 'string') return color;\n\t\tconst c = color instanceof Color ? color : new Color(color as any);\n\t\treturn `#${c.getHexString()}`;\n\t}\n\n\tprivate rectSetup(params: SetupContext<ZylemRectOptions>) {\n\t\tthis._cameraRef = (params.camera as unknown) as ZylemCamera | null;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\t(this._cameraRef.camera as any).add(this.group);\n\t\t}\n\n\t\tif (this.materials?.length && this._sprite) {\n\t\t\tconst mat = this.materials[0];\n\t\t\tif (mat instanceof ShaderMaterial) {\n\t\t\t\tmat.transparent = true;\n\t\t\t\tmat.depthTest = false;\n\t\t\t\tmat.depthWrite = false;\n\t\t\t\tif (this._texture) {\n\t\t\t\t\tif (mat.uniforms?.tDiffuse) mat.uniforms.tDiffuse.value = this._texture;\n\t\t\t\t\tif (mat.uniforms?.iResolution && this._canvas) mat.uniforms.iResolution.value.set(this._canvas.width, this._canvas.height, 1);\n\t\t\t\t}\n\t\t\t\tthis._mesh = new Mesh(new PlaneGeometry(1, 1), mat);\n\t\t\t\tthis.group?.add(this._mesh);\n\t\t\t\tthis._sprite.visible = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate rectUpdate(params: UpdateContext<ZylemRectOptions>) {\n\t\tif (!this._sprite) return;\n\n\t\t// If bounds provided, compute screen-space rect from it and update size/position\n\t\tif (this._cameraRef && this.options.bounds) {\n\t\t\tconst dom = this._cameraRef.renderer.domElement;\n\t\t\tconst screen = this.computeScreenBoundsFromOptions(this.options.bounds);\n\t\t\tif (screen) {\n\t\t\t\tconst { x, y, width, height } = screen;\n\t\t\t\tconst desiredW = Math.max(2, Math.floor(width));\n\t\t\t\tconst desiredH = Math.max(2, Math.floor(height));\n\t\t\t\tconst changed = desiredW !== (this.options.width ?? 0) || desiredH !== (this.options.height ?? 0);\n\t\t\t\tthis.options.screenPosition = new Vector2(Math.floor(x), Math.floor(y));\n\t\t\t\tthis.options.width = desiredW;\n\t\t\t\tthis.options.height = desiredH;\n\t\t\t\tthis.options.anchor = new Vector2(0, 0);\n\t\t\t\tif (changed) {\n\t\t\t\t\tthis.redrawRect();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate updateStickyTransform() {\n\t\tif (!this._sprite || !this._cameraRef) return;\n\t\tconst camera = this._cameraRef.camera;\n\t\tconst dom = this._cameraRef.renderer.domElement;\n\t\tconst width = dom.clientWidth;\n\t\tconst height = dom.clientHeight;\n\t\tconst px = (this.options.screenPosition ?? new Vector2(24, 24)).x;\n\t\tconst py = (this.options.screenPosition ?? new Vector2(24, 24)).y;\n\t\tconst zDist = Math.max(0.001, this.options.zDistance ?? 1);\n\n\t\tlet worldHalfW = 1;\n\t\tlet worldHalfH = 1;\n\t\tif ((camera as PerspectiveCamera).isPerspectiveCamera) {\n\t\t\tconst pc = camera as PerspectiveCamera;\n\t\t\tconst halfH = Math.tan((pc.fov * Math.PI) / 180 / 2) * zDist;\n\t\t\tconst halfW = halfH * pc.aspect;\n\t\t\tworldHalfW = halfW;\n\t\t\tworldHalfH = halfH;\n\t\t} else if ((camera as OrthographicCamera).isOrthographicCamera) {\n\t\t\tconst oc = camera as OrthographicCamera;\n\t\t\tworldHalfW = (oc.right - oc.left) / 2;\n\t\t\tworldHalfH = (oc.top - oc.bottom) / 2;\n\t\t}\n\n\t\tconst ndcX = (px / width) * 2 - 1;\n\t\tconst ndcY = 1 - (py / height) * 2;\n\t\tconst localX = ndcX * worldHalfW;\n\t\tconst localY = ndcY * worldHalfH;\n\n\t\tlet scaleX = 1;\n\t\tlet scaleY = 1;\n\t\tif (this._canvas) {\n\t\t\tconst planeH = worldHalfH * 2;\n\t\t\tconst unitsPerPixel = planeH / height;\n\t\t\tconst pixelH = this._canvas.height;\n\t\t\tscaleY = Math.max(0.0001, pixelH * unitsPerPixel);\n\t\t\tconst aspect = this._canvas.width / this._canvas.height;\n\t\t\tscaleX = scaleY * aspect;\n\t\t\tthis._sprite.scale.set(scaleX, scaleY, 1);\n\t\t\tif (this._mesh) this._mesh.scale.set(scaleX, scaleY, 1);\n\t\t}\n\n\t\tconst anchor = this.options.anchor ?? new Vector2(0, 0);\n\t\tconst ax = Math.min(100, Math.max(0, anchor.x)) / 100; // 0..1\n\t\tconst ay = Math.min(100, Math.max(0, anchor.y)) / 100; // 0..1\n\t\tconst offsetX = (0.5 - ax) * scaleX;\n\t\tconst offsetY = (ay - 0.5) * scaleY;\n\t\tthis.group?.position.set(localX + offsetX, localY + offsetY, -zDist);\n\t}\n\n\tprivate worldToScreen(point: Vector3) {\n\t\tif (!this._cameraRef) return { x: 0, y: 0 };\n\t\tconst camera = this._cameraRef.camera;\n\t\tconst dom = this._cameraRef.renderer.domElement;\n\t\tconst v = point.clone().project(camera);\n\t\tconst x = (v.x + 1) / 2 * dom.clientWidth;\n\t\tconst y = (1 - v.y) / 2 * dom.clientHeight;\n\t\treturn { x, y };\n\t}\n\n\tprivate computeScreenBoundsFromOptions(bounds: NonNullable<ZylemRectOptions['bounds']>): { x: number; y: number; width: number; height: number } | null {\n\t\tif (!this._cameraRef) return null;\n\t\tconst dom = this._cameraRef.renderer.domElement;\n\t\tif (bounds.screen) {\n\t\t\treturn { ...bounds.screen };\n\t\t}\n\t\tif (bounds.world) {\n\t\t\tconst { left, right, top, bottom, z = 0 } = bounds.world;\n\t\t\tconst tl = this.worldToScreen(new Vector3(left, top, z));\n\t\t\tconst br = this.worldToScreen(new Vector3(right, bottom, z));\n\t\t\tconst x = Math.min(tl.x, br.x);\n\t\t\tconst y = Math.min(tl.y, br.y);\n\t\t\tconst width = Math.abs(br.x - tl.x);\n\t\t\tconst height = Math.abs(br.y - tl.y);\n\t\t\treturn { x, y, width, height };\n\t\t}\n\t\treturn null;\n\t}\n\n\tupdateRect(options?: Partial<Pick<ZylemRectOptions, 'width' | 'height' | 'fillColor' | 'strokeColor' | 'strokeWidth' | 'radius'>>) {\n\t\tthis.options = { ...this.options, ...options } as ZylemRectOptions;\n\t\tthis.redrawRect();\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemRect.type),\n\t\t\twidth: this.options.width ?? 0,\n\t\t\theight: this.options.height ?? 0,\n\t\t\tsticky: this.options.stickToViewport,\n\t\t};\n\t}\n}\n\ntype RectOptions = BaseNode | Partial<ZylemRectOptions>;\n\nexport function createRect(...args: Array<RectOptions>): ZylemRect {\n\treturn createEntity<ZylemRect, ZylemRectOptions>({\n\t\targs,\n\t\tdefaultConfig: { ...rectDefaults },\n\t\tEntityClass: ZylemRect,\n\t\tBuilderClass: RectBuilder,\n\t\tentityType: ZylemRect.type,\n\t});\n}\n\n\n","/**\n * Thruster Behavior Module Index\n * \n * Re-exports all thruster-related components and behaviors.\n */\n\n// Components\nexport {\n\ttype ThrusterMovementComponent,\n\ttype ThrusterInputComponent,\n\ttype ThrusterStateComponent,\n\tcreateThrusterMovementComponent,\n\tcreateThrusterInputComponent,\n\tcreateThrusterStateComponent,\n} from './components';\n\n// FSM\nexport {\n\tThrusterState,\n\tThrusterEvent,\n\tThrusterFSM,\n\ttype ThrusterFSMContext,\n\ttype PlayerInput,\n} from './thruster-fsm';\n\n// Behaviors\nexport {\n\tThrusterMovementBehavior,\n\ttype Behavior,\n\ttype ThrusterEntity,\n} from './thruster-movement.behavior';\n\n// Typed Descriptor (new entity.use() API)\nexport { ThrusterBehavior, type ThrusterBehaviorOptions } from './thruster.descriptor';\n","/**\n * Screen Wrap Behavior Module\n */\n\nexport { ScreenWrapBehavior, type ScreenWrapOptions } from './screen-wrap.descriptor';\nexport { ScreenWrapFSM, ScreenWrapState, ScreenWrapEvent } from './screen-wrap-fsm';\n","/**\n * World Boundary 2D Module\n *\n * Barrel exports for the `world-boundary-2d` behavior and its FSM helpers.\n */\nexport { WorldBoundary2DBehavior } from './world-boundary-2d.descriptor';\n\nexport {\n\tWorldBoundary2DFSM,\n\tcomputeWorldBoundary2DHits,\n\thasAnyWorldBoundary2DHit,\n\ttype WorldBoundary2DHit,\n\ttype WorldBoundary2DHits,\n\ttype WorldBoundary2DPosition,\n\ttype WorldBoundary2DBounds,\n\tWorldBoundary2DState,\n\tWorldBoundary2DEvent,\n} from './world-boundary-2d-fsm';\n\nexport type {\n\tWorldBoundary2DOptions,\n\tWorldBoundary2DHandle,\n} from './world-boundary-2d.descriptor';\n","/**\n * Ricochet 2D Behavior Module\n *\n * Exports FSM, types, and behavior descriptor for 2D ricochet/reflection.\n */\n\n// FSM and types\nexport {\n\tRicochet2DFSM,\n\tRicochet2DState,\n\tRicochet2DEvent,\n\ttype Ricochet2DResult,\n\ttype Ricochet2DCollisionContext,\n} from './ricochet-2d-fsm';\n\n// Behavior descriptor, options, and handle\nexport {\n\tRicochet2DBehavior,\n\ttype Ricochet2DOptions,\n\ttype Ricochet2DHandle,\n} from './ricochet-2d.descriptor';\n\n","/**\n * Movement Sequence 2D Behavior Module\n *\n * Exports FSM, types, and behavior descriptor for 2D movement sequencing.\n */\n\n// FSM and types\nexport {\n\tMovementSequence2DFSM,\n\tMovementSequence2DState,\n\tMovementSequence2DEvent,\n\ttype MovementSequence2DStep,\n\ttype MovementSequence2DMovement,\n\ttype MovementSequence2DProgress,\n\ttype MovementSequence2DCurrentStep,\n} from './movement-sequence-2d-fsm';\n\n// Behavior descriptor, options, and handle\nexport {\n\tMovementSequence2DBehavior,\n\ttype MovementSequence2DOptions,\n\ttype MovementSequence2DHandle,\n} from './movement-sequence-2d.descriptor';\n","import { GameEntity } from '../entities/entity';\nimport { Ricochet2DHandle, Ricochet2DResult } from '../behaviors/ricochet-2d/ricochet-2d.descriptor';\nimport { WorldBoundary2DHandle } from '../behaviors/world-boundary-2d/world-boundary-2d.descriptor';\nimport { MoveableEntity } from '../actions/capabilities/moveable';\n\n/**\n * Coordinator that bridges WorldBoundary2DBehavior and Ricochet2DBehavior.\n * \n * Automatically handles:\n * 1. Checking boundary hits\n * 2. Computing collision normals\n * 3. Requesting ricochet result\n * 4. Applying movement\n */\nexport class BoundaryRicochetCoordinator {\n constructor(\n private entity: GameEntity<any> & MoveableEntity,\n private boundary: WorldBoundary2DHandle,\n private ricochet: Ricochet2DHandle\n ) {}\n\n /**\n * Update loop - call this every frame\n */\n public update(): Ricochet2DResult | null {\n const hits = this.boundary.getLastHits();\n if (!hits) return null;\n\n const anyHit = hits.left || hits.right || hits.top || hits.bottom;\n if (!anyHit) return null;\n\n // Compute collision normal from boundary hits\n let normalX = 0;\n let normalY = 0;\n if (hits.left) normalX = 1;\n if (hits.right) normalX = -1;\n if (hits.bottom) normalY = 1;\n if (hits.top) normalY = -1;\n\n // Compute ricochet result\n return this.ricochet.getRicochet({\n entity: this.entity,\n contact: { normal: { x: normalX, y: normalY } },\n });\n }\n}\n","/**\n * Behaviors Module Index\n *\n * Re-exports all ECS components and behaviors.\n */\n\n// Core Behavior System Interface\nexport type { BehaviorSystem, BehaviorSystemFactory } from './behavior-system';\n\n// Behavior Descriptor Pattern\nexport { defineBehavior } from './behavior-descriptor';\nexport type {\n BehaviorDescriptor,\n BehaviorRef,\n BehaviorHandle,\n DefineBehaviorConfig,\n} from './behavior-descriptor';\n\nexport { useBehavior } from './use-behavior';\n\n// Core ECS Components\nexport {\n type TransformComponent,\n type PhysicsBodyComponent,\n createTransformComponent,\n createPhysicsBodyComponent,\n} from './components';\n\n// Physics Behaviors\nexport { PhysicsStepBehavior } from './physics-step.behavior';\nexport { PhysicsSyncBehavior } from './physics-sync.behavior';\n\n// Thruster Module (components, FSM, and behaviors)\nexport * from './thruster';\n\n// Screen Wrap Module\nexport * from './screen-wrap';\n\n// World Boundary 2D Module\nexport * from './world-boundary-2d';\n\n// Ricochet 2D Module\nexport * from './ricochet-2d';\n\n// Movement Sequence 2D Module\nexport * from './movement-sequence-2d';\n\n// Coordinators\nexport * from '../coordinators/boundary-ricochet.coordinator';\n","// Core game functionality\nexport { createGame, Game } from '../lib/game/game';\nexport type { ZylemGameConfig } from '../lib/game/game-interfaces';\nexport { gameConfig } from '../lib/game/game-config';\n\nexport { createStage } from '../lib/stage/stage';\nexport { entitySpawner } from '../lib/stage/entity-spawner';\nexport type { StageOptions, LoadingEvent } from '../lib/stage/zylem-stage';\nexport type { StageBlueprint } from '../lib/core/blueprints';\nexport { StageManager, stageState } from '../lib/stage/stage-manager';\n\nexport { vessel } from '../lib/core/vessel';\n\n// Camera\nexport { createCamera } from '../lib/camera/camera';\nexport type { PerspectiveType } from '../lib/camera/perspective';\nexport { Perspectives } from '../lib/camera/perspective';\n\n// Utility types\nexport type { Vect3 } from '../lib/core/utility/vector';\n\n// Entities\nexport { createBox } from '../lib/entities/box';\nexport { createSphere } from '../lib/entities/sphere';\nexport { createSprite } from '../lib/entities/sprite';\nexport { createPlane } from '../lib/entities/plane';\nexport { createZone } from '../lib/entities/zone';\nexport { createActor } from '../lib/entities/actor';\nexport { createText } from '../lib/entities/text';\nexport { createRect } from '../lib/entities/rect';\nexport { createDisk } from '../lib/entities/disk';\nexport { createEntityFactory, type TemplateFactory } from '../lib/entities/entity-factory';\nexport { ZylemBox } from '../lib/entities/box';\n\n// ECS Components & Behaviors (new thruster system)\nexport * from '../lib/behaviors';\n\n// Capabilities\nexport { makeMoveable } from '../lib/actions/capabilities/moveable';\nexport { makeRotatable } from '../lib/actions/capabilities/rotatable';\nexport { makeTransformable } from '../lib/actions/capabilities/transformable';\nexport { rotatable } from '../lib/actions/capabilities/rotatable';\nexport { moveable } from '../lib/actions/capabilities/moveable';\nexport { rotateInDirection } from '../lib/actions/capabilities/rotatable';\nexport { move } from '../lib/actions/capabilities/moveable';\nexport { resetVelocity } from '../lib/actions/capabilities/moveable';\n\n\n// Destruction utilities\n// Destruction utilities\nexport { destroy } from '../lib/entities/destroy';\n\n// Sounds\nexport { ricochetSound, pingPongBeep } from '../lib/sounds';\n\n// External dependencies - these will be in separate vendor chunks\nexport { Howl } from 'howler';\nexport * as THREE from 'three';\nexport * as RAPIER from '@dimforge/rapier3d-compat';\n\n// Update helpers\nexport { globalChange, globalChanges, variableChange, variableChanges } from '../lib/actions/global-change';\n\n// State management - standalone functions\nexport { setGlobal, getGlobal, createGlobal, onGlobalChange, onGlobalChanges, getGlobals, clearGlobalSubscriptions } from '../lib/game/game-state';\nexport { setVariable, getVariable, createVariable, onVariableChange, onVariableChanges } from '../lib/stage/stage-state';\n\n// Debug state - exposed for direct mutation by editor integration\nexport { debugState, setDebugTool, setPaused, type DebugTools } from '../lib/debug/debug-state';\n\n// Web Components\nexport { ZylemGameElement, type ZylemGameState } from '../web-components/zylem-game';\n\n// Lifecycle types\nexport type { SetupContext, UpdateContext } from '../lib/core/base-node-life-cycle';\n\n// Interfaces\nexport type { StageEntity } from '../lib/interfaces/entity';\n\n// Entity type symbols for getEntityByName type inference\nexport { \n\tTEXT_TYPE, SPRITE_TYPE, BOX_TYPE, SPHERE_TYPE, \n\tRECT_TYPE, PLANE_TYPE, ZONE_TYPE, ACTOR_TYPE \n} from '../lib/types/entity-type-map';\n\n// Events\nexport {\n\tEventEmitterDelegate,\n\tzylemEventBus,\n\ttype ZylemEvents,\n\ttype GameEvents,\n\ttype StageEvents,\n\ttype EntityEvents,\n\ttype GameLoadingPayload,\n\ttype StateDispatchPayload,\n\ttype StageConfigPayload,\n\ttype EntityConfigPayload,\n} from '../lib/events';\n\n// Shaders\nexport { fireShader } from '../lib/graphics/shaders/fire.shader';\nexport { starShader } from '../lib/graphics/shaders/star.shader';\nexport { standardShader } from '../lib/graphics/shaders/standard.shader';\nexport { debugShader } from '../lib/graphics/shaders/debug.shader';\nexport { objectVertexShader } from '../lib/graphics/shaders/vertex/object.shader';\nexport type { ZylemShaderObject } from '../lib/graphics/material';\n","import { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BufferGeometry, Object3D, SkinnedMesh, Mesh, MeshStandardMaterial, Group, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { createEntity } from './create';\nimport { UpdateContext, UpdateFunction } from '../core/base-node-life-cycle';\nimport { EntityAssetLoader } from '../core/entity-asset-loader';\nimport { EntityLoaderDelegate } from './delegates/loader';\nimport { Vec3 } from '../core/vector';\nimport { AnimationDelegate, AnimationOptions } from './delegates/animation';\nimport { MaterialOptions } from '../graphics/material';\nimport { DebugInfoProvider } from './delegates/debug';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { commonDefaults } from './common';\nimport { standardShader } from '~/api/main';\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport type CollisionShapeType = 'capsule' | 'model';\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n\tcollisionShape?: CollisionShapeType;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\t...commonDefaults,\n\tcollision: {\n\t\tstatic: false,\n\t\tsize: new Vector3(0.5, 0.5, 0.5),\n\t\tposition: new Vector3(0, 0, 0),\n\t},\n\tmaterial: {\n\t\tshader: standardShader\n\t},\n\tanimations: [],\n\tmodels: [],\n\tcollisionShape: 'capsule',\n};\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate objectModel: Group | null = null;\n\tprivate collisionShape: CollisionShapeType = 'capsule';\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t\tthis.collisionShape = data.collisionShape ?? 'capsule';\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tif (this.collisionShape === 'model') {\n\t\t\treturn this.createColliderFromModel(this.objectModel, options);\n\t\t}\n\t\treturn this.createCapsuleCollider(options);\n\t}\n\n\t/**\n\t * Create a capsule collider based on size options (character controller style).\n\t */\n\tprivate createCapsuleCollider(options: ZylemActorOptions): ColliderDesc {\n\t\tconst size = options.collision?.size ?? options.size ?? { x: 0.5, y: 1, z: 0.5 };\n\t\tconst halfHeight = ((size as any).y || 1);\n\t\tconst radius = Math.max((size as any).x || 0.5, (size as any).z || 0.5);\n\t\tlet colliderDesc = ColliderDesc.capsule(halfHeight, radius);\n\t\tcolliderDesc.setSensor(false);\n\t\tcolliderDesc.setTranslation(0, halfHeight + radius, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n\n\t/**\n\t * Create a collider based on model geometry (works with Mesh and SkinnedMesh).\n\t * If collision.size and collision.position are provided, use those instead of computing from geometry.\n\t */\n\tprivate createColliderFromModel(objectModel: Group | null, options: ZylemActorOptions): ColliderDesc {\n\t\tconst collisionSize = options.collision?.size;\n\t\tconst collisionPosition = options.collision?.position;\n\n\t\t// If user provided explicit size, use that instead of computing from model\n\t\tif (collisionSize) {\n\t\t\tconst halfWidth = (collisionSize as any).x / 2;\n\t\t\tconst halfHeight = (collisionSize as any).y / 2;\n\t\t\tconst halfDepth = (collisionSize as any).z / 2;\n\n\t\t\tlet colliderDesc = ColliderDesc.cuboid(halfWidth, halfHeight, halfDepth);\n\t\t\tcolliderDesc.setSensor(false);\n\n\t\t\t// Use user-provided position or default to center\n\t\t\tconst posX = collisionPosition ? (collisionPosition as any).x : 0;\n\t\t\tconst posY = collisionPosition ? (collisionPosition as any).y : halfHeight;\n\t\t\tconst posZ = collisionPosition ? (collisionPosition as any).z : 0;\n\t\t\tcolliderDesc.setTranslation(posX, posY, posZ);\n\t\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\t\treturn colliderDesc;\n\t\t}\n\n\t\t// Fall back to computing from model geometry\n\t\tif (!objectModel) return this.createCapsuleCollider(options);\n\n\t\t// Find first Mesh (SkinnedMesh or regular Mesh)\n\t\tlet foundGeometry: BufferGeometry | null = null;\n\t\tobjectModel.traverse((child) => {\n\t\t\tif (!foundGeometry && (child as any).isMesh) {\n\t\t\t\tfoundGeometry = (child as Mesh).geometry as BufferGeometry;\n\t\t\t}\n\t\t});\n\n\t\tif (!foundGeometry) return this.createCapsuleCollider(options);\n\n\t\tconst geometry: BufferGeometry = foundGeometry;\n\t\tgeometry.computeBoundingBox();\n\t\tconst box = geometry.boundingBox;\n\t\tif (!box) return this.createCapsuleCollider(options);\n\n\t\tconst height = box.max.y - box.min.y;\n\t\tconst width = box.max.x - box.min.x;\n\t\tconst depth = box.max.z - box.min.z;\n\n\t\t// Create box collider based on mesh bounds\n\t\tlet colliderDesc = ColliderDesc.cuboid(width / 2, height / 2, depth / 2);\n\t\tcolliderDesc.setSensor(false);\n\t\t// Position collider at center of model\n\t\tconst centerY = (box.max.y + box.min.y) / 2;\n\t\tcolliderDesc.setTranslation(0, centerY, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n}\n\nclass ActorBuilder extends EntityBuilder<ZylemActor, ZylemActorOptions> {\n\tprotected createEntity(options: Partial<ZylemActorOptions>): ZylemActor {\n\t\treturn new ZylemActor(options);\n\t}\n}\n\nexport const ACTOR_TYPE = Symbol('Actor');\n\nexport class ZylemActor extends GameEntity<ZylemActorOptions> implements EntityLoaderDelegate, DebugInfoProvider {\n\tstatic type = ACTOR_TYPE;\n\n\tprivate _object: Object3D | null = null;\n\tprivate _animationDelegate: AnimationDelegate | null = null;\n\tprivate _modelFileNames: string[] = [];\n\tprivate _assetLoader: EntityAssetLoader = new EntityAssetLoader();\n\n\tcontrolledRotation: boolean = false;\n\n\tconstructor(options?: ZylemActorOptions) {\n\t\tsuper();\n\t\tthis.options = { ...actorDefaults, ...options };\n\t\t// Add actor-specific update to the lifecycle callbacks\n\t\tthis.prependUpdate(this.actorUpdate.bind(this) as UpdateFunction<this>);\n\t\tthis.controlledRotation = true;\n\t}\n\n\t/**\n\t * Initiates model and animation loading in background (deferred).\n\t * Call returns immediately; assets will be ready on subsequent updates.\n\t */\n\tload(): void {\n\t\tthis._modelFileNames = this.options.models || [];\n\t\t// Start async loading in background\n\t\tthis.loadModelsDeferred();\n\t}\n\n\t/**\n\t * Returns current data synchronously.\n\t * May return null values if loading is still in progress.\n\t */\n\tdata(): any {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t\tcollisionShape: this.options.collisionShape,\n\t\t};\n\t}\n\n\tactorUpdate(params: UpdateContext<ZylemActorOptions>): void {\n\t\tthis._animationDelegate?.update(params.delta);\n\t}\n\n\t/**\n\t * Clean up actor resources including animations, models, and groups\n\t */\n\tactorDestroy(): void {\n\t\t// Stop and dispose animation delegate\n\t\tif (this._animationDelegate) {\n\t\t\tthis._animationDelegate.dispose();\n\t\t\tthis._animationDelegate = null;\n\t\t}\n\n\t\t// Dispose geometries and materials from loaded object\n\t\tif (this._object) {\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tconst mesh = child as SkinnedMesh;\n\t\t\t\t\tmesh.geometry?.dispose();\n\t\t\t\t\tif (Array.isArray(mesh.material)) {\n\t\t\t\t\t\tmesh.material.forEach(m => m.dispose());\n\t\t\t\t\t} else if (mesh.material) {\n\t\t\t\t\t\tmesh.material.dispose();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._object = null;\n\t\t}\n\n\t\t// Clear group reference\n\t\tif (this.group) {\n\t\t\tthis.group.clear();\n\t\t\tthis.group = null as any;\n\t\t}\n\n\t\t// Clear file name references\n\t\tthis._modelFileNames = [];\n\t}\n\n\t/**\n\t * Deferred loading - starts async load and updates entity when complete.\n\t * Called by synchronous load() method.\n\t */\n\tprivate loadModelsDeferred(): void {\n\t\tif (this._modelFileNames.length === 0) return;\n\n\t\t// Emit loading started event\n\t\tthis.dispatch('entity:model:loading', {\n\t\t\tentityId: this.uuid,\n\t\t\tfiles: this._modelFileNames\n\t\t});\n\n\t\tconst promises = this._modelFileNames.map(file => this._assetLoader.loadFile(file));\n\t\tPromise.all(promises).then(results => {\n\t\t\tif (results[0]?.object) {\n\t\t\t\tthis._object = results[0].object;\n\t\t\t}\n\t\t\t// Count meshes for the loaded event\n\t\t\tlet meshCount = 0;\n\t\t\tif (this._object) {\n\t\t\t\tthis._object.traverse((child) => {\n\t\t\t\t\tif ((child as any).isMesh) meshCount++;\n\t\t\t\t});\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.attach(this._object);\n\t\t\t\tthis.group.scale.set(\n\t\t\t\t\tthis.options.scale?.x || 1,\n\t\t\t\t\tthis.options.scale?.y || 1,\n\t\t\t\t\tthis.options.scale?.z || 1\n\t\t\t\t);\n\n\t\t\t\t// Apply material overrides if specified\n\t\t\t\tthis.applyMaterialOverrides();\n\n\t\t\t\t// Load animations after model is ready\n\t\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\t\tthis._animationDelegate.loadAnimations(this.options.animations || []).then(() => {\n\t\t\t\t\tthis.dispatch('entity:animation:loaded', {\n\t\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\t\tanimationCount: this.options.animations?.length || 0\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Emit model loaded event\n\t\t\tthis.dispatch('entity:model:loaded', {\n\t\t\t\tentityId: this.uuid,\n\t\t\t\tsuccess: !!this._object,\n\t\t\t\tmeshCount\n\t\t\t});\n\t\t});\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\t/**\n\t * Apply material overrides from options to all meshes in the loaded model.\n\t * Only applies if material options are explicitly specified (not just defaults).\n\t */\n\tprivate applyMaterialOverrides(): void {\n\t\tconst materialOptions = this.options.material;\n\t\t// Only apply if user specified material options beyond defaults\n\t\tif (!materialOptions || (!materialOptions.color && !materialOptions.path)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._object) return;\n\n\t\tthis._object.traverse((child) => {\n\t\t\tif ((child as any).isMesh) {\n\t\t\t\tconst mesh = child as Mesh;\n\t\t\t\tif (materialOptions.color) {\n\t\t\t\t\t// Create new material with the specified color\n\t\t\t\t\tconst newMaterial = new MeshStandardMaterial({\n\t\t\t\t\t\tcolor: materialOptions.color,\n\t\t\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\t\t\tfog: true,\n\t\t\t\t\t});\n\t\t\t\t\tmesh.castShadow = true;\n\t\t\t\t\tmesh.receiveShadow = true;\n\t\t\t\t\tmesh.material = newMaterial;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\t/**\n\t * Provide custom debug information for the actor\n\t * This will be merged with the default debug information\n\t */\n\tgetDebugInfo(): Record<string, any> {\n\t\tconst debugInfo: Record<string, any> = {\n\t\t\ttype: 'Actor',\n\t\t\tmodels: this._modelFileNames.length > 0 ? this._modelFileNames : 'none',\n\t\t\tmodelLoaded: !!this._object,\n\t\t\tscale: this.options.scale ?\n\t\t\t\t`${this.options.scale.x}, ${this.options.scale.y}, ${this.options.scale.z}` :\n\t\t\t\t'1, 1, 1',\n\t\t};\n\n\t\t// Add animation info if available\n\t\tif (this._animationDelegate) {\n\t\t\tdebugInfo.currentAnimation = this._animationDelegate.currentAnimationKey || 'none';\n\t\t\tdebugInfo.animationsCount = this.options.animations?.length || 0;\n\t\t}\n\n\t\t// Add mesh info if model is loaded\n\t\tif (this._object) {\n\t\t\tlet meshCount = 0;\n\t\t\tlet vertexCount = 0;\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tmeshCount++;\n\t\t\t\t\tconst geometry = (child as SkinnedMesh).geometry;\n\t\t\t\t\tif (geometry && geometry.attributes.position) {\n\t\t\t\t\t\tvertexCount += geometry.attributes.position.count;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tdebugInfo.meshCount = meshCount;\n\t\t\tdebugInfo.vertexCount = vertexCount;\n\t\t}\n\n\t\treturn debugInfo;\n\t}\n}\n\ntype ActorOptions = BaseNode | ZylemActorOptions;\n\nexport function createActor(...args: Array<ActorOptions>): ZylemActor {\n\treturn createEntity<ZylemActor, ZylemActorOptions>({\n\t\targs,\n\t\tdefaultConfig: actorDefaults,\n\t\tEntityClass: ZylemActor,\n\t\tBuilderClass: ActorBuilder,\n\t\tCollisionBuilderClass: ActorCollisionBuilder,\n\t\tentityType: ZylemActor.type\n\t});\n}","export { createBox, ZylemBox } from '../lib/entities/box';\nexport { createSphere } from '../lib/entities/sphere';\nexport { createSprite } from '../lib/entities/sprite';\nexport { createPlane } from '../lib/entities/plane';\nexport { createZone } from '../lib/entities/zone';\nexport { createActor } from '../lib/entities/actor';\nexport { createText } from '../lib/entities/text';\nexport { createRect } from '../lib/entities/rect';\n"],"mappings":"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","names":["all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map","Mesh","Color","RepeatWrapping","ShaderMaterial","Vector2","Vector3","fragment","BufferGeometry","Mesh","Color","MeshStandardMaterial","MeshPhongMaterial","x","y","z","toDeg","Color","Vector3","ColliderDesc","Vector3","ColliderDesc","ColliderDesc","Group","Quaternion","Vector3","TextureLoader","BufferGeometry","ColliderDesc","Vector2","Vector3","scale","ActiveCollisionTypes","ColliderDesc","Vector3","Color","Group","ThreeSprite","SpriteMaterial","Vector2","Color","Group","ThreeSprite","SpriteMaterial","CanvasTexture","LinearFilter","Vector2","ClampToEdgeWrapping","ShaderMaterial","Mesh","PlaneGeometry","Vector3","ActiveCollisionTypes","ColliderDesc","MeshStandardMaterial","Group","Vector3","colliderDesc"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/entities/box.ts","../src/lib/entities/entity.ts","../src/lib/systems/transformable.system.ts","../src/lib/core/flags.ts","../src/lib/core/base-node.ts","../../../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/src/index.ts","../src/lib/events/event-emitter-delegate.ts","../src/lib/events/zylem-events.ts","../src/lib/actions/capabilities/transform-store.ts","../src/lib/actions/capabilities/moveable.ts","../src/lib/actions/capabilities/rotatable.ts","../src/lib/actions/capabilities/transformable.ts","../src/lib/entities/parts/collision-factories.ts","../src/lib/collision/collision-builder.ts","../src/lib/entities/common.ts","../src/lib/graphics/shaders/vertex/object.shader.ts","../src/lib/graphics/shaders/standard.shader.ts","../src/lib/entities/delegates/debug.ts","../src/lib/entities/parts/mesh-factories.ts","../src/lib/graphics/material.ts","../src/lib/core/utility/strings.ts","../src/lib/core/asset-manager.ts","../src/lib/core/loaders/texture-loader.ts","../src/lib/core/loaders/gltf-loader.ts","../src/lib/core/loaders/fbx-loader.ts","../src/lib/core/loaders/obj-loader.ts","../src/lib/core/loaders/audio-loader.ts","../src/lib/core/loaders/file-loader.ts","../src/lib/entities/sphere.ts","../src/lib/entities/sprite.ts","../src/lib/entities/builder.ts","../src/lib/graphics/mesh.ts","../src/lib/entities/delegates/loader.ts","../src/lib/entities/create.ts","../src/lib/entities/plane.ts","../src/lib/graphics/geometries/XZPlaneGeometry.ts","../src/lib/entities/zone.ts","../src/lib/game/game-state.ts","../src/lib/entities/actor.ts","../src/lib/core/entity-asset-loader.ts","../src/lib/entities/delegates/animation.ts","../src/lib/entities/text.ts","../src/lib/entities/rect.ts","../src/lib/entities/cone.ts","../src/lib/entities/pyramid.ts","../src/lib/entities/cylinder.ts","../src/lib/entities/pill.ts"],"sourcesContent":["import { Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { boxMesh } from './parts/mesh-factories';\nimport { boxCollision } from './parts/collision-factories';\n\ntype ZylemBoxOptions = GameEntityOptions;\n\nconst boxDefaults: ZylemBoxOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n};\n\nexport const BOX_TYPE = Symbol('Box');\n\nexport class ZylemBox extends GameEntity<ZylemBoxOptions> {\n\tstatic type = BOX_TYPE;\n\n\tconstructor(options?: ZylemBoxOptions) {\n\t\tsuper();\n\t\tthis.options = { ...boxDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\tconst { x: sizeX, y: sizeY, z: sizeZ } = this.options.size ?? { x: 1, y: 1, z: 1 };\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemBox.type),\n\t\t\tsize: `${sizeX}, ${sizeY}, ${sizeZ}`,\n\t\t};\n\t}\n}\n\ntype BoxOptions = BaseNode | Partial<ZylemBoxOptions>;\n\nexport function createBox(...args: Array<BoxOptions>): ZylemBox {\n\tconst options = mergeArgs(args, boxDefaults);\n\tconst entity = new ZylemBox(options);\n\tentity.add(\n\t\tboxMesh({ size: options.size, material: options.material, color: options.color }),\n\t\tboxCollision({\n\t\t\tsize: options.size,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn entity;\n}\n","import { Mesh, Material, ShaderMaterial, Group, Color, Vector3 } from 'three';\nimport {\n\tCollider,\n\tColliderDesc,\n\tRigidBody,\n\tRigidBodyDesc,\n\tVector,\n} from '@dimforge/rapier3d-compat';\nimport { position, rotation, scale } from '../systems/transformable.system';\nimport { Vec3 } from '../core/vector';\nimport { MaterialBuilder, MaterialOptions } from '../graphics/material';\nimport { CollisionOptions } from '../collision/collision-builder';\nimport { BaseNode } from '../core/base-node';\nimport {\n\tDestroyContext,\n\tSetupContext,\n\tUpdateContext,\n\tLoadedContext,\n\tCleanupContext,\n} from '../core/base-node-life-cycle';\nimport type { EntityMeshBuilder, EntityCollisionBuilder } from './builder';\nimport { Behavior } from '../behaviors/behavior';\nimport {\n\tEventEmitterDelegate,\n\tzylemEventBus,\n\ttype EntityEvents,\n} from '../events';\nimport type {\n\tBehaviorDescriptor,\n\tBehaviorRef,\n\tBehaviorHandle,\n} from '../behaviors/behavior-descriptor';\nimport type { TransformState } from '../actions/capabilities/transform-store';\nimport { createTransformStore } from '../actions/capabilities/transform-store';\nimport { makeTransformable } from '../actions/capabilities/transformable';\nimport type { MoveableEntity } from '../actions/capabilities/moveable';\nimport type { RotatableEntityAPI } from '../actions/capabilities/rotatable';\nimport { isCollisionComponent, type CollisionComponent } from './parts/collision-factories';\nimport type { NodeInterface } from '../core/node-interface';\nimport { commonDefaults } from './common';\nimport type { Action } from '../actions/action';\n\nexport interface CollisionContext<\n\tT,\n\tO extends GameEntityOptions,\n\tTGlobals extends Record<string, unknown> = any,\n> {\n\tentity: T;\n\t// Use 'any' for other's options type to break recursive type variance issues\n\tother: GameEntity<O | any>;\n\tglobals: TGlobals;\n}\n\nexport interface CollisionDelegate<T, O extends GameEntityOptions> {\n\t// Use 'any' for entity and options types to avoid contravariance issues\n\t// with function parameters. Type safety is still enforced at the call site via onCollision()\n\tcollision?: ((params: CollisionContext<any, any>) => void)[];\n}\n\nexport type IBuilder<BuilderOptions = any> = {\n\tpreBuild: (options: BuilderOptions) => BuilderOptions;\n\tbuild: (options: BuilderOptions) => BuilderOptions;\n\tpostBuild: (options: BuilderOptions) => BuilderOptions;\n};\n\nexport type GameEntityOptions = {\n\tname?: string;\n\tcolor?: Color;\n\tsize?: Vec3;\n\tposition?: Vec3;\n\tbatched?: boolean;\n\tcollision?: Partial<CollisionOptions>;\n\tmaterial?: Partial<MaterialOptions>;\n\tcustom?: { [key: string]: any };\n\tcollisionType?: string;\n\tcollisionGroup?: string;\n\tcollisionFilter?: string[];\n\t_builders?: {\n\t\tmeshBuilder?: IBuilder | EntityMeshBuilder | null;\n\t\tcollisionBuilder?: IBuilder | EntityCollisionBuilder | null;\n\t\tmaterialBuilder?: MaterialBuilder | null;\n\t};\n};\n\nexport abstract class GameEntityLifeCycle {\n\tabstract _setup(params: SetupContext<this>): void;\n\tabstract _update(params: UpdateContext<this>): void;\n\tabstract _destroy(params: DestroyContext<this>): void;\n}\n\nexport interface EntityDebugInfo {\n\tbuildInfo: () => Record<string, string>;\n}\n\nexport class GameEntity<O extends GameEntityOptions>\n\textends BaseNode<O>\n\timplements GameEntityLifeCycle, EntityDebugInfo, MoveableEntity, RotatableEntityAPI {\n\tpublic behaviors: Behavior[] = [];\n\tpublic group: Group | undefined;\n\tpublic mesh: Mesh | undefined;\n\tpublic materials: Material[] | undefined;\n\tpublic bodyDesc: RigidBodyDesc | null = null;\n\tpublic body: RigidBody | null = null;\n\tpublic colliderDesc: ColliderDesc | undefined;\n\tpublic collider: Collider | undefined;\n\tpublic custom: Record<string, any> = {};\n\n\t// Compound entity support: multiple colliders and meshes\n\t/** All collider descriptions for this entity (including primary) */\n\tpublic colliderDescs: ColliderDesc[] = [];\n\t/** All colliders attached to this entity's rigid body */\n\tpublic colliders: Collider[] = [];\n\t/** Additional meshes for compound visual entities (added via add()) */\n\tpublic compoundMeshes: Mesh[] = [];\n\n\tpublic debugInfo: Record<string, any> = {};\n\tpublic debugMaterial: ShaderMaterial | undefined;\n\n\tpublic collisionDelegate: CollisionDelegate<this, O> = {\n\t\tcollision: [],\n\t};\n\tpublic collisionType?: string;\n\n\t// Instancing support\n\t/** Batch key for instanced rendering (null if not instanced) */\n\tpublic batchKey: string | null = null;\n\t/** Index within the instanced mesh batch */\n\tpublic instanceId: number = -1;\n\t/** Whether this entity uses instanced rendering */\n\tpublic isInstanced: boolean = false;\n\n\t// Event delegate for dispatch/listen API\n\tprotected eventDelegate = new EventEmitterDelegate<EntityEvents>();\n\n\t// Behavior references (new ECS pattern)\n\tprivate behaviorRefs: BehaviorRef[] = [];\n\n\t// Transform store for batched physics updates (auto-created in create())\n\tpublic transformStore: TransformState;\n\n\t// Movement & rotation methods are assigned at runtime by makeTransformable.\n\t// The `implements` clause above ensures the type contract; declarations below\n\t// satisfy the compiler while the constructor fills them in.\n\tmoveX!: (delta: number) => void;\n\tmoveY!: (delta: number) => void;\n\tmoveZ!: (delta: number) => void;\n\tmoveXY!: (deltaX: number, deltaY: number) => void;\n\tmoveXZ!: (deltaX: number, deltaZ: number) => void;\n\tmove!: (vector: Vector3) => void;\n\tresetVelocity!: () => void;\n\tmoveForwardXY!: (delta: number, rotation2DAngle: number) => void;\n\tgetPosition!: () => Vector | null;\n\tgetVelocity!: () => Vector | null;\n\tsetPosition!: (x: number, y: number, z: number) => void;\n\tsetPositionX!: (x: number) => void;\n\tsetPositionY!: (y: number) => void;\n\tsetPositionZ!: (z: number) => void;\n\twrapAroundXY!: (boundsX: number, boundsY: number) => void;\n\twrapAround3D!: (boundsX: number, boundsY: number, boundsZ: number) => void;\n\trotateInDirection!: (moveVector: Vector3) => void;\n\trotateYEuler!: (amount: number) => void;\n\trotateEuler!: (eulerRotation: Vector3) => void;\n\trotateX!: (delta: number) => void;\n\trotateY!: (delta: number) => void;\n\trotateZ!: (delta: number) => void;\n\tsetRotationY!: (y: number) => void;\n\tsetRotationX!: (x: number) => void;\n\tsetRotationZ!: (z: number) => void;\n\tsetRotationDegrees!: (x: number, y: number, z: number) => void;\n\tsetRotationDegreesY!: (y: number) => void;\n\tsetRotationDegreesX!: (x: number) => void;\n\tsetRotationDegreesZ!: (z: number) => void;\n\tsetRotation!: (x: number, y: number, z: number) => void;\n\tgetRotation!: () => any;\n\n\tconstructor() {\n\t\tsuper();\n\t\tthis.transformStore = createTransformStore();\n\t\tmakeTransformable(this);\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Composable add() - accepts Mesh, CollisionComponent, or child entities\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add meshes, collision components, or child entities to this entity.\n\t * Supports fluent chaining: `entity.add(boxMesh()).add(boxCollision())`.\n\t *\n\t * - `Mesh`: First mesh becomes the primary mesh; subsequent meshes are\n\t * compound meshes grouped together.\n\t * - `CollisionComponent`: First sets bodyDesc + colliderDesc; subsequent\n\t * add extra colliders to the same rigid body.\n\t * - `NodeInterface`: Added as a child entity (delegates to BaseNode.add).\n\t */\n\tpublic add(...components: Array<NodeInterface | Mesh | CollisionComponent>): this {\n\t\tfor (const component of components) {\n\t\t\tif (component instanceof Mesh) {\n\t\t\t\tthis.addMeshComponent(component);\n\t\t\t} else if (isCollisionComponent(component)) {\n\t\t\t\tthis.addCollisionComponent(component);\n\t\t\t} else {\n\t\t\t\tsuper.add(component as NodeInterface);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\n\tprivate addMeshComponent(mesh: Mesh): void {\n\t\tif (!this.mesh) {\n\t\t\t// First mesh becomes the primary mesh\n\t\t\tthis.mesh = mesh;\n\t\t\tif (!this.materials) {\n\t\t\t\tthis.materials = [];\n\t\t\t}\n\t\t\tif (mesh.material) {\n\t\t\t\tconst mat = mesh.material;\n\t\t\t\tif (Array.isArray(mat)) {\n\t\t\t\t\tthis.materials.push(...mat);\n\t\t\t\t} else {\n\t\t\t\t\tthis.materials.push(mat);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Subsequent meshes are compound meshes\n\t\t\tthis.compoundMeshes.push(mesh);\n\t\t\t// Ensure the entity has a group so all meshes are parented together\n\t\t\tif (!this.group) {\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.add(this.mesh);\n\t\t\t}\n\t\t\tthis.group.add(mesh);\n\t\t}\n\t}\n\n\tprivate addCollisionComponent(collision: CollisionComponent): void {\n\t\tif (!this.bodyDesc) {\n\t\t\t// First collision sets the body description and primary collider\n\t\t\tthis.bodyDesc = collision.bodyDesc;\n\t\t\tthis.colliderDesc = collision.colliderDesc;\n\t\t\tthis.colliderDescs.push(collision.colliderDesc);\n\t\t\t// Apply entity position to the body\n\t\t\tconst pos = this.options?.position ?? { x: 0, y: 0, z: 0 };\n\t\t\tthis.bodyDesc.setTranslation(pos.x, pos.y, pos.z);\n\t\t} else {\n\t\t\t// Subsequent collisions add extra colliders to the same body\n\t\t\tthis.colliderDescs.push(collision.colliderDesc);\n\t\t}\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Actions API -- entity-scoped, self-contained stateful actions\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tprivate _actions: Action[] = [];\n\n\t/**\n\t * Run a fire-and-forget action. Auto-removed when done.\n\t * @example `me.runAction(moveBy({ x: 10, duration: 0.3 }))`\n\t */\n\tpublic runAction<A extends Action>(action: A): A {\n\t\tthis._actions.push(action);\n\t\treturn action;\n\t}\n\n\t/**\n\t * Register a persistent action (throttle, onPress). Not removed when done.\n\t * @example `const press = entity.action(onPress())`\n\t */\n\tpublic action<A extends Action>(action: A): A {\n\t\taction.persistent = true;\n\t\tthis._actions.push(action);\n\t\treturn action;\n\t}\n\n\t/**\n\t * Tick all registered actions. Called automatically before user onUpdate callbacks.\n\t *\n\t * Resets velocity/angularVelocity accumulation before ticking so that\n\t * actions can compose via `+=` without cross-frame build-up.\n\t * (The existing move helpers like `moveXY` use `=` which doesn't accumulate,\n\t * but action composition needs additive writes on a clean slate each frame.)\n\t */\n\tpublic _tickActions(delta: number): void {\n\t\tif (this._actions.length === 0) return;\n\n\t\t// Clear accumulation from the previous frame so that\n\t\t// actions can compose via `+=` on a clean slate each frame.\n\t\tconst store = this.transformStore;\n\t\tstore.velocity.x = 0;\n\t\tstore.velocity.y = 0;\n\t\tstore.velocity.z = 0;\n\t\tstore.dirty.velocity = false;\n\t\tstore.angularVelocity.x = 0;\n\t\tstore.angularVelocity.y = 0;\n\t\tstore.angularVelocity.z = 0;\n\t\tstore.dirty.angularVelocity = false;\n\n\t\tfor (let i = this._actions.length - 1; i >= 0; i--) {\n\t\t\tconst act = this._actions[i];\n\t\t\tact.tick(this, delta);\n\t\t\tif (act.done && !act.persistent) {\n\t\t\t\tthis._actions.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\t// If every non-persistent action finished this frame, zero out\n\t\t// any velocity they wrote so the entity doesn't drift.\n\t\tif (this._actions.length === 0) {\n\t\t\tstore.velocity.x = 0;\n\t\t\tstore.velocity.y = 0;\n\t\t\tstore.velocity.z = 0;\n\t\t\tstore.dirty.velocity = false;\n\t\t\tstore.angularVelocity.x = 0;\n\t\t\tstore.angularVelocity.y = 0;\n\t\t\tstore.angularVelocity.z = 0;\n\t\t\tstore.dirty.angularVelocity = false;\n\t\t}\n\t}\n\n\tpublic create(): this {\n\t\tconst { position: setupPosition } = this.options;\n\t\tconst { x, y, z } = setupPosition || { x: 0, y: 0, z: 0 };\n\t\tthis.behaviors = [\n\t\t\t{ component: position, values: { x, y, z } },\n\t\t\t{ component: scale, values: { x: 0, y: 0, z: 0 } },\n\t\t\t{ component: rotation, values: { x: 0, y: 0, z: 0, w: 0 } },\n\t\t];\n\t\tthis.name = this.options.name || '';\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add collision callbacks\n\t */\n\tpublic onCollision(\n\t\t...callbacks: ((params: CollisionContext<this, O>) => void)[]\n\t): this {\n\t\tconst existing = this.collisionDelegate.collision ?? [];\n\t\tthis.collisionDelegate.collision = [...existing, ...callbacks];\n\t\treturn this;\n\t}\n\n\t/**\n\t * Use a behavior on this entity via typed descriptor.\n\t * Behaviors will be auto-registered as systems when the entity is spawned.\n\t * @param descriptor The behavior descriptor (import from behaviors module)\n\t * @param options Optional overrides for the behavior's default options\n\t * @returns BehaviorHandle with behavior-specific methods for lazy FSM access\n\t */\n\tpublic use<\n\t\tO extends Record<string, any>,\n\t\tH extends Record<string, any> = Record<string, never>,\n\t>(\n\t\tdescriptor: BehaviorDescriptor<O, H>,\n\t\toptions?: Partial<O>,\n\t): BehaviorHandle<O, H> {\n\t\tconst behaviorRef: BehaviorRef<O> = {\n\t\t\tdescriptor: descriptor as BehaviorDescriptor<O, any>,\n\t\t\toptions: { ...descriptor.defaultOptions, ...options } as O,\n\t\t};\n\t\tthis.behaviorRefs.push(behaviorRef as BehaviorRef<any>);\n\n\t\t// Create base handle\n\t\tconst baseHandle = {\n\t\t\tgetFSM: () => behaviorRef.fsm ?? null,\n\t\t\tgetOptions: () => behaviorRef.options,\n\t\t\tref: behaviorRef,\n\t\t};\n\n\t\t// Merge behavior-specific methods if createHandle is provided\n\t\tconst customMethods = descriptor.createHandle?.(behaviorRef) ?? ({} as H);\n\n\t\treturn {\n\t\t\t...baseHandle,\n\t\t\t...customMethods,\n\t\t} as BehaviorHandle<O, H>;\n\t}\n\n\t/**\n\t * Get all behavior references attached to this entity.\n\t * Used by the stage to auto-register required systems.\n\t */\n\tpublic getBehaviorRefs(): BehaviorRef[] {\n\t\treturn this.behaviorRefs;\n\t}\n\n\t/**\n\t * Entity-specific setup - resets actions for a fresh stage session.\n\t * (User callbacks are handled by BaseNode's lifecycleCallbacks.setup)\n\t */\n\tpublic _setup(params: SetupContext<this>): void {\n\t\t// Reset actions for the new stage session.\n\t\t// Remove completed fire-and-forget actions; reset all others\n\t\t// so they replay from the beginning.\n\t\tfor (let i = this._actions.length - 1; i >= 0; i--) {\n\t\t\tconst act = this._actions[i];\n\t\t\tif (act.done && !act.persistent) {\n\t\t\t\tthis._actions.splice(i, 1);\n\t\t\t} else {\n\t\t\t\tact.reset();\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected async _loaded(_params: LoadedContext<this>): Promise<void> { }\n\n\t/**\n\t * Entity-specific update - updates materials.\n\t * Transform changes are applied by the stage after all update callbacks complete.\n\t * (User callbacks are handled by BaseNode's lifecycleCallbacks.update)\n\t */\n\tpublic _update(params: UpdateContext<this>): void {\n\t\tthis.updateMaterials(params);\n\t}\n\n\t/**\n\t * Entity-specific destroy -- reserved for consumer game logic.\n\t * Engine-internal resource disposal runs in _cleanup() instead.\n\t */\n\tpublic _destroy(params: DestroyContext<this>): void { }\n\n\t/**\n\t * Engine-internal resource cleanup -- runs automatically after destroy.\n\t * Disposes GPU/DOM resources (meshes, materials, debug material).\n\t *\n\t * Note: actions, collision callbacks, and behavior refs are intentionally\n\t * NOT cleared here -- they are registered by consumer code at module level\n\t * and must persist across stage reloads. Actions are reset in _setup().\n\t */\n\tprotected _cleanup(_params: CleanupContext<this>): void {\n\t\t// Dispose entity event emitter & subscriptions\n\t\tthis.disposeEvents();\n\n\t\t// Dispose compound meshes\n\t\tfor (const m of this.compoundMeshes) {\n\t\t\tm.geometry?.dispose();\n\t\t\tif (Array.isArray(m.material)) {\n\t\t\t\tm.material.forEach(mat => mat.dispose());\n\t\t\t} else {\n\t\t\t\tm.material?.dispose();\n\t\t\t}\n\t\t}\n\t\tthis.compoundMeshes.length = 0;\n\n\t\t// Dispose debug material\n\t\tthis.debugMaterial?.dispose();\n\t\tthis.debugMaterial = undefined;\n\n\t\t// Remove group from parent (camera or scene)\n\t\tthis.group?.removeFromParent();\n\n\t\t// Note: physics references (body, collider, colliders) are intentionally\n\t\t// NOT nulled here. They are needed by removeEntityByUuid() → world.destroyEntity()\n\t\t// which runs later when the stage processes markedForRemoval entities.\n\t}\n\n\tpublic _collision(other: GameEntity<O>, globals?: any): void {\n\t\tif (this.collisionDelegate.collision?.length) {\n\t\t\tconst callbacks = this.collisionDelegate.collision;\n\t\t\tcallbacks.forEach((callback) => {\n\t\t\t\tcallback({ entity: this, other, globals });\n\t\t\t});\n\t\t}\n\t}\n\n\tprotected updateMaterials(params: any) {\n\t\tif (!this.materials?.length) {\n\t\t\treturn;\n\t\t}\n\t\tfor (const material of this.materials) {\n\t\t\tif (material instanceof ShaderMaterial) {\n\t\t\t\tif (material.uniforms) {\n\t\t\t\t\tmaterial.uniforms.iTime &&\n\t\t\t\t\t\t(material.uniforms.iTime.value += params.delta);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic buildInfo(): Record<string, string> {\n\t\tconst info: Record<string, string> = {};\n\t\tinfo.name = this.name;\n\t\tinfo.uuid = this.uuid;\n\t\tinfo.eid = this.eid.toString();\n\t\treturn info;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Events API\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispatch an event from this entity.\n\t * Events are emitted both locally and to the global event bus.\n\t */\n\tdispatch<K extends keyof EntityEvents>(\n\t\tevent: K,\n\t\tpayload: EntityEvents[K],\n\t): void {\n\t\tthis.eventDelegate.dispatch(event, payload);\n\t\t(zylemEventBus as any).emit(event, payload);\n\t}\n\n\t/**\n\t * Listen for events on this entity instance.\n\t * @returns Unsubscribe function\n\t */\n\tlisten<K extends keyof EntityEvents>(\n\t\tevent: K,\n\t\thandler: (payload: EntityEvents[K]) => void,\n\t): () => void {\n\t\treturn this.eventDelegate.listen(event, handler);\n\t}\n\n\t/**\n\t * Clean up entity event subscriptions.\n\t */\n\tdisposeEvents(): void {\n\t\tthis.eventDelegate.dispose();\n\t}\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Bare entity factory\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a bare entity with no mesh or collision.\n * Use `.add(boxMesh(), boxCollision())` to compose its shape.\n *\n * @example\n * ```ts\n * const box = create({ position: { x: 0, y: 5, z: 0 } })\n * .add(boxMesh({ size: { x: 2, y: 2, z: 2 } }))\n * .add(boxCollision({ size: { x: 2, y: 2, z: 2 } }));\n * ```\n */\nexport function create(options?: Partial<GameEntityOptions>): GameEntity<GameEntityOptions> {\n\tconst entity = new (GameEntity as any)() as GameEntity<GameEntityOptions>;\n\tentity.options = { ...commonDefaults, ...options } as GameEntityOptions;\n\treturn entity;\n}\n","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 * Uses `any` for the type parameter to avoid invariance issues when subclasses\n\t * are assigned to BaseNode references. Type safety is enforced by the public\n\t * onSetup/onUpdate/etc. methods which are typed with `this`.\n\t */\n\tprotected lifecycleCallbacks: LifecycleCallbacks<any> = {\n\t\tsetup: [],\n\t\tloaded: [],\n\t\tupdate: [],\n\t\tdestroy: [],\n\t\tcleanup: [],\n\t};\n\n\tconstructor(args: BaseNodeOptions[] = []) {\n\t\tconst options = args\n\t\t\t.filter(arg => !(arg instanceof BaseNode))\n\t\t\t.reduce((acc, opt) => ({ ...acc, ...opt }), {});\n\t\tthis.options = options as Options;\n\t\tthis.uuid = nanoid();\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Fluent API for adding lifecycle callbacks\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\t/**\n\t * Add setup callbacks to be executed in order during nodeSetup\n\t */\n\tpublic onSetup(...callbacks: Array<SetupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.setup.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add loaded callbacks to be executed in order during nodeLoaded\n\t */\n\tpublic onLoaded(...callbacks: Array<LoadedFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.loaded.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add update callbacks to be executed in order during nodeUpdate\n\t */\n\tpublic onUpdate(...callbacks: Array<UpdateFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.update.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add destroy callbacks to be executed in order during nodeDestroy\n\t */\n\tpublic onDestroy(...callbacks: Array<DestroyFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.destroy.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add cleanup callbacks to be executed in order during nodeCleanup\n\t */\n\tpublic onCleanup(...callbacks: Array<CleanupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.cleanup.push(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepend setup callbacks (run before existing ones)\n\t */\n\tpublic prependSetup(...callbacks: Array<SetupFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.setup.unshift(...callbacks);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Prepend update callbacks (run before existing ones)\n\t */\n\tpublic prependUpdate(...callbacks: Array<UpdateFunction<this>>): this {\n\t\tthis.lifecycleCallbacks.update.unshift(...callbacks);\n\t\treturn this;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Tree structure\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic setParent(parent: NodeInterface | null): void {\n\t\tthis.parent = parent;\n\t}\n\n\tpublic getParent(): NodeInterface | null {\n\t\treturn this.parent;\n\t}\n\n\tpublic add(baseNode: NodeInterface): void {\n\t\tthis.children.push(baseNode);\n\t\tbaseNode.setParent(this);\n\t}\n\n\tpublic remove(baseNode: NodeInterface): void {\n\t\tconst index = this.children.indexOf(baseNode);\n\t\tif (index !== -1) {\n\t\t\tthis.children.splice(index, 1);\n\t\t\tbaseNode.setParent(null);\n\t\t}\n\t}\n\n\tpublic getChildren(): NodeInterface[] {\n\t\treturn this.children;\n\t}\n\n\tpublic isComposite(): boolean {\n\t\treturn this.children.length > 0;\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Abstract methods for subclass implementation\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic abstract create(): T;\n\n\tprotected abstract _setup(params: SetupContext<this>): void;\n\n\tprotected abstract _loaded(params: LoadedContext<this>): Promise<void>;\n\n\tprotected abstract _update(params: UpdateContext<this>): void;\n\n\tprotected abstract _destroy(params: DestroyContext<this>): void;\n\n\tprotected abstract _cleanup(params: CleanupContext<this>): void;\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Node lifecycle execution - runs internal + callback arrays\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic nodeSetup(params: SetupContext<this>) {\n\t\tif (DEBUG_FLAG) { /** */ }\n\t\tthis.markedForRemoval = false;\n\t\tif (typeof this._setup === 'function') {\n\t\t\tthis._setup(params);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.setup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tthis.children.forEach(child => child.nodeSetup(params));\n\t}\n\n\tpublic nodeUpdate(params: UpdateContext<this>): void {\n\t\tif (this.markedForRemoval) {\n\t\t\treturn;\n\t\t}\n\t\tif (typeof this._update === 'function') {\n\t\t\tthis._update(params);\n\t\t}\n\t\t// Tick entity actions before user callbacks so state is fresh\n\t\tif (typeof (this as any)._tickActions === 'function') {\n\t\t\t(this as any)._tickActions(params.delta);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.update) {\n\t\t\tcallback(params);\n\t\t}\n\t\tthis.children.forEach(child => child.nodeUpdate(params));\n\t}\n\n\tpublic nodeDestroy(params: DestroyContext<this>): void {\n\t\t// Guard against re-entry (e.g. destroy called twice during collision loop)\n\t\tif (this.markedForRemoval) return;\n\n\t\tthis.children.forEach(child => child.nodeDestroy(params));\n\n\t\t// Destroy phase -- consumer game logic (onDestroy callbacks + _destroy override)\n\t\tfor (const callback of this.lifecycleCallbacks.destroy) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._destroy === 'function') {\n\t\t\tthis._destroy(params);\n\t\t}\n\t\tthis.markedForRemoval = true;\n\n\t\t// Cleanup phase -- engine-internal resource disposal (onCleanup callbacks + _cleanup override)\n\t\tfor (const callback of this.lifecycleCallbacks.cleanup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._cleanup === 'function') {\n\t\t\tthis._cleanup(params);\n\t\t}\n\t}\n\n\tpublic async nodeLoaded(params: LoadedContext<this>): Promise<void> {\n\t\tif (typeof this._loaded === 'function') {\n\t\t\tawait this._loaded(params);\n\t\t}\n\t\tfor (const callback of this.lifecycleCallbacks.loaded) {\n\t\t\tcallback(params);\n\t\t}\n\t}\n\n\tpublic nodeCleanup(params: CleanupContext<this>): void {\n\t\tthis.children.forEach(child => (child as any).nodeCleanup?.(params));\n\t\tfor (const callback of this.lifecycleCallbacks.cleanup) {\n\t\t\tcallback(params);\n\t\t}\n\t\tif (typeof this._cleanup === 'function') {\n\t\t\tthis._cleanup(params);\n\t\t}\n\t}\n\n\t// ─────────────────────────────────────────────────────────────────────────────\n\t// Options\n\t// ─────────────────────────────────────────────────────────────────────────────\n\n\tpublic getOptions(): Options {\n\t\treturn this.options;\n\t}\n\n\tpublic setOptions(options: Partial<Options>): void {\n\t\tthis.options = { ...this.options, ...options };\n\t}\n}","export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler<T = unknown> = (event: T) => void;\nexport type WildcardHandler<T = Record<string, unknown>> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList<T = unknown> = Array<Handler<T>>;\nexport type WildCardEventHandlerList<T = Record<string, unknown>> = Array<\n\tWildcardHandler<T>\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>\n>;\n\nexport interface Emitter<Events extends Record<EventType, unknown>> {\n\tall: EventHandlerMap<Events>;\n\n\ton<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;\n\ton(type: '*', handler: WildcardHandler<Events>): void;\n\n\toff<Key extends keyof Events>(\n\t\ttype: Key,\n\t\thandler?: Handler<Events[Key]>\n\t): void;\n\toff(type: '*', handler: WildcardHandler<Events>): void;\n\n\temit<Key extends keyof Events>(type: Key, event: Events[Key]): void;\n\temit<Key extends keyof Events>(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt<Events extends Record<EventType, unknown>>(\n\tall?: EventHandlerMap<Events>\n): Emitter<Events> {\n\ttype GenericEventHandler =\n\t\t| Handler<Events[keyof Events]>\n\t\t| WildcardHandler<Events>;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array<GenericEventHandler> | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList<Events[keyof Events]>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList<Events>)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n","import mitt, { Emitter } from 'mitt';\n\n/**\n * Event scope identifier for routing events.\n */\nexport type EventScope = 'game' | 'stage' | 'entity';\n\n/**\n * Reusable delegate for event emission and subscription.\n * Use via composition in Game, Stage, and Entity classes.\n * \n * @example\n * class Game {\n * private eventDelegate = new EventEmitterDelegate<GameEvents>();\n * \n * dispatch<K extends keyof GameEvents>(event: K, payload: GameEvents[K]) {\n * this.eventDelegate.dispatch(event, payload);\n * }\n * }\n */\nexport class EventEmitterDelegate<TEvents extends Record<string, unknown>> {\n\tprivate emitter: Emitter<TEvents>;\n\tprivate unsubscribes: (() => void)[] = [];\n\n\tconstructor() {\n\t\tthis.emitter = mitt<TEvents>();\n\t}\n\n\t/**\n\t * Dispatch an event to all listeners.\n\t */\n\tdispatch<K extends keyof TEvents>(event: K, payload: TEvents[K]): void {\n\t\tthis.emitter.emit(event, payload);\n\t}\n\n\t/**\n\t * Subscribe to an event. Returns an unsubscribe function.\n\t */\n\tlisten<K extends keyof TEvents>(\n\t\tevent: K,\n\t\thandler: (payload: TEvents[K]) => void\n\t): () => void {\n\t\tthis.emitter.on(event, handler);\n\t\tconst unsub = () => this.emitter.off(event, handler);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Subscribe to all events.\n\t */\n\tlistenAll(handler: (type: keyof TEvents, payload: TEvents[keyof TEvents]) => void): () => void {\n\t\tthis.emitter.on('*', handler as any);\n\t\tconst unsub = () => this.emitter.off('*', handler as any);\n\t\tthis.unsubscribes.push(unsub);\n\t\treturn unsub;\n\t}\n\n\t/**\n\t * Clean up all subscriptions.\n\t */\n\tdispose(): void {\n\t\tthis.unsubscribes.forEach(fn => fn());\n\t\tthis.unsubscribes = [];\n\t\tthis.emitter.all.clear();\n\t}\n}\n","import mitt from 'mitt';\nimport type { LoadingEvent } from '../core/interfaces';\n\n/**\n * Payload for game loading events with stage context.\n */\nexport interface GameLoadingPayload extends LoadingEvent {\n\tstageName?: string;\n\tstageIndex?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Game Events\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Payload for stage configuration sent to editor. */\nexport interface StageConfigPayload {\n\tid: string;\n\tbackgroundColor: string;\n\tbackgroundImage: string | null;\n\tgravity: { x: number; y: number; z: number };\n\tinputs: Record<string, string[]>;\n\tvariables: Record<string, unknown>;\n}\n\n/** Payload for entity configuration sent to editor. */\nexport interface EntityConfigPayload {\n\tuuid: string;\n\tname: string;\n\ttype: string;\n\tposition: { x: number; y: number; z: number };\n\trotation: { x: number; y: number; z: number };\n\tscale: { x: number; y: number; z: number };\n}\n\n/** Payload for state dispatch events from game to editor. */\nexport interface StateDispatchPayload {\n\tscope: 'game' | 'stage' | 'entity';\n\tpath: string;\n\tvalue: unknown;\n\tpreviousValue?: unknown;\n\tconfig?: {\n\t\tid: string;\n\t\taspectRatio: number;\n\t\tfullscreen: boolean;\n\t\tbodyBackground: string | undefined;\n\t\tinternalResolution: { width: number; height: number } | undefined;\n\t\tdebug: boolean;\n\t} | null;\n\tstageConfig?: StageConfigPayload | null;\n\tentities?: EntityConfigPayload[] | null;\n}\n\nexport type GameEvents = {\n\t'loading:start': GameLoadingPayload;\n\t'loading:progress': GameLoadingPayload;\n\t'loading:complete': GameLoadingPayload;\n\t'paused': { paused: boolean };\n\t'debug': { enabled: boolean };\n\t'state:dispatch': StateDispatchPayload;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Stage Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type StageEvents = {\n\t'stage:loaded': { stageId: string };\n\t'stage:unloaded': { stageId: string };\n\t'stage:variable:changed': { key: string; value: unknown };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Entity Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type EntityEvents = {\n\t'entity:spawned': { entityId: string; name: string };\n\t'entity:destroyed': { entityId: string };\n\t'entity:collision': { entityId: string; otherId: string };\n\t'entity:model:loading': { entityId: string; files: string[] };\n\t'entity:model:loaded': { entityId: string; success: boolean; meshCount?: number };\n\t'entity:animation:loaded': { entityId: string; animationCount: number };\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Combined Event Map\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport type ZylemEvents = GameEvents & StageEvents & EntityEvents;\n\n/**\n * Global event bus for cross-package communication.\n * \n * Usage:\n * ```ts\n * import { zylemEventBus } from '@zylem/game-lib';\n * \n * // Subscribe\n * const unsub = zylemEventBus.on('loading:progress', (e) => console.log(e));\n * \n * // Emit\n * zylemEventBus.emit('loading:progress', { type: 'progress', progress: 0.5 });\n * \n * // Cleanup\n * unsub();\n * ```\n */\nexport const zylemEventBus = mitt<ZylemEvents>();\n","import { proxy } from 'valtio';\n\n/**\n * Transform state managed by Valtio for batched physics updates.\n * \n * This store accumulates transformation intents during the frame,\n * then applies them all at once after onUpdate() callbacks complete.\n * \n * Design decisions:\n * - Position: Accumulated deltas (additive)\n * - Rotation: Last value wins (replacement)\n * - Velocity: Accumulated deltas (additive)\n * - Angular velocity: Accumulated deltas (additive)\n */\nexport interface TransformState {\n\t/** Position deltas to be applied (accumulated) */\n\tposition: { x: number; y: number; z: number };\n\t\n\t/** Rotation quaternion (last value wins) */\n\trotation: { x: number; y: number; z: number; w: number };\n\t\n\t/** Linear velocity (accumulated) */\n\tvelocity: { x: number; y: number; z: number };\n\t\n\t/** Angular velocity (accumulated) */\n\tangularVelocity: { x: number; y: number; z: number };\n\t\n\t/** Dirty flags to track what needs to be applied */\n\tdirty: {\n\t\tposition: boolean;\n\t\trotation: boolean;\n\t\tvelocity: boolean;\n\t\tangularVelocity: boolean;\n\t};\n}\n\n/**\n * Create a new transform store with optional initial values.\n * The store is a Valtio proxy, making it reactive for debugging/visualization.\n * \n * @param initial Optional initial state values\n * @returns Reactive transform state\n */\nexport function createTransformStore(initial?: Partial<TransformState>): TransformState {\n\tconst defaultState: TransformState = {\n\t\tposition: { x: 0, y: 0, z: 0 },\n\t\trotation: { x: 0, y: 0, z: 0, w: 1 },\n\t\tvelocity: { x: 0, y: 0, z: 0 },\n\t\tangularVelocity: { x: 0, y: 0, z: 0 },\n\t\tdirty: {\n\t\t\tposition: false,\n\t\t\trotation: false,\n\t\t\tvelocity: false,\n\t\t\tangularVelocity: false,\n\t\t},\n\t};\n\n\treturn proxy({\n\t\t...defaultState,\n\t\t...initial,\n\t\t// Ensure dirty flags are properly initialized even if partial initial state\n\t\tdirty: {\n\t\t\t...defaultState.dirty,\n\t\t\t...initial?.dirty,\n\t\t},\n\t});\n}\n\n/**\n * Reset a transform store to its initial clean state.\n * Called after applying changes to prepare for the next frame.\n * \n * @param store The transform store to reset\n */\nexport function resetTransformStore(store: TransformState): void {\n\t// Reset position deltas\n\tstore.position.x = 0;\n\tstore.position.y = 0;\n\tstore.position.z = 0;\n\n\t// Reset rotation to identity quaternion\n\tstore.rotation.x = 0;\n\tstore.rotation.y = 0;\n\tstore.rotation.z = 0;\n\tstore.rotation.w = 1;\n\n\t// Reset velocity\n\tstore.velocity.x = 0;\n\tstore.velocity.y = 0;\n\tstore.velocity.z = 0;\n\n\t// Reset angular velocity\n\tstore.angularVelocity.x = 0;\n\tstore.angularVelocity.y = 0;\n\tstore.angularVelocity.z = 0;\n\n\t// Clear all dirty flags\n\tstore.dirty.position = false;\n\tstore.dirty.rotation = false;\n\tstore.dirty.velocity = false;\n\tstore.dirty.angularVelocity = false;\n}\n","import { Vector3 } from 'three';\nimport { RigidBody, Vector } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\n\nexport interface EntityWithBody {\n\tbody: RigidBody | null;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Move an entity along the X axis, preserving other velocities.\n */\nexport function moveX(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.x = delta;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move an entity along the Y axis, preserving other velocities.\n */\nexport function moveY(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.y = delta;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move an entity along the Z axis, preserving other velocities.\n */\nexport function moveZ(entity: EntityWithBody, delta: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.z = delta;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move an entity along the X and Y axis, preserving Z velocity.\n */\nexport function moveXY(entity: EntityWithBody, deltaX: number, deltaY: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.x = deltaX;\n\tentity.transformStore.velocity.y = deltaY;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move an entity along the X and Z axis, preserving Y velocity.\n */\nexport function moveXZ(entity: EntityWithBody, deltaX: number, deltaZ: number): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.x = deltaX;\n\tentity.transformStore.velocity.z = deltaZ;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Move entity based on a vector, adding to existing velocities.\n */\nexport function move(entity: EntityWithBody, vector: Vector3): void {\n\tif (!entity.transformStore) return;\n\tentity.transformStore.velocity.x += vector.x;\n\tentity.transformStore.velocity.y += vector.y;\n\tentity.transformStore.velocity.z += vector.z;\n\tentity.transformStore.dirty.velocity = true;\n}\n\n/**\n * Reset entity velocity\n */\nexport function resetVelocity(entity: EntityWithBody): void {\n\tif (!entity.body) return;\n\tentity.body.setLinvel(new Vector3(0, 0, 0), true);\n\tentity.body.setLinearDamping(5);\n}\n\n/**\n * Move entity forward in 2D space, preserving Z velocity\n */\nexport function moveForwardXY(entity: EntityWithBody, delta: number, rotation2DAngle: number): void {\n\tconst deltaX = Math.sin(-rotation2DAngle) * delta;\n\tconst deltaY = Math.cos(-rotation2DAngle) * delta;\n\tmoveXY(entity, deltaX, deltaY);\n}\n\n/**\n * Get entity position\n */\nexport function getPosition(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.translation();\n}\n\n/**\n * Get entity velocity\n */\nexport function getVelocity(entity: EntityWithBody): Vector | null {\n\tif (!entity.body) return null;\n\treturn entity.body.linvel();\n}\n\n/**\n * Set entity position\n */\nexport function setPosition(entity: EntityWithBody, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity X position\n */\nexport function setPositionX(entity: EntityWithBody, x: number): void {\n\tif (!entity.body) return;\n\tconst { y, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Y position\n */\nexport function setPositionY(entity: EntityWithBody, y: number): void {\n\tif (!entity.body) return;\n\tconst { x, z } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Set entity Z position\n */\nexport function setPositionZ(entity: EntityWithBody, z: number): void {\n\tif (!entity.body) return;\n\tconst { x, y } = entity.body.translation();\n\tentity.body.setTranslation({ x, y, z }, true);\n}\n\n/**\n * Wrap entity around 2D bounds\n */\nexport function wrapAroundXY(entity: EntityWithBody, boundsX: number, boundsY: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\n\tif (newX !== x || newY !== y) {\n\t\tsetPosition(entity, newX, newY, 0);\n\t}\n}\n\n/**\n * Wrap entity around 3D bounds\n */\nexport function wrapAround3D(entity: EntityWithBody, boundsX: number, boundsY: number, boundsZ: number): void {\n\tconst position = getPosition(entity);\n\tif (!position) return;\n\n\tconst { x, y, z } = position;\n\tconst newX = x > boundsX ? -boundsX : (x < -boundsX ? boundsX : x);\n\tconst newY = y > boundsY ? -boundsY : (y < -boundsY ? boundsY : y);\n\tconst newZ = z > boundsZ ? -boundsZ : (z < -boundsZ ? boundsZ : z);\n\n\tif (newX !== x || newY !== y || newZ !== z) {\n\t\tsetPosition(entity, newX, newY, newZ);\n\t}\n}\n\n/**\n * Enhanced moveable entity with bound methods\n */\nexport interface MoveableEntity extends EntityWithBody {\n\tmoveX(delta: number): void;\n\tmoveY(delta: number): void;\n\tmoveZ(delta: number): void;\n\tmoveXY(deltaX: number, deltaY: number): void;\n\tmoveXZ(deltaX: number, deltaZ: number): void;\n\tmove(vector: Vector3): void;\n\tresetVelocity(): void;\n\tmoveForwardXY(delta: number, rotation2DAngle: number): void;\n\tgetPosition(): Vector | null;\n\tgetVelocity(): Vector | null;\n\tsetPosition(x: number, y: number, z: number): void;\n\tsetPositionX(x: number): void;\n\tsetPositionY(y: number): void;\n\tsetPositionZ(z: number): void;\n\twrapAroundXY(boundsX: number, boundsY: number): void;\n\twrapAround3D(boundsX: number, boundsY: number, boundsZ: number): void;\n}\n\n/**\n * Enhance an entity with additive movement methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeMoveable<T extends EntityWithBody>(entity: T): T & MoveableEntity {\n\tconst moveable = entity as T & MoveableEntity;\n\n\t// Create transform store if it doesn't exist\n\tif (!moveable.transformStore) {\n\t\tmoveable.transformStore = createTransformStore();\n\t}\n\n\tmoveable.moveX = (delta: number) => moveX(entity, delta);\n\tmoveable.moveY = (delta: number) => moveY(entity, delta);\n\tmoveable.moveZ = (delta: number) => moveZ(entity, delta);\n\tmoveable.moveXY = (deltaX: number, deltaY: number) => moveXY(entity, deltaX, deltaY);\n\tmoveable.moveXZ = (deltaX: number, deltaZ: number) => moveXZ(entity, deltaX, deltaZ);\n\tmoveable.move = (vector: Vector3) => move(entity, vector);\n\tmoveable.resetVelocity = () => resetVelocity(entity);\n\tmoveable.moveForwardXY = (delta: number, rotation2DAngle: number) => moveForwardXY(entity, delta, rotation2DAngle);\n\tmoveable.getPosition = () => getPosition(entity);\n\tmoveable.getVelocity = () => getVelocity(entity);\n\tmoveable.setPosition = (x: number, y: number, z: number) => setPosition(entity, x, y, z);\n\tmoveable.setPositionX = (x: number) => setPositionX(entity, x);\n\tmoveable.setPositionY = (y: number) => setPositionY(entity, y);\n\tmoveable.setPositionZ = (z: number) => setPositionZ(entity, z);\n\tmoveable.wrapAroundXY = (boundsX: number, boundsY: number) => wrapAroundXY(entity, boundsX, boundsY);\n\tmoveable.wrapAround3D = (boundsX: number, boundsY: number, boundsZ: number) => wrapAround3D(entity, boundsX, boundsY, boundsZ);\n\n\treturn moveable;\n}","import { Euler, Vector3, MathUtils, Quaternion } from 'three';\nimport { RigidBody } from '@dimforge/rapier3d-compat';\nimport type { TransformState } from './transform-store';\nimport { createTransformStore } from './transform-store';\n\nexport interface RotatableEntity {\n\tbody: RigidBody | null;\n\tgroup: any;\n\ttransformStore?: TransformState;\n}\n\n/**\n * Rotate an entity in the direction of a movement vector\n */\nexport function rotateInDirection(entity: RotatableEntity, moveVector: Vector3): void {\n\tif (!entity.body) return;\n\tconst rotate = Math.atan2(-moveVector.x, moveVector.z);\n\trotateYEuler(entity, rotate);\n}\n\n/**\n * Rotate an entity around the Y axis using Euler angles\n */\nexport function rotateYEuler(entity: RotatableEntity, amount: number): void {\n\trotateEuler(entity, new Vector3(0, -amount, 0));\n}\n\n/**\n * Rotate an entity using Euler angles\n */\nexport function rotateEuler(entity: RotatableEntity, rotation: Vector3): void {\n\tif (!entity.group) return;\n\tconst euler = new Euler(rotation.x, rotation.y, rotation.z);\n\tentity.group.setRotationFromEuler(euler);\n}\n\n/**\n * Rotate an entity around the Y axis.\n */\nexport function rotateY(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaY = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For Y-axis rotation: q_delta = (0, deltaY, 0, deltaW)\n\tconst newW = q.w * deltaW - q.y * deltaY;\n\tconst newX = q.x * deltaW + q.z * deltaY;\n\tconst newY = q.y * deltaW + q.w * deltaY;\n\tconst newZ = q.z * deltaW - q.x * deltaY;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Rotate an entity around the X axis.\n */\nexport function rotateX(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaX = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For X-axis rotation: q_delta = (deltaX, 0, 0, deltaW)\n\tconst newW = q.w * deltaW - q.x * deltaX;\n\tconst newX = q.x * deltaW + q.w * deltaX;\n\tconst newY = q.y * deltaW + q.z * deltaX;\n\tconst newZ = q.z * deltaW - q.y * deltaX;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Rotate an entity around the Z axis.\n */\nexport function rotateZ(entity: RotatableEntity, delta: number): void {\n\tif (!entity.transformStore) return;\n\t\n\t// Create delta rotation quaternion\n\tconst halfAngle = delta / 2;\n\tconst deltaW = Math.cos(halfAngle);\n\tconst deltaZ = Math.sin(halfAngle);\n\t\n\t// Get current rotation from store\n\tconst q = entity.transformStore.rotation;\n\t\n\t// Multiply quaternions: q_new = q_current * q_delta\n\t// For Z-axis rotation: q_delta = (0, 0, deltaZ, deltaW)\n\tconst newW = q.w * deltaW - q.z * deltaZ;\n\tconst newX = q.x * deltaW - q.y * deltaZ;\n\tconst newY = q.y * deltaW + q.x * deltaZ;\n\tconst newZ = q.z * deltaW + q.w * deltaZ;\n\t\n\tentity.transformStore.rotation.w = newW;\n\tentity.transformStore.rotation.x = newX;\n\tentity.transformStore.rotation.y = newY;\n\tentity.transformStore.rotation.z = newZ;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation around Y axis.\n */\nexport function setRotationY(entity: RotatableEntity, y: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = y / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst yComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = 0;\n\tentity.transformStore.rotation.y = yComponent;\n\tentity.transformStore.rotation.z = 0;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation around Y axis\n */\nexport function setRotationDegreesY(entity: RotatableEntity, y: number): void {\n\tif (!entity.body) return;\n\tsetRotationY(entity, MathUtils.degToRad(y));\n}\n\n/**\n * Set rotation around X axis.\n */\nexport function setRotationX(entity: RotatableEntity, x: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = x / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst xComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = xComponent;\n\tentity.transformStore.rotation.y = 0;\n\tentity.transformStore.rotation.z = 0;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation around X axis\n */\nexport function setRotationDegreesX(entity: RotatableEntity, x: number): void {\n\tif (!entity.body) return;\n\tsetRotationX(entity, MathUtils.degToRad(x));\n}\n\n/**\n * Set rotation around Z axis.\n */\nexport function setRotationZ(entity: RotatableEntity, z: number): void {\n\tif (!entity.transformStore) return;\n\tconst halfAngle = z / 2;\n\tconst w = Math.cos(halfAngle);\n\tconst zComponent = Math.sin(halfAngle);\n\tentity.transformStore.rotation.w = w;\n\tentity.transformStore.rotation.x = 0;\n\tentity.transformStore.rotation.y = 0;\n\tentity.transformStore.rotation.z = zComponent;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation around Z axis\n */\nexport function setRotationDegreesZ(entity: RotatableEntity, z: number): void {\n\tif (!entity.body) return;\n\tsetRotationZ(entity, MathUtils.degToRad(z));\n}\n\n/**\n * Set rotation for all axes.\n */\nexport function setRotation(entity: RotatableEntity, x: number, y: number, z: number): void {\n\tif (!entity.transformStore) return;\n\tconst quat = new Quaternion().setFromEuler(new Euler(x, y, z));\n\tentity.transformStore.rotation.w = quat.w;\n\tentity.transformStore.rotation.x = quat.x;\n\tentity.transformStore.rotation.y = quat.y;\n\tentity.transformStore.rotation.z = quat.z;\n\tentity.transformStore.dirty.rotation = true;\n}\n\n/**\n * Set rotation for all axes\n */\nexport function setRotationDegrees(entity: RotatableEntity, x: number, y: number, z: number): void {\n\tif (!entity.body) return;\n\tsetRotation(entity, MathUtils.degToRad(x), MathUtils.degToRad(y), MathUtils.degToRad(z));\n}\n\n/**\n * Get current rotation\n */\nexport function getRotation(entity: RotatableEntity): any {\n\tif (!entity.body) return null;\n\treturn entity.body.rotation();\n}\n\n/**\n * Rotatable entity API with bound methods\n */\nexport interface RotatableEntityAPI extends RotatableEntity {\n\trotateInDirection(moveVector: Vector3): void;\n\trotateYEuler(amount: number): void;\n\trotateEuler(rotation: Vector3): void;\n\trotateY(delta: number): void;\n\trotateX(delta: number): void;\n\trotateZ(delta: number): void;\n\tsetRotationY(y: number): void;\n\tsetRotationX(x: number): void;\n\tsetRotationZ(z: number): void;\n\tsetRotationDegrees(x: number, y: number, z: number): void;\n\tsetRotationDegreesY(y: number): void;\n\tsetRotationDegreesX(x: number): void;\n\tsetRotationDegreesZ(z: number): void;\n\tsetRotation(x: number, y: number, z: number): void;\n\tgetRotation(): any;\n}\n\n/**\n * Enhance an entity instance with rotatable methods.\n * Automatically creates a transform store if one doesn't exist.\n */\nexport function makeRotatable<T extends RotatableEntity>(entity: T): T & RotatableEntityAPI {\n\tconst rotatableEntity = entity as T & RotatableEntityAPI;\n\n\t// Create transform store if it doesn't exist\n\tif (!rotatableEntity.transformStore) {\n\t\trotatableEntity.transformStore = createTransformStore();\n\t}\n\n\trotatableEntity.rotateInDirection = (moveVector: Vector3) => rotateInDirection(entity, moveVector);\n\trotatableEntity.rotateYEuler = (amount: number) => rotateYEuler(entity, amount);\n\trotatableEntity.rotateEuler = (rotation: Vector3) => rotateEuler(entity, rotation);\n\trotatableEntity.rotateX = (delta: number) => rotateX(entity, delta);\n\trotatableEntity.rotateY = (delta: number) => rotateY(entity, delta);\n\trotatableEntity.rotateZ = (delta: number) => rotateZ(entity, delta);\n\trotatableEntity.setRotationY = (y: number) => setRotationY(entity, y);\n\trotatableEntity.setRotationX = (x: number) => setRotationX(entity, x);\n\trotatableEntity.setRotationZ = (z: number) => setRotationZ(entity, z);\n\trotatableEntity.setRotationDegreesY = (y: number) => setRotationDegreesY(entity, y);\n\trotatableEntity.setRotationDegreesX = (x: number) => setRotationDegreesX(entity, x);\n\trotatableEntity.setRotationDegreesZ = (z: number) => setRotationDegreesZ(entity, z);\n\trotatableEntity.setRotationDegrees = (x: number, y: number, z: number) => setRotationDegrees(entity, x, y, z);\n\trotatableEntity.setRotation = (x: number, y: number, z: number) => setRotation(entity, x, y, z);\n\trotatableEntity.getRotation = () => getRotation(entity);\n\n\treturn rotatableEntity;\n}","import { makeMoveable, EntityWithBody, MoveableEntity } from './moveable';\nimport { makeRotatable, RotatableEntity, RotatableEntityAPI } from './rotatable';\n\n/**\n * Enhance an entity with both movement and rotation capabilities.\n * Transform store is automatically created by makeMoveable and makeRotatable.\n */\nexport function makeTransformable<\n\tT extends RotatableEntity & EntityWithBody\n>(entity: T): T & MoveableEntity & RotatableEntityAPI {\n\tconst withMovement = makeMoveable(entity);\n\tconst withRotation = makeRotatable(withMovement);\n\treturn withRotation;\n}\n\n","import {\n\tActiveCollisionTypes,\n\tColliderDesc,\n\tRigidBodyDesc,\n\tRigidBodyType,\n} from '@dimforge/rapier3d-compat';\nimport { Vector3 } from 'three';\nimport type { Vec3 } from '../../core/vector';\nimport {\n\tgetOrCreateCollisionGroupId,\n\tcreateCollisionFilter,\n\ttype CollisionOptions,\n} from '../../collision/collision-builder';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CollisionComponent type returned by all collision factories\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * A built collision component containing a rigid body description and collider description.\n * Returned by collision factory functions (boxCollision, sphereCollision, etc.)\n * and consumed by GameEntity.add().\n */\nexport interface CollisionComponent {\n\t__kind: 'collision';\n\tbodyDesc: RigidBodyDesc;\n\tcolliderDesc: ColliderDesc;\n}\n\n/**\n * Type guard for CollisionComponent.\n */\nexport function isCollisionComponent(obj: any): obj is CollisionComponent {\n\treturn obj && obj.__kind === 'collision';\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface BaseCollisionOptions {\n\t/** Whether the body is static (fixed) or dynamic */\n\tstatic?: boolean;\n\t/** Whether this collider is a sensor */\n\tsensor?: boolean;\n\t/** Position offset relative to the entity origin */\n\toffset?: Vec3;\n\t/** Collision type string for group filtering */\n\tcollisionType?: string;\n\t/** Allowed collision types for filtering */\n\tcollisionFilter?: string[];\n}\n\nfunction buildBodyDesc(isStatic: boolean): RigidBodyDesc {\n\tconst type = isStatic ? RigidBodyType.Fixed : RigidBodyType.Dynamic;\n\treturn new RigidBodyDesc(type)\n\t\t.setTranslation(0, 0, 0)\n\t\t.setGravityScale(1.0)\n\t\t.setCanSleep(false)\n\t\t.setCcdEnabled(true);\n}\n\nfunction applyCollisionOptions(\n\tcolliderDesc: ColliderDesc,\n\topts: BaseCollisionOptions,\n): void {\n\tif (opts.offset) {\n\t\tcolliderDesc.setTranslation(opts.offset.x, opts.offset.y, opts.offset.z);\n\t}\n\tif (opts.sensor) {\n\t\tcolliderDesc.setSensor(true);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.KINEMATIC_FIXED;\n\t}\n\tif (opts.collisionType) {\n\t\tconst groupId = getOrCreateCollisionGroupId(opts.collisionType);\n\t\tlet filter = 0b1111111111111111;\n\t\tif (opts.collisionFilter) {\n\t\t\tfilter = createCollisionFilter(opts.collisionFilter);\n\t\t}\n\t\tcolliderDesc.setCollisionGroups((groupId << 16) | filter);\n\t}\n}\n\nfunction makeComponent(\n\tcolliderDesc: ColliderDesc,\n\topts: BaseCollisionOptions,\n): CollisionComponent {\n\tapplyCollisionOptions(colliderDesc, opts);\n\treturn {\n\t\t__kind: 'collision',\n\t\tbodyDesc: buildBodyDesc(opts.static ?? false),\n\t\tcolliderDesc,\n\t};\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Box\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BoxCollisionOptions extends BaseCollisionOptions {\n\t/** Box dimensions (default: 1x1x1) */\n\tsize?: Vec3;\n}\n\n/**\n * Create a box (cuboid) collision component.\n */\nexport function boxCollision(opts: BoxCollisionOptions = {}): CollisionComponent {\n\tconst size = opts.size ?? { x: 1, y: 1, z: 1 };\n\tconst desc = ColliderDesc.cuboid(size.x / 2, size.y / 2, size.z / 2);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Sphere\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SphereCollisionOptions extends BaseCollisionOptions {\n\t/** Sphere radius (default: 1) */\n\tradius?: number;\n}\n\n/**\n * Create a sphere (ball) collision component.\n */\nexport function sphereCollision(opts: SphereCollisionOptions = {}): CollisionComponent {\n\tconst desc = ColliderDesc.ball(opts.radius ?? 1);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cone\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ConeCollisionOptions extends BaseCollisionOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a cone collision component.\n */\nexport function coneCollision(opts: ConeCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 1;\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cone(height / 2, radius);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pyramid (cone collider with 4-sided visual approximation)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PyramidCollisionOptions extends BaseCollisionOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a pyramid collision component (approximated as a cone).\n */\nexport function pyramidCollision(opts: PyramidCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 1;\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cone(height / 2, radius);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cylinder\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface CylinderCollisionOptions extends BaseCollisionOptions {\n\t/** Top radius (default: 1) */\n\tradiusTop?: number;\n\t/** Bottom radius (default: 1) */\n\tradiusBottom?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a cylinder collision component.\n */\nexport function cylinderCollision(opts: CylinderCollisionOptions = {}): CollisionComponent {\n\tconst radius = Math.max(opts.radiusTop ?? 1, opts.radiusBottom ?? 1);\n\tconst height = opts.height ?? 2;\n\tconst desc = ColliderDesc.cylinder(height / 2, radius);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pill (capsule)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PillCollisionOptions extends BaseCollisionOptions {\n\t/** Capsule hemisphere radius (default: 0.5) */\n\tradius?: number;\n\t/** Cylindrical section length (default: 1) */\n\tlength?: number;\n}\n\n/**\n * Create a pill (capsule) collision component.\n */\nexport function pillCollision(opts: PillCollisionOptions = {}): CollisionComponent {\n\tconst radius = opts.radius ?? 0.5;\n\tconst length = opts.length ?? 1;\n\tconst desc = ColliderDesc.capsule(length / 2, radius);\n\treturn makeComponent(desc, opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Plane (heightfield)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PlaneCollisionOptions extends BaseCollisionOptions {\n\t/** Tile dimensions (default: 10x10) */\n\ttile?: { x: number; y: number };\n\t/** Number of subdivisions per axis (default: 10) */\n\tsubdivisions?: number;\n\t/** Pre-computed height data for the heightfield */\n\theightData?: Float32Array;\n}\n\n/**\n * Create a plane (heightfield) collision component.\n * For flat planes, pass no heightData — a zeroed heightfield is used.\n */\nexport function planeCollision(opts: PlaneCollisionOptions = {}): CollisionComponent {\n\tconst tile = opts.tile ?? { x: 10, y: 10 };\n\tconst subdivisions = opts.subdivisions ?? 10;\n\tconst size = new Vector3(tile.x, 1, tile.y);\n\n\tconst totalVerts = (subdivisions + 1) * (subdivisions + 1);\n\tconst heightData = opts.heightData ?? new Float32Array(totalVerts);\n\n\tconst desc = ColliderDesc.heightfield(\n\t\tsubdivisions,\n\t\tsubdivisions,\n\t\theightData,\n\t\tsize,\n\t);\n\n\treturn makeComponent(desc, { ...opts, static: opts.static ?? true });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Zone (sensor cuboid)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ZoneCollisionOptions extends BaseCollisionOptions {\n\t/** Zone dimensions (default: 1x1x1) */\n\tsize?: Vec3;\n}\n\n/**\n * Create a zone (sensor cuboid) collision component.\n * Always a sensor; static by default.\n */\nexport function zoneCollision(opts: ZoneCollisionOptions = {}): CollisionComponent {\n\tconst size = opts.size ?? { x: 1, y: 1, z: 1 };\n\tconst desc = ColliderDesc.cuboid(size.x / 2, size.y / 2, size.z / 2);\n\tdesc.setSensor(true);\n\tdesc.activeCollisionTypes = ActiveCollisionTypes.KINEMATIC_FIXED;\n\treturn makeComponent(desc, { ...opts, static: opts.static ?? true, sensor: true });\n}\n","import { ActiveCollisionTypes, ColliderDesc, RigidBodyDesc, RigidBodyType, Vector3 } from \"@dimforge/rapier3d-compat\";\nimport { Vec3 } from \"../core/vector\";\n\n/**\n * Options for configuring entity collision behavior.\n */\nexport interface CollisionOptions {\n\tstatic?: boolean;\n\tsensor?: boolean;\n\tsize?: Vector3;\n\tposition?: Vector3;\n\tcollisionType?: string;\n\tcollisionFilter?: string[];\n}\n\nconst typeToGroup = new Map<string, number>();\nlet nextGroupId = 0;\n\nexport function getOrCreateCollisionGroupId(type: string): number {\n\tlet groupId = typeToGroup.get(type);\n\tif (groupId === undefined) {\n\t\tgroupId = nextGroupId++ % 16;\n\t\ttypeToGroup.set(type, groupId);\n\t}\n\treturn groupId;\n}\n\nexport function createCollisionFilter(allowedTypes: string[]): number {\n\tlet filter = 0;\n\tallowedTypes.forEach(type => {\n\t\tconst groupId = getOrCreateCollisionGroupId(type);\n\t\tfilter |= (1 << groupId);\n\t});\n\treturn filter;\n}\n\nexport class CollisionBuilder {\n\tstatic: boolean = false;\n\tsensor: boolean = false;\n\tgravity: Vec3 = new Vector3(0, 0, 0);\n\n\tbuild(options: Partial<CollisionOptions>): [RigidBodyDesc, ColliderDesc] {\n\t\tconst bodyDesc = this.bodyDesc({\n\t\t\tisDynamicBody: !this.static\n\t\t});\n\t\tconst collider = this.collider(options);\n\t\tconst type = options.collisionType;\n\t\tif (type) {\n\t\t\tlet groupId = getOrCreateCollisionGroupId(type);\n\t\t\tlet filter = 0b1111111111111111;\n\t\t\tif (options.collisionFilter) {\n\t\t\t\tfilter = createCollisionFilter(options.collisionFilter);\n\t\t\t}\n\t\t\tcollider.setCollisionGroups((groupId << 16) | filter);\n\t\t}\n\t\tconst { KINEMATIC_FIXED, DEFAULT } = ActiveCollisionTypes;\n\t\tcollider.activeCollisionTypes = (this.sensor) ? KINEMATIC_FIXED : DEFAULT;\n\t\treturn [bodyDesc, collider];\n\t}\n\n\twithCollision(collisionOptions: Partial<CollisionOptions>): this {\n\t\tthis.sensor = collisionOptions?.sensor ?? this.sensor;\n\t\tthis.static = collisionOptions?.static ?? this.static;\n\t\treturn this;\n\t}\n\n\tcollider(options: CollisionOptions): ColliderDesc {\n\t\tconst size = options.size ?? new Vector3(1, 1, 1);\n\t\tconst half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };\n\t\tlet colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);\n\t\treturn colliderDesc;\n\t}\n\n\tbodyDesc({ isDynamicBody = true }): RigidBodyDesc {\n\t\tconst type = isDynamicBody ? RigidBodyType.Dynamic : RigidBodyType.Fixed;\n\t\tconst bodyDesc = new RigidBodyDesc(type)\n\t\t\t.setTranslation(0, 0, 0)\n\t\t\t.setGravityScale(1.0)\n\t\t\t.setCanSleep(false)\n\t\t\t.setCcdEnabled(true);\n\t\treturn bodyDesc;\n\t}\n}","import { Color, Vector3 } from 'three';\nimport { standardShader } from '../graphics/shaders/standard.shader';\nimport { GameEntityOptions } from './entity';\nimport { BaseNode } from '../core/base-node';\n\nexport const commonDefaults: Partial<GameEntityOptions> = {\n position: new Vector3(0, 0, 0),\n material: {\n color: new Color('#ffffff'),\n shader: standardShader\n },\n collision: {\n static: false,\n },\n};\n\n/**\n * Merge a variadic args array (BaseNode children + options object) with defaults.\n * Returns the merged options. This replaces the createEntity() arg parsing logic.\n */\nexport function mergeArgs<T extends GameEntityOptions>(\n args: Array<BaseNode | Partial<T>>,\n defaults: Partial<T>,\n): T {\n const configArgs = args.filter(\n (arg): arg is Partial<T> => !(arg instanceof BaseNode),\n );\n let merged: Partial<T> = { ...defaults };\n for (const opt of configArgs) {\n merged = { ...merged, ...opt };\n }\n return merged as T;\n}\n","export const objectVertexShader = `\nuniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n\tvUv = uv;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n}\n`;\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\nuniform sampler2D tDiffuse;\nvarying vec2 vUv;\n\nvoid main() {\n\tvec4 texel = texture2D( tDiffuse, vUv );\n\n\tgl_FragColor = texel;\n}\n`;\n\nexport const standardShader = {\n vertex: objectVertexShader,\n fragment\n};\n","import { GameEntity, GameEntityOptions } from '../entity';\nimport { MeshStandardMaterial, MeshBasicMaterial, MeshPhongMaterial } from 'three';\n\n/**\n * Interface for entities that provide custom debug information\n */\nexport interface DebugInfoProvider {\n\tgetDebugInfo(): Record<string, any>;\n}\n\n/**\n * Helper to check if an object implements DebugInfoProvider\n */\nfunction hasDebugInfo(obj: any): obj is DebugInfoProvider {\n\treturn obj && typeof obj.getDebugInfo === 'function';\n}\n\n/**\n * Debug delegate that provides debug information for entities\n */\nexport class DebugDelegate {\n\tprivate entity: GameEntity<any>;\n\n\tconstructor(entity: GameEntity<any>) {\n\t\tthis.entity = entity;\n\t}\n\n\t/**\n\t * Get formatted position string\n\t */\n\tprivate getPositionString(): string {\n\t\tif (this.entity.mesh) {\n\t\t\tconst { x, y, z } = this.entity.mesh.position;\n\t\t\treturn `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`;\n\t\t}\n\t\tconst { x, y, z } = this.entity.options.position || { x: 0, y: 0, z: 0 };\n\t\treturn `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`;\n\t}\n\n\t/**\n\t * Get formatted rotation string (in degrees)\n\t */\n\tprivate getRotationString(): string {\n\t\tif (this.entity.mesh) {\n\t\t\tconst { x, y, z } = this.entity.mesh.rotation;\n\t\t\tconst toDeg = (rad: number) => (rad * 180 / Math.PI).toFixed(1);\n\t\t\treturn `${toDeg(x)}°, ${toDeg(y)}°, ${toDeg(z)}°`;\n\t\t}\n\t\tconst { x, y, z } = this.entity.options.rotation || { x: 0, y: 0, z: 0 };\n\t\tconst toDeg = (rad: number) => (rad * 180 / Math.PI).toFixed(1);\n\t\treturn `${toDeg(x)}°, ${toDeg(y)}°, ${toDeg(z)}°`;\n\t}\n\n\t/**\n\t * Get material information\n\t */\n\tprivate getMaterialInfo(): Record<string, any> {\n\t\tif (!this.entity.mesh || !this.entity.mesh.material) {\n\t\t\treturn { type: 'none' };\n\t\t}\n\n\t\tconst material = Array.isArray(this.entity.mesh.material)\n\t\t\t? this.entity.mesh.material[0]\n\t\t\t: this.entity.mesh.material;\n\n\t\tconst info: Record<string, any> = {\n\t\t\ttype: material.type\n\t\t};\n\n\t\tif (material instanceof MeshStandardMaterial ||\n\t\t\tmaterial instanceof MeshBasicMaterial ||\n\t\t\tmaterial instanceof MeshPhongMaterial) {\n\t\t\tinfo.color = `#${material.color.getHexString()}`;\n\t\t\tinfo.opacity = material.opacity;\n\t\t\tinfo.transparent = material.transparent;\n\t\t}\n\n\t\tif ('roughness' in material) {\n\t\t\tinfo.roughness = material.roughness;\n\t\t}\n\n\t\tif ('metalness' in material) {\n\t\t\tinfo.metalness = material.metalness;\n\t\t}\n\n\t\treturn info;\n\t}\n\n\tprivate getPhysicsInfo(): Record<string, any> | null {\n\t\tif (!this.entity.body) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst info: Record<string, any> = {\n\t\t\ttype: this.entity.body.bodyType(),\n\t\t\tmass: this.entity.body.mass(),\n\t\t\tisEnabled: this.entity.body.isEnabled(),\n\t\t\tisSleeping: this.entity.body.isSleeping()\n\t\t};\n\n\t\tconst velocity = this.entity.body.linvel();\n\t\tinfo.velocity = `${velocity.x.toFixed(2)}, ${velocity.y.toFixed(2)}, ${velocity.z.toFixed(2)}`;\n\n\t\treturn info;\n\t}\n\n\tpublic buildDebugInfo(): Record<string, any> {\n\t\tconst defaultInfo: Record<string, any> = {\n\t\t\tname: this.entity.name || this.entity.uuid,\n\t\t\tuuid: this.entity.uuid,\n\t\t\tposition: this.getPositionString(),\n\t\t\trotation: this.getRotationString(),\n\t\t\tmaterial: this.getMaterialInfo()\n\t\t};\n\n\t\tconst physicsInfo = this.getPhysicsInfo();\n\t\tif (physicsInfo) {\n\t\t\tdefaultInfo.physics = physicsInfo;\n\t\t}\n\n\t\tif (this.entity.behaviors.length > 0) {\n\t\t\tdefaultInfo.behaviors = this.entity.behaviors.map(b => b.constructor.name);\n\t\t}\n\n\t\tif (hasDebugInfo(this.entity)) {\n\t\t\tconst customInfo = this.entity.getDebugInfo();\n\t\t\treturn { ...defaultInfo, ...customInfo };\n\t\t}\n\n\t\treturn defaultInfo;\n\t}\n}\n\nclass EnhancedDebugInfoBuilder {\n\tprivate customBuilder?: (options: GameEntityOptions) => Record<string, any>;\n\n\tconstructor(customBuilder?: (options: GameEntityOptions) => Record<string, any>) {\n\t\tthis.customBuilder = customBuilder;\n\t}\n\n\tbuildInfo(options: GameEntityOptions, entity?: GameEntity<any>): Record<string, any> {\n\t\tif (this.customBuilder) {\n\t\t\treturn this.customBuilder(options);\n\t\t}\n\n\t\tif (entity) {\n\t\t\tconst delegate = new DebugDelegate(entity);\n\t\t\treturn delegate.buildDebugInfo();\n\t\t}\n\n\t\tconst { x, y, z } = options.position || { x: 0, y: 0, z: 0 };\n\t\treturn {\n\t\t\tname: (options as any).name || 'unnamed',\n\t\t\tposition: `${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`\n\t\t};\n\t}\n}\n","import {\n\tBoxGeometry,\n\tCapsuleGeometry,\n\tConeGeometry,\n\tCylinderGeometry,\n\tMesh,\n\tMeshStandardMaterial,\n\tSphereGeometry,\n\ttype Color,\n} from 'three';\nimport { MaterialBuilder, type MaterialOptions } from '../../graphics/material';\nimport type { Vec3 } from '../../core/vector';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Shared helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Shared options that every mesh factory accepts. */\ninterface BaseMeshOptions {\n\t/** Offset position relative to the entity origin */\n\tposition?: Vec3;\n\t/** Material options (texture, shader, etc.) */\n\tmaterial?: Partial<MaterialOptions>;\n\t/** Convenience color override */\n\tcolor?: Color;\n}\n\n/**\n * Build a material array from options.\n * Returns a fallback MeshStandardMaterial when no material options are provided.\n */\nfunction buildMaterial(\n\topts: BaseMeshOptions,\n\tentityType: symbol = Symbol('mesh'),\n): MeshStandardMaterial[] {\n\tif (opts.material || opts.color) {\n\t\tconst builder = new MaterialBuilder();\n\t\tbuilder.build(\n\t\t\t{ ...opts.material, color: opts.color ?? opts.material?.color },\n\t\t\tentityType,\n\t\t);\n\t\tif (builder.materials.length > 0) {\n\t\t\treturn builder.materials as MeshStandardMaterial[];\n\t\t}\n\t}\n\treturn [new MeshStandardMaterial()];\n}\n\nfunction finalizeMesh(mesh: Mesh, opts: BaseMeshOptions): Mesh {\n\tif (opts.position) {\n\t\tmesh.position.set(opts.position.x, opts.position.y, opts.position.z);\n\t}\n\tmesh.castShadow = true;\n\tmesh.receiveShadow = true;\n\treturn mesh;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Box\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BoxMeshOptions extends BaseMeshOptions {\n\t/** Box dimensions (default: 1x1x1) */\n\tsize?: Vec3;\n}\n\n/**\n * Create a box mesh.\n */\nexport function boxMesh(opts: BoxMeshOptions = {}): Mesh {\n\tconst size = opts.size ?? { x: 1, y: 1, z: 1 };\n\tconst geometry = new BoxGeometry(size.x, size.y, size.z);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Sphere\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface SphereMeshOptions extends BaseMeshOptions {\n\t/** Sphere radius (default: 1) */\n\tradius?: number;\n}\n\n/**\n * Create a sphere mesh.\n */\nexport function sphereMesh(opts: SphereMeshOptions = {}): Mesh {\n\tconst geometry = new SphereGeometry(opts.radius ?? 1);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cone\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ConeMeshOptions extends BaseMeshOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n\t/** Radial segments (default: 32) */\n\tradialSegments?: number;\n}\n\n/**\n * Create a cone mesh.\n */\nexport function coneMesh(opts: ConeMeshOptions = {}): Mesh {\n\tconst geometry = new ConeGeometry(\n\t\topts.radius ?? 1,\n\t\topts.height ?? 2,\n\t\topts.radialSegments ?? 32,\n\t);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pyramid (cone geometry with 4 segments)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PyramidMeshOptions extends BaseMeshOptions {\n\t/** Base radius (default: 1) */\n\tradius?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n}\n\n/**\n * Create a pyramid mesh (4-sided cone).\n */\nexport function pyramidMesh(opts: PyramidMeshOptions = {}): Mesh {\n\tconst geometry = new ConeGeometry(opts.radius ?? 1, opts.height ?? 2, 4);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cylinder\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface CylinderMeshOptions extends BaseMeshOptions {\n\t/** Top radius (default: 1) */\n\tradiusTop?: number;\n\t/** Bottom radius (default: 1) */\n\tradiusBottom?: number;\n\t/** Height (default: 2) */\n\theight?: number;\n\t/** Radial segments (default: 32) */\n\tradialSegments?: number;\n}\n\n/**\n * Create a cylinder mesh.\n */\nexport function cylinderMesh(opts: CylinderMeshOptions = {}): Mesh {\n\tconst geometry = new CylinderGeometry(\n\t\topts.radiusTop ?? 1,\n\t\topts.radiusBottom ?? 1,\n\t\topts.height ?? 2,\n\t\topts.radialSegments ?? 32,\n\t);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pill (capsule)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PillMeshOptions extends BaseMeshOptions {\n\t/** Capsule hemisphere radius (default: 0.5) */\n\tradius?: number;\n\t/** Cylindrical section length (default: 1) */\n\tlength?: number;\n\t/** Cap segments (default: 10) */\n\tcapSegments?: number;\n\t/** Radial segments (default: 20) */\n\tradialSegments?: number;\n}\n\n/**\n * Create a pill (capsule) mesh.\n */\nexport function pillMesh(opts: PillMeshOptions = {}): Mesh {\n\tconst geometry = new CapsuleGeometry(\n\t\topts.radius ?? 0.5,\n\t\topts.length ?? 1,\n\t\topts.capSegments ?? 10,\n\t\topts.radialSegments ?? 20,\n\t);\n\tconst materials = buildMaterial(opts);\n\treturn finalizeMesh(new Mesh(geometry, materials.at(-1)), opts);\n}\n","import { Color, Material, Vector2, Vector3 } from 'three';\nimport {\n\tMeshPhongMaterial,\n\tMeshStandardMaterial,\n\tRepeatWrapping,\n\tShaderMaterial,\n} from 'three';\nimport {\n\tMeshBasicNodeMaterial,\n\tMeshStandardNodeMaterial,\n} from 'three/webgpu';\nimport { shortHash, sortedStringify } from '../core/utility/strings';\nimport { standardShader } from './shaders/standard.shader';\nimport { assetManager } from '../core/asset-manager';\n\n/**\n * GLSL shader object (traditional approach for WebGL)\n */\nexport type ZylemShaderObject = { fragment: string; vertex: string };\n\n/**\n * TSL shader type (for WebGPU)\n * colorNode should be a TSL node that returns the fragment color\n */\nexport type ZylemTSLShader = {\n\tcolorNode: any; // TSL node - use any since Three.js types are still evolving\n\ttransparent?: boolean;\n};\n\n/**\n * Combined shader type supporting both GLSL and TSL\n */\nexport type ZylemShader = ZylemShaderObject | ZylemTSLShader;\n\n/**\n * Check if a shader is a TSL shader\n */\nexport function isTSLShader(shader: ZylemShader): shader is ZylemTSLShader {\n\treturn 'colorNode' in shader;\n}\n\n/**\n * Check if a shader is a GLSL shader\n */\nexport function isGLSLShader(shader: ZylemShader): shader is ZylemShaderObject {\n\treturn 'fragment' in shader && 'vertex' in shader;\n}\n\nexport interface MaterialOptions {\n\tpath?: string;\n\tnormalMap?: string;\n\trepeat?: Vector2;\n\tshader?: ZylemShader;\n\tcolor?: Color;\n\t/**\n\t * When true, prefer TSL/NodeMaterial (for WebGPU)\n\t * When false, prefer GLSL/ShaderMaterial (for WebGL)\n\t */\n\tuseTSL?: boolean;\n}\n\ntype BatchGeometryMap = Map<symbol, number>;\n\ninterface BatchMaterialMapObject {\n\tgeometryMap: BatchGeometryMap;\n\tmaterial: Material;\n}\n\ntype BatchKey = ReturnType<typeof shortHash>;\n\nexport type TexturePath = string | null;\n\nexport class MaterialBuilder {\n\tstatic batchMaterialMap: Map<BatchKey, BatchMaterialMapObject> = new Map();\n\n\tmaterials: Material[] = [];\n\n\t/** Whether to use TSL/NodeMaterial (for WebGPU compatibility) */\n\tprivate useTSL: boolean;\n\n\tconstructor(useTSL: boolean = false) {\n\t\tthis.useTSL = useTSL;\n\t}\n\n\tbatchMaterial(options: Partial<MaterialOptions>, entityType: symbol) {\n\t\tconst batchKey = shortHash(sortedStringify(options));\n\t\tconst mappedObject = MaterialBuilder.batchMaterialMap.get(batchKey);\n\t\tif (mappedObject) {\n\t\t\tconst count = mappedObject.geometryMap.get(entityType);\n\t\t\tif (count) {\n\t\t\t\tmappedObject.geometryMap.set(entityType, count + 1);\n\t\t\t} else {\n\t\t\t\tmappedObject.geometryMap.set(entityType, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tMaterialBuilder.batchMaterialMap.set(batchKey, {\n\t\t\t\tgeometryMap: new Map([[entityType, 1]]),\n\t\t\t\tmaterial: this.materials[0],\n\t\t\t});\n\t\t}\n\t}\n\n\tbuild(options: Partial<MaterialOptions>, entityType: symbol): void {\n\t\tconst { path, normalMap, repeat, color, shader, useTSL } = options;\n\t\t\n\t\t// Override TSL preference if specified in options\n\t\tconst shouldUseTSL = useTSL ?? this.useTSL;\n\n\t\t// If shader is provided, use it\n\t\tif (shader) {\n\t\t\tif (isTSLShader(shader)) {\n\t\t\t\t// TSL shader provided directly\n\t\t\t\tthis.setTSLShader(shader);\n\t\t\t} else if (isGLSLShader(shader)) {\n\t\t\t\t// GLSL shader provided\n\t\t\t\tif (shouldUseTSL) {\n\t\t\t\t\tconsole.warn('MaterialBuilder: GLSL shader provided but TSL mode requested. Using GLSL.');\n\t\t\t\t}\n\t\t\t\tthis.setShader(shader);\n\t\t\t}\n\t\t} else if (path) {\n\t\t\t// Texture path provided\n\t\t\tthis.setTexture(path, repeat, shouldUseTSL);\n\t\t}\n\n\t\tif (color) {\n\t\t\tthis.withColor(color, shouldUseTSL);\n\t\t}\n\n\t\tif (this.materials.length === 0) {\n\t\t\tthis.setColor(new Color('#ffffff'), shouldUseTSL);\n\t\t}\n\n\t\t// Apply normal map if present (to the last added material)\n\t\tif (normalMap && this.materials.length > 0) {\n\t\t\tthis.setNormalMap(normalMap, repeat);\n\t\t}\n\n\t\tthis.batchMaterial(options, entityType);\n\t}\n\n\twithColor(color: Color, useTSL: boolean = false): this {\n\t\tthis.setColor(color, useTSL);\n\t\treturn this;\n\t}\n\n\twithShader(shader: ZylemShaderObject): this {\n\t\tthis.setShader(shader);\n\t\treturn this;\n\t}\n\n\twithTSLShader(shader: ZylemTSLShader): this {\n\t\tthis.setTSLShader(shader);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set texture - loads in background (deferred).\n\t * Material is created immediately with null map, texture applies when loaded.\n\t */\n\tsetTexture(texturePath: TexturePath = null, repeat: Vector2 = new Vector2(1, 1), useTSL: boolean = false): void {\n\t\tif (!texturePath) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (useTSL) {\n\t\t\t// For TSL/WebGPU, use NodeMaterial\n\t\t\tconst material = new MeshStandardNodeMaterial();\n\t\t\tthis.materials.push(material);\n\n\t\t\t// Load texture in background and apply when ready\n\t\t\tassetManager.loadTexture(texturePath as string, {\n\t\t\t\tclone: true,\n\t\t\t\trepeat,\n\t\t\t}).then((texture) => {\n\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\tmaterial.map = texture;\n\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t});\n\t\t} else {\n\t\t\t// For WebGL, use traditional material\n\t\t\tconst material = new MeshPhongMaterial({\n\t\t\t\tmap: null,\n\t\t\t});\n\t\t\tthis.materials.push(material);\n\n\t\t\t// Load texture in background and apply when ready\n\t\t\tassetManager\n\t\t\t\t.loadTexture(texturePath as string, {\n\t\t\t\t\tclone: true,\n\t\t\t\t\trepeat,\n\t\t\t\t})\n\t\t\t\t.then((texture) => {\n\t\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\t\tmaterial.map = texture;\n\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Set normal map for the current material\n\t */\n\tsetNormalMap(normalMapPath: string, repeat: Vector2 = new Vector2(1, 1)): void {\n\t\tconst material = this.materials[this.materials.length - 1];\n\t\tif (!material) return;\n\n\t\tassetManager\n\t\t\t.loadTexture(normalMapPath, {\n\t\t\t\tclone: true,\n\t\t\t\trepeat,\n\t\t\t})\n\t\t\t.then((texture) => {\n\t\t\t\ttexture.wrapS = RepeatWrapping;\n\t\t\t\ttexture.wrapT = RepeatWrapping;\n\t\t\t\t\n\t\t\t\tif (material instanceof MeshStandardMaterial \n\t\t\t\t\t|| material instanceof MeshPhongMaterial\n\t\t\t\t\t|| material instanceof MeshStandardNodeMaterial) {\n\t\t\t\t\tmaterial.normalMap = texture;\n\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t} else if (material instanceof ShaderMaterial) {\n\t\t\t\t\t// Support for custom shaders if they have tNormal or normalMap uniform\n\t\t\t\t\tif (material.uniforms.tNormal) {\n\t\t\t\t\t\tmaterial.uniforms.tNormal.value = texture;\n\t\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (material.uniforms.normalMap) {\n\t\t\t\t\t\tmaterial.uniforms.normalMap.value = texture;\n\t\t\t\t\t\tmaterial.needsUpdate = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\tsetColor(color: Color, useTSL: boolean = false) {\n\t\tif (useTSL) {\n\t\t\t// TSL/WebGPU compatible material\n\t\t\tconst material = new MeshStandardNodeMaterial();\n\t\t\tmaterial.color = color;\n\t\t\tthis.materials.push(material);\n\t\t} else {\n\t\t\t// WebGL compatible material\n\t\t\tconst material = new MeshStandardMaterial({\n\t\t\t\tcolor: color,\n\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\tfog: true,\n\t\t\t});\n\t\t\tthis.materials.push(material);\n\t\t}\n\t}\n\n\t/**\n\t * Set GLSL shader (WebGL only)\n\t */\n\tsetShader(customShader: ZylemShaderObject) {\n\t\tconst { fragment, vertex } = customShader ?? standardShader;\n\n\t\tconst shader = new ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiResolution: { value: new Vector3(1, 1, 1) },\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null },\n\t\t\t\tnormalMap: { value: null },\n\t\t\t\tlightDir: { value: new Vector3(1, 1, 1) },\n\t\t\t\tnormalStrength: { value: 1.0 },\n\t\t\t},\n\t\t\tvertexShader: vertex,\n\t\t\tfragmentShader: fragment,\n\t\t\ttransparent: true,\n\t\t});\n\t\tthis.materials.push(shader);\n\t}\n\n\t/**\n\t * Set TSL shader (WebGPU compatible)\n\t */\n\tsetTSLShader(tslShader: ZylemTSLShader) {\n\t\tconst material = new MeshBasicNodeMaterial();\n\t\tmaterial.colorNode = tslShader.colorNode;\n\t\tif (tslShader.transparent) {\n\t\t\tmaterial.transparent = true;\n\t\t}\n\t\tthis.materials.push(material);\n\t}\n}\n\n// Re-export TSL utilities for shader authoring\nexport {\n\tuniform,\n\tuv,\n\ttime,\n\tvec3,\n\tvec4,\n\tfloat,\n\tFn,\n} from 'three/tsl';\n","export function sortedStringify(obj: Record<string, any>) {\n\tconst sortedObj = Object.keys(obj)\n\t\t.sort()\n\t\t.reduce((acc: Record<string, any>, key: string) => {\n\t\t\tacc[key] = obj[key];\n\t\t\treturn acc;\n\t\t}, {} as Record<string, any>);\n\n\treturn JSON.stringify(sortedObj);\n}\n\nexport function shortHash(objString: string) {\n\tlet hash = 0;\n\tfor (let i = 0; i < objString.length; i++) {\n\t\thash = Math.imul(31, hash) + objString.charCodeAt(i) | 0;\n\t}\n\treturn hash.toString(36);\n}","/**\n * Centralized Asset Manager for Zylem\n * \n * Provides caching, parallel loading, and unified access to all asset types.\n * All asset loading should funnel through this manager.\n */\n\nimport { Texture, Object3D, LoadingManager, Cache } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport mitt, { Emitter } from 'mitt';\n\nimport {\n\tAssetType,\n\tAssetLoadOptions,\n\tAssetManagerEvents,\n\tBatchLoadItem,\n\tModelLoadResult\n} from './asset-types';\n\nimport {\n\tTextureLoaderAdapter,\n\tGLTFLoaderAdapter,\n\tFBXLoaderAdapter,\n\tOBJLoaderAdapter,\n\tAudioLoaderAdapter,\n\tFileLoaderAdapter,\n\tJsonLoaderAdapter,\n\tTextureOptions,\n\tGLTFLoadOptions,\n\tFBXLoadOptions,\n\tOBJLoadOptions,\n\tFileLoadOptions\n} from './loaders';\n\n/**\n * Asset cache entry\n */\ninterface CacheEntry<T> {\n\tpromise: Promise<T>;\n\tresult?: T;\n\tloadedAt: number;\n}\n\n/**\n * AssetManager - Singleton for all asset loading\n * \n * Features:\n * - URL-based caching with deduplication\n * - Typed load methods for each asset type\n * - Batch loading with Promise.all() for parallelism\n * - Progress events via LoadingManager\n * - Clone support for shared assets (textures, models)\n */\nexport class AssetManager {\n\tprivate static instance: AssetManager | null = null;\n\n\t// Caches for different asset types\n\tprivate textureCache: Map<string, CacheEntry<Texture>> = new Map();\n\tprivate modelCache: Map<string, CacheEntry<ModelLoadResult>> = new Map();\n\tprivate audioCache: Map<string, CacheEntry<AudioBuffer>> = new Map();\n\tprivate fileCache: Map<string, CacheEntry<string | ArrayBuffer>> = new Map();\n\tprivate jsonCache: Map<string, CacheEntry<unknown>> = new Map();\n\n\t// Loaders\n\tprivate textureLoader: TextureLoaderAdapter;\n\tprivate gltfLoader: GLTFLoaderAdapter;\n\tprivate fbxLoader: FBXLoaderAdapter;\n\tprivate objLoader: OBJLoaderAdapter;\n\tprivate audioLoader: AudioLoaderAdapter;\n\tprivate fileLoader: FileLoaderAdapter;\n\tprivate jsonLoader: JsonLoaderAdapter;\n\n\t// Loading manager for progress tracking\n\tprivate loadingManager: LoadingManager;\n\n\t// Event emitter\n\tprivate events: Emitter<AssetManagerEvents>;\n\n\t// Stats\n\tprivate stats = {\n\t\ttexturesLoaded: 0,\n\t\tmodelsLoaded: 0,\n\t\taudioLoaded: 0,\n\t\tfilesLoaded: 0,\n\t\tcacheHits: 0,\n\t\tcacheMisses: 0\n\t};\n\n\tprivate constructor() {\n\t\t// Initialize loaders\n\t\tthis.textureLoader = new TextureLoaderAdapter();\n\t\tthis.gltfLoader = new GLTFLoaderAdapter();\n\t\tthis.fbxLoader = new FBXLoaderAdapter();\n\t\tthis.objLoader = new OBJLoaderAdapter();\n\t\tthis.audioLoader = new AudioLoaderAdapter();\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t\tthis.jsonLoader = new JsonLoaderAdapter();\n\n\t\t// Initialize loading manager\n\t\tthis.loadingManager = new LoadingManager();\n\t\tthis.loadingManager.onProgress = (url, loaded, total) => {\n\t\t\tthis.events.emit('batch:progress', { loaded, total });\n\t\t};\n\n\t\t// Initialize event emitter\n\t\tthis.events = mitt<AssetManagerEvents>();\n\n\t\t// Enable Three.js built-in cache\n\t\tCache.enabled = true;\n\t}\n\n\t/**\n\t * Get the singleton instance\n\t */\n\tstatic getInstance(): AssetManager {\n\t\tif (!AssetManager.instance) {\n\t\t\tAssetManager.instance = new AssetManager();\n\t\t}\n\t\treturn AssetManager.instance;\n\t}\n\n\t/**\n\t * Reset the singleton (useful for testing)\n\t */\n\tstatic resetInstance(): void {\n\t\tif (AssetManager.instance) {\n\t\t\tAssetManager.instance.clearCache();\n\t\t\tAssetManager.instance = null;\n\t\t}\n\t}\n\n\t// ==================== TEXTURE LOADING ====================\n\n\t/**\n\t * Load a texture with caching\n\t */\n\tasync loadTexture(url: string, options?: TextureOptions): Promise<Texture> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.TEXTURE,\n\t\t\tthis.textureCache,\n\t\t\t() => this.textureLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(texture) => {\n\t\t\t\tif (!options?.clone) return texture;\n\t\t\t\tconst cloned = this.textureLoader.clone(texture);\n\t\t\t\t// Re-apply per-instance texture options to the clone so that\n\t\t\t\t// different callers sharing the same cached base texture can\n\t\t\t\t// use independent repeat / wrap values.\n\t\t\t\tif (options.repeat) {\n\t\t\t\t\tcloned.repeat.copy(options.repeat);\n\t\t\t\t}\n\t\t\t\tif (options.wrapS !== undefined) {\n\t\t\t\t\tcloned.wrapS = options.wrapS;\n\t\t\t\t}\n\t\t\t\tif (options.wrapT !== undefined) {\n\t\t\t\t\tcloned.wrapT = options.wrapT;\n\t\t\t\t}\n\t\t\t\treturn cloned;\n\t\t\t}\n\t\t);\n\t}\n\n\t// ==================== MODEL LOADING ====================\n\n\t/**\n\t * Load a GLTF/GLB model with caching\n\t */\n\tasync loadGLTF(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.GLTF,\n\t\t\tthis.modelCache,\n\t\t\t() => this.gltfLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.gltfLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an FBX model with caching\n\t */\n\tasync loadFBX(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.FBX,\n\t\t\tthis.modelCache,\n\t\t\t() => this.fbxLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.fbxLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Load an OBJ model with caching\n\t */\n\tasync loadOBJ(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Include mtlPath in cache key for OBJ files\n\t\tconst cacheKey = options?.mtlPath ? `${url}:${options.mtlPath}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.OBJ,\n\t\t\tthis.modelCache,\n\t\t\t() => this.objLoader.load(url, options),\n\t\t\toptions,\n\t\t\t(result) => options?.clone ? this.objLoader.clone(result) : result\n\t\t);\n\t}\n\n\t/**\n\t * Auto-detect model type and load\n\t */\n\tasync loadModel(url: string, options?: AssetLoadOptions): Promise<ModelLoadResult> {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\t\n\t\tswitch (ext) {\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb':\n\t\t\t\treturn this.loadGLTF(url, options);\n\t\t\tcase 'fbx':\n\t\t\t\treturn this.loadFBX(url, options);\n\t\t\tcase 'obj':\n\t\t\t\treturn this.loadOBJ(url, options);\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported model format: ${ext}`);\n\t\t}\n\t}\n\n\t// ==================== AUDIO LOADING ====================\n\n\t/**\n\t * Load an audio buffer with caching\n\t */\n\tasync loadAudio(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.AUDIO,\n\t\t\tthis.audioCache,\n\t\t\t() => this.audioLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t// ==================== FILE LOADING ====================\n\n\t/**\n\t * Load a raw file with caching\n\t */\n\tasync loadFile(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst cacheKey = options?.responseType ? `${url}:${options.responseType}` : url;\n\t\treturn this.loadWithCache(\n\t\t\tcacheKey,\n\t\t\tAssetType.FILE,\n\t\t\tthis.fileCache,\n\t\t\t() => this.fileLoader.load(url, options),\n\t\t\toptions\n\t\t);\n\t}\n\n\t/**\n\t * Load a JSON file with caching\n\t */\n\tasync loadJSON<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\treturn this.loadWithCache(\n\t\t\turl,\n\t\t\tAssetType.JSON,\n\t\t\tthis.jsonCache,\n\t\t\t() => this.jsonLoader.load<T>(url, options),\n\t\t\toptions\n\t\t) as Promise<T>;\n\t}\n\n\t// ==================== BATCH LOADING ====================\n\n\t/**\n\t * Load multiple assets in parallel\n\t */\n\tasync loadBatch(items: BatchLoadItem[]): Promise<Map<string, any>> {\n\t\tconst results = new Map<string, any>();\n\t\t\n\t\tconst promises = items.map(async (item) => {\n\t\t\ttry {\n\t\t\t\tlet result: any;\n\t\t\t\t\n\t\t\t\tswitch (item.type) {\n\t\t\t\t\tcase AssetType.TEXTURE:\n\t\t\t\t\t\tresult = await this.loadTexture(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.GLTF:\n\t\t\t\t\t\tresult = await this.loadGLTF(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FBX:\n\t\t\t\t\t\tresult = await this.loadFBX(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.OBJ:\n\t\t\t\t\t\tresult = await this.loadOBJ(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.AUDIO:\n\t\t\t\t\t\tresult = await this.loadAudio(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.FILE:\n\t\t\t\t\t\tresult = await this.loadFile(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase AssetType.JSON:\n\t\t\t\t\t\tresult = await this.loadJSON(item.url, item.options);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new Error(`Unknown asset type: ${item.type}`);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tresults.set(item.url, result);\n\t\t\t} catch (error) {\n\t\t\t\tthis.events.emit('asset:error', {\n\t\t\t\t\turl: item.url,\n\t\t\t\t\ttype: item.type,\n\t\t\t\t\terror: error as Error\n\t\t\t\t});\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\n\t\tawait Promise.all(promises);\n\t\t\n\t\tthis.events.emit('batch:complete', { urls: items.map(i => i.url) });\n\t\t\n\t\treturn results;\n\t}\n\n\t/**\n\t * Preload assets without returning results\n\t */\n\tasync preload(items: BatchLoadItem[]): Promise<void> {\n\t\tawait this.loadBatch(items);\n\t}\n\n\t// ==================== CACHE MANAGEMENT ====================\n\n\t/**\n\t * Check if an asset is cached\n\t */\n\tisCached(url: string): boolean {\n\t\treturn this.textureCache.has(url) ||\n\t\t\tthis.modelCache.has(url) ||\n\t\t\tthis.audioCache.has(url) ||\n\t\t\tthis.fileCache.has(url) ||\n\t\t\tthis.jsonCache.has(url);\n\t}\n\n\t/**\n\t * Clear all caches or a specific URL\n\t */\n\tclearCache(url?: string): void {\n\t\tif (url) {\n\t\t\tthis.textureCache.delete(url);\n\t\t\tthis.modelCache.delete(url);\n\t\t\tthis.audioCache.delete(url);\n\t\t\tthis.fileCache.delete(url);\n\t\t\tthis.jsonCache.delete(url);\n\t\t} else {\n\t\t\tthis.textureCache.clear();\n\t\t\tthis.modelCache.clear();\n\t\t\tthis.audioCache.clear();\n\t\t\tthis.fileCache.clear();\n\t\t\tthis.jsonCache.clear();\n\t\t\tCache.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Get cache statistics\n\t */\n\tgetStats(): typeof this.stats {\n\t\treturn { ...this.stats };\n\t}\n\n\t// ==================== EVENTS ====================\n\n\t/**\n\t * Subscribe to asset manager events\n\t */\n\ton<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.on(event, handler);\n\t}\n\n\t/**\n\t * Unsubscribe from asset manager events\n\t */\n\toff<K extends keyof AssetManagerEvents>(\n\t\tevent: K,\n\t\thandler: (payload: AssetManagerEvents[K]) => void\n\t): void {\n\t\tthis.events.off(event, handler);\n\t}\n\n\t// ==================== PRIVATE HELPERS ====================\n\n\t/**\n\t * Generic cache wrapper for loading assets\n\t */\n\tprivate async loadWithCache<T>(\n\t\turl: string,\n\t\ttype: AssetType,\n\t\tcache: Map<string, CacheEntry<T>>,\n\t\tloader: () => Promise<T>,\n\t\toptions?: AssetLoadOptions,\n\t\tcloner?: (result: T) => T\n\t): Promise<T> {\n\t\t// Check for force reload\n\t\tif (options?.forceReload) {\n\t\t\tcache.delete(url);\n\t\t}\n\n\t\t// Check cache\n\t\tconst cached = cache.get(url);\n\t\tif (cached) {\n\t\t\tthis.stats.cacheHits++;\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: true });\n\t\t\t\n\t\t\tconst result = await cached.promise;\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t}\n\n\t\t// Cache miss - start loading\n\t\tthis.stats.cacheMisses++;\n\t\tthis.events.emit('asset:loading', { url, type });\n\n\t\tconst promise = loader();\n\t\tconst entry: CacheEntry<T> = {\n\t\t\tpromise,\n\t\t\tloadedAt: Date.now()\n\t\t};\n\t\tcache.set(url, entry);\n\n\t\ttry {\n\t\t\tconst result = await promise;\n\t\t\tentry.result = result;\n\t\t\t\n\t\t\t// Update stats\n\t\t\tthis.updateStats(type);\n\t\t\t\n\t\t\tthis.events.emit('asset:loaded', { url, type, fromCache: false });\n\t\t\t\n\t\t\treturn cloner ? cloner(result) : result;\n\t\t} catch (error) {\n\t\t\t// Remove failed entry from cache\n\t\t\tcache.delete(url);\n\t\t\tthis.events.emit('asset:error', { url, type, error: error as Error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate updateStats(type: AssetType): void {\n\t\tswitch (type) {\n\t\t\tcase AssetType.TEXTURE:\n\t\t\t\tthis.stats.texturesLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.GLTF:\n\t\t\tcase AssetType.FBX:\n\t\t\tcase AssetType.OBJ:\n\t\t\t\tthis.stats.modelsLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.AUDIO:\n\t\t\t\tthis.stats.audioLoaded++;\n\t\t\t\tbreak;\n\t\t\tcase AssetType.FILE:\n\t\t\tcase AssetType.JSON:\n\t\t\t\tthis.stats.filesLoaded++;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Singleton instance export for convenience\n */\nexport const assetManager = AssetManager.getInstance();","/**\n * Texture loader adapter for the Asset Manager\n */\n\nimport { TextureLoader, Texture, RepeatWrapping, Vector2, Wrapping } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface TextureOptions extends AssetLoadOptions {\n\trepeat?: Vector2;\n\twrapS?: Wrapping;\n\twrapT?: Wrapping;\n}\n\nexport class TextureLoaderAdapter implements LoaderAdapter<Texture> {\n\tprivate loader: TextureLoader;\n\n\tconstructor() {\n\t\tthis.loader = new TextureLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'tga'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: TextureOptions): Promise<Texture> {\n\t\tconst texture = await this.loader.loadAsync(url, (event) => {\n\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t}\n\t\t});\n\n\t\t// Apply texture options\n\t\tif (options?.repeat) {\n\t\t\ttexture.repeat.copy(options.repeat);\n\t\t}\n\t\ttexture.wrapS = options?.wrapS ?? RepeatWrapping;\n\t\ttexture.wrapT = options?.wrapT ?? RepeatWrapping;\n\n\t\treturn texture;\n\t}\n\n\t/**\n\t * Clone a texture for independent usage\n\t */\n\tclone(texture: Texture): Texture {\n\t\tconst cloned = texture.clone();\n\t\tcloned.needsUpdate = true;\n\t\treturn cloned;\n\t}\n}\n","/**\n * GLTF loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parseAsync\n */\n\nimport { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface GLTFLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parseAsync pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers, so this mainly\n\t * provides a cleaner async/await pattern rather than performance gains\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class GLTFLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: GLTFLoader;\n\n\tconstructor() {\n\t\tthis.loader = new GLTFLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['gltf', 'glb'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parseAsync\n\t * Both fetch and parsing are async, keeping the main thread responsive\n\t */\n\tprivate async loadWithAsyncFetch(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using GLTFLoader.parseAsync\n\t\t\t// The url is passed as the path for resolving relative resources\n\t\t\tconst gltf = await this.loader.parseAsync(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject: gltf.scene,\n\t\t\t\tanimations: gltf.animations,\n\t\t\t\tgltf\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch GLTF load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: GLTFLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(gltf: GLTF) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject: gltf.scene,\n\t\t\t\t\t\tanimations: gltf.animations,\n\t\t\t\t\t\tgltf\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded GLTF scene for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: result.animations?.map(anim => anim.clone()),\n\t\t\tgltf: result.gltf\n\t\t};\n\t}\n}\n","/**\n * FBX loader adapter for the Asset Manager\n * Uses native fetch (already async/non-blocking in browsers) + parse\n */\n\nimport { Object3D } from 'three';\nimport { FBXLoader } from 'three/addons/loaders/FBXLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface FBXLoadOptions extends AssetLoadOptions {\n\t/** \n\t * Use async fetch + parse pattern instead of loader.load()\n\t * Note: fetch() is already non-blocking in browsers\n\t */\n\tuseAsyncFetch?: boolean;\n}\n\nexport class FBXLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: FBXLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FBXLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'fbx';\n\t}\n\n\tasync load(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\tif (options?.useAsyncFetch) {\n\t\t\treturn this.loadWithAsyncFetch(url, options);\n\t\t}\n\t\treturn this.loadMainThread(url, options);\n\t}\n\n\t/**\n\t * Load using native fetch + parse\n\t */\n\tprivate async loadWithAsyncFetch(url: string, _options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\ttry {\n\t\t\tconst response = await fetch(url);\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new Error(`Failed to fetch ${url}: ${response.status} ${response.statusText}`);\n\t\t\t}\n\t\t\tconst buffer = await response.arrayBuffer();\n\n\t\t\t// Parse on main thread using FBXLoader.parse\n\t\t\tconst object = this.loader.parse(buffer, url);\n\n\t\t\treturn {\n\t\t\t\tobject,\n\t\t\t\tanimations: (object as any).animations || []\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconsole.error(`Async fetch FBX load failed for ${url}, falling back to loader.load():`, error);\n\t\t\treturn this.loadMainThread(url, _options);\n\t\t}\n\t}\n\n\tprivate async loadMainThread(url: string, options?: FBXLoadOptions): Promise<ModelLoadResult> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Object3D) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: (object as any).animations || []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded FBX object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: result.animations?.map(anim => anim.clone())\n\t\t};\n\t}\n}\n","/**\n * OBJ loader adapter for the Asset Manager\n * Supports optional MTL (material) file loading\n */\n\nimport { Object3D, Group } from 'three';\nimport { OBJLoader } from 'three/addons/loaders/OBJLoader.js';\nimport { MTLLoader } from 'three/addons/loaders/MTLLoader.js';\nimport { LoaderAdapter, AssetLoadOptions, ModelLoadResult } from '../asset-types';\n\nexport interface OBJLoadOptions extends AssetLoadOptions {\n\t/** Path to MTL material file */\n\tmtlPath?: string;\n}\n\nexport class OBJLoaderAdapter implements LoaderAdapter<ModelLoadResult> {\n\tprivate loader: OBJLoader;\n\tprivate mtlLoader: MTLLoader;\n\n\tconstructor() {\n\t\tthis.loader = new OBJLoader();\n\t\tthis.mtlLoader = new MTLLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'obj';\n\t}\n\n\tasync load(url: string, options?: OBJLoadOptions): Promise<ModelLoadResult> {\n\t\t// Load MTL first if provided\n\t\tif (options?.mtlPath) {\n\t\t\tawait this.loadMTL(options.mtlPath);\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(object: Group) => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tobject,\n\t\t\t\t\t\tanimations: []\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\tprivate async loadMTL(url: string): Promise<void> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.mtlLoader.load(\n\t\t\t\turl,\n\t\t\t\t(materials) => {\n\t\t\t\t\tmaterials.preload();\n\t\t\t\t\tthis.loader.setMaterials(materials);\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Clone a loaded OBJ object for reuse\n\t */\n\tclone(result: ModelLoadResult): ModelLoadResult {\n\t\treturn {\n\t\t\tobject: result.object.clone(),\n\t\t\tanimations: []\n\t\t};\n\t}\n}\n","/**\n * Audio loader adapter for the Asset Manager\n */\n\nimport { AudioLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport class AudioLoaderAdapter implements LoaderAdapter<AudioBuffer> {\n\tprivate loader: AudioLoader;\n\n\tconstructor() {\n\t\tthis.loader = new AudioLoader();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ['mp3', 'ogg', 'wav', 'flac', 'aac', 'm4a'].includes(ext || '');\n\t}\n\n\tasync load(url: string, options?: AssetLoadOptions): Promise<AudioBuffer> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(buffer) => resolve(buffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n","/**\n * File loader adapter for the Asset Manager\n */\n\nimport { FileLoader } from 'three';\nimport { LoaderAdapter, AssetLoadOptions } from '../asset-types';\n\nexport interface FileLoadOptions extends AssetLoadOptions {\n\tresponseType?: 'text' | 'arraybuffer' | 'blob' | 'json';\n}\n\nexport class FileLoaderAdapter implements LoaderAdapter<string | ArrayBuffer> {\n\tprivate loader: FileLoader;\n\n\tconstructor() {\n\t\tthis.loader = new FileLoader();\n\t}\n\n\tisSupported(_url: string): boolean {\n\t\t// FileLoader can handle any file type\n\t\treturn true;\n\t}\n\n\tasync load(url: string, options?: FileLoadOptions): Promise<string | ArrayBuffer> {\n\t\tconst responseType = options?.responseType ?? 'text';\n\t\tthis.loader.setResponseType(responseType as any);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.loader.load(\n\t\t\t\turl,\n\t\t\t\t(data) => resolve(data as string | ArrayBuffer),\n\t\t\t\t(event) => {\n\t\t\t\t\tif (options?.onProgress && event.lengthComputable) {\n\t\t\t\t\t\toptions.onProgress(event.loaded / event.total);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t(error) => reject(error)\n\t\t\t);\n\t\t});\n\t}\n}\n\n/**\n * JSON loader using FileLoader\n */\nexport class JsonLoaderAdapter implements LoaderAdapter<unknown> {\n\tprivate fileLoader: FileLoaderAdapter;\n\n\tconstructor() {\n\t\tthis.fileLoader = new FileLoaderAdapter();\n\t}\n\n\tisSupported(url: string): boolean {\n\t\tconst ext = url.split('.').pop()?.toLowerCase();\n\t\treturn ext === 'json';\n\t}\n\n\tasync load<T = unknown>(url: string, options?: AssetLoadOptions): Promise<T> {\n\t\tconst data = await this.fileLoader.load(url, { ...options, responseType: 'json' });\n\t\treturn data as T;\n\t}\n}\n","import { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { sphereMesh } from './parts/mesh-factories';\nimport { sphereCollision } from './parts/collision-factories';\n\ntype ZylemSphereOptions = GameEntityOptions & {\n\tradius?: number;\n};\n\nconst sphereDefaults: ZylemSphereOptions = {\n\t...commonDefaults,\n\tradius: 1,\n};\n\nexport const SPHERE_TYPE = Symbol('Sphere');\n\nexport class ZylemSphere extends GameEntity<ZylemSphereOptions> {\n\tstatic type = SPHERE_TYPE;\n\n\tconstructor(options?: ZylemSphereOptions) {\n\t\tsuper();\n\t\tthis.options = { ...sphereDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 1;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemSphere.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t};\n\t}\n}\n\ntype SphereOptions = BaseNode | Partial<ZylemSphereOptions>;\n\nexport function createSphere(...args: Array<SphereOptions>): ZylemSphere {\n\tconst options = mergeArgs(args, sphereDefaults);\n\tconst entity = new ZylemSphere(options);\n\tentity.add(\n\t\tsphereMesh({ radius: options.radius, material: options.material, color: options.color }),\n\t\tsphereCollision({\n\t\t\tradius: options.radius,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn entity;\n}\n","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { Color, Euler, Group, Quaternion, Vector3 } from 'three';\nimport {\n\tTextureLoader,\n\tSpriteMaterial,\n\tSprite as ThreeSprite,\n} from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { createEntity } from './create';\nimport { DestroyContext, DestroyFunction, UpdateContext, UpdateFunction } from '../core/base-node-life-cycle';\nimport { DebugDelegate } from './delegates/debug';\nimport { standardShader } from '../graphics/shaders/standard.shader';\n\nexport type SpriteImage = { name: string; file: string };\nexport type SpriteAnimation = {\n\tname: string;\n\tframes: string[];\n\tspeed: number | number[];\n\tloop: boolean;\n};\n\ntype ZylemSpriteOptions = GameEntityOptions & {\n\timages?: SpriteImage[];\n\tanimations?: SpriteAnimation[];\n\tsize?: Vector3;\n\tcollisionSize?: Vector3;\n};\n\nimport { commonDefaults } from './common';\n\nconst spriteDefaults: ZylemSpriteOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n\timages: [],\n\tanimations: [],\n};\n\nexport class SpriteCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemSpriteOptions): ColliderDesc {\n\t\tconst size = options.collisionSize || options.size || new Vector3(1, 1, 1);\n\t\tconst half = { x: size.x / 2, y: size.y / 2, z: size.z / 2 };\n\t\tlet colliderDesc = ColliderDesc.cuboid(half.x, half.y, half.z);\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class SpriteBuilder extends EntityBuilder<ZylemSprite, ZylemSpriteOptions> {\n\tprotected createEntity(options: Partial<ZylemSpriteOptions>): ZylemSprite {\n\t\treturn new ZylemSprite(options);\n\t}\n}\n\nexport const SPRITE_TYPE = Symbol('Sprite');\n\nexport class ZylemSprite extends GameEntity<ZylemSpriteOptions> {\n\tstatic type = SPRITE_TYPE;\n\n\tprotected sprites: ThreeSprite[] = [];\n\tprotected spriteMap: Map<string, number> = new Map();\n\tprotected currentSpriteIndex: number = 0;\n\tprotected animations: Map<string, any> = new Map();\n\tprotected currentAnimation: any = null;\n\tprotected currentAnimationFrame: string = '';\n\tprotected currentAnimationIndex: number = 0;\n\tprotected currentAnimationTime: number = 0;\n\n\tconstructor(options?: ZylemSpriteOptions) {\n\t\tsuper();\n\t\tthis.options = { ...spriteDefaults, ...options };\n\t\t// Add sprite-specific lifecycle callbacks (only registered once)\n\t\tthis.prependUpdate(this.spriteUpdate.bind(this) as any);\n\t\tthis.onCleanup(this.spriteDestroy.bind(this) as any);\n\t}\n\n\tpublic create(): this {\n\t\t// Clear previous state to prevent accumulation on reload\n\t\tthis.sprites = [];\n\t\tthis.spriteMap.clear();\n\t\tthis.animations.clear();\n\t\tthis.currentAnimation = null;\n\t\tthis.currentAnimationFrame = '';\n\t\tthis.currentAnimationIndex = 0;\n\t\tthis.currentAnimationTime = 0;\n\t\tthis.group = undefined;\n\t\t\n\t\t// Recreate sprites and animations\n\t\tthis.createSpritesFromImages(this.options?.images || []);\n\t\tthis.createAnimations(this.options?.animations || []);\n\t\t\n\t\t// Call parent create\n\t\treturn super.create();\n\t}\n\n\tprotected createSpritesFromImages(images: SpriteImage[]) {\n\t\t// Use synchronous load() which returns a texture that updates when ready\n\t\t// This maintains compatibility with the synchronous create() method\n\t\tconst textureLoader = new TextureLoader();\n\t\timages.forEach((image, index) => {\n\t\t\tconst spriteMap = textureLoader.load(image.file);\n\t\t\tconst material = new SpriteMaterial({\n\t\t\t\tmap: spriteMap,\n\t\t\t\ttransparent: true,\n\t\t\t});\n\t\t\tconst _sprite = new ThreeSprite(material);\n\t\t\t_sprite.position.normalize();\n\t\t\tthis.sprites.push(_sprite);\n\t\t\tthis.spriteMap.set(image.name, index);\n\t\t});\n\t\tthis.group = new Group();\n\t\tthis.group.add(...this.sprites);\n\t}\n\n\tprotected createAnimations(animations: SpriteAnimation[]) {\n\t\tanimations.forEach(animation => {\n\t\t\tconst { name, frames, loop = false, speed = 1 } = animation;\n\t\t\tconst internalAnimation = {\n\t\t\t\tframes: frames.map((frame, index) => ({\n\t\t\t\t\tkey: frame,\n\t\t\t\t\tindex,\n\t\t\t\t\ttime: (typeof speed === 'number' ? speed : speed[index]) * (index + 1),\n\t\t\t\t\tduration: typeof speed === 'number' ? speed : speed[index]\n\t\t\t\t})),\n\t\t\t\tloop,\n\t\t\t};\n\t\t\tthis.animations.set(name, internalAnimation);\n\t\t});\n\t}\n\n\tsetSprite(key: string) {\n\t\tconst spriteIndex = this.spriteMap.get(key);\n\t\tconst useIndex = spriteIndex ?? 0;\n\t\tthis.currentSpriteIndex = useIndex;\n\t\tthis.sprites.forEach((_sprite, i) => {\n\t\t\t_sprite.visible = this.currentSpriteIndex === i;\n\t\t});\n\t}\n\n\tsetAnimation(name: string, delta: number) {\n\t\tconst animation = this.animations.get(name);\n\t\tif (!animation) return;\n\n\t\tconst { loop, frames } = animation;\n\t\tconst frame = frames[this.currentAnimationIndex];\n\n\t\tif (name === this.currentAnimation) {\n\t\t\tthis.currentAnimationFrame = frame.key;\n\t\t\tthis.currentAnimationTime += delta;\n\t\t\tthis.setSprite(this.currentAnimationFrame);\n\t\t} else {\n\t\t\tthis.currentAnimation = name;\n\t\t}\n\n\t\tif (this.currentAnimationTime > frame.time) {\n\t\t\tthis.currentAnimationIndex++;\n\t\t}\n\n\t\tif (this.currentAnimationIndex >= frames.length) {\n\t\t\tif (loop) {\n\t\t\t\tthis.currentAnimationIndex = 0;\n\t\t\t\tthis.currentAnimationTime = 0;\n\t\t\t} else {\n\t\t\t\tthis.currentAnimationTime = frames[this.currentAnimationIndex].time;\n\t\t\t}\n\t\t}\n\t}\n\n\tspriteUpdate(params: UpdateContext<ZylemSpriteOptions>): void {\n\t\tthis.sprites.forEach(_sprite => {\n\t\t\tif (_sprite.material) {\n\t\t\t\tconst q = this.body?.rotation();\n\t\t\t\tif (q) {\n\t\t\t\t\tconst quat = new Quaternion(q.x, q.y, q.z, q.w);\n\t\t\t\t\tconst euler = new Euler().setFromQuaternion(quat, 'XYZ');\n\t\t\t\t\t_sprite.material.rotation = euler.z;\n\t\t\t\t}\n\t\t\t\t_sprite.scale.set(this.options.size?.x ?? 1, this.options.size?.y ?? 1, this.options.size?.z ?? 1);\n\t\t\t}\n\t\t});\n\t}\n\n\tspriteDestroy(params: DestroyContext<ZylemSpriteOptions>): void {\n\t\tthis.sprites.forEach(_sprite => {\n\t\t\t_sprite.removeFromParent();\n\t\t});\n\t\tthis.group?.remove(...this.sprites);\n\t\tthis.group?.removeFromParent();\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemSprite.type),\n\t\t};\n\t}\n}\n\ntype SpriteOptions = BaseNode | Partial<ZylemSpriteOptions>;\n\nexport function createSprite(...args: Array<SpriteOptions>): ZylemSprite {\n\treturn createEntity<ZylemSprite, ZylemSpriteOptions>({\n\t\targs,\n\t\tdefaultConfig: spriteDefaults,\n\t\tEntityClass: ZylemSprite,\n\t\tBuilderClass: SpriteBuilder,\n\t\tCollisionBuilderClass: SpriteCollisionBuilder,\n\t\tentityType: ZylemSprite.type\n\t});\n}","import { ColliderDesc } from \"@dimforge/rapier3d-compat\";\nimport { GameEntity, GameEntityOptions } from \"./entity\";\nimport { BufferGeometry, Group, Material, Mesh, Color } from \"three\";\nimport { CollisionBuilder } from \"../collision/collision-builder\";\nimport { MeshBuilder } from \"../graphics/mesh\";\nimport { MaterialBuilder, MaterialOptions } from \"../graphics/material\";\nimport { Vec3 } from \"../core/vector\";\n\nexport abstract class EntityCollisionBuilder extends CollisionBuilder {\n\tabstract collider(options: GameEntityOptions): ColliderDesc;\n}\n\nexport abstract class EntityMeshBuilder extends MeshBuilder {\n\tbuild(options: GameEntityOptions): BufferGeometry {\n\t\treturn new BufferGeometry();\n\t}\n\n\tpostBuild(): void {\n\t\treturn;\n\t}\n}\n\nexport abstract class EntityBuilder<T extends GameEntity<U> & P, U extends GameEntityOptions, P = any> {\n\tprotected meshBuilder: EntityMeshBuilder | null;\n\tprotected collisionBuilder: EntityCollisionBuilder | null;\n\tprotected materialBuilder: MaterialBuilder | null;\n\tprotected options: Partial<U>;\n\tprotected entity: T;\n\n\tconstructor(\n\t\toptions: Partial<U>,\n\t\tentity: T,\n\t\tmeshBuilder: EntityMeshBuilder | null,\n\t\tcollisionBuilder: EntityCollisionBuilder | null,\n\t) {\n\t\tthis.options = options;\n\t\tthis.entity = entity;\n\t\tthis.meshBuilder = meshBuilder;\n\t\tthis.collisionBuilder = collisionBuilder;\n\t\tthis.materialBuilder = new MaterialBuilder();\n\t\tconst builders: NonNullable<GameEntityOptions[\"_builders\"]> = {\n\t\t\tmeshBuilder: this.meshBuilder,\n\t\t\tcollisionBuilder: this.collisionBuilder,\n\t\t\tmaterialBuilder: this.materialBuilder,\n\t\t};\n\t\t(this.options as Partial<GameEntityOptions>)._builders = builders;\n\t}\n\n\twithPosition(setupPosition: Vec3): this {\n\t\tthis.options.position = setupPosition;\n\t\treturn this;\n\t}\n\n\twithMaterial(options: Partial<MaterialOptions>, entityType: symbol): this {\n\t\tif (this.materialBuilder) {\n\t\t\tthis.materialBuilder.build(options, entityType);\n\t\t}\n\t\treturn this;\n\t}\n\n\tapplyMaterialToGroup(group: Group, materials: Material[]): void {\n\t\tgroup.traverse((child) => {\n\t\t\tif (child instanceof Mesh) {\n\t\t\t\tif (child.type === 'SkinnedMesh' && materials[0] && !child.material.map) {\n\t\t\t\t\tchild.material = materials[0];\n\t\t\t\t}\n\t\t\t}\n\t\t\tchild.castShadow = true;\n\t\t\tchild.receiveShadow = true;\n\t\t});\n\t}\n\n\tbuild(): T {\n\t\tconst entity = this.entity;\n\t\tif (this.materialBuilder) {\n\t\t\tentity.materials = this.materialBuilder.materials;\n\t\t}\n\t\tif (this.meshBuilder && entity.materials) {\n\t\t\tconst geometry = this.meshBuilder.build(this.options);\n\t\t\tentity.mesh = this.meshBuilder._build(this.options, geometry, entity.materials);\n\t\t\tthis.meshBuilder.postBuild();\n\t\t}\n\n\t\tif (entity.group && entity.materials) {\n\t\t\tthis.applyMaterialToGroup(entity.group, entity.materials);\n\t\t}\n\n\t\tif (this.collisionBuilder) {\n\t\t\tthis.collisionBuilder.withCollision(this.options?.collision || {});\n\t\t\tconst [bodyDesc, colliderDesc] = this.collisionBuilder.build(this.options as any);\n\t\t\tentity.bodyDesc = bodyDesc;\n\t\t\tentity.colliderDesc = colliderDesc;\n\t\t\tentity.colliderDescs.push(colliderDesc);\n\n\t\t\tconst { x, y, z } = this.options.position || { x: 0, y: 0, z: 0 };\n\t\t\tentity.bodyDesc.setTranslation(x, y, z);\n\t\t}\n\t\tif (this.options.collisionType) {\n\t\t\tentity.collisionType = this.options.collisionType;\n\t\t}\n\n\t\tif (this.options.color instanceof Color) {\n\t\t\tconst applyColor = (material: Material) => {\n\t\t\t\tconst anyMat = material as any;\n\t\t\t\tif (anyMat && anyMat.color && anyMat.color.set) {\n\t\t\t\t\tanyMat.color.set(this.options.color as Color);\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (entity.materials?.length) {\n\t\t\t\tfor (const mat of entity.materials) applyColor(mat);\n\t\t\t}\n\t\t\tif (entity.mesh && entity.mesh.material) {\n\t\t\t\tconst mat = entity.mesh.material as any;\n\t\t\t\tif (Array.isArray(mat)) mat.forEach(applyColor); else applyColor(mat);\n\t\t\t}\n\t\t\tif (entity.group) {\n\t\t\t\tentity.group.traverse((child) => {\n\t\t\t\t\tif (child instanceof Mesh && child.material) {\n\t\t\t\t\t\tconst mat = child.material as any;\n\t\t\t\t\t\tif (Array.isArray(mat)) mat.forEach(applyColor); else applyColor(mat);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn entity;\n\t}\n\n\tprotected abstract createEntity(options: Partial<U>): T;\n}\n","import { BufferGeometry, Material, Mesh } from 'three';\nimport { GameEntityOptions } from '../entities/entity';\n\n/**\n * TODO: allow for multiple materials requires geometry groups\n * TODO: allow for instanced uniforms\n * TODO: allow for geometry groups\n * TODO: allow for batched meshes\n * import { InstancedUniformsMesh } from 'three-instanced-uniforms-mesh';\n * may not need geometry groups for shaders though\n * setGeometry<T extends BufferGeometry>(geometry: T) {\n * MeshBuilder.bachedMesh = new BatchedMesh(10, 5000, 10000, material);\n * }\n */\n\nexport type MeshBuilderOptions = Partial<Pick<GameEntityOptions, 'batched' | 'material'>>;\n\nexport class MeshBuilder {\n\n\t_build(meshOptions: MeshBuilderOptions, geometry: BufferGeometry, materials: Material[]): Mesh {\n\t\tconst { batched, material } = meshOptions;\n\t\tif (batched) {\n\t\t\tconsole.warn('warning: mesh batching is not implemented');\n\t\t}\n\t\tconst mesh = new Mesh(geometry, materials.at(-1));\n\t\tmesh.position.set(0, 0, 0);\n\t\tmesh.castShadow = true;\n\t\tmesh.receiveShadow = true;\n\t\treturn mesh;\n\t}\n\n\t_postBuild(): void {\n\t\treturn;\n\t}\n}","// this class is not for asset loading, it is for loading entity specific data\n// this is to keep the entity class focused purely on entity logic\n\nexport function isLoadable(obj: any): obj is EntityLoaderDelegate {\n\treturn typeof obj?.load === \"function\" && typeof obj?.data === \"function\";\n}\n\nexport interface EntityLoaderDelegate {\n\t/** Initiates loading (may be async internally, but call returns immediately) */\n\tload(): void;\n\t/** Returns data synchronously (may be null if still loading) */\n\tdata(): any;\n}\n\nexport class EntityLoader {\n\tentityReference: EntityLoaderDelegate;\n\n\tconstructor(entity: EntityLoaderDelegate) {\n\t\tthis.entityReference = entity;\n\t}\n\n\tload(): void {\n\t\tif (this.entityReference.load) {\n\t\t\tthis.entityReference.load();\n\t\t}\n\t}\n\n\tdata(): any {\n\t\tif (this.entityReference.data) {\n\t\t\treturn this.entityReference.data();\n\t\t}\n\t\treturn null;\n\t}\n}","import { GameEntityOptions, GameEntity } from \"./entity\";\nimport { BaseNode } from \"../core/base-node\";\nimport { EntityBuilder } from \"./builder\";\nimport { EntityCollisionBuilder } from \"./builder\";\nimport { EntityMeshBuilder } from \"./builder\";\nimport { EntityLoader, isLoadable } from \"./delegates/loader\";\n\nexport interface CreateGameEntityOptions<T extends GameEntity<any>, CreateOptions extends GameEntityOptions> {\n\targs: Array<any>;\n\tdefaultConfig: GameEntityOptions;\n\tEntityClass: new (options: any) => T;\n\tBuilderClass: new (options: any, entity: T, meshBuilder: any, collisionBuilder: any) => EntityBuilder<T, CreateOptions>;\n\tMeshBuilderClass?: new (data: any) => EntityMeshBuilder;\n\tCollisionBuilderClass?: new (data: any) => EntityCollisionBuilder;\n\tentityType: symbol;\n};\n\nexport function createEntity<T extends GameEntity<any>, CreateOptions extends GameEntityOptions>(params: CreateGameEntityOptions<T, CreateOptions>): T {\n\tconst {\n\t\targs,\n\t\tdefaultConfig,\n\t\tEntityClass,\n\t\tBuilderClass,\n\t\tentityType,\n\t\tMeshBuilderClass,\n\t\tCollisionBuilderClass,\n\t} = params;\n\n\tlet builder: EntityBuilder<T, CreateOptions> | null = null;\n\tlet configuration;\n\n\tconst configurationIndex = args.findIndex(node => !(node instanceof BaseNode));\n\tif (configurationIndex !== -1) {\n\t\tconst subArgs = args.splice(configurationIndex, 1);\n\t\tconfiguration = subArgs.find(node => !(node instanceof BaseNode));\n\t}\n\n\tconst mergedConfiguration = configuration ? { ...defaultConfig, ...configuration } : defaultConfig;\n\targs.push(mergedConfiguration);\n\n\tfor (const arg of args) {\n\t\tif (arg instanceof BaseNode) {\n\t\t\tcontinue;\n\t\t}\n\t\tlet entityData = null;\n\t\tconst entity = new EntityClass(arg);\n\t\ttry {\n\t\t\tif (isLoadable(entity)) {\n\t\t\t\tconst loader = new EntityLoader(entity);\n\t\t\t\tloader.load();\n\t\t\t\tentityData = loader.data();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error creating entity with loader:\", error);\n\t\t}\n\t\tbuilder = new BuilderClass(\n\t\t\targ,\n\t\t\tentity,\n\t\t\tMeshBuilderClass ? new MeshBuilderClass(entityData) : null,\n\t\t\tCollisionBuilderClass ? new CollisionBuilderClass(entityData) : null,\n\t\t);\n\t\tif (arg.material) {\n\t\t\tbuilder.withMaterial(arg.material, entityType);\n\t\t}\n\t}\n\n\tif (!builder) {\n\t\tthrow new Error(`missing options for ${String(entityType)}, builder is not initialized.`);\n\t}\n\n\treturn builder.build();\n}\n\n","import { ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { PlaneGeometry, Vector2, Vector3 } from 'three';\nimport { TexturePath } from '../graphics/material';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { EntityMeshBuilder } from './builder';\nimport { XZPlaneGeometry } from '../graphics/geometries/XZPlaneGeometry';\nimport { createEntity } from './create';\n\ntype ZylemPlaneOptions = GameEntityOptions & {\n\ttile?: Vector2;\n\trepeat?: Vector2;\n\ttexture?: TexturePath;\n\tsubdivisions?: number;\n\trandomizeHeight?: boolean;\n\theightMap?: number[];\n\theightScale?: number;\n};\n\nconst DEFAULT_SUBDIVISIONS = 4;\n\nimport { commonDefaults } from './common';\n\nconst planeDefaults: ZylemPlaneOptions = {\n\t...commonDefaults,\n\ttile: new Vector2(10, 10),\n\trepeat: new Vector2(1, 1),\n\tcollision: {\n\t\tstatic: true,\n\t},\n\tsubdivisions: DEFAULT_SUBDIVISIONS,\n\trandomizeHeight: false,\n\theightScale: 1,\n};\n\nexport class PlaneCollisionBuilder extends EntityCollisionBuilder {\n\tcollider(options: ZylemPlaneOptions): ColliderDesc {\n\t\tconst tile = options.tile ?? new Vector2(1, 1);\n\t\tconst subdivisions = options.subdivisions ?? DEFAULT_SUBDIVISIONS;\n\t\tconst size = new Vector3(tile.x, 1, tile.y);\n\n\t\tconst heightData = (options._builders?.meshBuilder as unknown as PlaneMeshBuilder)?.heightData;\n\t\tconst scale = new Vector3(size.x, 1, size.z);\n\t\tlet colliderDesc = ColliderDesc.heightfield(\n\t\t\tsubdivisions,\n\t\t\tsubdivisions,\n\t\t\theightData,\n\t\t\tscale\n\t\t);\n\n\t\treturn colliderDesc;\n\t}\n}\n\nexport class PlaneMeshBuilder extends EntityMeshBuilder {\n\theightData: Float32Array = new Float32Array();\n\tcolumnsRows = new Map();\n\tprivate subdivisions: number = DEFAULT_SUBDIVISIONS;\n\n\tbuild(options: ZylemPlaneOptions): XZPlaneGeometry {\n\t\tconst tile = options.tile ?? new Vector2(1, 1);\n\t\tconst subdivisions = options.subdivisions ?? DEFAULT_SUBDIVISIONS;\n\t\tthis.subdivisions = subdivisions;\n\t\tconst size = new Vector3(tile.x, 1, tile.y);\n\t\tconst heightScale = options.heightScale ?? 1;\n\n\t\tconst geometry = new XZPlaneGeometry(size.x, size.z, subdivisions, subdivisions);\n\t\tconst vertexGeometry = new PlaneGeometry(size.x, size.z, subdivisions, subdivisions);\n\t\tconst dx = size.x / subdivisions;\n\t\tconst dy = size.z / subdivisions;\n\t\tconst originalVertices = geometry.attributes.position.array;\n\t\tconst vertices = vertexGeometry.attributes.position.array;\n\t\tconst columsRows = new Map();\n\n\t\t// Get height data source\n\t\tconst heightMapData = options.heightMap;\n\t\tconst useRandomHeight = options.randomizeHeight ?? false;\n\n\t\tfor (let i = 0; i < vertices.length; i += 3) {\n\t\t\tconst vertexIndex = i / 3;\n\t\t\tlet row = Math.floor(Math.abs((vertices as any)[i] + (size.x / 2)) / dx);\n\t\t\tlet column = Math.floor(Math.abs((vertices as any)[i + 1] - (size.z / 2)) / dy);\n\n\t\t\tlet height = 0;\n\t\t\tif (heightMapData && heightMapData.length > 0) {\n\t\t\t\t// Loop the height map data if it doesn't cover all vertices\n\t\t\t\tconst heightIndex = vertexIndex % heightMapData.length;\n\t\t\t\theight = heightMapData[heightIndex] * heightScale;\n\t\t\t} else if (useRandomHeight) {\n\t\t\t\theight = Math.random() * 4 * heightScale;\n\t\t\t}\n\n\t\t\t(vertices as any)[i + 2] = height;\n\t\t\toriginalVertices[i + 1] = height;\n\t\t\tif (!columsRows.get(column)) {\n\t\t\t\tcolumsRows.set(column, new Map());\n\t\t\t}\n\t\t\tcolumsRows.get(column).set(row, height);\n\t\t}\n\t\tthis.columnsRows = columsRows;\n\t\treturn geometry;\n\t}\n\n\tpostBuild(): void {\n\t\tconst heights = [];\n\t\tfor (let i = 0; i <= this.subdivisions; ++i) {\n\t\t\tfor (let j = 0; j <= this.subdivisions; ++j) {\n\t\t\t\tconst row = this.columnsRows.get(j);\n\t\t\t\tif (!row) {\n\t\t\t\t\theights.push(0);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst data = row.get(i);\n\t\t\t\theights.push(data ?? 0);\n\t\t\t}\n\t\t}\n\t\tthis.heightData = new Float32Array(heights as unknown as number[]);\n\t}\n}\n\nexport class PlaneBuilder extends EntityBuilder<ZylemPlane, ZylemPlaneOptions> {\n\tprotected createEntity(options: Partial<ZylemPlaneOptions>): ZylemPlane {\n\t\treturn new ZylemPlane(options);\n\t}\n}\n\nexport const PLANE_TYPE = Symbol('Plane');\n\nexport class ZylemPlane extends GameEntity<ZylemPlaneOptions> {\n\tstatic type = PLANE_TYPE;\n\n\tconstructor(options?: ZylemPlaneOptions) {\n\t\tsuper();\n\t\tthis.options = { ...planeDefaults, ...options };\n\t}\n}\n\ntype PlaneOptions = BaseNode | Partial<ZylemPlaneOptions>;\n\nexport function createPlane(...args: Array<PlaneOptions>): ZylemPlane {\n\treturn createEntity<ZylemPlane, ZylemPlaneOptions>({\n\t\targs,\n\t\tdefaultConfig: planeDefaults,\n\t\tEntityClass: ZylemPlane,\n\t\tBuilderClass: PlaneBuilder,\n\t\tMeshBuilderClass: PlaneMeshBuilder,\n\t\tCollisionBuilderClass: PlaneCollisionBuilder,\n\t\tentityType: ZylemPlane.type\n\t});\n}\n","// @ts-nocheck\nimport { BufferGeometry, Float32BufferAttribute } from 'three';\n\nclass XZPlaneGeometry extends BufferGeometry {\n\n\tconstructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) {\n\n\t\tsuper();\n\n\t\tthis.type = 'XZPlaneGeometry';\n\n\t\tthis.parameters = {\n\t\t\twidth: width,\n\t\t\theight: height,\n\t\t\twidthSegments: widthSegments,\n\t\t\theightSegments: heightSegments\n\t\t};\n\n\t\tconst width_half = width / 2;\n\t\tconst height_half = height / 2;\n\n\t\tconst gridX = Math.floor(widthSegments);\n\t\tconst gridY = Math.floor(heightSegments);\n\n\t\tconst gridX1 = gridX + 1;\n\t\tconst gridY1 = gridY + 1;\n\n\t\tconst segment_width = width / gridX;\n\t\tconst segment_height = height / gridY;\n\n\t\tconst indices = [];\n\t\tconst vertices = [];\n\t\tconst normals = [];\n\t\tconst uvs = [];\n\n\t\tfor (let iy = 0; iy < gridY1; iy++) {\n\n\t\t\tconst z = iy * segment_height - height_half;\n\n\t\t\tfor (let ix = 0; ix < gridX1; ix++) {\n\n\t\t\t\tconst x = ix * segment_width - width_half;\n\n\t\t\t\tvertices.push(x, 0, z);\n\n\t\t\t\tnormals.push(0, 1, 0);\n\n\t\t\t\tuvs.push(ix / gridX);\n\t\t\t\tuvs.push(1 - (iy / gridY));\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor (let iy = 0; iy < gridY; iy++) {\n\n\t\t\tfor (let ix = 0; ix < gridX; ix++) {\n\n\t\t\t\tconst a = ix + gridX1 * iy;\n\t\t\t\tconst b = ix + gridX1 * (iy + 1);\n\t\t\t\tconst c = (ix + 1) + gridX1 * (iy + 1);\n\t\t\t\tconst d = (ix + 1) + gridX1 * iy;\n\n\t\t\t\tindices.push(a, b, d);\n\t\t\t\tindices.push(b, c, d);\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.setIndex(indices);\n\t\tthis.setAttribute('position', new Float32BufferAttribute(vertices, 3));\n\t\tthis.setAttribute('normal', new Float32BufferAttribute(normals, 3));\n\t\tthis.setAttribute('uv', new Float32BufferAttribute(uvs, 2));\n\n\t}\n\n\tcopy(source) {\n\n\t\tsuper.copy(source);\n\n\t\tthis.parameters = Object.assign({}, source.parameters);\n\n\t\treturn this;\n\t}\n\n\tstatic fromJSON(data) {\n\t\treturn new XZPlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments);\n\t}\n\n}\n\nexport { XZPlaneGeometry };","import { Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { CollisionHandlerDelegate } from '../collision/world';\nimport { state } from '../game/game-state';\nimport { commonDefaults, mergeArgs } from './common';\nimport { zoneCollision } from './parts/collision-factories';\n\nexport type OnHeldParams = {\n\tdelta: number;\n\tself: ZylemZone;\n\tvisitor: GameEntity<any>;\n\theldTime: number;\n\tglobals: any;\n}\n\nexport type OnEnterParams = Pick<OnHeldParams, 'self' | 'visitor' | 'globals'>;\nexport type OnExitParams = Pick<OnHeldParams, 'self' | 'visitor' | 'globals'>;\n\ntype ZylemZoneOptions = GameEntityOptions & {\n\tsize?: Vector3;\n\tstatic?: boolean;\n\tonEnter?: (params: OnEnterParams) => void;\n\tonHeld?: (params: OnHeldParams) => void;\n\tonExit?: (params: OnExitParams) => void;\n};\n\nconst zoneDefaults: ZylemZoneOptions = {\n\t...commonDefaults,\n\tsize: new Vector3(1, 1, 1),\n\tcollision: {\n\t\tstatic: true,\n\t},\n};\n\nexport const ZONE_TYPE = Symbol('Zone');\n\nexport class ZylemZone extends GameEntity<ZylemZoneOptions> implements CollisionHandlerDelegate {\n\tstatic type = ZONE_TYPE;\n\n\tprivate _enteredZone: Map<string, number> = new Map();\n\tprivate _exitedZone: Map<string, number> = new Map();\n\tprivate _zoneEntities: Map<string, any> = new Map();\n\n\tconstructor(options?: ZylemZoneOptions) {\n\t\tsuper();\n\t\tthis.options = { ...zoneDefaults, ...options };\n\t}\n\n\tpublic handlePostCollision({ delta }: { delta: number }): boolean {\n\t\tthis._enteredZone.forEach((val, key) => {\n\t\t\tthis.exited(delta, key);\n\t\t});\n\t\treturn this._enteredZone.size > 0;\n\t}\n\n\tpublic handleIntersectionEvent({ other, delta }: { other: any, delta: number }) {\n\t\tconst hasEntered = this._enteredZone.get(other.uuid);\n\t\tif (!hasEntered) {\n\t\t\tthis.entered(other);\n\t\t\tthis._zoneEntities.set(other.uuid, other);\n\t\t} else {\n\t\t\tthis.held(delta, other);\n\t\t}\n\t}\n\n\tonEnter(callback: (params: OnEnterParams) => void) {\n\t\tthis.options.onEnter = callback;\n\t\treturn this;\n\t}\n\n\tonHeld(callback: (params: OnHeldParams) => void) {\n\t\tthis.options.onHeld = callback;\n\t\treturn this;\n\t}\n\n\tonExit(callback: (params: OnExitParams) => void) {\n\t\tthis.options.onExit = callback;\n\t\treturn this;\n\t}\n\n\tentered(other: any) {\n\t\tthis._enteredZone.set(other.uuid, 1);\n\t\tif (this.options.onEnter) {\n\t\t\tthis.options.onEnter({\n\t\t\t\tself: this,\n\t\t\t\tvisitor: other,\n\t\t\t\tglobals: state.globals\n\t\t\t});\n\t\t}\n\t}\n\n\texited(delta: number, key: string) {\n\t\tconst hasExited = this._exitedZone.get(key);\n\t\tif (hasExited && hasExited > 1 + delta) {\n\t\t\tthis._exitedZone.delete(key);\n\t\t\tthis._enteredZone.delete(key);\n\t\t\tconst other = this._zoneEntities.get(key);\n\t\t\tif (this.options.onExit) {\n\t\t\t\tthis.options.onExit({\n\t\t\t\t\tself: this,\n\t\t\t\t\tvisitor: other,\n\t\t\t\t\tglobals: state.globals\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._exitedZone.set(key, 1 + delta);\n\t}\n\n\theld(delta: number, other: any) {\n\t\tconst heldTime = this._enteredZone.get(other.uuid) ?? 0;\n\t\tthis._enteredZone.set(other.uuid, heldTime + delta);\n\t\tthis._exitedZone.set(other.uuid, 1);\n\t\tif (this.options.onHeld) {\n\t\t\tthis.options.onHeld({\n\t\t\t\tdelta,\n\t\t\t\tself: this,\n\t\t\t\tvisitor: other,\n\t\t\t\tglobals: state.globals,\n\t\t\t\theldTime\n\t\t\t});\n\t\t}\n\t}\n}\n\ntype ZoneOptions = BaseNode | Partial<ZylemZoneOptions>;\n\nexport function createZone(...args: Array<ZoneOptions>): ZylemZone {\n\tconst options = mergeArgs(args, zoneDefaults);\n\tconst entity = new ZylemZone(options);\n\tentity.add(\n\t\tzoneCollision({\n\t\t\tsize: options.size,\n\t\t\tstatic: options.collision?.static ?? true,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn entity;\n}\n","import { 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 { ActiveCollisionTypes, ColliderDesc } from '@dimforge/rapier3d-compat';\nimport { BufferGeometry, Object3D, SkinnedMesh, Mesh, MeshStandardMaterial, Group, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { createEntity } from './create';\nimport { UpdateContext, UpdateFunction } from '../core/base-node-life-cycle';\nimport { EntityAssetLoader } from '../core/entity-asset-loader';\nimport { EntityLoaderDelegate } from './delegates/loader';\nimport { Vec3 } from '../core/vector';\nimport { AnimationDelegate, AnimationOptions } from './delegates/animation';\nimport { MaterialOptions } from '../graphics/material';\nimport { DebugInfoProvider } from './delegates/debug';\nimport { EntityBuilder } from './builder';\nimport { EntityCollisionBuilder } from './builder';\nimport { commonDefaults } from './common';\nimport { standardShader } from '../graphics/shaders/standard.shader';\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport type CollisionShapeType = 'capsule' | 'model';\n\ntype ZylemActorOptions = GameEntityOptions & {\n\tstatic?: boolean;\n\tanimations?: AnimationObject[];\n\tmodels?: string[];\n\tscale?: Vec3;\n\tmaterial?: MaterialOptions;\n\tcollisionShape?: CollisionShapeType;\n};\n\nconst actorDefaults: ZylemActorOptions = {\n\t...commonDefaults,\n\tcollision: {\n\t\tstatic: false,\n\t\tsize: new Vector3(0.5, 0.5, 0.5),\n\t\tposition: new Vector3(0, 0, 0),\n\t},\n\tmaterial: {\n\t\tshader: standardShader\n\t},\n\tanimations: [],\n\tmodels: [],\n\tcollisionShape: 'capsule',\n};\n\nclass ActorCollisionBuilder extends EntityCollisionBuilder {\n\tprivate objectModel: Group | null = null;\n\tprivate collisionShape: CollisionShapeType = 'capsule';\n\n\tconstructor(data: any) {\n\t\tsuper();\n\t\tthis.objectModel = data.objectModel;\n\t\tthis.collisionShape = data.collisionShape ?? 'capsule';\n\t}\n\n\tcollider(options: ZylemActorOptions): ColliderDesc {\n\t\tif (this.collisionShape === 'model') {\n\t\t\treturn this.createColliderFromModel(this.objectModel, options);\n\t\t}\n\t\treturn this.createCapsuleCollider(options);\n\t}\n\n\t/**\n\t * Create a capsule collider based on size options (character controller style).\n\t */\n\tprivate createCapsuleCollider(options: ZylemActorOptions): ColliderDesc {\n\t\tconst size = options.collision?.size ?? options.size ?? { x: 0.5, y: 1, z: 0.5 };\n\t\tconst halfHeight = ((size as any).y || 1);\n\t\tconst radius = Math.max((size as any).x || 0.5, (size as any).z || 0.5);\n\t\tlet colliderDesc = ColliderDesc.capsule(halfHeight, radius);\n\t\tcolliderDesc.setSensor(false);\n\t\tcolliderDesc.setTranslation(0, halfHeight + radius, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n\n\t/**\n\t * Create a collider based on model geometry (works with Mesh and SkinnedMesh).\n\t * If collision.size and collision.position are provided, use those instead of computing from geometry.\n\t */\n\tprivate createColliderFromModel(objectModel: Group | null, options: ZylemActorOptions): ColliderDesc {\n\t\tconst collisionSize = options.collision?.size;\n\t\tconst collisionPosition = options.collision?.position;\n\n\t\t// If user provided explicit size, use that instead of computing from model\n\t\tif (collisionSize) {\n\t\t\tconst halfWidth = (collisionSize as any).x / 2;\n\t\t\tconst halfHeight = (collisionSize as any).y / 2;\n\t\t\tconst halfDepth = (collisionSize as any).z / 2;\n\n\t\t\tlet colliderDesc = ColliderDesc.cuboid(halfWidth, halfHeight, halfDepth);\n\t\t\tcolliderDesc.setSensor(false);\n\n\t\t\t// Use user-provided position or default to center\n\t\t\tconst posX = collisionPosition ? (collisionPosition as any).x : 0;\n\t\t\tconst posY = collisionPosition ? (collisionPosition as any).y : halfHeight;\n\t\t\tconst posZ = collisionPosition ? (collisionPosition as any).z : 0;\n\t\t\tcolliderDesc.setTranslation(posX, posY, posZ);\n\t\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\t\treturn colliderDesc;\n\t\t}\n\n\t\t// Fall back to computing from model geometry\n\t\tif (!objectModel) return this.createCapsuleCollider(options);\n\n\t\t// Find first Mesh (SkinnedMesh or regular Mesh)\n\t\tlet foundGeometry: BufferGeometry | null = null;\n\t\tobjectModel.traverse((child) => {\n\t\t\tif (!foundGeometry && (child as any).isMesh) {\n\t\t\t\tfoundGeometry = (child as Mesh).geometry as BufferGeometry;\n\t\t\t}\n\t\t});\n\n\t\tif (!foundGeometry) return this.createCapsuleCollider(options);\n\n\t\tconst geometry: BufferGeometry = foundGeometry;\n\t\tgeometry.computeBoundingBox();\n\t\tconst box = geometry.boundingBox;\n\t\tif (!box) return this.createCapsuleCollider(options);\n\n\t\tconst height = box.max.y - box.min.y;\n\t\tconst width = box.max.x - box.min.x;\n\t\tconst depth = box.max.z - box.min.z;\n\n\t\t// Create box collider based on mesh bounds\n\t\tlet colliderDesc = ColliderDesc.cuboid(width / 2, height / 2, depth / 2);\n\t\tcolliderDesc.setSensor(false);\n\t\t// Position collider at center of model\n\t\tconst centerY = (box.max.y + box.min.y) / 2;\n\t\tcolliderDesc.setTranslation(0, centerY, 0);\n\t\tcolliderDesc.activeCollisionTypes = ActiveCollisionTypes.DEFAULT;\n\t\treturn colliderDesc;\n\t}\n}\n\nclass ActorBuilder extends EntityBuilder<ZylemActor, ZylemActorOptions> {\n\tprotected createEntity(options: Partial<ZylemActorOptions>): ZylemActor {\n\t\treturn new ZylemActor(options);\n\t}\n}\n\nexport const ACTOR_TYPE = Symbol('Actor');\n\nexport class ZylemActor extends GameEntity<ZylemActorOptions> implements EntityLoaderDelegate, DebugInfoProvider {\n\tstatic type = ACTOR_TYPE;\n\n\tprivate _object: Object3D | null = null;\n\tprivate _animationDelegate: AnimationDelegate | null = null;\n\tprivate _modelFileNames: string[] = [];\n\tprivate _assetLoader: EntityAssetLoader = new EntityAssetLoader();\n\n\tcontrolledRotation: boolean = false;\n\n\tconstructor(options?: ZylemActorOptions) {\n\t\tsuper();\n\t\tthis.options = { ...actorDefaults, ...options };\n\t\t// Add actor-specific update to the lifecycle callbacks\n\t\tthis.prependUpdate(this.actorUpdate.bind(this) as UpdateFunction<this>);\n\t\tthis.controlledRotation = true;\n\t}\n\n\t/**\n\t * Initiates model and animation loading in background (deferred).\n\t * Call returns immediately; assets will be ready on subsequent updates.\n\t */\n\tload(): void {\n\t\tthis._modelFileNames = this.options.models || [];\n\t\t// Start async loading in background\n\t\tthis.loadModelsDeferred();\n\t}\n\n\t/**\n\t * Returns current data synchronously.\n\t * May return null values if loading is still in progress.\n\t */\n\tdata(): any {\n\t\treturn {\n\t\t\tanimations: this._animationDelegate?.animations,\n\t\t\tobjectModel: this._object,\n\t\t\tcollisionShape: this.options.collisionShape,\n\t\t};\n\t}\n\n\tactorUpdate(params: UpdateContext<ZylemActorOptions>): void {\n\t\tthis._animationDelegate?.update(params.delta);\n\t}\n\n\t/**\n\t * Clean up actor resources including animations, models, and groups\n\t */\n\tactorDestroy(): void {\n\t\t// Stop and dispose animation delegate\n\t\tif (this._animationDelegate) {\n\t\t\tthis._animationDelegate.dispose();\n\t\t\tthis._animationDelegate = null;\n\t\t}\n\n\t\t// Dispose geometries and materials from loaded object\n\t\tif (this._object) {\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tconst mesh = child as SkinnedMesh;\n\t\t\t\t\tmesh.geometry?.dispose();\n\t\t\t\t\tif (Array.isArray(mesh.material)) {\n\t\t\t\t\t\tmesh.material.forEach(m => m.dispose());\n\t\t\t\t\t} else if (mesh.material) {\n\t\t\t\t\t\tmesh.material.dispose();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis._object = null;\n\t\t}\n\n\t\t// Clear group reference\n\t\tif (this.group) {\n\t\t\tthis.group.clear();\n\t\t\tthis.group = null as any;\n\t\t}\n\n\t\t// Clear file name references\n\t\tthis._modelFileNames = [];\n\t}\n\n\t/**\n\t * Deferred loading - starts async load and updates entity when complete.\n\t * Called by synchronous load() method.\n\t */\n\tprivate loadModelsDeferred(): void {\n\t\tif (this._modelFileNames.length === 0) return;\n\n\t\t// Emit loading started event\n\t\tthis.dispatch('entity:model:loading', {\n\t\t\tentityId: this.uuid,\n\t\t\tfiles: this._modelFileNames\n\t\t});\n\n\t\tconst promises = this._modelFileNames.map(file => this._assetLoader.loadFile(file));\n\t\tPromise.all(promises).then(results => {\n\t\t\tif (results[0]?.object) {\n\t\t\t\tthis._object = results[0].object;\n\t\t\t}\n\t\t\t// Count meshes for the loaded event\n\t\t\tlet meshCount = 0;\n\t\t\tif (this._object) {\n\t\t\t\tthis._object.traverse((child) => {\n\t\t\t\t\tif ((child as any).isMesh) meshCount++;\n\t\t\t\t});\n\t\t\t\tthis.group = new Group();\n\t\t\t\tthis.group.attach(this._object);\n\t\t\t\tthis.group.scale.set(\n\t\t\t\t\tthis.options.scale?.x || 1,\n\t\t\t\t\tthis.options.scale?.y || 1,\n\t\t\t\t\tthis.options.scale?.z || 1\n\t\t\t\t);\n\n\t\t\t\t// Apply material overrides if specified\n\t\t\t\tthis.applyMaterialOverrides();\n\n\t\t\t\t// Load animations after model is ready\n\t\t\t\tthis._animationDelegate = new AnimationDelegate(this._object);\n\t\t\t\tthis._animationDelegate.loadAnimations(this.options.animations || []).then(() => {\n\t\t\t\t\tthis.dispatch('entity:animation:loaded', {\n\t\t\t\t\t\tentityId: this.uuid,\n\t\t\t\t\t\tanimationCount: this.options.animations?.length || 0\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Emit model loaded event\n\t\t\tthis.dispatch('entity:model:loaded', {\n\t\t\t\tentityId: this.uuid,\n\t\t\t\tsuccess: !!this._object,\n\t\t\t\tmeshCount\n\t\t\t});\n\t\t});\n\t}\n\n\tplayAnimation(animationOptions: AnimationOptions) {\n\t\tthis._animationDelegate?.playAnimation(animationOptions);\n\t}\n\n\t/**\n\t * Apply material overrides from options to all meshes in the loaded model.\n\t * Only applies if material options are explicitly specified (not just defaults).\n\t */\n\tprivate applyMaterialOverrides(): void {\n\t\tconst materialOptions = this.options.material;\n\t\t// Only apply if user specified material options beyond defaults\n\t\tif (!materialOptions || (!materialOptions.color && !materialOptions.path)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._object) return;\n\n\t\tthis._object.traverse((child) => {\n\t\t\tif ((child as any).isMesh) {\n\t\t\t\tconst mesh = child as Mesh;\n\t\t\t\tif (materialOptions.color) {\n\t\t\t\t\t// Create new material with the specified color\n\t\t\t\t\tconst newMaterial = new MeshStandardMaterial({\n\t\t\t\t\t\tcolor: materialOptions.color,\n\t\t\t\t\t\temissiveIntensity: 0.5,\n\t\t\t\t\t\tlightMapIntensity: 0.5,\n\t\t\t\t\t\tfog: true,\n\t\t\t\t\t});\n\t\t\t\t\tmesh.castShadow = true;\n\t\t\t\t\tmesh.receiveShadow = true;\n\t\t\t\t\tmesh.material = newMaterial;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tget object(): Object3D | null {\n\t\treturn this._object;\n\t}\n\n\t/**\n\t * Provide custom debug information for the actor\n\t * This will be merged with the default debug information\n\t */\n\tgetDebugInfo(): Record<string, any> {\n\t\tconst debugInfo: Record<string, any> = {\n\t\t\ttype: 'Actor',\n\t\t\tmodels: this._modelFileNames.length > 0 ? this._modelFileNames : 'none',\n\t\t\tmodelLoaded: !!this._object,\n\t\t\tscale: this.options.scale ?\n\t\t\t\t`${this.options.scale.x}, ${this.options.scale.y}, ${this.options.scale.z}` :\n\t\t\t\t'1, 1, 1',\n\t\t};\n\n\t\t// Add animation info if available\n\t\tif (this._animationDelegate) {\n\t\t\tdebugInfo.currentAnimation = this._animationDelegate.currentAnimationKey || 'none';\n\t\t\tdebugInfo.animationsCount = this.options.animations?.length || 0;\n\t\t}\n\n\t\t// Add mesh info if model is loaded\n\t\tif (this._object) {\n\t\t\tlet meshCount = 0;\n\t\t\tlet vertexCount = 0;\n\t\t\tthis._object.traverse((child) => {\n\t\t\t\tif ((child as any).isMesh) {\n\t\t\t\t\tmeshCount++;\n\t\t\t\t\tconst geometry = (child as SkinnedMesh).geometry;\n\t\t\t\t\tif (geometry && geometry.attributes.position) {\n\t\t\t\t\t\tvertexCount += geometry.attributes.position.count;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tdebugInfo.meshCount = meshCount;\n\t\t\tdebugInfo.vertexCount = vertexCount;\n\t\t}\n\n\t\treturn debugInfo;\n\t}\n}\n\ntype ActorOptions = BaseNode | ZylemActorOptions;\n\nexport function createActor(...args: Array<ActorOptions>): ZylemActor {\n\treturn createEntity<ZylemActor, ZylemActorOptions>({\n\t\targs,\n\t\tdefaultConfig: actorDefaults,\n\t\tEntityClass: ZylemActor,\n\t\tBuilderClass: ActorBuilder,\n\t\tCollisionBuilderClass: ActorCollisionBuilder,\n\t\tentityType: ZylemActor.type\n\t});\n}","/**\n * Entity Asset Loader - Refactored to use AssetManager\n * \n * This module provides a compatibility layer for existing code that uses EntityAssetLoader.\n * All loading now goes through the centralized AssetManager for caching.\n */\n\nimport { AnimationClip, Object3D } from 'three';\nimport { GLTF } from 'three/addons/loaders/GLTFLoader.js';\nimport { assetManager } from './asset-manager';\n\nexport interface AssetLoaderResult {\n\tobject?: Object3D;\n\tanimation?: AnimationClip;\n\tgltf?: GLTF;\n}\n\n/**\n * EntityAssetLoader - Uses AssetManager for all model loading\n * \n * This class is now a thin wrapper around AssetManager, providing backward\n * compatibility for existing code while benefiting from centralized caching.\n */\nexport class EntityAssetLoader {\n\t/**\n\t * Load a model file (FBX, GLTF, GLB, OBJ) using the asset manager\n\t */\n\tasync loadFile(file: string): Promise<AssetLoaderResult> {\n\t\tconst ext = file.split('.').pop()?.toLowerCase();\n\n\t\tswitch (ext) {\n\t\t\tcase 'fbx': {\n\t\t\t\tconst result = await assetManager.loadFBX(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tanimation: result.animations?.[0]\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'gltf':\n\t\t\tcase 'glb': {\n\t\t\t\tconst result = await assetManager.loadGLTF(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object,\n\t\t\t\t\tgltf: result.gltf\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase 'obj': {\n\t\t\t\tconst result = await assetManager.loadOBJ(file);\n\t\t\t\treturn {\n\t\t\t\t\tobject: result.object\n\t\t\t\t};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unsupported file type: ${file}`);\n\t\t}\n\t}\n}\n","import {\n\tAnimationAction,\n\tAnimationClip,\n\tAnimationMixer,\n\tLoopOnce,\n\tLoopRepeat,\n\tObject3D,\n} from 'three';\nimport { EntityAssetLoader, AssetLoaderResult } from '../../core/entity-asset-loader';\n\nexport type AnimationOptions = {\n\tkey: string;\n\tpauseAtEnd?: boolean;\n\tpauseAtPercentage?: number;\n\tfadeToKey?: string;\n\tfadeDuration?: number;\n};\n\ntype AnimationObject = {\n\tkey?: string;\n\tpath: string;\n};\n\nexport class AnimationDelegate {\n\tprivate _mixer: AnimationMixer | null = null;\n\tprivate _actions: Record<string, AnimationAction> = {};\n\tprivate _animations: AnimationClip[] = [];\n\tprivate _currentAction: AnimationAction | null = null;\n\n\tprivate _pauseAtPercentage = 0;\n\tprivate _isPaused = false;\n\tprivate _queuedKey: string | null = null;\n\tprivate _fadeDuration = 0.5;\n\n\tprivate _currentKey: string = '';\n\tprivate _assetLoader = new EntityAssetLoader();\n\n\tconstructor(private target: Object3D) { }\n\n\tasync loadAnimations(animations: AnimationObject[]): Promise<void> {\n\t\tif (!animations.length) return;\n\n\t\tconst results = await Promise.all(animations.map(a => this._assetLoader.loadFile(a.path)));\n\t\t\n\t\t// Build animations list while preserving original key mapping\n\t\t// Filter to only successful loads and pair with their original keys\n\t\tconst loadedAnimations: { key: string; clip: AnimationClip }[] = [];\n\t\tresults.forEach((result, i) => {\n\t\t\tif (result.animation) {\n\t\t\t\tloadedAnimations.push({\n\t\t\t\t\tkey: animations[i].key || i.toString(),\n\t\t\t\t\tclip: result.animation\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tif (!loadedAnimations.length) return;\n\n\t\tthis._animations = loadedAnimations.map(a => a.clip);\n\t\tthis._mixer = new AnimationMixer(this.target);\n\t\t\n\t\t// Create actions with correct key mapping\n\t\tloadedAnimations.forEach(({ key, clip }) => {\n\t\t\tthis._actions[key] = this._mixer!.clipAction(clip);\n\t\t});\n\n\t\tthis.playAnimation({ key: loadedAnimations[0].key });\n\t}\n\n\tupdate(delta: number): void {\n\t\tif (!this._mixer || !this._currentAction) return;\n\n\t\tthis._mixer.update(delta);\n\n\t\tconst pauseAtTime = this._currentAction.getClip().duration * (this._pauseAtPercentage / 100);\n\t\tif (\n\t\t\t!this._isPaused &&\n\t\t\tthis._pauseAtPercentage > 0 &&\n\t\t\tthis._currentAction.time >= pauseAtTime\n\t\t) {\n\t\t\tthis._currentAction.time = pauseAtTime;\n\t\t\tthis._currentAction.paused = true;\n\t\t\tthis._isPaused = true;\n\n\t\t\tif (this._queuedKey !== null) {\n\t\t\t\tconst next = this._actions[this._queuedKey];\n\t\t\t\tnext.reset().play();\n\t\t\t\tthis._currentAction.crossFadeTo(next, this._fadeDuration, false);\n\t\t\t\tthis._currentAction = next;\n\t\t\t\tthis._currentKey = this._queuedKey;\n\t\t\t\tthis._queuedKey = null;\n\t\t\t}\n\t\t}\n\t}\n\n\tplayAnimation(opts: AnimationOptions): void {\n\t\tif (!this._mixer) return;\n\t\tconst { key, pauseAtPercentage = 0, pauseAtEnd = false, fadeToKey, fadeDuration = 0.5 } = opts;\n\t\tif (key === this._currentKey) return;\n\n\t\t// Check if the new action exists BEFORE stopping the current animation\n\t\t// This prevents T-posing when an animation key doesn't exist\n\t\tconst action = this._actions[key];\n\t\tif (!action) return;\n\n\t\tthis._queuedKey = fadeToKey || null;\n\t\tthis._fadeDuration = fadeDuration;\n\n\t\tthis._pauseAtPercentage = pauseAtEnd ? 100 : pauseAtPercentage;\n\t\tthis._isPaused = false;\n\n\t\tconst prev = this._currentAction;\n\t\t// Don't stop prev here - crossFadeTo needs it playing for smooth transition\n\n\t\tif (this._pauseAtPercentage > 0) {\n\t\t\taction.setLoop(LoopOnce, Infinity);\n\t\t\taction.clampWhenFinished = true;\n\t\t} else {\n\t\t\taction.setLoop(LoopRepeat, Infinity);\n\t\t\taction.clampWhenFinished = false;\n\t\t}\n\n\t\t// Start the new action\n\t\taction.reset().play();\n\n\t\t// Crossfade from previous if it exists\n\t\tif (prev) {\n\t\t\tprev.crossFadeTo(action, fadeDuration, false);\n\t\t}\n\n\t\tthis._currentAction = action;\n\t\tthis._currentKey = key;\n\t}\n\n\t/**\n\t * Dispose of all animation resources\n\t */\n\tdispose(): void {\n\t\t// Stop all actions\n\t\tObject.values(this._actions).forEach(action => {\n\t\t\taction.stop();\n\t\t});\n\n\t\t// Stop and uncache mixer\n\t\tif (this._mixer) {\n\t\t\tthis._mixer.stopAllAction();\n\t\t\tthis._mixer.uncacheRoot(this.target);\n\t\t\tthis._mixer = null;\n\t\t}\n\n\t\t// Clear references\n\t\tthis._actions = {};\n\t\tthis._animations = [];\n\t\tthis._currentAction = null;\n\t\tthis._currentKey = '';\n\t}\n\n\tget currentAnimationKey() { return this._currentKey; }\n\tget animations() { return this._animations; }\n}\n","import { Color, Group, Sprite as ThreeSprite, SpriteMaterial, CanvasTexture, LinearFilter, Vector2, PerspectiveCamera, OrthographicCamera, ClampToEdgeWrapping } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { createEntity } from './create';\nimport { UpdateContext, SetupContext } from '../core/base-node-life-cycle';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { DebugDelegate } from './delegates/debug';\n\ntype ZylemTextOptions = GameEntityOptions & {\n\ttext?: string;\n\tfontFamily?: string;\n\tfontSize?: number;\n\tfontColor?: Color | string;\n\tbackgroundColor?: Color | string | null;\n\tpadding?: number;\n\tstickToViewport?: boolean;\n\tscreenPosition?: Vector2;\n\tzDistance?: number;\n};\n\nconst textDefaults: ZylemTextOptions = {\n\tposition: undefined,\n\ttext: '',\n\tfontFamily: 'Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace',\n\tfontSize: 18,\n\tfontColor: '#FFFFFF',\n\tbackgroundColor: null,\n\tpadding: 4,\n\tstickToViewport: true,\n\tscreenPosition: new Vector2(24, 24),\n\tzDistance: 1,\n};\n\nexport class TextBuilder extends EntityBuilder<ZylemText, ZylemTextOptions> {\n\tprotected createEntity(options: Partial<ZylemTextOptions>): ZylemText {\n\t\treturn new ZylemText(options);\n\t}\n}\n\nexport const TEXT_TYPE = Symbol('Text');\n\nexport class ZylemText extends GameEntity<ZylemTextOptions> {\n\tstatic type = TEXT_TYPE;\n\n\tprivate _sprite: ThreeSprite | null = null;\n\tprivate _texture: CanvasTexture | null = null;\n\tprivate _canvas: HTMLCanvasElement | null = null;\n\tprivate _ctx: CanvasRenderingContext2D | null = null;\n\tprivate _cameraRef: ZylemCamera | null = null;\n\tprivate _lastCanvasW: number = 0;\n\tprivate _lastCanvasH: number = 0;\n\n\tconstructor(options?: ZylemTextOptions) {\n\t\tsuper();\n\t\tthis.options = { ...textDefaults, ...options } as ZylemTextOptions;\n\t\t// Add text-specific lifecycle callbacks (only registered once)\n\t\tthis.prependSetup(this.textSetup.bind(this) as any);\n\t\tthis.prependUpdate(this.textUpdate.bind(this) as any);\n\t\tthis.onCleanup(this.textDestroy.bind(this) as any);\n\t}\n\n\tpublic create(): this {\n\t\t// Clear previous state to prevent issues on reload\n\t\tthis._sprite = null;\n\t\tthis._texture = null;\n\t\tthis._canvas = null;\n\t\tthis._ctx = null;\n\t\tthis._lastCanvasW = 0;\n\t\tthis._lastCanvasH = 0;\n\t\tthis.group = new Group();\n\t\t\n\t\t// Recreate the sprite\n\t\tthis.createSprite();\n\t\t\n\t\t// Call parent create\n\t\treturn super.create();\n\t}\n\n\tprivate createSprite() {\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._ctx = this._canvas.getContext('2d');\n\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\tthis._texture.minFilter = LinearFilter;\n\t\tthis._texture.magFilter = LinearFilter;\n\t\tconst material = new SpriteMaterial({\n\t\t\tmap: this._texture,\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\talphaTest: 0.5,\n\t\t});\n\t\tthis._sprite = new ThreeSprite(material);\n\t\tthis.group?.add(this._sprite);\n\t\tthis.redrawText(this.options.text ?? '');\n\t}\n\n\tprivate measureAndResizeCanvas(text: string, fontSize: number, fontFamily: string, padding: number) {\n\t\tif (!this._canvas || !this._ctx) return { sizeChanged: false };\n\t\tthis._ctx.font = `${fontSize}px ${fontFamily}`;\n\t\tconst metrics = this._ctx.measureText(text);\n\t\tconst textWidth = Math.ceil(metrics.width);\n\t\tconst textHeight = Math.ceil(fontSize * 1.4);\n\t\tconst nextW = Math.max(2, textWidth + padding * 2);\n\t\tconst nextH = Math.max(2, textHeight + padding * 2);\n\t\tconst sizeChanged = nextW !== this._lastCanvasW || nextH !== this._lastCanvasH;\n\t\tthis._canvas.width = nextW;\n\t\tthis._canvas.height = nextH;\n\t\tthis._lastCanvasW = nextW;\n\t\tthis._lastCanvasH = nextH;\n\t\treturn { sizeChanged };\n\t}\n\n\tprivate drawCenteredText(text: string, fontSize: number, fontFamily: string) {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tthis._ctx.font = `${fontSize}px ${fontFamily}`;\n\t\tthis._ctx.textAlign = 'center';\n\t\tthis._ctx.textBaseline = 'middle';\n\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\t\tif (this.options.backgroundColor) {\n\t\t\tthis._ctx.fillStyle = this.toCssColor(this.options.backgroundColor);\n\t\t\tthis._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height);\n\t\t}\n\t\tthis._ctx.fillStyle = this.toCssColor(this.options.fontColor ?? '#FFFFFF');\n\t\tthis._ctx.fillText(text, this._canvas.width / 2, this._canvas.height / 2);\n\t}\n\n\tprivate updateTexture(sizeChanged: boolean) {\n\t\tif (!this._texture || !this._canvas) return;\n\t\tif (sizeChanged) {\n\t\t\tthis._texture.dispose();\n\t\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\t\tthis._texture.minFilter = LinearFilter;\n\t\t\tthis._texture.magFilter = LinearFilter;\n\t\t\tthis._texture.wrapS = ClampToEdgeWrapping;\n\t\t\tthis._texture.wrapT = ClampToEdgeWrapping;\n\t\t}\n\t\tthis._texture.image = this._canvas;\n\t\tthis._texture.needsUpdate = true;\n\t\tif (this._sprite && this._sprite.material) {\n\t\t\t(this._sprite.material as any).map = this._texture;\n\t\t\tthis._sprite.material.needsUpdate = true;\n\t\t}\n\t}\n\n\tprivate redrawText(_text: string) {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tconst fontSize = this.options.fontSize ?? 18;\n\t\tconst fontFamily = this.options.fontFamily ?? (textDefaults.fontFamily as string);\n\t\tconst padding = this.options.padding ?? 4;\n\n\t\tconst { sizeChanged } = this.measureAndResizeCanvas(_text, fontSize, fontFamily, padding);\n\t\tthis.drawCenteredText(_text, fontSize, fontFamily);\n\t\tthis.updateTexture(Boolean(sizeChanged));\n\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate toCssColor(color: Color | string): string {\n\t\tif (typeof color === 'string') return color;\n\t\tconst c = color instanceof Color ? color : new Color(color as any);\n\t\treturn `#${c.getHexString()}`;\n\t}\n\n\tprivate textSetup(params: SetupContext<ZylemTextOptions>) {\n\t\tthis._cameraRef = (params.camera as unknown) as ZylemCamera | null;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\t(this._cameraRef.camera as any).add(this.group);\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate textUpdate(params: UpdateContext<ZylemTextOptions>) {\n\t\tif (!this._sprite) return;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate getResolution() {\n\t\treturn {\n\t\t\twidth: this._cameraRef?.screenResolution.x ?? 1,\n\t\t\theight: this._cameraRef?.screenResolution.y ?? 1,\n\t\t};\n\t}\n\n\tprivate getScreenPixels(sp: Vector2, width: number, height: number) {\n\t\tconst isPercentX = sp.x >= 0 && sp.x <= 1;\n\t\tconst isPercentY = sp.y >= 0 && sp.y <= 1;\n\t\treturn {\n\t\t\tpx: isPercentX ? sp.x * width : sp.x,\n\t\t\tpy: isPercentY ? sp.y * height : sp.y,\n\t\t};\n\t}\n\n\tprivate computeWorldExtents(camera: PerspectiveCamera | OrthographicCamera, zDist: number) {\n\t\tlet worldHalfW = 1;\n\t\tlet worldHalfH = 1;\n\t\tif ((camera as PerspectiveCamera).isPerspectiveCamera) {\n\t\t\tconst pc = camera as PerspectiveCamera;\n\t\t\tconst halfH = Math.tan((pc.fov * Math.PI) / 180 / 2) * zDist;\n\t\t\tconst halfW = halfH * pc.aspect;\n\t\t\tworldHalfW = halfW;\n\t\t\tworldHalfH = halfH;\n\t\t} else if ((camera as OrthographicCamera).isOrthographicCamera) {\n\t\t\tconst oc = camera as OrthographicCamera;\n\t\t\tworldHalfW = (oc.right - oc.left) / 2;\n\t\t\tworldHalfH = (oc.top - oc.bottom) / 2;\n\t\t}\n\t\treturn { worldHalfW, worldHalfH };\n\t}\n\n\tprivate updateSpriteScale(worldHalfH: number, viewportHeight: number) {\n\t\tif (!this._canvas || !this._sprite) return;\n\t\tconst planeH = worldHalfH * 2;\n\t\tconst unitsPerPixel = planeH / viewportHeight;\n\t\tconst pixelH = this._canvas.height;\n\t\tconst scaleY = Math.max(0.0001, pixelH * unitsPerPixel);\n\t\tconst aspect = this._canvas.width / this._canvas.height;\n\t\tconst scaleX = scaleY * aspect;\n\t\tthis._sprite.scale.set(scaleX, scaleY, 1);\n\t}\n\n\tprivate updateStickyTransform() {\n\t\tif (!this._sprite || !this._cameraRef) return;\n\t\tconst camera = this._cameraRef.camera as PerspectiveCamera | OrthographicCamera;\n\t\tconst { width, height } = this.getResolution();\n\t\tconst sp = this.options.screenPosition ?? new Vector2(24, 24);\n\t\tconst { px, py } = this.getScreenPixels(sp, width, height);\n\t\tconst zDist = Math.max(0.001, this.options.zDistance ?? 1);\n\t\tconst { worldHalfW, worldHalfH } = this.computeWorldExtents(camera, zDist);\n\n\t\tconst ndcX = (px / width) * 2 - 1;\n\t\tconst ndcY = 1 - (py / height) * 2;\n\t\tconst localX = ndcX * worldHalfW;\n\t\tconst localY = ndcY * worldHalfH;\n\t\tthis.group?.position.set(localX, localY, -zDist);\n\t\tthis.updateSpriteScale(worldHalfH, height);\n\t}\n\n\tupdateText(_text: string) {\n\t\tthis.options.text = _text;\n\t\tthis.redrawText(_text);\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemText.type),\n\t\t\ttext: this.options.text ?? '',\n\t\t\tsticky: this.options.stickToViewport,\n\t\t};\n\t}\n\n\t/**\n\t * Dispose of Three.js resources when the entity is destroyed.\n\t */\n\tprivate textDestroy(): void {\n\t\t// Dispose texture\n\t\tthis._texture?.dispose();\n\t\t\n\t\t// Dispose sprite material\n\t\tif (this._sprite?.material) {\n\t\t\t(this._sprite.material as SpriteMaterial).dispose();\n\t\t}\n\t\t\n\t\t// Remove sprite from group\n\t\tif (this._sprite) {\n\t\t\tthis._sprite.removeFromParent();\n\t\t}\n\t\t\n\t\t// Remove group from parent (camera or scene)\n\t\tthis.group?.removeFromParent();\n\t\t\n\t\t// Clear references\n\t\tthis._sprite = null;\n\t\tthis._texture = null;\n\t\tthis._canvas = null;\n\t\tthis._ctx = null;\n\t\tthis._cameraRef = null;\n\t}\n}\n\ntype TextOptions = BaseNode | Partial<ZylemTextOptions>;\n\nexport function createText(...args: Array<TextOptions>): ZylemText {\n\treturn createEntity<ZylemText, ZylemTextOptions>({\n\t\targs,\n\t\tdefaultConfig: { ...textDefaults },\n\t\tEntityClass: ZylemText,\n\t\tBuilderClass: TextBuilder,\n\t\tentityType: ZylemText.type,\n\t});\n}\n\n\n","import { Color, Group, Sprite as ThreeSprite, SpriteMaterial, CanvasTexture, LinearFilter, Vector2, PerspectiveCamera, OrthographicCamera, ClampToEdgeWrapping, ShaderMaterial, Mesh, PlaneGeometry, Vector3 } from 'three';\nimport { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { EntityBuilder } from './builder';\nimport { createEntity } from './create';\nimport { UpdateContext, SetupContext } from '../core/base-node-life-cycle';\nimport { ZylemCamera } from '../camera/zylem-camera';\nimport { DebugDelegate } from './delegates/debug';\n\ntype ZylemRectOptions = GameEntityOptions & {\n\twidth?: number;\n\theight?: number;\n\tfillColor?: Color | string | null;\n\tstrokeColor?: Color | string | null;\n\tstrokeWidth?: number;\n\tradius?: number;\n\tpadding?: number;\n\tstickToViewport?: boolean;\n\tscreenPosition?: Vector2;\n\tzDistance?: number;\n\tanchor?: Vector2; // 0-100 per axis, default top-left (0,0)\n\tbounds?: {\n\t\tscreen?: { x: number; y: number; width: number; height: number };\n\t\tworld?: { left: number; right: number; top: number; bottom: number; z?: number };\n\t};\n};\n\nconst rectDefaults: ZylemRectOptions = {\n\tposition: undefined,\n\twidth: 120,\n\theight: 48,\n\tfillColor: '#FFFFFF',\n\tstrokeColor: null,\n\tstrokeWidth: 0,\n\tradius: 0,\n\tpadding: 0,\n\tstickToViewport: true,\n\tscreenPosition: new Vector2(24, 24),\n\tzDistance: 1,\n\tanchor: new Vector2(0, 0),\n};\n\nexport class RectBuilder extends EntityBuilder<ZylemRect, ZylemRectOptions> {\n\tprotected createEntity(options: Partial<ZylemRectOptions>): ZylemRect {\n\t\treturn new ZylemRect(options);\n\t}\n}\n\nexport const RECT_TYPE = Symbol('Rect');\n\nexport class ZylemRect extends GameEntity<ZylemRectOptions> {\n\tstatic type = RECT_TYPE;\n\n\tprivate _sprite: ThreeSprite | null = null;\n\tprivate _mesh: Mesh | null = null;\n\tprivate _texture: CanvasTexture | null = null;\n\tprivate _canvas: HTMLCanvasElement | null = null;\n\tprivate _ctx: CanvasRenderingContext2D | null = null;\n\tprivate _cameraRef: ZylemCamera | null = null;\n\tprivate _lastCanvasW: number = 0;\n\tprivate _lastCanvasH: number = 0;\n\n\tconstructor(options?: ZylemRectOptions) {\n\t\tsuper();\n\t\tthis.options = { ...rectDefaults, ...options } as ZylemRectOptions;\n\t\tthis.group = new Group();\n\t\tthis.createSprite();\n\t\t// Add rect-specific lifecycle callbacks\n\t\tthis.prependSetup(this.rectSetup.bind(this) as any);\n\t\tthis.prependUpdate(this.rectUpdate.bind(this) as any);\n\t}\n\n\tprivate createSprite() {\n\t\tthis._canvas = document.createElement('canvas');\n\t\tthis._ctx = this._canvas.getContext('2d');\n\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\tthis._texture.minFilter = LinearFilter;\n\t\tthis._texture.magFilter = LinearFilter;\n\t\tconst material = new SpriteMaterial({\n\t\t\tmap: this._texture,\n\t\t\ttransparent: true,\n\t\t\tdepthTest: false,\n\t\t\tdepthWrite: false,\n\t\t\talphaTest: 0.5,\n\t\t});\n\t\tthis._sprite = new ThreeSprite(material);\n\t\tthis.group?.add(this._sprite);\n\t\tthis.redrawRect();\n\t}\n\n\tprivate redrawRect() {\n\t\tif (!this._canvas || !this._ctx) return;\n\t\tconst width = Math.max(2, Math.floor((this.options.width ?? 120)));\n\t\tconst height = Math.max(2, Math.floor((this.options.height ?? 48)));\n\t\tconst padding = this.options.padding ?? 0;\n\t\tconst strokeWidth = this.options.strokeWidth ?? 0;\n\t\tconst totalW = width + padding * 2 + strokeWidth;\n\t\tconst totalH = height + padding * 2 + strokeWidth;\n\t\tconst nextW = Math.max(2, totalW);\n\t\tconst nextH = Math.max(2, totalH);\n\t\tconst sizeChanged = nextW !== this._lastCanvasW || nextH !== this._lastCanvasH;\n\t\tthis._canvas.width = nextW;\n\t\tthis._canvas.height = nextH;\n\t\tthis._lastCanvasW = nextW;\n\t\tthis._lastCanvasH = nextH;\n\n\t\tthis._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);\n\n\t\tconst radius = Math.max(0, this.options.radius ?? 0);\n\t\tconst rectX = Math.floor(padding + strokeWidth / 2);\n\t\tconst rectY = Math.floor(padding + strokeWidth / 2);\n\t\tconst rectW = Math.floor(width);\n\t\tconst rectH = Math.floor(height);\n\n\t\tthis._ctx.beginPath();\n\t\tif (radius > 0) {\n\t\t\tthis.roundedRectPath(this._ctx, rectX, rectY, rectW, rectH, radius);\n\t\t} else {\n\t\t\tthis._ctx.rect(rectX, rectY, rectW, rectH);\n\t\t}\n\n\t\tif (this.options.fillColor) {\n\t\t\tthis._ctx.fillStyle = this.toCssColor(this.options.fillColor);\n\t\t\tthis._ctx.fill();\n\t\t}\n\n\t\tif ((this.options.strokeColor && (strokeWidth > 0))) {\n\t\t\tthis._ctx.lineWidth = strokeWidth;\n\t\t\tthis._ctx.strokeStyle = this.toCssColor(this.options.strokeColor);\n\t\t\tthis._ctx.stroke();\n\t\t}\n\n\t\tif (this._texture) {\n\t\t\tif (sizeChanged) {\n\t\t\t\tthis._texture.dispose();\n\t\t\t\tthis._texture = new CanvasTexture(this._canvas);\n\t\t\t\tthis._texture.minFilter = LinearFilter;\n\t\t\t\tthis._texture.magFilter = LinearFilter;\n\t\t\t\tthis._texture.wrapS = ClampToEdgeWrapping;\n\t\t\t\tthis._texture.wrapT = ClampToEdgeWrapping;\n\t\t\t\tif (this._sprite && this._sprite.material instanceof ShaderMaterial) {\n\t\t\t\t\tconst shader = this._sprite.material as ShaderMaterial;\n\t\t\t\t\tif (shader.uniforms?.tDiffuse) shader.uniforms.tDiffuse.value = this._texture;\n\t\t\t\t\tif (shader.uniforms?.iResolution) shader.uniforms.iResolution.value.set(this._canvas.width, this._canvas.height, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._texture.image = this._canvas;\n\t\t\tthis._texture.needsUpdate = true;\n\t\t\tif (this._sprite && this._sprite.material) {\n\t\t\t\t(this._sprite.material as any).map = this._texture;\n\t\t\t\tthis._sprite.material.needsUpdate = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tgetWidth() {\n\t\treturn this.options.width ?? 0;\n\t}\n\n\tgetHeight() {\n\t\treturn this.options.height ?? 0;\n\t}\n\n\tprivate roundedRectPath(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number) {\n\t\tconst radius = Math.min(r, Math.floor(Math.min(w, h) / 2));\n\t\tctx.moveTo(x + radius, y);\n\t\tctx.lineTo(x + w - radius, y);\n\t\tctx.quadraticCurveTo(x + w, y, x + w, y + radius);\n\t\tctx.lineTo(x + w, y + h - radius);\n\t\tctx.quadraticCurveTo(x + w, y + h, x + w - radius, y + h);\n\t\tctx.lineTo(x + radius, y + h);\n\t\tctx.quadraticCurveTo(x, y + h, x, y + h - radius);\n\t\tctx.lineTo(x, y + radius);\n\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t}\n\n\tprivate toCssColor(color: Color | string): string {\n\t\tif (typeof color === 'string') return color;\n\t\tconst c = color instanceof Color ? color : new Color(color as any);\n\t\treturn `#${c.getHexString()}`;\n\t}\n\n\t/**\n\t * Get the viewport resolution from the renderer DOM element,\n\t * falling back to the camera's screenResolution if the renderer\n\t * is not available (e.g. when using the new RendererManager path).\n\t */\n\tprivate getResolution(): { width: number; height: number } {\n\t\ttry {\n\t\t\tconst dom = this._cameraRef?.renderer?.domElement;\n\t\t\tif (dom) {\n\t\t\t\treturn { width: dom.clientWidth || 1, height: dom.clientHeight || 1 };\n\t\t\t}\n\t\t} catch { /* renderer not available */ }\n\t\treturn {\n\t\t\twidth: this._cameraRef?.screenResolution?.x ?? 1,\n\t\t\theight: this._cameraRef?.screenResolution?.y ?? 1,\n\t\t};\n\t}\n\n\tprivate rectSetup(params: SetupContext<ZylemRectOptions>) {\n\t\tthis._cameraRef = (params.camera as unknown) as ZylemCamera | null;\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\t(this._cameraRef.camera as any).add(this.group);\n\t\t}\n\n\t\tif (this.materials?.length && this._sprite) {\n\t\t\tconst mat = this.materials[0];\n\t\t\tif (mat instanceof ShaderMaterial) {\n\t\t\t\tmat.transparent = true;\n\t\t\t\tmat.depthTest = false;\n\t\t\t\tmat.depthWrite = false;\n\t\t\t\tif (this._texture) {\n\t\t\t\t\tif (mat.uniforms?.tDiffuse) mat.uniforms.tDiffuse.value = this._texture;\n\t\t\t\t\tif (mat.uniforms?.iResolution && this._canvas) mat.uniforms.iResolution.value.set(this._canvas.width, this._canvas.height, 1);\n\t\t\t\t}\n\t\t\t\tthis._mesh = new Mesh(new PlaneGeometry(1, 1), mat);\n\t\t\t\tthis.group?.add(this._mesh);\n\t\t\t\tthis._sprite.visible = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate rectUpdate(params: UpdateContext<ZylemRectOptions>) {\n\t\tif (!this._sprite) return;\n\n\t\t// If bounds provided, compute screen-space rect from it and update size/position\n\t\tif (this._cameraRef && this.options.bounds) {\n\t\t\tconst screen = this.computeScreenBoundsFromOptions(this.options.bounds);\n\t\t\tif (screen) {\n\t\t\t\tconst { x, y, width, height } = screen;\n\t\t\t\tconst desiredW = Math.max(2, Math.floor(width));\n\t\t\t\tconst desiredH = Math.max(2, Math.floor(height));\n\t\t\t\tconst changed = desiredW !== (this.options.width ?? 0) || desiredH !== (this.options.height ?? 0);\n\t\t\t\tthis.options.screenPosition = new Vector2(Math.floor(x), Math.floor(y));\n\t\t\t\tthis.options.width = desiredW;\n\t\t\t\tthis.options.height = desiredH;\n\t\t\t\tthis.options.anchor = new Vector2(0, 0);\n\t\t\t\tif (changed) {\n\t\t\t\t\tthis.redrawRect();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tprivate updateStickyTransform() {\n\t\tif (!this._sprite || !this._cameraRef) return;\n\t\tconst camera = this._cameraRef.camera;\n\t\tconst { width, height } = this.getResolution();\n\t\tconst px = (this.options.screenPosition ?? new Vector2(24, 24)).x;\n\t\tconst py = (this.options.screenPosition ?? new Vector2(24, 24)).y;\n\t\tconst zDist = Math.max(0.001, this.options.zDistance ?? 1);\n\n\t\tlet worldHalfW = 1;\n\t\tlet worldHalfH = 1;\n\t\tif ((camera as PerspectiveCamera).isPerspectiveCamera) {\n\t\t\tconst pc = camera as PerspectiveCamera;\n\t\t\tconst halfH = Math.tan((pc.fov * Math.PI) / 180 / 2) * zDist;\n\t\t\tconst halfW = halfH * pc.aspect;\n\t\t\tworldHalfW = halfW;\n\t\t\tworldHalfH = halfH;\n\t\t} else if ((camera as OrthographicCamera).isOrthographicCamera) {\n\t\t\tconst oc = camera as OrthographicCamera;\n\t\t\tworldHalfW = (oc.right - oc.left) / 2;\n\t\t\tworldHalfH = (oc.top - oc.bottom) / 2;\n\t\t}\n\n\t\tconst ndcX = (px / width) * 2 - 1;\n\t\tconst ndcY = 1 - (py / height) * 2;\n\t\tconst localX = ndcX * worldHalfW;\n\t\tconst localY = ndcY * worldHalfH;\n\n\t\tlet scaleX = 1;\n\t\tlet scaleY = 1;\n\t\tif (this._canvas) {\n\t\t\tconst planeH = worldHalfH * 2;\n\t\t\tconst unitsPerPixel = planeH / height;\n\t\t\tconst pixelH = this._canvas.height;\n\t\t\tscaleY = Math.max(0.0001, pixelH * unitsPerPixel);\n\t\t\tconst aspect = this._canvas.width / this._canvas.height;\n\t\t\tscaleX = scaleY * aspect;\n\t\t\tthis._sprite.scale.set(scaleX, scaleY, 1);\n\t\t\tif (this._mesh) this._mesh.scale.set(scaleX, scaleY, 1);\n\t\t}\n\n\t\tconst anchor = this.options.anchor ?? new Vector2(0, 0);\n\t\tconst ax = Math.min(100, Math.max(0, anchor.x)) / 100; // 0..1\n\t\tconst ay = Math.min(100, Math.max(0, anchor.y)) / 100; // 0..1\n\t\tconst offsetX = (0.5 - ax) * scaleX;\n\t\tconst offsetY = (ay - 0.5) * scaleY;\n\t\tthis.group?.position.set(localX + offsetX, localY + offsetY, -zDist);\n\t}\n\n\tprivate worldToScreen(point: Vector3) {\n\t\tif (!this._cameraRef) return { x: 0, y: 0 };\n\t\tconst camera = this._cameraRef.camera;\n\t\tconst { width, height } = this.getResolution();\n\t\tconst v = point.clone().project(camera);\n\t\tconst x = (v.x + 1) / 2 * width;\n\t\tconst y = (1 - v.y) / 2 * height;\n\t\treturn { x, y };\n\t}\n\n\tprivate computeScreenBoundsFromOptions(bounds: NonNullable<ZylemRectOptions['bounds']>): { x: number; y: number; width: number; height: number } | null {\n\t\tif (!this._cameraRef) return null;\n\t\tif (bounds.screen) {\n\t\t\treturn { ...bounds.screen };\n\t\t}\n\t\tif (bounds.world) {\n\t\t\tconst { left, right, top, bottom, z = 0 } = bounds.world;\n\t\t\tconst tl = this.worldToScreen(new Vector3(left, top, z));\n\t\t\tconst br = this.worldToScreen(new Vector3(right, bottom, z));\n\t\t\tconst x = Math.min(tl.x, br.x);\n\t\t\tconst y = Math.min(tl.y, br.y);\n\t\t\tconst width = Math.abs(br.x - tl.x);\n\t\t\tconst height = Math.abs(br.y - tl.y);\n\t\t\treturn { x, y, width, height };\n\t\t}\n\t\treturn null;\n\t}\n\n\tupdateRect(options?: Partial<Pick<ZylemRectOptions, 'width' | 'height' | 'fillColor' | 'strokeColor' | 'strokeWidth' | 'radius'>>) {\n\t\tthis.options = { ...this.options, ...options } as ZylemRectOptions;\n\t\tthis.redrawRect();\n\t\tif (this.options.stickToViewport && this._cameraRef) {\n\t\t\tthis.updateStickyTransform();\n\t\t}\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemRect.type),\n\t\t\twidth: this.options.width ?? 0,\n\t\t\theight: this.options.height ?? 0,\n\t\t\tsticky: this.options.stickToViewport,\n\t\t};\n\t}\n}\n\ntype RectOptions = BaseNode | Partial<ZylemRectOptions>;\n\nexport function createRect(...args: Array<RectOptions>): ZylemRect {\n\treturn createEntity<ZylemRect, ZylemRectOptions>({\n\t\targs,\n\t\tdefaultConfig: { ...rectDefaults },\n\t\tEntityClass: ZylemRect,\n\t\tBuilderClass: RectBuilder,\n\t\tentityType: ZylemRect.type,\n\t});\n}\n\n\n","import { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { coneMesh } from './parts/mesh-factories';\nimport { coneCollision } from './parts/collision-factories';\n\ntype ZylemConeOptions = GameEntityOptions & {\n\t/** Base radius of the cone */\n\tradius?: number;\n\t/** Height of the cone */\n\theight?: number;\n\t/** Number of radial segments (higher = smoother) */\n\tradialSegments?: number;\n};\n\nconst coneDefaults: ZylemConeOptions = {\n\t...commonDefaults,\n\tradius: 1,\n\theight: 2,\n\tradialSegments: 32,\n};\n\nexport const CONE_TYPE = Symbol('Cone');\n\n/**\n * A cone entity with configurable radius, height, and radial segments.\n * Uses a Rapier cone collider for physics.\n */\nexport class ZylemCone extends GameEntity<ZylemConeOptions> {\n\tstatic type = CONE_TYPE;\n\n\tconstructor(options?: ZylemConeOptions) {\n\t\tsuper();\n\t\tthis.options = { ...coneDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 1;\n\t\tconst height = this.options.height ?? 2;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemCone.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t\theight: height.toFixed(2),\n\t\t};\n\t}\n}\n\ntype ConeOptions = BaseNode | Partial<ZylemConeOptions>;\n\n/**\n * Create a cone entity.\n * @param args Options or child nodes\n */\nexport function createCone(...args: Array<ConeOptions>): ZylemCone {\n\tconst options = mergeArgs(args, coneDefaults);\n\tconst entity = new ZylemCone(options);\n\tentity.add(\n\t\tconeMesh({\n\t\t\tradius: options.radius,\n\t\t\theight: options.height,\n\t\t\tradialSegments: options.radialSegments,\n\t\t\tmaterial: options.material,\n\t\t\tcolor: options.color,\n\t\t}),\n\t\tconeCollision({\n\t\t\tradius: options.radius,\n\t\t\theight: options.height,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn entity;\n}\n","import { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { pyramidMesh } from './parts/mesh-factories';\nimport { pyramidCollision } from './parts/collision-factories';\n\ntype ZylemPyramidOptions = GameEntityOptions & {\n\t/** Base radius of the pyramid */\n\tradius?: number;\n\t/** Height of the pyramid */\n\theight?: number;\n};\n\nconst pyramidDefaults: ZylemPyramidOptions = {\n\t...commonDefaults,\n\tradius: 1,\n\theight: 2,\n};\n\nexport const PYRAMID_TYPE = Symbol('Pyramid');\n\n/**\n * A pyramid entity (4-sided cone).\n * Uses ConeGeometry with 4 radial segments for the visual mesh\n * and a Rapier cone collider for physics.\n */\nexport class ZylemPyramid extends GameEntity<ZylemPyramidOptions> {\n\tstatic type = PYRAMID_TYPE;\n\n\tconstructor(options?: ZylemPyramidOptions) {\n\t\tsuper();\n\t\tthis.options = { ...pyramidDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 1;\n\t\tconst height = this.options.height ?? 2;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemPyramid.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t\theight: height.toFixed(2),\n\t\t};\n\t}\n}\n\ntype PyramidOptions = BaseNode | Partial<ZylemPyramidOptions>;\n\n/**\n * Create a pyramid entity.\n * @param args Options or child nodes\n */\nexport function createPyramid(...args: Array<PyramidOptions>): ZylemPyramid {\n\tconst options = mergeArgs(args, pyramidDefaults);\n\tconst entity = new ZylemPyramid(options);\n\tentity.add(\n\t\tpyramidMesh({\n\t\t\tradius: options.radius,\n\t\t\theight: options.height,\n\t\t\tmaterial: options.material,\n\t\t\tcolor: options.color,\n\t\t}),\n\t\tpyramidCollision({\n\t\t\tradius: options.radius,\n\t\t\theight: options.height,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn entity;\n}\n","import { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { cylinderMesh } from './parts/mesh-factories';\nimport { cylinderCollision } from './parts/collision-factories';\n\ntype ZylemCylinderOptions = GameEntityOptions & {\n\t/** Top radius of the cylinder */\n\tradiusTop?: number;\n\t/** Bottom radius of the cylinder */\n\tradiusBottom?: number;\n\t/** Height of the cylinder */\n\theight?: number;\n\t/** Number of radial segments (higher = smoother) */\n\tradialSegments?: number;\n};\n\nconst cylinderDefaults: ZylemCylinderOptions = {\n\t...commonDefaults,\n\tradiusTop: 1,\n\tradiusBottom: 1,\n\theight: 2,\n\tradialSegments: 32,\n};\n\nexport const CYLINDER_TYPE = Symbol('Cylinder');\n\n/**\n * A cylinder entity with configurable top/bottom radii, height, and segments.\n * Uses a Rapier cylinder collider for physics.\n */\nexport class ZylemCylinder extends GameEntity<ZylemCylinderOptions> {\n\tstatic type = CYLINDER_TYPE;\n\n\tconstructor(options?: ZylemCylinderOptions) {\n\t\tsuper();\n\t\tthis.options = { ...cylinderDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radiusTop = this.options.radiusTop ?? 1;\n\t\tconst radiusBottom = this.options.radiusBottom ?? 1;\n\t\tconst height = this.options.height ?? 2;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemCylinder.type),\n\t\t\tradiusTop: radiusTop.toFixed(2),\n\t\t\tradiusBottom: radiusBottom.toFixed(2),\n\t\t\theight: height.toFixed(2),\n\t\t};\n\t}\n}\n\ntype CylinderOptions = BaseNode | Partial<ZylemCylinderOptions>;\n\n/**\n * Create a cylinder entity.\n * @param args Options or child nodes\n */\nexport function createCylinder(...args: Array<CylinderOptions>): ZylemCylinder {\n\tconst options = mergeArgs(args, cylinderDefaults);\n\tconst entity = new ZylemCylinder(options);\n\tentity.add(\n\t\tcylinderMesh({\n\t\t\tradiusTop: options.radiusTop,\n\t\t\tradiusBottom: options.radiusBottom,\n\t\t\theight: options.height,\n\t\t\tradialSegments: options.radialSegments,\n\t\t\tmaterial: options.material,\n\t\t\tcolor: options.color,\n\t\t}),\n\t\tcylinderCollision({\n\t\t\tradiusTop: options.radiusTop,\n\t\t\tradiusBottom: options.radiusBottom,\n\t\t\theight: options.height,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn entity;\n}\n","import { BaseNode } from '../core/base-node';\nimport { GameEntityOptions, GameEntity } from './entity';\nimport { DebugDelegate } from './delegates/debug';\nimport { commonDefaults, mergeArgs } from './common';\nimport { pillMesh } from './parts/mesh-factories';\nimport { pillCollision } from './parts/collision-factories';\n\ntype ZylemPillOptions = GameEntityOptions & {\n\t/** Radius of the capsule hemispheres */\n\tradius?: number;\n\t/** Length of the cylindrical middle section */\n\tlength?: number;\n\t/** Number of cap segments (higher = smoother) */\n\tcapSegments?: number;\n\t/** Number of radial segments (higher = smoother) */\n\tradialSegments?: number;\n};\n\nconst pillDefaults: ZylemPillOptions = {\n\t...commonDefaults,\n\tradius: 0.5,\n\tlength: 1,\n\tcapSegments: 10,\n\tradialSegments: 20,\n};\n\nexport const PILL_TYPE = Symbol('Pill');\n\n/**\n * A pill/capsule entity with configurable radius and cylindrical length.\n * Uses Three.js CapsuleGeometry for rendering and Rapier capsule collider for physics.\n */\nexport class ZylemPill extends GameEntity<ZylemPillOptions> {\n\tstatic type = PILL_TYPE;\n\n\tconstructor(options?: ZylemPillOptions) {\n\t\tsuper();\n\t\tthis.options = { ...pillDefaults, ...options };\n\t}\n\n\tbuildInfo(): Record<string, any> {\n\t\tconst delegate = new DebugDelegate(this as any);\n\t\tconst baseInfo = delegate.buildDebugInfo();\n\t\tconst radius = this.options.radius ?? 0.5;\n\t\tconst length = this.options.length ?? 1;\n\t\treturn {\n\t\t\t...baseInfo,\n\t\t\ttype: String(ZylemPill.type),\n\t\t\tradius: radius.toFixed(2),\n\t\t\tlength: length.toFixed(2),\n\t\t};\n\t}\n}\n\ntype PillOptions = BaseNode | Partial<ZylemPillOptions>;\n\n/**\n * Create a pill (capsule) entity.\n * @param args Options or child nodes\n */\nexport function createPill(...args: Array<PillOptions>): ZylemPill {\n\tconst options = mergeArgs(args, pillDefaults);\n\tconst entity = new ZylemPill(options);\n\tentity.add(\n\t\tpillMesh({\n\t\t\tradius: options.radius,\n\t\t\tlength: options.length,\n\t\t\tcapSegments: options.capSegments,\n\t\t\tradialSegments: options.radialSegments,\n\t\t\tmaterial: options.material,\n\t\t\tcolor: options.color,\n\t\t}),\n\t\tpillCollision({\n\t\t\tradius: options.radius,\n\t\t\tlength: options.length,\n\t\t\tstatic: options.collision?.static,\n\t\t\tsensor: options.collision?.sensor,\n\t\t\tcollisionType: options.collisionType,\n\t\t\tcollisionFilter: options.collisionFilter,\n\t\t}),\n\t);\n\treturn entity;\n}\n"],"mappings":"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","names":["Vector3","all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map","position","Vector3","Quaternion","Vector3","rotation","Quaternion","ActiveCollisionTypes","ColliderDesc","RigidBodyDesc","RigidBodyType","Vector3","Vector3","RigidBodyType","RigidBodyDesc","ActiveCollisionTypes","ColliderDesc","ColliderDesc","ActiveCollisionTypes","Vector3","Vector3","x","y","z","toDeg","Mesh","MeshStandardMaterial","Color","Vector2","Vector3","MeshPhongMaterial","MeshStandardMaterial","RepeatWrapping","ShaderMaterial","Color","Vector2","RepeatWrapping","MeshPhongMaterial","MeshStandardMaterial","ShaderMaterial","fragment","Vector3","MeshStandardMaterial","Mesh","Vector3","ColliderDesc","Euler","Group","Quaternion","Vector3","TextureLoader","BufferGeometry","Mesh","Color","Mesh","BufferGeometry","Mesh","Color","Vector3","ColliderDesc","TextureLoader","Group","Quaternion","Euler","ColliderDesc","Vector2","Vector3","BufferGeometry","Vector2","Vector3","scale","ColliderDesc","Vector3","proxy","proxy","Vector3","ActiveCollisionTypes","ColliderDesc","MeshStandardMaterial","Group","Vector3","Vector3","ColliderDesc","ActiveCollisionTypes","colliderDesc","Group","MeshStandardMaterial","Color","Group","ThreeSprite","SpriteMaterial","Vector2","Vector2","Group","SpriteMaterial","ThreeSprite","Color","Color","Group","ThreeSprite","SpriteMaterial","CanvasTexture","LinearFilter","Vector2","ClampToEdgeWrapping","ShaderMaterial","Mesh","PlaneGeometry","Vector3","Vector2","Group","CanvasTexture","LinearFilter","SpriteMaterial","ThreeSprite","ClampToEdgeWrapping","ShaderMaterial","Color","Mesh","PlaneGeometry","Vector3"]}
|