@yagejs/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/dist/index.cjs +3035 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1512 -0
- package/dist/index.d.ts +1512 -0
- package/dist/index.js +2943 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/Vec2.ts","../src/MathUtils.ts","../src/EventBus.ts","../src/Logger.ts","../src/EngineContext.ts","../src/EventToken.ts","../src/AssetHandle.ts","../src/AssetManager.ts","../src/Blueprint.ts","../src/Trait.ts","../src/Serializable.ts","../src/EntityFilter.ts","../src/Component.ts","../src/Transform.ts","../src/Entity.ts","../src/QueryCache.ts","../src/System.ts","../src/SystemScheduler.ts","../src/ComponentUpdateSystem.ts","../src/ErrorBoundary.ts","../src/GameLoop.ts","../src/Scene.ts","../src/SceneManager.ts","../src/Process.ts","../src/Tween.ts","../src/interpolate.ts","../src/KeyframeTrack.ts","../src/ProcessSlot.ts","../src/ProcessComponent.ts","../src/KeyframeAnimator.ts","../src/Sequence.ts","../src/TimerEntity.ts","../src/ProcessSystem.ts","../src/Inspector.ts","../src/Engine.ts","../src/test-utils.ts"],"sourcesContent":["export const VERSION = \"0.0.0\";\n\nexport { Phase } from \"./types.js\";\nexport type {\n ComponentClass,\n Plugin,\n EasingFunction,\n} from \"./types.js\";\n\nexport { Vec2 } from \"./Vec2.js\";\nexport type { Vec2Like } from \"./Vec2.js\";\n\nexport { MathUtils } from \"./MathUtils.js\";\n\nexport { EventBus } from \"./EventBus.js\";\nexport type { EventMap, EngineEvents } from \"./EventBus.js\";\n\nexport { Logger, LogLevel } from \"./Logger.js\";\nexport type { LoggerConfig, LogEntry } from \"./Logger.js\";\n\nexport {\n EngineContext,\n ServiceKey,\n EngineKey,\n EventBusKey,\n SceneManagerKey,\n LoggerKey,\n InspectorKey,\n QueryCacheKey,\n ErrorBoundaryKey,\n GameLoopKey,\n SystemSchedulerKey,\n ProcessSystemKey,\n AssetManagerKey,\n} from \"./EngineContext.js\";\n\nexport { EventToken, defineEvent } from \"./EventToken.js\";\n\nexport { AssetHandle } from \"./AssetHandle.js\";\nexport type { AssetLoader } from \"./AssetHandle.js\";\n\nexport { AssetManager } from \"./AssetManager.js\";\n\nexport { defineBlueprint } from \"./Blueprint.js\";\nexport type { Blueprint } from \"./Blueprint.js\";\n\nexport { TraitToken, defineTrait, trait } from \"./Trait.js\";\nexport {\n serializable,\n SERIALIZABLE_KEY,\n SerializableRegistry,\n isSerializable,\n getSerializableType,\n} from \"./Serializable.js\";\nexport type { SnapshotResolver } from \"./Serializable.js\";\n\nexport { filterEntities } from \"./EntityFilter.js\";\nexport type { EntityFilter } from \"./EntityFilter.js\";\n\nexport { Component } from \"./Component.js\";\n\nexport { Transform } from \"./Transform.js\";\nexport type { TransformData } from \"./Transform.js\";\n\nexport { Entity, _resetEntityIdCounter } from \"./Entity.js\";\nexport type { EntityCallbacks } from \"./Entity.js\";\n\nexport { QueryCache, QueryResult } from \"./QueryCache.js\";\n\nexport { System } from \"./System.js\";\n\nexport { SystemScheduler } from \"./SystemScheduler.js\";\n\nexport {\n ComponentUpdateSystem,\n ComponentFixedUpdateSystem,\n} from \"./ComponentUpdateSystem.js\";\n\nexport { ErrorBoundary } from \"./ErrorBoundary.js\";\n\nexport { GameLoop } from \"./GameLoop.js\";\nexport type { GameLoopCallbacks, GameLoopConfig } from \"./GameLoop.js\";\n\nexport { Scene } from \"./Scene.js\";\n\nexport { SceneManager } from \"./SceneManager.js\";\n\nexport { Process } from \"./Process.js\";\nexport type { ProcessOptions } from \"./Process.js\";\nexport {\n easeLinear,\n easeInQuad,\n easeOutQuad,\n easeInOutQuad,\n easeOutBounce,\n} from \"./Process.js\";\n\nexport { Tween } from \"./Tween.js\";\n\nexport { interpolate } from \"./interpolate.js\";\nexport type { Interpolatable } from \"./interpolate.js\";\n\nexport { createKeyframeTrack } from \"./KeyframeTrack.js\";\nexport type { Keyframe, KeyframeTrackOptions } from \"./KeyframeTrack.js\";\n\nexport { KeyframeAnimator } from \"./KeyframeAnimator.js\";\nexport type { KeyframeAnimationDef } from \"./KeyframeAnimator.js\";\n\nexport { Sequence } from \"./Sequence.js\";\n\nexport { ProcessComponent } from \"./ProcessComponent.js\";\n\nexport { ProcessSlot } from \"./ProcessSlot.js\";\nexport type { ProcessSlotConfig } from \"./ProcessSlot.js\";\n\nexport { TimerEntity } from \"./TimerEntity.js\";\n\nexport { ProcessSystem } from \"./ProcessSystem.js\";\n\nexport { Inspector } from \"./Inspector.js\";\nexport type {\n EngineSnapshot,\n EntitySnapshot,\n SceneSnapshot,\n SystemSnapshot,\n ErrorSnapshot,\n} from \"./Inspector.js\";\n\nexport { Engine } from \"./Engine.js\";\nexport type { EngineConfig } from \"./Engine.js\";\n\nexport {\n createTestEngine,\n createMockScene,\n createMockEntity,\n advanceFrames,\n} from \"./test-utils.js\";\n","import type { Component } from \"./Component.js\";\n\n/** Constructor type for components. */\nexport type ComponentClass<C extends Component = Component> = new (\n ...args: never[]\n) => C;\n\n/** Game loop phase identifiers. Systems run in one specific phase. */\nexport enum Phase {\n EarlyUpdate = \"earlyUpdate\",\n FixedUpdate = \"fixedUpdate\",\n Update = \"update\",\n LateUpdate = \"lateUpdate\",\n Render = \"render\",\n EndOfFrame = \"endOfFrame\",\n}\n\n/** Plugin interface for extending the engine. */\nexport interface Plugin {\n /** Unique plugin name. */\n readonly name: string;\n /** Semantic version string. */\n readonly version: string;\n /** Names of plugins this plugin depends on. */\n readonly dependencies?: readonly string[];\n /** Install services into the engine context. Called in topological order. */\n install?(context: import(\"./EngineContext.js\").EngineContext): void | Promise<void>;\n /** Register systems with the scheduler. Called after install. */\n registerSystems?(scheduler: import(\"./SystemScheduler.js\").SystemScheduler): void;\n /** Called after all plugins are installed and the engine has started. */\n onStart?(): void;\n /** Called when the engine is destroyed. */\n onDestroy?(): void;\n}\n\n/** An easing function mapping t in [0,1] to a value in [0,1]. */\nexport type EasingFunction = (t: number) => number;\n","/** Default epsilon for floating-point comparisons. */\nconst EPSILON = 1e-6;\n\n/** Any object with x and y numeric properties. */\nexport interface Vec2Like {\n readonly x: number;\n readonly y: number;\n}\n\n/** Immutable 2D vector. All operations return new instances. */\nexport class Vec2 implements Vec2Like {\n /** The zero vector (0, 0). */\n static readonly ZERO = new Vec2(0, 0);\n /** The one vector (1, 1). */\n static readonly ONE = new Vec2(1, 1);\n /** Up direction (0, -1) — screen coordinates. */\n static readonly UP = new Vec2(0, -1);\n /** Down direction (0, 1) — screen coordinates. */\n static readonly DOWN = new Vec2(0, 1);\n /** Left direction (-1, 0). */\n static readonly LEFT = new Vec2(-1, 0);\n /** Right direction (1, 0). */\n static readonly RIGHT = new Vec2(1, 0);\n\n constructor(\n /** The x component. */\n public readonly x: number,\n /** The y component. */\n public readonly y: number,\n ) {}\n\n /** Add another vector. */\n add(other: Vec2Like): Vec2 {\n return new Vec2(this.x + other.x, this.y + other.y);\n }\n\n /** Subtract another vector. */\n sub(other: Vec2Like): Vec2 {\n return new Vec2(this.x - other.x, this.y - other.y);\n }\n\n /** Scale by a scalar. */\n scale(scalar: number): Vec2 {\n return new Vec2(this.x * scalar, this.y * scalar);\n }\n\n /** Component-wise multiply with another vector. */\n multiply(other: Vec2Like): Vec2 {\n return new Vec2(this.x * other.x, this.y * other.y);\n }\n\n /** Dot product with another vector. */\n dot(other: Vec2Like): number {\n return this.x * other.x + this.y * other.y;\n }\n\n /** Cross product (z-component of the 3D cross product). */\n cross(other: Vec2Like): number {\n return this.x * other.y - this.y * other.x;\n }\n\n /** Magnitude of this vector. */\n length(): number {\n return Math.sqrt(this.x * this.x + this.y * this.y);\n }\n\n /** Squared magnitude (avoids sqrt). */\n lengthSq(): number {\n return this.x * this.x + this.y * this.y;\n }\n\n /** Return a unit vector in the same direction. Returns ZERO for zero-length vectors. */\n normalize(): Vec2 {\n const len = this.length();\n if (len < EPSILON) return Vec2.ZERO;\n return new Vec2(this.x / len, this.y / len);\n }\n\n /** Euclidean distance to another vector. */\n distance(other: Vec2Like): number {\n const dx = this.x - other.x;\n const dy = this.y - other.y;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n /** Squared distance to another vector (avoids sqrt). */\n distanceSq(other: Vec2Like): number {\n const dx = this.x - other.x;\n const dy = this.y - other.y;\n return dx * dx + dy * dy;\n }\n\n /** Linear interpolation toward another vector. */\n lerp(other: Vec2Like, t: number): Vec2 {\n return new Vec2(\n this.x + (other.x - this.x) * t,\n this.y + (other.y - this.y) * t,\n );\n }\n\n /** Angle of this vector in radians (atan2). */\n angle(): number {\n return Math.atan2(this.y, this.x);\n }\n\n /** Rotate this vector by radians. */\n rotate(radians: number): Vec2 {\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n return new Vec2(this.x * cos - this.y * sin, this.x * sin + this.y * cos);\n }\n\n /** Check equality with optional epsilon tolerance. */\n equals(other: Vec2Like, epsilon: number = EPSILON): boolean {\n return (\n Math.abs(this.x - other.x) < epsilon &&\n Math.abs(this.y - other.y) < epsilon\n );\n }\n\n /** String representation. */\n toString(): string {\n return `Vec2(${this.x}, ${this.y})`;\n }\n\n /** Create a unit vector from an angle in radians, optionally scaled. */\n static fromAngle(radians: number, length: number = 1): Vec2 {\n return new Vec2(Math.cos(radians) * length, Math.sin(radians) * length);\n }\n\n /** Euclidean distance between two vectors. */\n static distance(a: Vec2Like, b: Vec2Like): number {\n const dx = a.x - b.x;\n const dy = a.y - b.y;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n /** Linear interpolation between two vectors. */\n static lerp(a: Vec2Like, b: Vec2Like, t: number): Vec2 {\n return new Vec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);\n }\n}\n","/** Common math utility functions. */\nexport const MathUtils = {\n /** Linear interpolation between a and b. */\n lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n },\n\n /** Clamp a value between min and max. */\n clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n },\n\n /** Remap a value from one range to another. */\n remap(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n ): number {\n const t = (value - inMin) / (inMax - inMin);\n return outMin + (outMax - outMin) * t;\n },\n\n /** Random float in [min, max). */\n randomRange(min: number, max: number): number {\n return min + Math.random() * (max - min);\n },\n\n /** Random integer in [min, max] (inclusive). */\n randomInt(min: number, max: number): number {\n return Math.floor(min + Math.random() * (max - min + 1));\n },\n\n /** Convert degrees to radians. */\n degToRad(degrees: number): number {\n return (degrees * Math.PI) / 180;\n },\n\n /** Convert radians to degrees. */\n radToDeg(radians: number): number {\n return (radians * 180) / Math.PI;\n },\n\n /** Move current toward target by at most step. */\n approach(current: number, target: number, step: number): number {\n if (current < target) {\n return Math.min(current + step, target);\n }\n return Math.max(current - step, target);\n },\n\n /** Wrap value into the range [min, max). */\n wrap(value: number, min: number, max: number): number {\n const range = max - min;\n return ((((value - min) % range) + range) % range) + min;\n },\n} as const;\n","import type { Component } from \"./Component.js\";\nimport type { ComponentClass } from \"./types.js\";\n\n// Forward declarations for event payloads\ntype EntityRef = { readonly id: number; readonly name: string };\ntype SceneRef = { readonly name: string };\n\n/** Base type for event map definitions. */\nexport type EventMap = Record<string, unknown>;\n\n/** Well-known engine events. */\nexport interface EngineEvents {\n \"entity:created\": { entity: EntityRef };\n \"entity:destroyed\": { entity: EntityRef };\n \"component:added\": { entity: EntityRef; component: Component };\n \"component:removed\": { entity: EntityRef; componentClass: ComponentClass };\n \"scene:pushed\": { scene: SceneRef };\n \"scene:popped\": { scene: SceneRef };\n \"scene:replaced\": { oldScene: SceneRef; newScene: SceneRef };\n \"engine:started\": undefined;\n \"engine:stopped\": undefined;\n}\n\n/** Typed publish/subscribe event bus. */\nexport class EventBus<E = EventMap> {\n private handlers = new Map<keyof E, Array<(data: never) => void>>();\n\n /** Subscribe to an event. Returns an unsubscribe function. */\n on<K extends keyof E>(event: K, handler: (data: E[K]) => void): () => void {\n let list = this.handlers.get(event);\n if (!list) {\n list = [];\n this.handlers.set(event, list);\n }\n list.push(handler as (data: never) => void);\n return () => {\n const arr = this.handlers.get(event);\n if (arr) {\n const idx = arr.indexOf(handler as (data: never) => void);\n if (idx !== -1) arr.splice(idx, 1);\n }\n };\n }\n\n /** Subscribe to an event, auto-unsubscribe after first emission. */\n once<K extends keyof E>(event: K, handler: (data: E[K]) => void): () => void {\n const unsub = this.on(event, (data) => {\n unsub();\n handler(data);\n });\n return unsub;\n }\n\n /** Emit an event. Handlers are called synchronously in registration order. */\n emit<K extends keyof E>(event: K, data: E[K]): void {\n const list = this.handlers.get(event);\n if (!list) return;\n // Iterate a copy so handlers can unsubscribe during emission\n const snapshot = [...list];\n for (const handler of snapshot) {\n handler(data as never);\n }\n }\n\n /** Remove all handlers for an event, or all handlers if no event specified. */\n clear(event?: keyof E): void {\n if (event !== undefined) {\n this.handlers.delete(event);\n } else {\n this.handlers.clear();\n }\n }\n}\n","/** Log severity levels. */\nexport enum LogLevel {\n Debug = 0,\n Info = 1,\n Warn = 2,\n Error = 3,\n None = 4,\n}\n\n/** Configuration for the Logger. */\nexport interface LoggerConfig {\n /** Minimum log level. Default: Info. */\n level?: LogLevel;\n /** Category whitelist. Empty = all categories allowed. */\n categories?: string[];\n /** Ring buffer size. Default: 500. */\n bufferSize?: number;\n /** Custom output handler. */\n output?: (entry: LogEntry) => void;\n}\n\n/** A single log entry. */\nexport interface LogEntry {\n /** Log severity level. */\n level: LogLevel;\n /** Category string (e.g., \"physics\", \"core\"). */\n category: string;\n /** Log message. */\n message: string;\n /** Optional structured data. */\n data?: unknown;\n /** Timestamp in milliseconds since epoch. */\n timestamp: number;\n /** Game frame number at time of log. */\n frame: number;\n}\n\nconst LEVEL_LABELS: Record<LogLevel, string> = {\n [LogLevel.Debug]: \"DEBUG\",\n [LogLevel.Info]: \"INFO\",\n [LogLevel.Warn]: \"WARN\",\n [LogLevel.Error]: \"ERROR\",\n [LogLevel.None]: \"NONE\",\n};\n\n/** Structured logger with ring buffer, levels, and category filtering. */\nexport class Logger {\n private readonly level: LogLevel;\n private readonly categories: Set<string>;\n private readonly bufferSize: number;\n private readonly output: ((entry: LogEntry) => void) | undefined;\n private readonly buffer: LogEntry[];\n private writeIndex = 0;\n private count = 0;\n private currentFrame = 0;\n\n constructor(config?: LoggerConfig) {\n this.level = config?.level ?? LogLevel.Info;\n this.categories = new Set(config?.categories ?? []);\n this.bufferSize = config?.bufferSize ?? 500;\n this.output = config?.output;\n this.buffer = new Array<LogEntry>(this.bufferSize);\n }\n\n /** Set the current frame number (incremented externally by the game loop). */\n setFrame(frame: number): void {\n this.currentFrame = frame;\n }\n\n /** Log a debug message. */\n debug(category: string, message: string, data?: unknown): void {\n this.log(LogLevel.Debug, category, message, data);\n }\n\n /** Log an info message. */\n info(category: string, message: string, data?: unknown): void {\n this.log(LogLevel.Info, category, message, data);\n }\n\n /** Log a warning message. */\n warn(category: string, message: string, data?: unknown): void {\n this.log(LogLevel.Warn, category, message, data);\n }\n\n /** Log an error message. */\n error(category: string, message: string, data?: unknown): void {\n this.log(LogLevel.Error, category, message, data);\n }\n\n /** Get recent log entries from the ring buffer. */\n getRecent(count?: number): LogEntry[] {\n const available = Math.min(this.count, this.bufferSize);\n const n = count !== undefined ? Math.min(count, available) : available;\n const result: LogEntry[] = [];\n // Read the most recent n entries\n for (let i = 0; i < n; i++) {\n const idx =\n (this.writeIndex - n + i + this.bufferSize) % this.bufferSize;\n const entry = this.buffer[idx];\n if (entry) result.push(entry);\n }\n return result;\n }\n\n /** Format recent logs as structured text for agent consumption. */\n formatRecentLogs(count?: number): string {\n return this.getRecent(count)\n .map((e) => {\n const levelStr = LEVEL_LABELS[e.level] ?? \"UNKNOWN\";\n const dataStr =\n e.data !== undefined ? ` ${JSON.stringify(e.data)}` : \"\";\n return `[${levelStr}][${e.category}] f${e.frame} ${e.message}${dataStr}`;\n })\n .join(\"\\n\");\n }\n\n /** Clear the ring buffer. */\n clear(): void {\n this.writeIndex = 0;\n this.count = 0;\n this.buffer.fill(undefined as unknown as LogEntry);\n }\n\n private log(\n level: LogLevel,\n category: string,\n message: string,\n data?: unknown,\n ): void {\n if (level < this.level) return;\n if (this.categories.size > 0 && !this.categories.has(category)) return;\n\n const entry: LogEntry = {\n level,\n category,\n message,\n data,\n timestamp: Date.now(),\n frame: this.currentFrame,\n };\n\n this.buffer[this.writeIndex] = entry;\n this.writeIndex = (this.writeIndex + 1) % this.bufferSize;\n this.count++;\n\n this.output?.(entry);\n }\n}\n","/** A typed key for service registration and resolution. */\nexport class ServiceKey<T> {\n constructor(\n /** Unique string identifier for this service. */\n public readonly id: string,\n ) {}\n\n /** Phantom field to preserve the generic type. */\n declare readonly _type: T;\n}\n\n/** Dependency injection container for engine services. */\nexport class EngineContext {\n private services = new Map<string, unknown>();\n\n /** Register a service. Throws if the key is already registered. */\n register<T>(key: ServiceKey<T>, service: T): void {\n if (this.services.has(key.id)) {\n throw new Error(`Service \"${key.id}\" is already registered.`);\n }\n this.services.set(key.id, service);\n }\n\n /** Resolve a service. Throws if not registered. */\n resolve<T>(key: ServiceKey<T>): T {\n if (!this.services.has(key.id)) {\n throw new Error(`Service \"${key.id}\" is not registered.`);\n }\n return this.services.get(key.id) as T;\n }\n\n /** Resolve a service, returning undefined if not registered. */\n tryResolve<T>(key: ServiceKey<T>): T | undefined {\n return this.services.get(key.id) as T | undefined;\n }\n\n /** Remove a registered service. No-op if not registered. */\n unregister<T>(key: ServiceKey<T>): void {\n this.services.delete(key.id);\n }\n\n /** Check if a service is registered. */\n has<T>(key: ServiceKey<T>): boolean {\n return this.services.has(key.id);\n }\n}\n\n// ---- Well-known service keys ----\n// We use lazy types to avoid circular imports. The generic parameter documents\n// the expected service type. Consumers import both the key and the type.\n\n/** Key for the Engine instance. */\nexport const EngineKey = new ServiceKey<\n import(\"./Engine.js\").Engine\n>(\"engine\");\n\n/** Key for the EventBus instance. */\nexport const EventBusKey = new ServiceKey<\n import(\"./EventBus.js\").EventBus<import(\"./EventBus.js\").EngineEvents>\n>(\"eventBus\");\n\n/** Key for the SceneManager instance. */\nexport const SceneManagerKey = new ServiceKey<\n import(\"./SceneManager.js\").SceneManager\n>(\"sceneManager\");\n\n/** Key for the Logger instance. */\nexport const LoggerKey = new ServiceKey<import(\"./Logger.js\").Logger>(\"logger\");\n\n/** Key for the Inspector instance. */\nexport const InspectorKey = new ServiceKey<\n import(\"./Inspector.js\").Inspector\n>(\"inspector\");\n\n/** Key for the QueryCache instance. */\nexport const QueryCacheKey = new ServiceKey<\n import(\"./QueryCache.js\").QueryCache\n>(\"queryCache\");\n\n/** Key for the ErrorBoundary instance. */\nexport const ErrorBoundaryKey = new ServiceKey<\n import(\"./ErrorBoundary.js\").ErrorBoundary\n>(\"errorBoundary\");\n\n/** Key for the GameLoop instance. */\nexport const GameLoopKey = new ServiceKey<\n import(\"./GameLoop.js\").GameLoop\n>(\"gameLoop\");\n\n/** Key for the SystemScheduler instance. */\nexport const SystemSchedulerKey = new ServiceKey<\n import(\"./SystemScheduler.js\").SystemScheduler\n>(\"systemScheduler\");\n\n/** Key for the ProcessSystem instance. */\nexport const ProcessSystemKey = new ServiceKey<\n import(\"./ProcessSystem.js\").ProcessSystem\n>(\"processSystem\");\n\n/** Key for the AssetManager instance. */\nexport const AssetManagerKey = new ServiceKey<\n import(\"./AssetManager.js\").AssetManager\n>(\"assetManager\");\n","/**\n * A phantom-typed token for entity events.\n * Similar to ServiceKey, but used for entity-level event pub/sub.\n */\nexport class EventToken<T = void> {\n constructor(\n /** Unique string identifier for this event. */\n public readonly name: string,\n ) {}\n\n /** Phantom field to preserve the generic type. */\n declare readonly _type: T;\n}\n\n/** Create a typed event token. */\nexport function defineEvent<T = void>(name: string): EventToken<T> {\n return new EventToken<T>(name);\n}\n","/**\n * A phantom-typed handle referencing an asset by type and path.\n * Created by plugin-specific factory functions (e.g. `texture()`, `sound()`).\n * Core knows nothing about concrete asset types.\n */\nexport class AssetHandle<T> {\n constructor(\n /** Loader type key (e.g. \"texture\", \"sound\"). */\n readonly type: string,\n /** Asset path or URL. */\n readonly path: string,\n ) {}\n\n /** Phantom field to preserve the generic type at compile time. */\n declare readonly _type: T;\n}\n\n/** Interface that plugins implement to load/unload a specific asset type. */\nexport interface AssetLoader<T = unknown> {\n load(path: string): Promise<T>;\n unload?(path: string, asset: T): void;\n}\n","import type { AssetHandle, AssetLoader } from \"./AssetHandle.js\";\n\n/**\n * Orchestrates asset loading across plugin-provided loaders.\n * Core owns the \"when\" and \"what\"; plugins own the \"how\".\n */\nexport class AssetManager {\n private loaders = new Map<string, AssetLoader>();\n private cache = new Map<string, unknown>();\n\n /** Register a loader for a given asset type. Called by plugins during install(). */\n registerLoader(type: string, loader: AssetLoader): void {\n this.loaders.set(type, loader);\n }\n\n /** Retrieve a loaded asset. Throws if not loaded. */\n get<T>(handle: AssetHandle<T>): T {\n const key = this.key(handle);\n const asset = this.cache.get(key);\n if (asset === undefined) {\n throw new Error(`Asset not loaded: \"${handle.path}\" (type: ${handle.type})`);\n }\n return asset as T;\n }\n\n /** Check if an asset is loaded. */\n has(handle: AssetHandle<unknown>): boolean {\n return this.cache.has(this.key(handle));\n }\n\n /**\n * Load all assets, skipping already-cached ones.\n * Reports progress via optional callback (0→1).\n */\n async loadAll(\n handles: readonly AssetHandle<unknown>[],\n onProgress?: (ratio: number) => void,\n ): Promise<void> {\n const toLoad = handles.filter((h) => !this.cache.has(this.key(h)));\n if (toLoad.length === 0) {\n onProgress?.(1);\n return;\n }\n let done = 0;\n onProgress?.(0);\n await Promise.all(\n toLoad.map(async (handle) => {\n const loader = this.loaders.get(handle.type);\n if (!loader) {\n throw new Error(\n `No loader registered for asset type \"${handle.type}\". Missing plugin?`,\n );\n }\n const asset = await loader.load(handle.path);\n this.cache.set(this.key(handle), asset);\n onProgress?.(++done / toLoad.length);\n }),\n );\n }\n\n /** Unload a single asset and remove from cache. */\n unload(handle: AssetHandle<unknown>): void {\n const key = this.key(handle);\n const asset = this.cache.get(key);\n if (asset === undefined) return;\n const loader = this.loaders.get(handle.type);\n loader?.unload?.(handle.path, asset);\n this.cache.delete(key);\n }\n\n /** Unload all cached assets. */\n clear(): void {\n for (const [key, asset] of this.cache) {\n const [type, ...pathParts] = key.split(\":\");\n const path = pathParts.join(\":\");\n this.loaders.get(type!)?.unload?.(path, asset);\n }\n this.cache.clear();\n }\n\n private key(handle: AssetHandle<unknown>): string {\n return `${handle.type}:${handle.path}`;\n }\n}\n","import type { Entity } from \"./Entity.js\";\n\n/**\n * A reusable entity template. Blueprints define how to assemble\n * an entity from components, given optional parameters.\n */\nexport interface Blueprint<P = void> {\n readonly name: string;\n build(entity: Entity, params: P): void;\n}\n\n/** Create a blueprint from a name and a build function. */\nexport function defineBlueprint<P = void>(\n name: string,\n build: (entity: Entity, params: P) => void,\n): Blueprint<P> {\n return { name, build };\n}\n","import type { Entity } from \"./Entity.js\";\n\n/**\n * Trait system — discoverable, type-safe entity capabilities.\n *\n * Traits let entity subclasses declare capabilities (`Interactable`, `Damageable`)\n * that are enforced at compile time (via decorator constraint) and queryable at\n * runtime via `hasTrait()`.\n */\n\n/** Symbol key for storing the set of trait symbols on a class. */\nexport const TRAITS_KEY = Symbol(\"TRAITS_KEY\");\n\n/**\n * A phantom-typed token representing a trait.\n * Follows the same pattern as EventToken / ServiceKey.\n */\nexport class TraitToken<T> {\n readonly symbol: symbol;\n\n constructor(\n /** Human-readable name for debugging. */\n public readonly name: string,\n ) {\n this.symbol = Symbol(`Trait:${name}`);\n }\n\n /** Phantom field to preserve the generic type. */\n declare readonly _type: T;\n}\n\n/**\n * Create a typed trait token.\n *\n * ```ts\n * const Interactable = defineTrait<{ interact(): void; priority: number }>(\"Interactable\");\n * ```\n */\nexport function defineTrait<T>(name: string): TraitToken<T> {\n return new TraitToken<T>(name);\n}\n\n/**\n * Class decorator that registers a trait on an entity subclass.\n * The type constraint enforces that the class implements all trait members.\n *\n * ```ts\n * @trait(Interactable)\n * class LightEntity extends Entity {\n * priority = 4;\n * interact() { ... } // TS error if missing\n * }\n * ```\n */\nexport function trait<Trait>(token: TraitToken<Trait>) {\n return <T extends typeof Entity & { prototype: Trait }>(target: T): T => {\n const traitSymbols = new Set(target[TRAITS_KEY] ?? []);\n traitSymbols.add(token.symbol);\n target[TRAITS_KEY] = traitSymbols;\n\n return target;\n };\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any -- Constructor types require `any` for TS decorator compatibility */\n\n/**\n * Passed to `afterRestore` hooks so user code can resolve entity references\n * that were captured as IDs at save time.\n */\nexport interface SnapshotResolver {\n /** Resolve a save-time entity ID to the restored entity instance. Returns null if not found. */\n entity(savedId: number): import(\"./Entity.js\").Entity | null;\n}\n\n/** Symbol stored on classes decorated with @serializable. Holds the type string. */\nexport const SERIALIZABLE_KEY = Symbol(\"SERIALIZABLE\");\n\n/** Global registry mapping type strings to classes. */\nconst registry = new Map<string, new (...args: any[]) => any>();\n\n/** Read-only access to the serializable type registry. */\nexport const SerializableRegistry = {\n /** Look up a class by its type string. */\n get(type: string): (new (...args: any[]) => any) | undefined {\n return registry.get(type);\n },\n /** Check if a type string is registered. */\n has(type: string): boolean {\n return registry.has(type);\n },\n /** Iterate all registered [type, class] entries. */\n entries(): IterableIterator<\n [string, new (...args: any[]) => any]\n > {\n return registry.entries();\n },\n /** Remove a type from the registry. */\n delete(type: string): boolean {\n return registry.delete(type);\n },\n};\n\n/** Check if an instance belongs to a @serializable-decorated class. */\nexport function isSerializable(instance: object): boolean {\n return SERIALIZABLE_KEY in instance.constructor;\n}\n\n/** Get the type string from a @serializable-decorated class or instance. */\nexport function getSerializableType(\n target: object | (new (...args: any[]) => any),\n): string | undefined {\n const ctor = typeof target === \"function\" ? target : target.constructor;\n return (ctor as unknown as Record<symbol, string>)[SERIALIZABLE_KEY];\n}\n\n/**\n * Decorator that registers a class in the global SerializableRegistry.\n *\n * Works on Component, Entity, and Scene subclasses.\n *\n * ```ts\n * // Zero-arg — uses class.name as type string\n * @serializable\n * class Transform extends Component { ... }\n *\n * // With override — for name collisions or minified builds\n * @serializable({ type: \"MyTransform\" })\n * class Transform extends Component { ... }\n * ```\n */\nexport function serializable<\n T extends new (...args: any[]) => any,\n>(target: T): T;\nexport function serializable(\n config: { type: string },\n): <T extends new (...args: any[]) => any>(target: T) => T;\nexport function serializable(\n targetOrConfig:\n | (new (...args: any[]) => any)\n | { type: string },\n) {\n if (typeof targetOrConfig === \"function\") {\n // Called as @serializable (no args)\n const target = targetOrConfig;\n const type = target.name;\n (target as unknown as Record<symbol, string>)[SERIALIZABLE_KEY] = type;\n registry.set(type, target);\n return target;\n }\n // Called as @serializable({ type: \"...\" })\n const config = targetOrConfig;\n return <T extends new (...args: any[]) => any>(target: T): T => {\n (target as unknown as Record<symbol, string>)[SERIALIZABLE_KEY] =\n config.type;\n registry.set(config.type, target);\n return target;\n };\n}\n","import type { Entity } from \"./Entity.js\";\nimport type { TraitToken } from \"./Trait.js\";\n\n/** Filter criteria for entity queries. All fields are AND'd together. */\nexport interface EntityFilter {\n /** Match entities whose class implements this trait. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n trait?: TraitToken<any>;\n /** Match entities that have ALL of these tags. */\n tags?: string[];\n /** Match entities with this exact name. */\n name?: string;\n /** Custom predicate — called after other checks pass. */\n filter?: (entity: Entity) => boolean;\n}\n\n/** Apply a filter to an iterable of entities. Skips destroyed entities. */\nexport function filterEntities(\n entities: Iterable<Entity>,\n filter: EntityFilter,\n): Entity[] {\n const result: Entity[] = [];\n for (const entity of entities) {\n if (entity.isDestroyed) continue;\n if (filter.name !== undefined && entity.name !== filter.name) continue;\n if (filter.tags) {\n let allMatch = true;\n for (const tag of filter.tags) {\n if (!entity.tags.has(tag)) {\n allMatch = false;\n break;\n }\n }\n if (!allMatch) continue;\n }\n if (filter.trait && !entity.hasTrait(filter.trait)) continue;\n if (filter.filter && !filter.filter(entity)) continue;\n result.push(entity);\n }\n return result;\n}\n","import type { EngineContext, ServiceKey } from \"./EngineContext.js\";\nimport type { Entity } from \"./Entity.js\";\nimport type { EventToken } from \"./EventToken.js\";\nimport type { ComponentClass } from \"./types.js\";\nimport type { SnapshotResolver } from \"./Serializable.js\";\n\n/**\n * Base class for all components.\n *\n * Components are the primary authoring model. Game developers write behavior\n * in components using optional `update(dt)` and `fixedUpdate(dt)` methods.\n * The built-in ComponentUpdateSystem calls these methods automatically.\n */\nexport abstract class Component {\n /**\n * Back-reference to the owning entity. Set by the engine when the component\n * is added to an entity. Do not set manually.\n */\n entity!: import(\"./Entity.js\").Entity;\n\n /** Whether this component is active. Disabled components are skipped by ComponentUpdateSystem. */\n enabled = true;\n\n private _serviceCache: Map<string, unknown> | undefined;\n private _cleanups?: Array<() => void>;\n\n /**\n * Access the entity's scene. Throws if the entity is not in a scene.\n * Prefer this over `this.entity.scene!` in component methods.\n */\n get scene(): import(\"./Scene.js\").Scene {\n const scene = this.entity.scene;\n if (!scene) {\n throw new Error(\n \"Cannot access scene: entity is not attached to a scene.\",\n );\n }\n return scene;\n }\n\n /**\n * Access the EngineContext from the entity's scene.\n * Throws if the entity is not in a scene.\n */\n get context(): EngineContext {\n return this.scene.context;\n }\n\n /** Resolve a service by key, cached after first lookup. */\n protected use<T>(key: ServiceKey<T>): T {\n this._serviceCache ??= new Map();\n let value = this._serviceCache.get(key.id);\n if (value === undefined) {\n value = this.context.resolve(key);\n this._serviceCache.set(key.id, value);\n }\n return value as T;\n }\n\n /**\n * Lazy proxy-based service resolution. Can be used at field-declaration time:\n * ```ts\n * readonly camera = this.service(CameraKey);\n * ```\n * The actual resolution is deferred until first property access.\n */\n protected service<T extends object>(key: ServiceKey<T>): T {\n let resolved: T | undefined;\n return new Proxy({} as object, {\n get: (_target, prop) => {\n resolved ??= this.use(key);\n const value = (resolved as Record<string | symbol, unknown>)[prop];\n return typeof value === \"function\"\n ? (value as (...args: unknown[]) => unknown).bind(resolved)\n : value;\n },\n set: (_target, prop, value) => {\n resolved ??= this.use(key);\n (resolved as Record<string | symbol, unknown>)[prop] = value;\n return true;\n },\n }) as T;\n }\n\n /**\n * Lazy proxy-based sibling component resolution. Can be used at field-declaration time:\n * ```ts\n * readonly anim = this.sibling(AnimatedSpriteComponent);\n * ```\n * The actual resolution is deferred until first property access.\n */\n protected sibling<C extends Component>(cls: ComponentClass<C>): C {\n let resolved: C | undefined;\n return new Proxy({} as object, {\n get: (_target, prop) => {\n resolved ??= this.entity.get(cls);\n const value = (resolved as Record<string | symbol, unknown>)[prop];\n return typeof value === \"function\"\n ? (value as (...args: unknown[]) => unknown).bind(resolved)\n : value;\n },\n set: (_target, prop, value) => {\n resolved ??= this.entity.get(cls);\n (resolved as Record<string | symbol, unknown>)[prop] = value;\n return true;\n },\n }) as C;\n }\n\n /** Subscribe to events on any entity, auto-unsubscribe on removal. */\n protected listen<T>(\n entity: Entity,\n token: EventToken<T>,\n handler: (data: T) => void,\n ): void {\n const unsub = entity.on(token, handler);\n this.addCleanup(unsub);\n }\n\n /** Subscribe to scene-level bubbled events, auto-unsubscribe on removal. */\n protected listenScene<T>(\n token: EventToken<T>,\n handler: (data: T, entity: Entity) => void,\n ): void {\n const unsub = this.scene.on(token, handler);\n this.addCleanup(unsub);\n }\n\n /** Register a cleanup function to run when this component is removed or destroyed. */\n protected addCleanup(fn: () => void): void {\n this._cleanups ??= [];\n this._cleanups.push(fn);\n }\n\n /**\n * Run and clear all registered cleanups.\n * Called by Entity.remove() and Entity._performDestroy() before onRemove/onDestroy.\n * @internal\n */\n _runCleanups(): void {\n if (this._cleanups) {\n for (const fn of this._cleanups) {\n fn();\n }\n this._cleanups.length = 0;\n }\n }\n\n /** Called when the component is added to an entity. */\n onAdd?(): void;\n\n /** Called when the component is removed from an entity. */\n onRemove?(): void;\n\n /** Called when the component is destroyed (entity destroyed or component removed). */\n onDestroy?(): void;\n\n /** Called every frame by the built-in ComponentUpdateSystem. */\n update?(dt: number): void;\n\n /** Called every fixed timestep by the built-in ComponentUpdateSystem. */\n fixedUpdate?(dt: number): void;\n\n /** Return a JSON-serializable snapshot of this component's state. Used by the save system. */\n serialize?(): unknown;\n\n /** Called after onAdd() during save/load restoration. Apply state that depends on onAdd() having run. */\n afterRestore?(data: unknown, resolve: SnapshotResolver): void;\n}\n","import { Component } from \"./Component.js\";\nimport { serializable } from \"./Serializable.js\";\nimport { Vec2 } from \"./Vec2.js\";\nimport type { Vec2Like } from \"./Vec2.js\";\n\n/** Serialized transform state. */\nexport interface TransformData {\n position: { x: number; y: number };\n rotation: number;\n scale: { x: number; y: number };\n}\n\n/** Mutable transform component for entity positioning. */\n@serializable\nexport class Transform extends Component {\n // Private backing fields\n private _position: Vec2;\n private _rotation: number;\n private _scale: Vec2;\n private _worldPosition: Vec2;\n private _worldRotation: number;\n private _worldScale: Vec2;\n private _dirty = false;\n\n constructor(options?: {\n position?: Vec2Like;\n rotation?: number;\n scale?: Vec2Like;\n }) {\n super();\n this._position = options?.position\n ? new Vec2(options.position.x, options.position.y)\n : Vec2.ZERO;\n this._rotation = options?.rotation ?? 0;\n this._scale = options?.scale\n ? new Vec2(options.scale.x, options.scale.y)\n : Vec2.ONE;\n this._worldPosition = this._position;\n this._worldRotation = this._rotation;\n this._worldScale = this._scale;\n }\n\n /** Local position (relative to parent, or world if no parent). */\n get position(): Vec2 {\n return this._position;\n }\n\n set position(v: Vec2) {\n this._position = v;\n this._markDirty();\n }\n\n /** Local rotation in radians. */\n get rotation(): number {\n return this._rotation;\n }\n\n set rotation(v: number) {\n this._rotation = v;\n this._markDirty();\n }\n\n /** Local scale factor. */\n get scale(): Vec2 {\n return this._scale;\n }\n\n set scale(v: Vec2) {\n this._scale = v;\n this._markDirty();\n }\n\n /** Computed world position. Recomputed lazily when dirty. */\n get worldPosition(): Vec2 {\n if (this._dirty) this._recompute();\n return this._worldPosition;\n }\n\n /** Set position in world space. Back-computes the local position from the parent chain. */\n set worldPosition(v: Vec2) {\n const pt = this.entity?.parent?.tryGet(Transform);\n if (!pt) {\n this._position = v;\n } else {\n const delta = v.sub(pt.worldPosition).rotate(-pt.worldRotation);\n const ps = pt.worldScale;\n this._position = new Vec2(delta.x / ps.x, delta.y / ps.y);\n }\n this._markDirty();\n }\n\n /** Computed world rotation. Recomputed lazily when dirty. */\n get worldRotation(): number {\n if (this._dirty) this._recompute();\n return this._worldRotation;\n }\n\n /** Set rotation in world space. Back-computes the local rotation from the parent chain. */\n set worldRotation(v: number) {\n const pt = this.entity?.parent?.tryGet(Transform);\n if (!pt) {\n this._rotation = v;\n } else {\n this._rotation = v - pt.worldRotation;\n }\n this._markDirty();\n }\n\n /** Computed world scale. Recomputed lazily when dirty. */\n get worldScale(): Vec2 {\n if (this._dirty) this._recompute();\n return this._worldScale;\n }\n\n /** Set position directly. */\n setPosition(x: number, y: number): void {\n this._position = new Vec2(x, y);\n this._markDirty();\n }\n\n /** Translate by an offset. */\n translate(dx: number, dy: number): void {\n this._position = new Vec2(this._position.x + dx, this._position.y + dy);\n this._markDirty();\n }\n\n /** Set rotation in radians. */\n setRotation(radians: number): void {\n this._rotation = radians;\n this._markDirty();\n }\n\n /** Rotate by a delta in radians. */\n rotate(deltaRadians: number): void {\n this._rotation += deltaRadians;\n this._markDirty();\n }\n\n /** Set scale. */\n setScale(x: number, y: number): void {\n this._scale = new Vec2(x, y);\n this._markDirty();\n }\n\n /**\n * Mark this transform and all descendant transforms as dirty.\n * @internal\n */\n _markDirty(): void {\n if (this._dirty) return;\n this._dirty = true;\n for (const child of this.entity?.children.values() ?? []) {\n child.tryGet(Transform)?._markDirty();\n }\n }\n\n private _recompute(): void {\n this._dirty = false;\n const pt = this.entity?.parent?.tryGet(Transform);\n if (!pt) {\n // Root or no parent: world = local\n this._worldPosition = this._position;\n this._worldRotation = this._rotation;\n this._worldScale = this._scale;\n return;\n }\n // Compose with parent world (triggers parent recompute if needed)\n const rotatedLocal = this._position\n .multiply(pt.worldScale)\n .rotate(pt.worldRotation);\n this._worldPosition = pt.worldPosition.add(rotatedLocal);\n this._worldRotation = pt.worldRotation + this._rotation;\n this._worldScale = pt.worldScale.multiply(this._scale);\n }\n\n // ---- Save/load support ----\n\n serialize(): TransformData {\n return {\n position: { x: this._position.x, y: this._position.y },\n rotation: this._rotation,\n scale: { x: this._scale.x, y: this._scale.y },\n };\n }\n\n static fromSnapshot(data: TransformData): Transform {\n return new Transform({\n position: { x: data.position.x, y: data.position.y },\n rotation: data.rotation,\n scale: { x: data.scale.x, y: data.scale.y },\n });\n }\n}\n","import type { Component } from \"./Component.js\";\nimport type { ComponentClass } from \"./types.js\";\nimport type { EventToken } from \"./EventToken.js\";\nimport type { SnapshotResolver } from \"./Serializable.js\";\nimport { TRAITS_KEY, type TraitToken } from \"./Trait.js\";\nimport { Transform } from \"./Transform.js\";\n\n/** Auto-incrementing entity ID counter. */\nlet nextEntityId = 1;\n\n/** Shared empty map returned by `children` when no children exist. */\nconst EMPTY_CHILDREN: ReadonlyMap<string, Entity> = new Map();\n\n/** Reset the entity ID counter. Exposed for testing only. */\nexport function _resetEntityIdCounter(): void {\n nextEntityId = 1;\n}\n\n/**\n * Callback interface for notifying external systems (QueryCache, EventBus)\n * about entity component changes. Injected by Scene.\n */\nexport interface EntityCallbacks {\n onComponentAdded(entity: Entity, componentClass: ComponentClass): void;\n onComponentRemoved(entity: Entity, componentClass: ComponentClass): void;\n}\n\n/**\n * An entity is a named container of components with O(1) lookups by type.\n */\nexport class Entity {\n static [TRAITS_KEY]: Set<symbol> = new Set();\n /** Unique auto-incrementing ID. */\n readonly id: number;\n /** Display name for debugging. */\n readonly name: string;\n /** Tags for group queries. */\n readonly tags: Set<string>;\n\n private components = new Map<ComponentClass, Component>();\n private _destroyed = false;\n private _scene: import(\"./Scene.js\").Scene | null = null;\n private callbacks: EntityCallbacks | null = null;\n private _eventHandlers?: Map<string, Set<(data: never) => void>>;\n private _parent: Entity | null = null;\n private _children: Map<string, Entity> | null = null;\n\n constructor(name?: string, tags?: Iterable<string>) {\n this.id = nextEntityId++;\n this.name = name ?? new.target.name ?? \"Entity\";\n this.tags = new Set(tags);\n }\n\n /** The scene this entity belongs to, or null. */\n get scene(): import(\"./Scene.js\").Scene | null {\n return this._scene;\n }\n\n /** True if destroy() has been called. */\n get isDestroyed(): boolean {\n return this._destroyed;\n }\n\n /** The parent entity, or null if this is a root entity. */\n get parent(): Entity | null {\n return this._parent;\n }\n\n /** Named children as a read-only map. Empty map if no children. */\n get children(): ReadonlyMap<string, Entity> {\n return this._children ?? EMPTY_CHILDREN;\n }\n\n /** Add a named child entity. Auto-adds to parent's scene if not already in one. */\n addChild(name: string, child: Entity): void {\n if (child === this) {\n throw new Error(`Entity \"${this.name}\" cannot be a child of itself.`);\n }\n if (child._parent) {\n throw new Error(\n `Entity \"${child.name}\" already has a parent (\"${child._parent.name}\"). Remove it first.`,\n );\n }\n this._children ??= new Map();\n if (this._children.has(name)) {\n throw new Error(\n `Entity \"${this.name}\" already has a child named \"${name}\".`,\n );\n }\n child._parent = this;\n this._children.set(name, child);\n\n // Mark child transform dirty so world values recompute with new parent\n child.tryGet(Transform)?._markDirty();\n\n // Auto-add to parent's scene\n if (this._scene && !child._scene) {\n this._scene._addExistingEntity(child);\n }\n }\n\n /** Remove a named child. Returns the detached entity. */\n removeChild(name: string): Entity {\n const child = this._children?.get(name);\n if (!child) {\n throw new Error(`Entity \"${this.name}\" has no child named \"${name}\".`);\n }\n child._parent = null;\n this._children!.delete(name);\n\n // Mark child transform dirty so world values recompute without parent\n child.tryGet(Transform)?._markDirty();\n\n return child;\n }\n\n /** Get a child by name. Throws if not found. */\n getChild(name: string): Entity {\n const child = this._children?.get(name);\n if (!child) {\n throw new Error(`Entity \"${this.name}\" has no child named \"${name}\".`);\n }\n return child;\n }\n\n /** Get a child by name, or undefined if not found. */\n tryGetChild(name: string): Entity | undefined {\n return this._children?.get(name);\n }\n\n /** Add a component instance. Returns the component for chaining. */\n add<C extends Component>(component: C): C {\n const cls = component.constructor as ComponentClass;\n if (this.components.has(cls)) {\n throw new Error(\n `Entity \"${this.name}\" already has component ${cls.name}.`,\n );\n }\n component.entity = this;\n this.components.set(cls, component);\n component.onAdd?.();\n this.callbacks?.onComponentAdded(this, cls);\n return component;\n }\n\n /** Get a component by class. Throws if not found. */\n get<C extends Component>(cls: ComponentClass<C>): C {\n const comp = this.components.get(cls);\n if (!comp) {\n throw new Error(\n `Entity \"${this.name}\" does not have component ${cls.name}.`,\n );\n }\n return comp as C;\n }\n\n /** Get a component by class, or undefined if not found. */\n tryGet<C extends Component>(cls: ComponentClass<C>): C | undefined {\n return this.components.get(cls) as C | undefined;\n }\n\n /** Check if entity has a component of the given class. */\n has(cls: ComponentClass): boolean {\n return this.components.has(cls);\n }\n\n /** Remove a component by class. */\n remove(cls: ComponentClass): void {\n const comp = this.components.get(cls);\n if (!comp) return;\n comp._runCleanups();\n comp.onRemove?.();\n comp.onDestroy?.();\n this.components.delete(cls);\n this.callbacks?.onComponentRemoved(this, cls);\n }\n\n /** Subscribe to a typed event on this entity. Returns an unsubscribe function. */\n on<T>(token: EventToken<T>, handler: (data: T) => void): () => void {\n this._eventHandlers ??= new Map();\n let handlers = this._eventHandlers.get(token.name);\n if (!handlers) {\n handlers = new Set();\n this._eventHandlers.set(token.name, handlers);\n }\n handlers.add(handler as (data: never) => void);\n\n return () => {\n handlers.delete(handler as (data: never) => void);\n };\n }\n\n /** Emit a typed event on this entity. Bubbles to the scene. */\n emit(token: EventToken<void>): void;\n emit<T>(token: EventToken<T>, data: T): void;\n emit<T>(token: EventToken<T>, data?: T): void {\n if (this._destroyed) return;\n\n const handlers = this._eventHandlers?.get(token.name);\n if (handlers) {\n // Snapshot for safe unsubscribe during iteration\n for (const handler of [...handlers]) {\n handler(data as never);\n }\n }\n\n this._scene?._onEntityEvent(token.name, data, this);\n }\n\n /** Get all components as an iterable. */\n getAll(): Iterable<Component> {\n return this.components.values();\n }\n\n /** Mark for deferred destruction. Actual cleanup happens at end of frame. */\n destroy(): void {\n if (this._destroyed) return;\n this._destroyed = true;\n\n // Cascade to children\n if (this._children) {\n for (const child of this._children.values()) {\n child.destroy();\n }\n }\n\n this._scene?._queueDestroy(this);\n }\n\n /**\n * Internal: perform actual destruction — remove all components and clear state.\n * Called by Scene during endOfFrame flush.\n * @internal\n */\n _performDestroy(): void {\n // Detach from parent\n if (this._parent?._children) {\n for (const [name, child] of this._parent._children) {\n if (child === this) {\n this._parent._children.delete(name);\n break;\n }\n }\n }\n this._parent = null;\n\n // Clear own children references (they are destroyed separately via cascade)\n this._children?.clear();\n\n for (const [cls, comp] of this.components) {\n comp._runCleanups();\n comp.onRemove?.();\n comp.onDestroy?.();\n this.callbacks?.onComponentRemoved(this, cls);\n }\n this.components.clear();\n this._eventHandlers?.clear();\n }\n\n /**\n * Optional setup method. Called by `scene.spawn(Class, params)` after the\n * entity is wired to its scene, so components can access services.\n * Override in subclasses — do NOT use the constructor for component setup.\n */\n setup?(params: unknown): void;\n\n /** Return a JSON-serializable snapshot of this entity's custom state. Used by the save system. */\n serialize?(): unknown;\n\n /** Called after components are restored during save/load. Rebuild non-serializable state here. */\n afterRestore?(data: unknown, resolve: SnapshotResolver): void;\n\n /** Check if this entity's class implements a given trait. Acts as a type guard. */\n hasTrait<T>(token: TraitToken<T>): this is this & T {\n // Walk the constructor chain so plain subclasses inherit parent traits\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ctor: any = this.constructor;\n while (ctor) {\n const traits = ctor[TRAITS_KEY] as Set<symbol> | undefined;\n if (traits?.has(token.symbol)) return true;\n ctor = Object.getPrototypeOf(ctor);\n }\n return false;\n }\n\n /**\n * Internal: set the scene and callbacks. Called by Scene.spawn().\n * @internal\n */\n _setScene(\n scene: import(\"./Scene.js\").Scene | null,\n callbacks: EntityCallbacks | null,\n ): void {\n this._scene = scene;\n this.callbacks = callbacks;\n }\n}\n","import type { Entity } from \"./Entity.js\";\nimport type { ComponentClass } from \"./types.js\";\n\n/** A filter used to register a query — an array of required component classes. */\nexport type QueryFilter = readonly ComponentClass[];\n\n/** A live, iterable set of entities matching a query filter. */\nexport class QueryResult {\n /** @internal */\n readonly _entities = new Set<Entity>();\n /** @internal */\n readonly _filter: QueryFilter;\n\n /** @internal */\n constructor(filter: QueryFilter) {\n this._filter = filter;\n }\n\n /** Iterate matching entities. */\n [Symbol.iterator](): Iterator<Entity> {\n return this._entities[Symbol.iterator]();\n }\n\n /** Number of matching entities. */\n get size(): number {\n return this._entities.size;\n }\n\n /** Get the first match (useful for singleton queries). */\n get first(): Entity | undefined {\n for (const e of this._entities) return e;\n return undefined;\n }\n\n /** Convert to array (allocates). */\n toArray(): Entity[] {\n return [...this._entities];\n }\n}\n\n/** Incrementally maintained entity sets based on component signatures. */\nexport class QueryCache {\n private queries: QueryResult[] = [];\n\n /** Register a query. Returns a stable reference to a live result set. */\n register(filter: QueryFilter): QueryResult {\n const result = new QueryResult(filter);\n this.queries.push(result);\n return result;\n }\n\n /** Called by Entity when a component is added. */\n onComponentAdded(entity: Entity): void {\n for (const q of this.queries) {\n if (this.matches(entity, q._filter)) {\n q._entities.add(entity);\n }\n }\n }\n\n /** Called by Entity when a component is removed. */\n onComponentRemoved(entity: Entity): void {\n for (const q of this.queries) {\n if (!this.matches(entity, q._filter)) {\n q._entities.delete(entity);\n }\n }\n }\n\n /** Called when an entity is destroyed. */\n onEntityDestroyed(entity: Entity): void {\n for (const q of this.queries) {\n q._entities.delete(entity);\n }\n }\n\n private matches(entity: Entity, filter: QueryFilter): boolean {\n for (const cls of filter) {\n if (!entity.has(cls)) return false;\n }\n return true;\n }\n}\n","import type { EngineContext, ServiceKey } from \"./EngineContext.js\";\nimport type { Phase } from \"./types.js\";\n\n/**\n * Base class for systems. Systems run in a specific game loop phase,\n * query for entities matching a component signature, and operate on them.\n *\n * Systems are primarily for engine plugins (physics, rendering, audio).\n * Game developers typically write Components instead.\n */\nexport abstract class System {\n /** The phase this system runs in. */\n abstract readonly phase: Phase;\n\n /** Execution priority within the phase. Lower = earlier. Default: 0. */\n readonly priority: number = 0;\n\n /** Whether this system is active. */\n enabled = true;\n\n /** Reference to the engine context, set on registration. */\n protected context!: EngineContext;\n\n private _serviceCache: Map<string, unknown> | undefined;\n\n /**\n * Set the engine context. Called by Engine during startup.\n * @internal\n */\n _setContext(context: EngineContext): void {\n this.context = context;\n }\n\n /** Resolve a service by key, cached after first lookup. */\n protected use<T>(key: ServiceKey<T>): T {\n this._serviceCache ??= new Map();\n let value = this._serviceCache.get(key.id);\n if (value === undefined) {\n value = this.context.resolve(key);\n this._serviceCache.set(key.id, value);\n }\n return value as T;\n }\n\n /** Called once when the system is registered with the engine. */\n onRegister?(context: EngineContext): void;\n\n /** Called every frame (or every fixed step for FixedUpdate). */\n abstract update(dt: number): void;\n\n /** Called when the system is removed. */\n onUnregister?(): void;\n}\n","import type { System } from \"./System.js\";\nimport type { ErrorBoundary } from \"./ErrorBoundary.js\";\nimport type { Phase } from \"./types.js\";\n\n/** Manages ordered execution of systems within each phase. */\nexport class SystemScheduler {\n private phases = new Map<Phase, System[]>();\n private errorBoundary: ErrorBoundary | null = null;\n\n /** Set the error boundary for wrapping system execution. */\n setErrorBoundary(boundary: ErrorBoundary): void {\n this.errorBoundary = boundary;\n }\n\n /** Register a system. Sorted by priority within its phase. */\n add(system: System): void {\n let list = this.phases.get(system.phase);\n if (!list) {\n list = [];\n this.phases.set(system.phase, list);\n }\n list.push(system);\n list.sort((a, b) => a.priority - b.priority);\n }\n\n /** Remove a system. */\n remove(system: System): void {\n const list = this.phases.get(system.phase);\n if (!list) return;\n const idx = list.indexOf(system);\n if (idx !== -1) list.splice(idx, 1);\n }\n\n /** Run all enabled systems in a given phase. Wraps each in ErrorBoundary if available. */\n run(phase: Phase, dt: number): void {\n const list = this.phases.get(phase);\n if (!list) return;\n for (const system of list) {\n if (!system.enabled) continue;\n if (this.errorBoundary) {\n this.errorBoundary.wrapSystem(system, () => system.update(dt));\n } else {\n system.update(dt);\n }\n }\n }\n\n /** Get all systems registered for a phase. */\n getSystems(phase: Phase): readonly System[] {\n return this.phases.get(phase) ?? [];\n }\n\n /** Get all systems across all phases. */\n getAllSystems(): System[] {\n const all: System[] = [];\n for (const list of this.phases.values()) {\n all.push(...list);\n }\n return all;\n }\n}\n","import { System } from \"./System.js\";\nimport { Phase } from \"./types.js\";\nimport type { EngineContext } from \"./EngineContext.js\";\nimport type { ErrorBoundary } from \"./ErrorBoundary.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport { SceneManagerKey, ErrorBoundaryKey } from \"./EngineContext.js\";\n\n/**\n * Built-in system that bridges the OOP and ECS worlds.\n *\n * Iterates all entities in non-paused scenes and calls component\n * `update(dt)` or `fixedUpdate(dt)` methods on enabled components.\n *\n * This system runs at two phases:\n * - Phase.FixedUpdate for fixedUpdate(dt)\n * - Phase.Update for update(dt)\n *\n * We actually register two separate instances — one per phase — since\n * a System can only belong to one phase.\n */\nabstract class BaseComponentUpdateSystem extends System {\n /** High priority so game logic runs after engine systems like physics. */\n override readonly priority = 1000;\n\n protected sceneManager!: SceneManager;\n protected errorBoundary!: ErrorBoundary;\n\n override onRegister(context: EngineContext): void {\n this.sceneManager = context.resolve(SceneManagerKey);\n this.errorBoundary = context.resolve(ErrorBoundaryKey);\n }\n}\n\n/** Calls `fixedUpdate(dt)` on all enabled components in non-paused scenes. */\nexport class ComponentFixedUpdateSystem extends BaseComponentUpdateSystem {\n override readonly phase = Phase.FixedUpdate;\n\n update(dt: number): void {\n for (const scene of this.sceneManager.activeScenes) {\n const sceneDt = dt * scene.timeScale;\n for (const entity of scene.getEntities()) {\n if (entity.isDestroyed) continue;\n for (const component of entity.getAll()) {\n if (!component.enabled || !component.fixedUpdate) continue;\n const fixedUpdate = component.fixedUpdate;\n this.errorBoundary.wrapComponent(component, () =>\n fixedUpdate.call(component, sceneDt),\n );\n }\n }\n }\n }\n}\n\n/** Calls `update(dt)` on all enabled components in non-paused scenes. */\nexport class ComponentUpdateSystem extends BaseComponentUpdateSystem {\n override readonly phase = Phase.Update;\n\n update(dt: number): void {\n for (const scene of this.sceneManager.activeScenes) {\n const sceneDt = dt * scene.timeScale;\n for (const entity of scene.getEntities()) {\n if (entity.isDestroyed) continue;\n for (const component of entity.getAll()) {\n if (!component.enabled || !component.update) continue;\n const update = component.update;\n this.errorBoundary.wrapComponent(component, () =>\n update.call(component, sceneDt),\n );\n }\n }\n }\n }\n}\n","import type { System } from \"./System.js\";\nimport type { Component } from \"./Component.js\";\nimport type { Logger } from \"./Logger.js\";\n\n/**\n * Wraps system and component execution. On error, disables the offending\n * system/component and logs the error. The game loop never crashes.\n */\nexport class ErrorBoundary {\n private logger: Logger;\n private disabledSystems: Array<{ system: System; error: string }> = [];\n private disabledComponents: Array<{ component: Component; error: string }> = [];\n\n constructor(logger: Logger) {\n this.logger = logger;\n }\n\n /** Wrap a system update call. On throw, disables the system. */\n wrapSystem(system: System, fn: () => void): void {\n try {\n fn();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n system.enabled = false;\n this.disabledSystems.push({ system, error: message });\n this.logger.error(\n \"core\",\n `System ${system.constructor.name} threw and was disabled`,\n { error: message },\n );\n }\n }\n\n /** Wrap a component lifecycle or update call. On throw, disables the component. */\n wrapComponent(component: Component, fn: () => void): void {\n try {\n fn();\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n component.enabled = false;\n this.disabledComponents.push({ component, error: message });\n const entityName = component.entity?.name ?? \"unknown\";\n this.logger.error(\n \"core\",\n `Component ${component.constructor.name} on entity \"${entityName}\" threw and was disabled`,\n { error: message },\n );\n }\n }\n\n /** Get all disabled systems and components for inspection. */\n getDisabled(): {\n systems: ReadonlyArray<{ system: System; error: string }>;\n components: ReadonlyArray<{ component: Component; error: string }>;\n } {\n return {\n systems: this.disabledSystems,\n components: this.disabledComponents,\n };\n }\n}\n","/** Callbacks invoked by the game loop each frame. */\nexport interface GameLoopCallbacks {\n earlyUpdate(dt: number): void;\n fixedUpdate(fixedDt: number): void;\n update(dt: number): void;\n lateUpdate(dt: number): void;\n render(dt: number): void;\n endOfFrame(dt: number): void;\n}\n\n/** Configuration for the game loop. */\nexport interface GameLoopConfig {\n /** Fixed timestep in ms. Default: 1000/60. */\n fixedTimestep?: number;\n /** Max fixed steps per frame to prevent spiral of death. Default: 5. */\n maxFixedStepsPerFrame?: number;\n}\n\n/**\n * Game loop with fixed timestep accumulator.\n *\n * Driven by an external ticker (e.g., PixiJS Ticker) or manual `tick()` calls\n * for testing. Implements deterministic fixed updates with variable rendering.\n */\nexport class GameLoop {\n /** Fixed timestep in ms. */\n readonly fixedTimestep: number;\n /** Max fixed steps per frame. */\n readonly maxFixedStepsPerFrame: number;\n\n private accumulator = 0;\n private running = false;\n private callbacks: GameLoopCallbacks | null = null;\n private tickerUnsubscribe: (() => void) | null = null;\n private rafId: number | null = null;\n private lastTime = 0;\n private _frameCount = 0;\n\n constructor(config?: GameLoopConfig) {\n this.fixedTimestep = config?.fixedTimestep ?? 1000 / 60;\n this.maxFixedStepsPerFrame = config?.maxFixedStepsPerFrame ?? 5;\n }\n\n /** Current frame count. */\n get frameCount(): number {\n return this._frameCount;\n }\n\n /** Whether the loop is running. */\n get isRunning(): boolean {\n return this.running;\n }\n\n /** Ratio of accumulated time to fixed timestep, for physics interpolation. */\n get interpolationAlpha(): number {\n return this.accumulator / this.fixedTimestep;\n }\n\n /** Provide the callbacks that the loop invokes each frame. */\n setCallbacks(callbacks: GameLoopCallbacks): void {\n this.callbacks = callbacks;\n }\n\n /**\n * Attach an external ticker (e.g., PixiJS Ticker).\n * The ticker calls `tick(dt)` every frame.\n * If no ticker is attached, the loop uses requestAnimationFrame.\n */\n attachTicker(\n subscribe: (callback: (dt: number) => void) => () => void,\n ): void {\n this.tickerUnsubscribe = subscribe((dt) => this.tick(dt));\n }\n\n /** Start the loop. */\n start(): void {\n if (this.running) return;\n this.running = true;\n this._frameCount = 0;\n this.accumulator = 0;\n\n // If no external ticker, use rAF (only in browser environments)\n if (!this.tickerUnsubscribe && typeof requestAnimationFrame !== \"undefined\") {\n this.lastTime = performance.now();\n const loop = (now: number) => {\n if (!this.running) return;\n const dt = now - this.lastTime;\n this.lastTime = now;\n this.tick(dt);\n this.rafId = requestAnimationFrame(loop);\n };\n this.rafId = requestAnimationFrame(loop);\n }\n }\n\n /** Stop the loop. */\n stop(): void {\n this.running = false;\n if (this.rafId !== null && typeof cancelAnimationFrame !== \"undefined\") {\n cancelAnimationFrame(this.rafId);\n this.rafId = null;\n }\n if (this.tickerUnsubscribe) {\n this.tickerUnsubscribe();\n this.tickerUnsubscribe = null;\n }\n }\n\n /** Process one frame with the given dt in milliseconds. */\n tick(dtMs: number): void {\n if (!this.callbacks) return;\n\n this._frameCount++;\n\n // 1. Early Update\n this.callbacks.earlyUpdate(dtMs);\n\n // 2. Fixed Update (accumulator-based)\n this.accumulator += dtMs;\n let steps = 0;\n while (\n this.accumulator >= this.fixedTimestep &&\n steps < this.maxFixedStepsPerFrame\n ) {\n this.callbacks.fixedUpdate(this.fixedTimestep);\n this.accumulator -= this.fixedTimestep;\n steps++;\n }\n\n // 3. Update\n this.callbacks.update(dtMs);\n\n // 4. Late Update\n this.callbacks.lateUpdate(dtMs);\n\n // 5. Render\n this.callbacks.render(dtMs);\n\n // 6. End of Frame\n this.callbacks.endOfFrame(dtMs);\n }\n}\n","import { Entity } from \"./Entity.js\";\nimport type { EntityCallbacks } from \"./Entity.js\";\nimport type { EngineContext } from \"./EngineContext.js\";\nimport type { QueryCache } from \"./QueryCache.js\";\nimport type { EventBus, EngineEvents } from \"./EventBus.js\";\nimport type { Blueprint } from \"./Blueprint.js\";\nimport type { EventToken } from \"./EventToken.js\";\nimport type { AssetHandle } from \"./AssetHandle.js\";\nimport type { AssetManager } from \"./AssetManager.js\";\nimport type { ServiceKey } from \"./EngineContext.js\";\nimport type { SnapshotResolver } from \"./Serializable.js\";\nimport { filterEntities } from \"./EntityFilter.js\";\nimport type { EntityFilter } from \"./EntityFilter.js\";\nimport type { TraitToken } from \"./Trait.js\";\nimport {\n QueryCacheKey,\n EventBusKey,\n AssetManagerKey,\n SceneManagerKey,\n} from \"./EngineContext.js\";\n\n/**\n * Scenes own entities and define lifecycle hooks.\n * Each scene is a self-contained world with its own entity pool.\n */\nexport abstract class Scene {\n /** Name for debugging/inspection. */\n abstract readonly name: string;\n\n /** Whether scenes below this one in the stack should be paused. Default: true. */\n readonly pauseBelow: boolean = true;\n\n /** Whether scenes below this one should still render. Default: false. */\n readonly transparentBelow: boolean = false;\n\n /** Asset handles to load before onEnter(). Override in subclasses. */\n readonly preload?: readonly AssetHandle<unknown>[];\n\n /** Manual pause flag. Set by game code to pause this scene regardless of stack position. */\n paused = false;\n\n /** Time scale multiplier for this scene. 1.0 = normal, 0.5 = half speed. Default: 1. */\n timeScale = 1;\n\n private entities = new Set<Entity>();\n private destroyQueue: Entity[] = [];\n private _context!: EngineContext;\n private entityCallbacks!: EntityCallbacks;\n private queryCache: QueryCache | undefined;\n private bus: EventBus<EngineEvents> | undefined;\n private _entityEventHandlers?: Map<\n string,\n Set<(data: never, entity: Entity) => void>\n >;\n\n /** Access the EngineContext. */\n get context(): EngineContext {\n return this._context;\n }\n\n /** Whether this scene is effectively paused (manual pause or paused by stack). */\n get isPaused(): boolean {\n if (this.paused) return true;\n const sm = this._context?.tryResolve(SceneManagerKey);\n if (!sm) return false;\n const stack = sm.all;\n const idx = stack.indexOf(this);\n if (idx === -1) return false;\n for (let i = idx + 1; i < stack.length; i++) {\n if (stack[i]!.pauseBelow) return true;\n }\n return false;\n }\n\n /** Convenience accessor for the AssetManager. */\n get assets(): AssetManager {\n return this._context.resolve(AssetManagerKey);\n }\n\n /**\n * Lazy proxy-based service resolution. Can be used at field-declaration time:\n * ```ts\n * readonly layers = this.service(RenderLayerManagerKey);\n * ```\n * The actual resolution is deferred until first property access.\n */\n protected service<T extends object>(key: ServiceKey<T>): T {\n let resolved: T | undefined;\n return new Proxy({} as object, {\n get: (_target, prop) => {\n resolved ??= this._context.resolve(key);\n const value = (resolved as Record<string | symbol, unknown>)[prop];\n return typeof value === \"function\"\n ? (value as (...args: unknown[]) => unknown).bind(resolved)\n : value;\n },\n set: (_target, prop, value) => {\n resolved ??= this._context.resolve(key);\n (resolved as Record<string | symbol, unknown>)[prop] = value;\n return true;\n },\n }) as T;\n }\n\n /** Spawn a new entity in this scene. */\n spawn(name?: string): Entity;\n spawn<P>(blueprint: Blueprint<P>, params: P): Entity;\n spawn(blueprint: Blueprint<void>): Entity;\n /** Spawn an entity subclass with setup params. */\n spawn<E extends Entity, P>(\n Class: new () => E & { setup(params: P): void },\n params: P,\n ): E;\n /** Spawn an entity subclass without setup params. */\n spawn<E extends Entity>(Class: new () => E): E;\n spawn(\n nameOrBlueprintOrClass?: string | Blueprint<unknown> | (new () => Entity),\n params?: unknown,\n ): Entity {\n // Class-based spawn: argument is a constructor function for an Entity subclass\n if (typeof nameOrBlueprintOrClass === \"function\") {\n const entity = new nameOrBlueprintOrClass();\n entity._setScene(this, this.entityCallbacks);\n this.entities.add(entity);\n this.bus?.emit(\"entity:created\", { entity });\n entity.setup?.(params);\n return entity;\n }\n\n const isBlueprint =\n typeof nameOrBlueprintOrClass === \"object\" &&\n nameOrBlueprintOrClass !== null &&\n \"build\" in nameOrBlueprintOrClass;\n\n const name = isBlueprint\n ? (nameOrBlueprintOrClass as Blueprint<unknown>).name\n : (nameOrBlueprintOrClass as string | undefined);\n\n const entity = new Entity(name);\n entity._setScene(this, this.entityCallbacks);\n this.entities.add(entity);\n this.bus?.emit(\"entity:created\", { entity });\n\n if (isBlueprint) {\n (nameOrBlueprintOrClass as Blueprint<unknown>).build(entity, params);\n }\n\n return entity;\n }\n\n /**\n * Add an existing entity to this scene (used by Entity.addChild for auto-scene-membership).\n * @internal\n */\n _addExistingEntity(entity: Entity): void {\n entity._setScene(this, this.entityCallbacks);\n this.entities.add(entity);\n this.bus?.emit(\"entity:created\", { entity });\n\n // Register pre-existing components with QueryCache\n if (!entity.getAll()[Symbol.iterator]().next().done) {\n this.queryCache?.onComponentAdded(entity);\n }\n }\n\n /** Mark an entity for destruction. Deferred to endOfFrame flush. */\n destroyEntity(entity: Entity): void {\n entity.destroy();\n }\n\n /**\n * Add an entity to the destroy queue. Called by Entity.destroy().\n * @internal\n */\n _queueDestroy(entity: Entity): void {\n this.destroyQueue.push(entity);\n }\n\n /** Get all active entities. */\n getEntities(): ReadonlySet<Entity> {\n return this.entities;\n }\n\n /** Find entity by name (first match). */\n findEntity(name: string): Entity | undefined {\n for (const e of this.entities) {\n if (e.name === name && !e.isDestroyed) return e;\n }\n return undefined;\n }\n\n /** Find entities by tag. */\n findEntitiesByTag(tag: string): Entity[] {\n const result: Entity[] = [];\n for (const e of this.entities) {\n if (e.tags.has(tag) && !e.isDestroyed) result.push(e);\n }\n return result;\n }\n\n /** Find entities matching a filter. Trait filter narrows the return type. */\n findEntities<T>(filter: EntityFilter & { trait: TraitToken<T> }): (Entity & T)[];\n findEntities(filter?: EntityFilter): Entity[];\n findEntities(filter?: EntityFilter): Entity[] {\n if (!filter) {\n const result: Entity[] = [];\n for (const e of this.entities) {\n if (!e.isDestroyed) result.push(e);\n }\n return result;\n }\n return filterEntities(this.entities, filter);\n }\n\n /** Subscribe to bubbled entity events at the scene level. Handler receives (data, emittingEntity). */\n on<T>(\n token: EventToken<T>,\n handler: (data: T, entity: Entity) => void,\n ): () => void {\n this._entityEventHandlers ??= new Map();\n let handlers = this._entityEventHandlers.get(token.name);\n if (!handlers) {\n handlers = new Set();\n this._entityEventHandlers.set(token.name, handlers);\n }\n handlers.add(handler as (data: never, entity: Entity) => void);\n\n return () => {\n handlers.delete(handler as (data: never, entity: Entity) => void);\n };\n }\n\n /**\n * Called by Entity.emit() for bubbling entity events to the scene.\n * @internal\n */\n _onEntityEvent(eventName: string, data: unknown, entity: Entity): void {\n const handlers = this._entityEventHandlers?.get(eventName);\n if (handlers) {\n for (const handler of [...handlers]) {\n (handler as (data: unknown, entity: Entity) => void)(data, entity);\n }\n }\n }\n\n // ---- Lifecycle hooks (override in subclasses) ----\n\n /** Called during asset preloading with progress ratio (0→1). */\n onProgress?(ratio: number): void;\n\n /** Called when the scene is entered (after preload completes). */\n onEnter?(): void;\n\n /** Called when the scene is exited (popped or replaced). */\n onExit?(): void;\n\n /** Called when a scene is pushed on top of this one. */\n onPause?(): void;\n\n /** Called when the scene above is popped, restoring this scene. */\n onResume?(): void;\n\n /** Return a JSON-serializable snapshot of this scene's custom state. Used by the save system. */\n serialize?(): unknown;\n\n /** Called after entities are restored during save/load. Rebuild non-serializable state here. */\n afterRestore?(data: unknown, resolve: SnapshotResolver): void;\n\n // ---- Internal methods ----\n\n /**\n * Set the engine context. Called by SceneManager when the scene is pushed.\n * @internal\n */\n _setContext(context: EngineContext): void {\n this._context = context;\n this.queryCache = context.tryResolve(QueryCacheKey) as\n | QueryCache\n | undefined;\n this.bus = context.tryResolve(EventBusKey) as\n | EventBus<EngineEvents>\n | undefined;\n\n this.entityCallbacks = {\n onComponentAdded: (entity, cls) => {\n this.queryCache?.onComponentAdded(entity);\n this.bus?.emit(\"component:added\", {\n entity,\n component: entity.get(cls),\n });\n },\n onComponentRemoved: (entity, cls) => {\n this.queryCache?.onComponentRemoved(entity);\n this.bus?.emit(\"component:removed\", { entity, componentClass: cls });\n },\n };\n }\n\n /**\n * Flush the destroy queue — destroy pending entities.\n * Called by the engine during the endOfFrame phase.\n * @internal\n */\n _flushDestroyQueue(): void {\n for (const entity of this.destroyQueue) {\n entity._performDestroy();\n this.queryCache?.onEntityDestroyed(entity);\n this.entities.delete(entity);\n this.bus?.emit(\"entity:destroyed\", { entity });\n }\n this.destroyQueue.length = 0;\n }\n\n /**\n * Destroy all entities — used during scene exit.\n * @internal\n */\n _destroyAllEntities(): void {\n for (const entity of this.entities) {\n entity._performDestroy();\n this.queryCache?.onEntityDestroyed(entity);\n }\n this.entities.clear();\n this.destroyQueue.length = 0;\n this._entityEventHandlers?.clear();\n }\n}\n","import type { Scene } from \"./Scene.js\";\nimport type { EngineContext } from \"./EngineContext.js\";\nimport type { EventBus, EngineEvents } from \"./EventBus.js\";\nimport type { AssetManager } from \"./AssetManager.js\";\nimport { EventBusKey, AssetManagerKey } from \"./EngineContext.js\";\n\n/** Stack-based scene manager with push/pop/replace semantics. */\nexport class SceneManager {\n private stack: Scene[] = [];\n private _context!: EngineContext;\n private bus: EventBus<EngineEvents> | undefined;\n private assetManager: AssetManager | undefined;\n\n /**\n * Set the engine context.\n * @internal\n */\n _setContext(context: EngineContext): void {\n this._context = context;\n this.bus = context.tryResolve(EventBusKey) as\n | EventBus<EngineEvents>\n | undefined;\n this.assetManager = context.tryResolve(AssetManagerKey);\n }\n\n /** The topmost (active) scene. */\n get active(): Scene | undefined {\n return this.stack[this.stack.length - 1];\n }\n\n /** All scenes in the stack, bottom to top. */\n get all(): readonly Scene[] {\n return this.stack;\n }\n\n /** All non-paused scenes in the stack, bottom to top. */\n get activeScenes(): readonly Scene[] {\n return this.stack.filter((s) => !s.isPaused);\n }\n\n /**\n * Push a scene onto the stack. Scenes below may receive onPause().\n * If the scene declares a `preload` array, assets are loaded before onEnter().\n * Await the returned promise when using preloaded scenes.\n */\n push(scene: Scene): Promise<void> {\n // Snapshot isPaused state before push\n const wasPaused = new Map(this.stack.map((s) => [s, s.isPaused]));\n\n scene._setContext(this._context);\n this.stack.push(scene);\n\n // Fire onPause for scenes that transitioned to paused\n this._firePauseTransitions(wasPaused);\n\n if (scene.preload?.length && this.assetManager) {\n return this.assetManager\n .loadAll(scene.preload, scene.onProgress?.bind(scene))\n .then(() => {\n scene.onEnter?.();\n this.bus?.emit(\"scene:pushed\", { scene });\n });\n }\n\n scene.onEnter?.();\n this.bus?.emit(\"scene:pushed\", { scene });\n return Promise.resolve();\n }\n\n /** Pop the top scene. Scenes below may receive onResume(). */\n pop(): Scene | undefined {\n // Snapshot isPaused state before pop\n const wasPaused = new Map(this.stack.map((s) => [s, s.isPaused]));\n\n const removed = this.stack.pop();\n if (!removed) return undefined;\n\n removed.onExit?.();\n removed._destroyAllEntities();\n\n // Fire onResume for scenes that transitioned from paused to active\n this._fireResumeTransitions(wasPaused);\n\n this.bus?.emit(\"scene:popped\", { scene: removed });\n\n return removed;\n }\n\n /**\n * Replace the top scene. Old scene receives onExit().\n * New scene receives onEnter() (after preload, if declared).\n */\n replace(scene: Scene): Promise<void> {\n // Snapshot before\n const wasPaused = new Map(this.stack.map((s) => [s, s.isPaused]));\n\n const old = this.stack.pop();\n if (old) {\n old.onExit?.();\n old._destroyAllEntities();\n }\n\n scene._setContext(this._context);\n this.stack.push(scene);\n\n // Fire transitions for the replace (both directions possible)\n this._firePauseTransitions(wasPaused);\n this._fireResumeTransitions(wasPaused);\n\n if (scene.preload?.length && this.assetManager) {\n return this.assetManager\n .loadAll(scene.preload, scene.onProgress?.bind(scene))\n .then(() => {\n scene.onEnter?.();\n if (old) {\n this.bus?.emit(\"scene:replaced\", {\n oldScene: old,\n newScene: scene,\n });\n } else {\n this.bus?.emit(\"scene:pushed\", { scene });\n }\n });\n }\n\n scene.onEnter?.();\n if (old) {\n this.bus?.emit(\"scene:replaced\", { oldScene: old, newScene: scene });\n } else {\n this.bus?.emit(\"scene:pushed\", { scene });\n }\n return Promise.resolve();\n }\n\n /** Clear all scenes. Each receives onExit() from top to bottom. */\n clear(): void {\n while (this.stack.length > 0) {\n const scene = this.stack.pop();\n if (!scene) break;\n scene.onExit?.();\n scene._destroyAllEntities();\n this.bus?.emit(\"scene:popped\", { scene });\n }\n }\n\n /**\n * Flush destroy queues for all active scenes.\n * Called by the engine during endOfFrame.\n * @internal\n */\n _flushDestroyQueues(): void {\n for (const scene of this.stack) {\n scene._flushDestroyQueue();\n }\n }\n\n /** Fire onPause() for scenes that transitioned from not-paused to paused. */\n private _firePauseTransitions(wasPaused: Map<Scene, boolean>): void {\n for (const s of this.stack) {\n const was = wasPaused.get(s) ?? false;\n if (s.isPaused && !was) {\n s.onPause?.();\n }\n }\n }\n\n /** Fire onResume() for scenes that transitioned from paused to not-paused. */\n private _fireResumeTransitions(wasPaused: Map<Scene, boolean>): void {\n for (const s of this.stack) {\n const was = wasPaused.get(s) ?? false;\n if (!s.isPaused && was) {\n s.onResume?.();\n }\n }\n }\n}\n","import type { EasingFunction } from \"./types.js\";\n\n/** Options for creating a Process. */\nexport interface ProcessOptions {\n /** Called each frame with dt (ms) and elapsed (ms). Return true to complete early. */\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n update?: (dt: number, elapsed: number) => boolean | void;\n /** Called when the process completes. */\n onComplete?: () => void;\n /** Auto-complete after this duration in ms. */\n duration?: number;\n /** Loop the process. */\n loop?: boolean;\n /** Tags for process filtering. */\n tags?: string[];\n}\n\n/**\n * A Process represents an ongoing action updated each frame.\n * Used internally by Tween and Sequence, and directly for custom coroutines.\n */\nexport class Process {\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n private readonly updateFn: (dt: number, elapsed: number) => boolean | void;\n private readonly onCompleteFn: (() => void) | undefined;\n private readonly duration: number | undefined;\n private readonly loop: boolean;\n /** Tags for filtering/grouping. */\n readonly tags: readonly string[];\n\n private elapsed = 0;\n private _completed = false;\n private _paused = false;\n private _cancelled = false;\n private resolvePromise?: () => void;\n\n /** Create a timer that fires `onComplete` after `duration` ms. */\n static delay(duration: number, onComplete?: () => void, tags?: string[]): Process {\n const opts: ProcessOptions = { duration };\n if (onComplete !== undefined) opts.onComplete = onComplete;\n if (tags !== undefined) opts.tags = tags;\n return new Process(opts);\n }\n\n constructor(options: ProcessOptions) {\n this.updateFn = options.update ?? (() => {});\n this.onCompleteFn = options.onComplete;\n this.duration = options.duration;\n this.loop = options.loop ?? false;\n this.tags = options.tags ?? [];\n }\n\n /** Whether the process has completed. */\n get completed(): boolean {\n return this._completed;\n }\n\n /** Whether the process is paused. */\n get paused(): boolean {\n return this._paused;\n }\n\n /** Pause the process. */\n pause(): void {\n this._paused = true;\n }\n\n /** Resume the process. */\n resume(): void {\n this._paused = false;\n }\n\n /** Cancel the process. */\n cancel(): void {\n this._cancelled = true;\n this._completed = true;\n this.resolvePromise?.();\n }\n\n /** Returns a promise that resolves when the process completes or is cancelled. */\n toPromise(): Promise<void> {\n if (this._completed) return Promise.resolve();\n return new Promise<void>((resolve) => {\n this.resolvePromise = resolve;\n });\n }\n\n /**\n * Advance the process by dt milliseconds.\n * @internal\n */\n _update(dt: number): void {\n if (this._completed || this._paused || this._cancelled) return;\n\n this.elapsed += dt;\n\n // Check duration-based completion\n if (this.duration !== undefined && this.elapsed >= this.duration) {\n const result = this.updateFn(dt, this.elapsed);\n if (this.loop && result !== true) {\n this.elapsed = this.elapsed % this.duration;\n return;\n }\n this.complete();\n return;\n }\n\n // Check callback-based completion\n const result = this.updateFn(dt, this.elapsed);\n if (result === true) {\n if (this.loop) {\n this.elapsed = 0;\n return;\n }\n this.complete();\n }\n }\n\n /**\n * Reset the process to its initial state so it can be re-run.\n * @internal Used by Sequence for loop/repeat with direct instances.\n */\n _reset(): void {\n this.elapsed = 0;\n this._completed = false;\n this._paused = false;\n this._cancelled = false;\n delete this.resolvePromise;\n }\n\n private complete(): void {\n this._completed = true;\n this.onCompleteFn?.();\n this.resolvePromise?.();\n }\n}\n\n// ---- Built-in easing functions ----\n\n/** Linear easing (no easing). */\nexport const easeLinear: EasingFunction = (t) => t;\n\n/** Ease in quadratic. */\nexport const easeInQuad: EasingFunction = (t) => t * t;\n\n/** Ease out quadratic. */\nexport const easeOutQuad: EasingFunction = (t) => t * (2 - t);\n\n/** Ease in-out quadratic. */\nexport const easeInOutQuad: EasingFunction = (t) =>\n t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;\n\n/** Ease out bounce. */\nexport const easeOutBounce: EasingFunction = (t) => {\n if (t < 1 / 2.75) {\n return 7.5625 * t * t;\n } else if (t < 2 / 2.75) {\n const t2 = t - 1.5 / 2.75;\n return 7.5625 * t2 * t2 + 0.75;\n } else if (t < 2.5 / 2.75) {\n const t2 = t - 2.25 / 2.75;\n return 7.5625 * t2 * t2 + 0.9375;\n } else {\n const t2 = t - 2.625 / 2.75;\n return 7.5625 * t2 * t2 + 0.984375;\n }\n};\n","import {\n Process,\n easeLinear,\n} from \"./Process.js\";\nimport { Vec2 } from \"./Vec2.js\";\nimport type { Vec2Like } from \"./Vec2.js\";\nimport type { EasingFunction } from \"./types.js\";\n\n/** Static factory for creating tween Processes. */\nexport const Tween = {\n /** Tween a numeric property on a target object. */\n to(\n target: Record<string, number>,\n property: string,\n to: number,\n duration: number,\n easing: EasingFunction = easeLinear,\n ): Process {\n const from = target[property] ?? 0;\n return new Process({\n duration,\n update: (_dt, elapsed) => {\n const t = Math.min(elapsed / duration, 1);\n target[property] = from + (to - from) * easing(t);\n },\n });\n },\n\n /** Tween using a custom setter. */\n custom(\n setter: (value: number) => void,\n from: number,\n to: number,\n duration: number,\n easing: EasingFunction = easeLinear,\n ): Process {\n return new Process({\n duration,\n update: (_dt, elapsed) => {\n const t = Math.min(elapsed / duration, 1);\n setter(from + (to - from) * easing(t));\n },\n });\n },\n\n /** Tween a Vec2 value. */\n vec2(\n setter: (value: Vec2) => void,\n from: Vec2Like,\n to: Vec2Like,\n duration: number,\n easing: EasingFunction = easeLinear,\n ): Process {\n return new Process({\n duration,\n update: (_dt, elapsed) => {\n const t = Math.min(elapsed / duration, 1);\n const e = easing(t);\n setter(\n new Vec2(from.x + (to.x - from.x) * e, from.y + (to.y - from.y) * e),\n );\n },\n });\n },\n};\n","import { Vec2 } from \"./Vec2.js\";\nimport type { Vec2Like } from \"./Vec2.js\";\nimport type { EasingFunction } from \"./types.js\";\n\n/** Types that can be interpolated by keyframe tracks. */\nexport type Interpolatable = number | Vec2Like;\n\n/**\n * Interpolate between two values of the same type.\n * - `number` → linear interpolation\n * - `Vec2Like` → component-wise lerp, returns `Vec2`\n */\nexport function interpolate<T extends Interpolatable>(\n from: T,\n to: T,\n t: number,\n easing?: EasingFunction,\n): T {\n const e = easing ? easing(t) : t;\n if (typeof from === \"number\") {\n return (from + ((to as number) - from) * e) as T;\n }\n const a = from as Vec2Like;\n const b = to as Vec2Like;\n return new Vec2(a.x + (b.x - a.x) * e, a.y + (b.y - a.y) * e) as unknown as T;\n}\n","import { Process, easeLinear } from \"./Process.js\";\nimport { interpolate } from \"./interpolate.js\";\nimport type { Interpolatable } from \"./interpolate.js\";\nimport type { EasingFunction } from \"./types.js\";\n\n/** A single keyframe in an animation track. */\nexport interface Keyframe<T extends Interpolatable> {\n /** Time in ms from the start of the track. */\n time: number;\n /** Value at this keyframe. */\n data: T;\n /** Easing from this keyframe to the next (overrides track default). */\n easing?: EasingFunction;\n /** Fired once when playback passes this keyframe's time. */\n event?: () => void;\n}\n\n/** Options for creating a keyframe track. */\nexport interface KeyframeTrackOptions<T extends Interpolatable> {\n /** At least 2 keyframes, sorted by time. */\n keyframes: Keyframe<T>[];\n /** Called each frame with the interpolated value. */\n setter: (value: T) => void;\n /** Total duration in ms. Defaults to the last keyframe's time. */\n duration?: number;\n /** Whether to loop the track. */\n loop?: boolean;\n /** Playback speed multiplier (default 1). */\n speed?: number;\n /** Default easing between keyframes (default easeLinear). */\n easing?: EasingFunction;\n /** Called when the track completes (non-looping only). */\n onComplete?: () => void;\n}\n\n/**\n * Create a Process that animates through keyframes.\n * Returns a standard Process — composable with Sequence, ProcessComponent.run(), etc.\n */\nexport function createKeyframeTrack<T extends Interpolatable>(\n options: KeyframeTrackOptions<T>,\n): Process {\n const {\n keyframes,\n setter,\n speed = 1,\n easing: defaultEasing = easeLinear,\n onComplete,\n } = options;\n\n const duration = options.duration ?? keyframes[keyframes.length - 1]!.time;\n if (duration <= 0) {\n throw new Error(\"createKeyframeTrack: duration must be > 0\");\n }\n const loop = options.loop ?? false;\n\n let internalElapsed = 0;\n const firedEvents = new Set<number>();\n\n const processOpts: import(\"./Process.js\").ProcessOptions = {\n update(dt) {\n internalElapsed += dt * speed;\n\n // Handle completion / looping\n if (internalElapsed >= duration) {\n if (loop) {\n // Complete the pass — fire any events that haven't fired this cycle\n for (let i = 0; i < keyframes.length; i++) {\n if (keyframes[i]!.event && !firedEvents.has(i)) {\n keyframes[i]!.event!();\n }\n }\n internalElapsed = internalElapsed % duration;\n firedEvents.clear();\n return;\n } else {\n // Clamp to final value\n setter(keyframes[keyframes.length - 1]!.data);\n // Fire any remaining events\n for (let i = 0; i < keyframes.length; i++) {\n if (!firedEvents.has(i) && keyframes[i]!.event) {\n keyframes[i]!.event!();\n }\n }\n // Return true to complete — Process calls onComplete for us\n return true;\n }\n }\n\n // Fire events for keyframes we've passed\n for (let i = 0; i < keyframes.length; i++) {\n if (\n !firedEvents.has(i) &&\n keyframes[i]!.event &&\n internalElapsed >= keyframes[i]!.time\n ) {\n firedEvents.add(i);\n keyframes[i]!.event!();\n }\n }\n\n // Find the current segment (linear scan — tracks are small)\n let segIdx = 0;\n for (let i = 0; i < keyframes.length - 1; i++) {\n if (internalElapsed >= keyframes[i]!.time) {\n segIdx = i;\n }\n }\n\n const kfA = keyframes[segIdx]!;\n const kfB = keyframes[segIdx + 1]!;\n const segDuration = kfB.time - kfA.time;\n const segT =\n segDuration > 0\n ? Math.min((internalElapsed - kfA.time) / segDuration, 1)\n : 1;\n const segEasing = kfA.easing ?? defaultEasing;\n\n setter(interpolate(kfA.data, kfB.data, segT, segEasing));\n },\n };\n if (onComplete) processOpts.onComplete = onComplete;\n\n return new Process(processOpts);\n}\n","/** Configuration for a ProcessSlot. */\nexport interface ProcessSlotConfig {\n /** Auto-complete after this duration in ms. */\n duration?: number;\n /** Called each frame with dt (ms) and elapsed (ms). Return true to complete early. */\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n update?: (dt: number, elapsed: number) => boolean | void;\n /** Called on natural completion only. */\n onComplete?: () => void;\n /** Called on complete, cancel, OR restart — like `finally`. */\n cleanup?: () => void;\n /** Tags for filtering. */\n tags?: string[];\n /** Loop the slot's process. */\n loop?: boolean;\n}\n\n/**\n * A reusable, restartable process handle owned by a ProcessComponent.\n *\n * Starts in `completed` state (ready to use). Call `start()` to activate.\n * Use for cooldowns, invincibility windows, flash effects, shakes, etc.\n */\nexport class ProcessSlot {\n private config: ProcessSlotConfig;\n private _elapsed = 0;\n private _completed = true;\n private _paused = false;\n\n /** Tags for filtering/grouping. */\n readonly tags: readonly string[];\n\n constructor(config: ProcessSlotConfig = {}) {\n this.config = config;\n this.tags = config.tags ?? [];\n }\n\n /** Whether the slot has completed (starts true). */\n get completed(): boolean {\n return this._completed;\n }\n\n /** Whether the slot is actively running (not completed and not paused). */\n get running(): boolean {\n return !this._completed && !this._paused;\n }\n\n /** Milliseconds elapsed since start. */\n get elapsed(): number {\n return this._elapsed;\n }\n\n /** Progress ratio 0..1 (elapsed / duration). 0 if no duration set. */\n get ratio(): number {\n const d = this.config.duration;\n if (d === undefined || d <= 0) return 0;\n return Math.min(this._elapsed / d, 1);\n }\n\n /** Start the slot. No-op if already running (use restart() to force). */\n start(overrides?: Partial<ProcessSlotConfig>): this {\n if (!this._completed) return this;\n this._elapsed = 0;\n this._completed = false;\n this._paused = false;\n if (overrides) {\n this.config = { ...this.config, ...overrides };\n if (overrides.tags) {\n (this as { tags: readonly string[] }).tags = overrides.tags;\n }\n }\n return this;\n }\n\n /** Cancel if running, then start fresh. Always restarts. */\n restart(overrides?: Partial<ProcessSlotConfig>): this {\n if (!this._completed) {\n this.config.cleanup?.();\n this._completed = true;\n }\n // Force start by ensuring completed is true\n this._completed = true;\n return this.start(overrides);\n }\n\n /** Cancel the slot. Calls cleanup if running. */\n cancel(): void {\n if (this._completed) return;\n this.config.cleanup?.();\n this._completed = true;\n }\n\n /** Pause the slot. */\n pause(): void {\n if (!this._completed) this._paused = true;\n }\n\n /** Resume the slot. */\n resume(): void {\n this._paused = false;\n }\n\n /** Set/override the onComplete callback. Chainable. */\n onComplete(fn: () => void): this {\n this.config = { ...this.config, onComplete: fn };\n return this;\n }\n\n /**\n * Advance the slot by dt milliseconds.\n * @internal — called by ProcessComponent\n */\n _tick(dt: number): void {\n if (this._completed || this._paused) return;\n\n this._elapsed += dt;\n\n // Run per-frame update\n const result = this.config.update?.(dt, this._elapsed);\n\n // Check duration-based completion\n const duration = this.config.duration;\n if (duration !== undefined && this._elapsed >= duration) {\n if (this.config.loop && result !== true) {\n this._elapsed = this._elapsed % duration;\n return;\n }\n this._complete();\n return;\n }\n\n // Check callback-based completion\n if (result === true) {\n if (this.config.loop) {\n this._elapsed = 0;\n return;\n }\n this._complete();\n }\n }\n\n private _complete(): void {\n this._completed = true;\n try {\n this.config.onComplete?.();\n } finally {\n this.config.cleanup?.();\n }\n }\n}\n","import { Component } from \"./Component.js\";\nimport type { Process } from \"./Process.js\";\nimport { ProcessSlot } from \"./ProcessSlot.js\";\nimport type { ProcessSlotConfig } from \"./ProcessSlot.js\";\n\n/**\n * A component that holds a set of processes on an entity.\n * Processes are ticked automatically by ProcessSystem each frame.\n * All processes are cancelled when the entity is destroyed.\n */\nexport class ProcessComponent extends Component {\n private processes = new Set<Process>();\n private slots = new Set<ProcessSlot>();\n\n /**\n * Run a one-off process (tween, sequence, delay).\n * Optionally apply tags for cancel-by-tag.\n */\n run(process: Process, options?: { tags?: string[] }): Process {\n if (options?.tags?.length) {\n (process as { tags: readonly string[] }).tags = [\n ...process.tags,\n ...options.tags,\n ];\n }\n this.processes.add(process);\n return process;\n }\n\n /** Create a reusable, restartable process slot. */\n slot(config?: ProcessSlotConfig): ProcessSlot {\n const s = new ProcessSlot(config);\n this.slots.add(s);\n return s;\n }\n\n /** Cancel all processes and slots, or only those matching a tag. */\n cancel(tag?: string): void {\n // Cancel one-off processes\n for (const p of this.processes) {\n if (tag === undefined || p.tags.includes(tag)) {\n p.cancel();\n this.processes.delete(p);\n }\n }\n\n // Cancel slots\n for (const s of this.slots) {\n if (tag === undefined || s.tags.includes(tag)) {\n s.cancel();\n }\n }\n }\n\n /** Number of active (non-completed) processes and slots. */\n get count(): number {\n let n = 0;\n for (const p of this.processes) {\n if (!p.completed) n++;\n }\n for (const s of this.slots) {\n if (!s.completed) n++;\n }\n return n;\n }\n\n /**\n * Advance all processes and slots by dt milliseconds and remove completed one-offs.\n * @internal — called by ProcessSystem\n */\n _tick(dt: number): void {\n for (const p of this.processes) {\n p._update(dt);\n if (p.completed) {\n this.processes.delete(p);\n }\n }\n for (const s of this.slots) {\n s._tick(dt);\n }\n }\n\n /** Cancel all processes and slots on entity destroy. */\n override onDestroy(): void {\n this.cancel();\n }\n}\n","import { Component } from \"./Component.js\";\nimport { ProcessComponent } from \"./ProcessComponent.js\";\nimport { createKeyframeTrack } from \"./KeyframeTrack.js\";\nimport type { Keyframe, KeyframeTrackOptions } from \"./KeyframeTrack.js\";\nimport type { Process } from \"./Process.js\";\nimport type { Interpolatable } from \"./interpolate.js\";\nimport type { EasingFunction } from \"./types.js\";\n\n/** Definition for a named keyframe animation. */\nexport interface KeyframeAnimationDef<T extends Interpolatable = Interpolatable> {\n keyframes: Keyframe<T>[];\n setter: (value: T) => void;\n loop?: boolean;\n speed?: number;\n duration?: number;\n easing?: EasingFunction;\n onEnter?: () => void;\n onExit?: (complete: boolean) => void;\n}\n\n/**\n * Component that manages named keyframe animations.\n *\n * Multiple animations can play concurrently (bob + pulse).\n * Each animation runs as a Process on the sibling ProcessComponent.\n * Requires a sibling ProcessComponent on the same entity.\n */\nexport class KeyframeAnimator<T extends string = string> extends Component {\n private readonly defs: Record<string, KeyframeAnimationDef>;\n private readonly active = new Map<string, Process>();\n private readonly pc = this.sibling(ProcessComponent);\n\n constructor(animations: Record<T, KeyframeAnimationDef>) {\n super();\n this.defs = animations;\n }\n\n /** Start (or restart) a named animation. */\n play(name: T): void {\n const def = this.defs[name];\n if (!def) return;\n\n // Restart if already playing\n if (this.active.has(name)) {\n this.stopInternal(name, false);\n }\n\n def.onEnter?.();\n\n const opts: KeyframeTrackOptions<Interpolatable> = {\n keyframes: def.keyframes,\n setter: def.setter,\n onComplete: () => {\n this.active.delete(name);\n def.onExit?.(true);\n },\n };\n if (def.loop !== undefined) opts.loop = def.loop;\n if (def.speed !== undefined) opts.speed = def.speed;\n if (def.duration !== undefined) opts.duration = def.duration;\n if (def.easing !== undefined) opts.easing = def.easing;\n\n const process = createKeyframeTrack(opts);\n\n this.active.set(name, process);\n this.pc.run(process);\n }\n\n /** Stop a named animation. */\n stop(name: T): void {\n this.stopInternal(name, false);\n }\n\n /** Stop all playing animations. */\n stopAll(): void {\n for (const name of [...this.active.keys()]) {\n this.stopInternal(name, false);\n }\n }\n\n /** Whether a named animation is currently playing. */\n isPlaying(name: T): boolean {\n return this.active.has(name);\n }\n\n override onDestroy(): void {\n this.stopAll();\n }\n\n private stopInternal(name: string, complete: boolean): void {\n const process = this.active.get(name);\n if (!process) return;\n process.cancel();\n this.active.delete(name);\n this.defs[name]?.onExit?.(complete);\n }\n}\n","import { Process } from \"./Process.js\";\n\ntype StepFactory = () => Process;\n\ninterface Step {\n type: \"single\" | \"parallel\";\n factories: StepFactory[];\n}\n\n/**\n * Builds a chain of Processes that run in order.\n * Supports sequential steps, waits, callbacks, and parallel groups.\n */\nexport class Sequence {\n private steps: Step[] = [];\n private _loop = false;\n private _repeatCount: number | undefined;\n\n /** Add a step (Process or factory function). */\n then(step: Process | StepFactory): this {\n this.steps.push({\n type: \"single\",\n factories: [typeof step === \"function\" ? step : wrapInstance(step)],\n });\n return this;\n }\n\n /** Add a delay in ms. */\n wait(ms: number): this {\n this.steps.push({\n type: \"single\",\n factories: [\n () =>\n new Process({\n duration: ms,\n update: () => {},\n }),\n ],\n });\n return this;\n }\n\n /** Add an instant callback. */\n call(fn: () => void): this {\n this.steps.push({\n type: \"single\",\n factories: [\n () =>\n new Process({\n update: () => {\n fn();\n return true; // complete immediately\n },\n }),\n ],\n });\n return this;\n }\n\n /** Run steps in parallel (all must complete before sequence continues). */\n parallel(...steps: Array<Process | StepFactory>): this {\n this.steps.push({\n type: \"parallel\",\n factories: steps.map((s) =>\n typeof s === \"function\" ? s : wrapInstance(s),\n ),\n });\n return this;\n }\n\n /** Loop the sequence indefinitely. */\n loop(): this {\n this._loop = true;\n return this;\n }\n\n /** Repeat the sequence a fixed number of times (1 = play once, 2 = play twice, etc.). */\n repeat(times: number): this {\n this._repeatCount = times;\n return this;\n }\n\n /**\n * Build the sequence into a Process without registering with a scene.\n * Exposed for unit testing.\n * @internal\n */\n _build(): Process {\n const steps = this.steps;\n const looping = this._loop;\n const repeatCount = this._repeatCount;\n let stepIndex = 0;\n let active: Process[] = [];\n let iteration = 1;\n\n return new Process({\n update: (dt) => {\n // Initialize current step if needed\n if (active.length === 0 && stepIndex < steps.length) {\n const step = steps[stepIndex];\n if (!step) return true;\n active = step.factories.map((f) => f());\n }\n\n // Update all active processes\n for (const proc of active) {\n proc._update(dt);\n }\n\n // Check if all active processes are complete\n if (active.every((p) => p.completed)) {\n active = [];\n stepIndex++;\n if (stepIndex >= steps.length) {\n // Check if we should loop/repeat\n if (looping) {\n stepIndex = 0;\n return false;\n }\n if (repeatCount !== undefined && iteration < repeatCount) {\n iteration++;\n stepIndex = 0;\n return false;\n }\n return true; // sequence complete\n }\n }\n\n return false;\n },\n });\n }\n\n /** Build and start the sequence. Returns the wrapping Process. */\n start(): Process {\n return this._build();\n }\n}\n\n/** Wrap a direct Process instance so it gets _reset() before each re-use. */\nfunction wrapInstance(proc: Process): StepFactory {\n return () => {\n proc._reset();\n return proc;\n };\n}\n","import { Entity } from \"./Entity.js\";\nimport { ProcessComponent } from \"./ProcessComponent.js\";\nimport { ProcessSlot } from \"./ProcessSlot.js\";\nimport type { ProcessSlotConfig } from \"./ProcessSlot.js\";\nimport type { Process } from \"./Process.js\";\n\n/**\n * A pre-built entity that exposes the ProcessComponent API directly.\n * Useful for scene-level timing without manual component wiring.\n *\n * ```ts\n * const timers = this.spawn(TimerEntity);\n * timers.run(Process.delay(500, () => { ... }));\n * const cd = timers.slot({ duration: 300 });\n * ```\n */\nexport class TimerEntity extends Entity {\n private pc!: ProcessComponent;\n\n setup() {\n this.pc = this.add(new ProcessComponent());\n }\n\n run(process: Process, options?: { tags?: string[] }): Process {\n return this.pc.run(process, options);\n }\n\n slot(config?: ProcessSlotConfig): ProcessSlot {\n return this.pc.slot(config);\n }\n\n cancel(tag?: string): void {\n this.pc.cancel(tag);\n }\n}\n","import { System } from \"./System.js\";\nimport { Phase } from \"./types.js\";\nimport type { EngineContext } from \"./EngineContext.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport type { Process } from \"./Process.js\";\nimport { ProcessComponent } from \"./ProcessComponent.js\";\nimport { SceneManagerKey } from \"./EngineContext.js\";\n\n/**\n * Built-in system that ticks all ProcessComponents on entities in non-paused\n * scenes, plus a scene-level set of global processes.\n *\n * Runs at Phase.Update with priority 500, ensuring tweened values are fresh\n * before ComponentUpdateSystem (priority 1000) reads them.\n */\nexport class ProcessSystem extends System {\n override readonly phase = Phase.Update;\n override readonly priority = 500;\n\n /** Global time scale multiplier. Stacks multiplicatively with per-scene timeScale. */\n timeScale = 1;\n\n private sceneManager!: SceneManager;\n private sceneProcesses = new Set<Process>();\n\n override onRegister(context: EngineContext): void {\n this.sceneManager = context.resolve(SceneManagerKey);\n }\n\n /** Add a scene-level process (not tied to any entity). */\n add(process: Process): Process {\n this.sceneProcesses.add(process);\n return process;\n }\n\n /** Cancel scene-level processes, optionally by tag. */\n cancel(tag?: string): void {\n for (const p of this.sceneProcesses) {\n if (tag === undefined || p.tags.includes(tag)) {\n p.cancel();\n }\n }\n if (tag === undefined) {\n this.sceneProcesses.clear();\n }\n }\n\n update(dt: number): void {\n const globalScaledDt = dt * this.timeScale;\n\n // Tick scene-level processes (global timeScale only, not scene-bound)\n for (const p of this.sceneProcesses) {\n p._update(globalScaledDt);\n if (p.completed) {\n this.sceneProcesses.delete(p);\n }\n }\n\n // Tick entity ProcessComponents in all non-paused scenes\n for (const scene of this.sceneManager.activeScenes) {\n const effectiveDt = globalScaledDt * scene.timeScale;\n for (const entity of scene.getEntities()) {\n if (entity.isDestroyed) continue;\n const pc = entity.tryGet(ProcessComponent);\n if (!pc) continue;\n pc._tick(effectiveDt);\n }\n }\n }\n}\n","import { Transform } from \"./Transform.js\";\nimport type { Entity } from \"./Entity.js\";\nimport type { Component } from \"./Component.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport type { GameLoop } from \"./GameLoop.js\";\nimport {\n EngineContext,\n ErrorBoundaryKey,\n SystemSchedulerKey,\n} from \"./EngineContext.js\";\n\n/** Full engine state snapshot. */\nexport interface EngineSnapshot {\n frameCount: number;\n sceneStack: SceneSnapshot[];\n entityCount: number;\n systemCount: number;\n errors: ErrorSnapshot;\n}\n\n/** Snapshot of a single entity. */\nexport interface EntitySnapshot {\n id: number;\n name: string;\n tags: string[];\n components: string[];\n position?: { x: number; y: number };\n}\n\n/** Snapshot of a scene in the stack. */\nexport interface SceneSnapshot {\n name: string;\n entityCount: number;\n paused: boolean;\n}\n\n/** Snapshot of a registered system. */\nexport interface SystemSnapshot {\n name: string;\n phase: string;\n priority: number;\n enabled: boolean;\n}\n\n/** Snapshot of error boundary state. */\nexport interface ErrorSnapshot {\n disabledSystems: string[];\n disabledComponents: Array<{\n entity: string;\n component: string;\n error: string;\n }>;\n}\n\n/** Internal engine reference to avoid circular dependency with Engine class. */\ninterface EngineRef {\n readonly context: EngineContext;\n readonly scenes: SceneManager;\n readonly loop: GameLoop;\n}\n\n/**\n * Programmatic state queries for testing and debugging.\n * Exposed on `window.__yage__` in debug mode.\n */\nexport class Inspector {\n private engine: EngineRef;\n\n constructor(engine: EngineRef) {\n this.engine = engine;\n }\n\n /** Full state snapshot (serializable). */\n snapshot(): EngineSnapshot {\n return {\n frameCount: this.engine.loop.frameCount,\n sceneStack: this.getSceneStack(),\n entityCount: this.countEntities(),\n systemCount: this.getSystems().length,\n errors: this.getErrors(),\n };\n }\n\n /** Find entity by name in the active scene. */\n getEntityByName(name: string): EntitySnapshot | undefined {\n const entity = this.findActiveEntity(name);\n if (!entity) return undefined;\n return this.entityToSnapshot(entity);\n }\n\n /** Get entity position (from Transform component). */\n getEntityPosition(name: string): { x: number; y: number } | undefined {\n const entity = this.findActiveEntity(name);\n if (!entity) return undefined;\n const transform = this.getTransform(entity);\n if (!transform) return undefined;\n return { x: transform.position.x, y: transform.position.y };\n }\n\n /** Check if an entity has a component by class name string. */\n hasComponent(entityName: string, componentClass: string): boolean {\n return this.findComponentByName(entityName, componentClass) !== undefined;\n }\n\n /** Get component data (serializable subset) by class name string. */\n getComponentData(entityName: string, componentClass: string): unknown {\n const comp = this.findComponentByName(entityName, componentClass);\n if (!comp) return undefined;\n return this.serializeComponent(comp);\n }\n\n /** Get all entities in the active scene as snapshots. */\n getEntities(): EntitySnapshot[] {\n const scene = this.engine.scenes.active;\n if (!scene) return [];\n const result: EntitySnapshot[] = [];\n for (const entity of scene.getEntities()) {\n if (!entity.isDestroyed) {\n result.push(this.entityToSnapshot(entity));\n }\n }\n return result;\n }\n\n /** Get scene stack info. */\n getSceneStack(): SceneSnapshot[] {\n return this.engine.scenes.all.map((scene) => ({\n name: scene.name,\n entityCount: scene.getEntities().size,\n paused: scene.isPaused,\n }));\n }\n\n /** Get active system info. */\n getSystems(): SystemSnapshot[] {\n const scheduler = this.engine.context.tryResolve(SystemSchedulerKey);\n if (!scheduler) return [];\n return scheduler.getAllSystems().map((sys) => ({\n name: sys.constructor.name,\n phase: sys.phase,\n priority: sys.priority,\n enabled: sys.enabled,\n }));\n }\n\n /** Get disabled components/systems from error boundary. */\n getErrors(): ErrorSnapshot {\n const boundary = this.engine.context.tryResolve(ErrorBoundaryKey);\n if (!boundary) return { disabledSystems: [], disabledComponents: [] };\n const disabled = boundary.getDisabled();\n return {\n disabledSystems: disabled.systems.map(\n (s) => s.system.constructor.name,\n ),\n disabledComponents: disabled.components.map((c) => ({\n entity: c.component.entity?.name ?? \"unknown\",\n component: c.component.constructor.name,\n error: c.error,\n })),\n };\n }\n\n private findActiveEntity(name: string): Entity | undefined {\n return this.engine.scenes.active?.findEntity(name);\n }\n\n private findComponentByName(\n entityName: string,\n componentClass: string,\n ): Component | undefined {\n const entity = this.findActiveEntity(entityName);\n if (!entity) return undefined;\n for (const comp of entity.getAll()) {\n if (comp.constructor.name === componentClass) return comp;\n }\n return undefined;\n }\n\n private entityToSnapshot(entity: Entity): EntitySnapshot {\n const transform = this.getTransform(entity);\n const snapshot: EntitySnapshot = {\n id: entity.id,\n name: entity.name,\n tags: [...entity.tags],\n components: [...entity.getAll()].map((c) => c.constructor.name),\n };\n if (transform) {\n snapshot.position = {\n x: transform.position.x,\n y: transform.position.y,\n };\n }\n return snapshot;\n }\n\n private getTransform(entity: Entity): Transform | undefined {\n return entity.has(Transform) ? entity.get(Transform) : undefined;\n }\n\n private serializeComponent(comp: Component): unknown {\n const result: Record<string, unknown> = {};\n for (const key of Object.getOwnPropertyNames(comp)) {\n if (key === \"entity\") continue;\n const value = (comp as unknown as Record<string, unknown>)[key];\n if (typeof value !== \"function\") {\n result[key] = value;\n }\n }\n return result;\n }\n\n private countEntities(): number {\n let count = 0;\n for (const scene of this.engine.scenes.all) {\n count += scene.getEntities().size;\n }\n return count;\n }\n}\n","import {\n EngineContext,\n EngineKey,\n EventBusKey,\n SceneManagerKey,\n LoggerKey,\n InspectorKey,\n QueryCacheKey,\n ErrorBoundaryKey,\n GameLoopKey,\n SystemSchedulerKey,\n ProcessSystemKey,\n AssetManagerKey,\n} from \"./EngineContext.js\";\nimport { AssetManager } from \"./AssetManager.js\";\nimport { EventBus } from \"./EventBus.js\";\nimport type { EngineEvents } from \"./EventBus.js\";\nimport { Logger } from \"./Logger.js\";\nimport type { LoggerConfig } from \"./Logger.js\";\nimport { QueryCache } from \"./QueryCache.js\";\nimport { ErrorBoundary } from \"./ErrorBoundary.js\";\nimport { GameLoop } from \"./GameLoop.js\";\nimport { SceneManager } from \"./SceneManager.js\";\nimport { SystemScheduler } from \"./SystemScheduler.js\";\nimport { Inspector } from \"./Inspector.js\";\nimport {\n ComponentUpdateSystem,\n ComponentFixedUpdateSystem,\n} from \"./ComponentUpdateSystem.js\";\nimport { ProcessSystem } from \"./ProcessSystem.js\";\nimport { Phase } from \"./types.js\";\nimport type { Plugin } from \"./types.js\";\n\n/** Engine configuration. */\nexport interface EngineConfig {\n /** Enable debug mode (Inspector API, debug logging). */\n debug?: boolean;\n /** Fixed timestep in ms (default: 1000/60). */\n fixedTimestep?: number;\n /** Max fixed steps per frame to prevent spiral of death (default: 5). */\n maxFixedStepsPerFrame?: number;\n /** Logger configuration. */\n logger?: LoggerConfig;\n}\n\n/**\n * The top-level entry point. Owns the plugin registry, game loop,\n * scene manager, and DI container.\n */\nexport class Engine {\n /** The dependency injection container. */\n readonly context: EngineContext;\n /** The scene manager. */\n readonly scenes: SceneManager;\n /** The event bus. */\n readonly events: EventBus<EngineEvents>;\n /** The game loop. */\n readonly loop: GameLoop;\n /** The logger. */\n readonly logger: Logger;\n /** The inspector (debug queries). */\n readonly inspector: Inspector;\n\n private readonly scheduler: SystemScheduler;\n private readonly errorBoundary: ErrorBoundary;\n private readonly queryCache: QueryCache;\n /** The asset manager. */\n readonly assets: AssetManager;\n\n private readonly plugins: Map<string, Plugin> = new Map();\n private sortedPlugins: Plugin[] = [];\n private started = false;\n private readonly debug: boolean;\n\n constructor(config?: EngineConfig) {\n this.debug = config?.debug ?? false;\n\n // Create core services\n this.context = new EngineContext();\n this.events = new EventBus<EngineEvents>();\n this.logger = new Logger(config?.logger);\n this.queryCache = new QueryCache();\n this.errorBoundary = new ErrorBoundary(this.logger);\n this.loop = new GameLoop(config);\n this.scenes = new SceneManager();\n this.scheduler = new SystemScheduler();\n this.inspector = new Inspector(this);\n this.assets = new AssetManager();\n\n // Wire up the scheduler with error boundary\n this.scheduler.setErrorBoundary(this.errorBoundary);\n\n // Register all well-known services\n this.context.register(EngineKey, this);\n this.context.register(EventBusKey, this.events);\n this.context.register(SceneManagerKey, this.scenes);\n this.context.register(LoggerKey, this.logger);\n this.context.register(QueryCacheKey, this.queryCache);\n this.context.register(ErrorBoundaryKey, this.errorBoundary);\n this.context.register(GameLoopKey, this.loop);\n this.context.register(InspectorKey, this.inspector);\n this.context.register(SystemSchedulerKey, this.scheduler);\n this.context.register(AssetManagerKey, this.assets);\n\n // Wire scene manager with context\n this.scenes._setContext(this.context);\n\n // Register built-in ComponentUpdateSystem (bridge between OOP and ECS)\n this.registerBuiltInSystems();\n\n // Wire game loop callbacks\n this.loop.setCallbacks({\n earlyUpdate: (dt) => {\n this.logger.setFrame(this.loop.frameCount);\n this.scheduler.run(Phase.EarlyUpdate, dt);\n },\n fixedUpdate: (dt) => this.scheduler.run(Phase.FixedUpdate, dt),\n update: (dt) => this.scheduler.run(Phase.Update, dt),\n lateUpdate: (dt) => this.scheduler.run(Phase.LateUpdate, dt),\n render: (dt) => this.scheduler.run(Phase.Render, dt),\n endOfFrame: (dt) => {\n this.scheduler.run(Phase.EndOfFrame, dt);\n this.scenes._flushDestroyQueues();\n },\n });\n }\n\n /** Register a plugin. Must be called before start(). */\n use(plugin: Plugin): this {\n if (this.started) {\n throw new Error(\"Cannot register plugins after engine has started.\");\n }\n if (this.plugins.has(plugin.name)) {\n throw new Error(`Plugin \"${plugin.name}\" is already registered.`);\n }\n this.plugins.set(plugin.name, plugin);\n return this;\n }\n\n /** Start the engine. Installs plugins in topological order, starts the game loop. */\n async start(): Promise<void> {\n if (this.started) return;\n this.started = true;\n\n // Topological sort of plugins (cached for reverse teardown)\n this.sortedPlugins = this.topologicalSort();\n const sorted = this.sortedPlugins;\n\n // Install each plugin\n for (const plugin of sorted) {\n await plugin.install?.(this.context);\n }\n\n // Register systems from each plugin\n for (const plugin of sorted) {\n plugin.registerSystems?.(this.scheduler);\n }\n\n // Initialize systems\n for (const sys of this.scheduler.getAllSystems()) {\n sys._setContext(this.context);\n sys.onRegister?.(this.context);\n }\n\n // Start the game loop\n this.loop.start();\n\n // Expose debug API in browser before plugin onStart hooks run so plugins\n // can safely augment the debug surface.\n if (this.debug && typeof globalThis !== \"undefined\") {\n (globalThis as Record<string, unknown>)[\"__yage__\"] = {\n inspector: this.inspector,\n logger: this.logger,\n };\n }\n\n // Notify plugins\n for (const plugin of sorted) {\n plugin.onStart?.();\n }\n\n // Emit engine started event\n this.events.emit(\"engine:started\", undefined);\n }\n\n /** Stop the engine. Destroys all scenes, plugins, and the game loop. */\n destroy(): void {\n // Emit stop event\n this.events.emit(\"engine:stopped\", undefined);\n\n // Stop the loop\n this.loop.stop();\n\n // Clear scenes\n this.scenes.clear();\n\n // Unregister all systems (reverse order for clean teardown)\n const allSystems = this.scheduler.getAllSystems();\n for (let i = allSystems.length - 1; i >= 0; i--) {\n allSystems[i]!.onUnregister?.();\n }\n\n // Destroy plugins in reverse topological order (dependents first)\n for (let i = this.sortedPlugins.length - 1; i >= 0; i--) {\n const plugin = this.sortedPlugins[i];\n if (plugin) plugin.onDestroy?.();\n }\n\n // Clean up debug API\n if (\n this.debug &&\n typeof globalThis !== \"undefined\" &&\n \"__yage__\" in globalThis\n ) {\n delete (globalThis as Record<string, unknown>)[\"__yage__\"];\n }\n\n this.events.clear();\n this.started = false;\n }\n\n private registerBuiltInSystems(): void {\n const fixedUpdate = new ComponentFixedUpdateSystem();\n const update = new ComponentUpdateSystem();\n const processSystem = new ProcessSystem();\n this.scheduler.add(fixedUpdate);\n this.scheduler.add(update);\n this.scheduler.add(processSystem);\n this.context.register(ProcessSystemKey, processSystem);\n }\n\n /**\n * Topological sort of plugins using Kahn's algorithm.\n * Errors on missing dependencies, circular dependencies, and duplicates.\n */\n private topologicalSort(): Plugin[] {\n const plugins = [...this.plugins.values()];\n const nameMap = new Map<string, Plugin>();\n const inDegree = new Map<string, number>();\n const edges = new Map<string, string[]>(); // dep → dependents\n\n for (const p of plugins) {\n nameMap.set(p.name, p);\n inDegree.set(p.name, 0);\n edges.set(p.name, []);\n }\n\n for (const p of plugins) {\n for (const dep of p.dependencies ?? []) {\n if (!nameMap.has(dep)) {\n throw new Error(\n `Plugin \"${p.name}\" depends on \"${dep}\", which is not registered.`,\n );\n }\n const depEdges = edges.get(dep);\n if (depEdges) depEdges.push(p.name);\n inDegree.set(p.name, (inDegree.get(p.name) ?? 0) + 1);\n }\n }\n\n // Queue: all nodes with in-degree 0\n const queue: string[] = [];\n for (const [name, degree] of inDegree) {\n if (degree === 0) queue.push(name);\n }\n\n const result: Plugin[] = [];\n while (queue.length > 0) {\n const name = queue.shift();\n if (name === undefined) break;\n const plugin = nameMap.get(name);\n if (!plugin) continue;\n result.push(plugin);\n for (const dependent of edges.get(name) ?? []) {\n const newDegree = (inDegree.get(dependent) ?? 0) - 1;\n inDegree.set(dependent, newDegree);\n if (newDegree === 0) queue.push(dependent);\n }\n }\n\n if (result.length !== plugins.length) {\n throw new Error(\"Circular dependency detected among plugins.\");\n }\n\n return result;\n }\n}\n","import { Engine } from \"./Engine.js\";\nimport type { EngineConfig } from \"./Engine.js\";\nimport { Scene } from \"./Scene.js\";\nimport { Entity, _resetEntityIdCounter } from \"./Entity.js\";\nimport { EngineContext, QueryCacheKey, EventBusKey, ErrorBoundaryKey } from \"./EngineContext.js\";\nimport { QueryCache } from \"./QueryCache.js\";\nimport { EventBus } from \"./EventBus.js\";\nimport type { EngineEvents } from \"./EventBus.js\";\nimport { ErrorBoundary } from \"./ErrorBoundary.js\";\nimport { Logger, LogLevel } from \"./Logger.js\";\n\nclass _TestScene extends Scene {\n readonly name: string;\n constructor(name: string) {\n super();\n this.name = name;\n }\n}\n\n/** Create a fully wired Engine for integration tests. */\nexport async function createTestEngine(\n config?: EngineConfig,\n): Promise<Engine> {\n _resetEntityIdCounter();\n const engine = new Engine(config);\n await engine.start();\n return engine;\n}\n\n/** Create a lightweight mock scene with EngineContext for unit tests. */\nexport function createMockScene(name = \"mock-scene\"): {\n scene: Scene;\n context: EngineContext;\n} {\n _resetEntityIdCounter();\n const ctx = new EngineContext();\n const queryCache = new QueryCache();\n const bus = new EventBus<EngineEvents>();\n const logger = new Logger({ level: LogLevel.Debug });\n const boundary = new ErrorBoundary(logger);\n\n ctx.register(QueryCacheKey, queryCache);\n ctx.register(EventBusKey, bus);\n ctx.register(ErrorBoundaryKey, boundary);\n\n const scene = new _TestScene(name);\n scene._setContext(ctx);\n\n return { scene, context: ctx };\n}\n\n/** Create a mock entity spawned in a mock scene with full EngineContext access. */\nexport function createMockEntity(name = \"mock-entity\"): {\n entity: Entity;\n scene: Scene;\n context: EngineContext;\n} {\n const { scene, context } = createMockScene();\n const entity = scene.spawn(name);\n return { entity, scene, context };\n}\n\n/** Advance the game loop by N frames (manual tick). */\nexport function advanceFrames(\n engine: Engine,\n n: number,\n dtMs = 1000 / 60,\n): void {\n for (let i = 0; i < n; i++) {\n engine.loop.tick(dtMs);\n }\n}\n"],"mappings":"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","names":["Phase","LogLevel","entity","result"]}
|