@yagejs/core 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +534 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +265 -13
- package/dist/index.d.ts +265 -13
- package/dist/index.js +520 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/Vec2.ts","../src/MathUtils.ts","../src/EngineContext.ts","../src/Random.ts","../src/EventBus.ts","../src/Logger.ts","../src/SceneHooks.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/Inspector.ts","../src/Scene.ts","../src/Process.ts","../src/LoadingScene.ts","../src/SceneTransition.ts","../src/SceneManager.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/ProcessQueue.ts","../src/Engine.ts","../src/RendererAdapter.ts","../src/ui-consume-registry.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\";\nexport type { SmoothDampResult } from \"./MathUtils.js\";\n\nexport {\n RandomKey,\n createRandomService,\n createDefaultRandomSeed,\n globalRandom,\n normalizeSeed,\n} from \"./Random.js\";\nexport type { RandomService } from \"./Random.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\";\nexport type { ServiceScope, ServiceKeyOptions } from \"./EngineContext.js\";\n\nexport type { SceneHooks } from \"./SceneHooks.js\";\nexport { SceneHookRegistry, SceneHookRegistryKey } from \"./SceneHooks.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 { Inspector } from \"./Inspector.js\";\nexport type {\n EntitySnapshot,\n SceneSnapshot,\n SystemSnapshot,\n ErrorSnapshot,\n ComponentStateSnapshot,\n WorldEntitySnapshot,\n UINodeSnapshot,\n UITreeSnapshot,\n PhysicsSnapshot,\n EventLogEntry,\n WorldSceneSnapshot,\n CameraSnapshot,\n InputStateSnapshot,\n PointerSnapshot,\n EngineSnapshot,\n InspectorTimeController,\n} from \"./Inspector.js\";\n\nexport { Scene } from \"./Scene.js\";\n\nexport { LoadingScene } from \"./LoadingScene.js\";\n\nexport { SceneManager } from \"./SceneManager.js\";\n\nexport type {\n SceneTransition,\n SceneTransitionContext,\n SceneTransitionKind,\n SceneTransitionOptions,\n} from \"./SceneTransition.js\";\nexport { resolveTransition } from \"./SceneTransition.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 {\n makeEntityScopedQueue,\n makeGlobalScopedQueue,\n makeSceneScopedQueue,\n} from \"./ProcessQueue.js\";\nexport type { ScopedProcessQueue } from \"./ProcessQueue.js\";\n\nexport { Engine } from \"./Engine.js\";\nexport type { EngineConfig } from \"./Engine.js\";\n\nexport { RendererAdapterKey } from \"./RendererAdapter.js\";\nexport type { RendererAdapter } from \"./RendererAdapter.js\";\n\nexport {\n markPointerConsumeContainer,\n unmarkPointerConsumeContainer,\n isPointerConsumeContainer,\n} from \"./ui-consume-registry.js\";\n\nexport {\n createTestEngine,\n createMockScene,\n createMockEntity,\n advanceFrames,\n} from \"./test-utils.js\";\n","import type { Component } from \"./Component.js\";\nimport type { EngineContext } from \"./EngineContext.js\";\nimport type { SystemScheduler } from \"./SystemScheduler.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: EngineContext): void | Promise<void>;\n /** Register systems with the scheduler. Called after install. */\n registerSystems?(scheduler: SystemScheduler): void;\n /** Called after all plugins are installed and the engine has started. */\n onStart?(): void | Promise<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 /** Move current toward target by at most maxDelta without overshooting. */\n static moveTowards(\n current: Vec2Like,\n target: Vec2Like,\n maxDelta: number,\n ): Vec2 {\n const dx = target.x - current.x;\n const dy = target.y - current.y;\n const distanceSq = dx * dx + dy * dy;\n\n if (distanceSq < EPSILON * EPSILON) {\n return new Vec2(target.x, target.y);\n }\n\n if (maxDelta <= 0) {\n return new Vec2(current.x, current.y);\n }\n\n const distance = Math.sqrt(distanceSq);\n if (distance <= maxDelta) {\n return new Vec2(target.x, target.y);\n }\n\n const scale = maxDelta / distance;\n return new Vec2(current.x + dx * scale, current.y + dy * scale);\n }\n}\n","const TAU = Math.PI * 2;\nconst MIN_SMOOTH_TIME = 0.0001;\n\nexport interface SmoothDampResult {\n /** Smoothed value after this step. */\n readonly value: number;\n /** Velocity to pass into the next smoothDamp step. */\n readonly velocity: number;\n}\n\nfunction normalizeAngle(radians: number): number {\n const wrapped = ((((radians + Math.PI) % TAU) + TAU) % TAU) - Math.PI;\n // Preserve sign at +/-PI so direction survives the half-turn.\n return wrapped === -Math.PI && radians > 0 ? Math.PI : wrapped;\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 /** Return the clamped interpolation factor that produces v between a and b. */\n inverseLerp(a: number, b: number, v: number): number {\n if (a === b) return 0;\n return MathUtils.clamp((v - a) / (b - a), 0, 1);\n },\n\n /** Interpolate between angles in radians along the shortest path. */\n lerpAngle(a: number, b: number, t: number): number {\n return normalizeAngle(a + MathUtils.shortestAngleBetween(a, b) * t);\n },\n\n /** Signed shortest angular delta from a to b, in radians. */\n shortestAngleBetween(a: number, b: number): number {\n return normalizeAngle(b - a);\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 /** Bounce t between 0 and length. */\n pingPong(t: number, length: number): number {\n if (length <= 0) return 0;\n const wrapped = MathUtils.wrap(t, 0, length * 2);\n return length - Math.abs(wrapped - length);\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 /**\n * Smoothly damp current toward target without overshooting.\n * Pass the returned velocity back into the next call.\n */\n smoothDamp(\n current: number,\n target: number,\n velocity: number,\n smoothTime: number,\n deltaTime: number,\n maxSpeed: number = Infinity,\n ): SmoothDampResult {\n if (deltaTime <= 0) {\n return { value: current, velocity };\n }\n\n const safeSmoothTime = Math.max(MIN_SMOOTH_TIME, smoothTime);\n const omega = 2 / safeSmoothTime;\n const x = omega * deltaTime;\n const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x);\n const originalTarget = target;\n const maxChange = maxSpeed * safeSmoothTime;\n const change = MathUtils.clamp(current - target, -maxChange, maxChange);\n const adjustedTarget = current - change;\n const temp = (velocity + omega * change) * deltaTime;\n const nextVelocity = (velocity - omega * temp) * exp;\n let value = adjustedTarget + (change + temp) * exp;\n let resultVelocity = nextVelocity;\n const targetIsAboveCurrent = originalTarget - current > 0;\n const valuePassedTarget = targetIsAboveCurrent\n ? value > originalTarget\n : value < originalTarget;\n\n if (valuePassedTarget) {\n value = originalTarget;\n resultVelocity = 0;\n }\n\n return { value, velocity: resultVelocity };\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 { AssetManager } from \"./AssetManager.js\";\nimport type { Engine } from \"./Engine.js\";\nimport type { ErrorBoundary } from \"./ErrorBoundary.js\";\nimport type { EngineEvents, EventBus } from \"./EventBus.js\";\nimport type { GameLoop } from \"./GameLoop.js\";\nimport type { Inspector } from \"./Inspector.js\";\nimport type { Logger } from \"./Logger.js\";\nimport type { ProcessSystem } from \"./ProcessSystem.js\";\nimport type { QueryCache } from \"./QueryCache.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport type { SystemScheduler } from \"./SystemScheduler.js\";\n\n/** The resolution scope for a service. */\nexport type ServiceScope = \"engine\" | \"scene\";\n\n/** Options passed to `new ServiceKey(id, options)`. */\nexport interface ServiceKeyOptions {\n /**\n * Declared scope. `\"scene\"` keys are expected to be registered per-scene\n * via a `beforeEnter` hook; `Component.use` will check scene scope first\n * and warn if it falls back to engine scope.\n * Default: `\"engine\"`.\n */\n scope?: ServiceScope;\n}\n\n/** A typed key for service registration and resolution. */\nexport class ServiceKey<T> {\n /** Declared scope (engine or scene). Defaults to `\"engine\"`. */\n readonly scope: ServiceScope;\n\n constructor(\n /** Unique string identifier for this service. */\n public readonly id: string,\n options?: ServiceKeyOptions,\n ) {\n this.scope = options?.scope ?? \"engine\";\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 type-only imports to avoid circular imports. The generic parameter\n// documents the expected service type. Consumers import both the key and the\n// type.\n\n/** Key for the Engine instance. */\nexport const EngineKey = new ServiceKey<Engine>(\"engine\");\n\n/** Key for the EventBus instance. */\nexport const EventBusKey = new ServiceKey<EventBus<EngineEvents>>(\"eventBus\");\n\n/** Key for the SceneManager instance. */\nexport const SceneManagerKey = new ServiceKey<SceneManager>(\"sceneManager\");\n\n/** Key for the Logger instance. */\nexport const LoggerKey = new ServiceKey<Logger>(\"logger\");\n\n/** Key for the Inspector instance. */\nexport const InspectorKey = new ServiceKey<Inspector>(\"inspector\");\n\n/** Key for the QueryCache instance. */\nexport const QueryCacheKey = new ServiceKey<QueryCache>(\"queryCache\");\n\n/** Key for the ErrorBoundary instance. */\nexport const ErrorBoundaryKey = new ServiceKey<ErrorBoundary>(\"errorBoundary\");\n\n/** Key for the GameLoop instance. */\nexport const GameLoopKey = new ServiceKey<GameLoop>(\"gameLoop\");\n\n/** Key for the SystemScheduler instance. */\nexport const SystemSchedulerKey = new ServiceKey<SystemScheduler>(\n \"systemScheduler\",\n);\n\n/** Key for the ProcessSystem instance. */\nexport const ProcessSystemKey = new ServiceKey<ProcessSystem>(\"processSystem\");\n\n/** Key for the AssetManager instance. */\nexport const AssetManagerKey = new ServiceKey<AssetManager>(\"assetManager\");\n","import { ServiceKey } from \"./EngineContext.js\";\n\n/** Seeded random service used by runtime systems that must be deterministic. */\nexport interface RandomService {\n /** Random float in the range [0, 1). */\n float(): number;\n /** Random float in the range [min, max). */\n range(min: number, max: number): number;\n /** Random integer in the range [min, max] (inclusive). */\n int(min: number, max: number): number;\n /** Pick a random element from a non-empty array. */\n pick<T>(arr: readonly T[]): T;\n /** Shuffle an array in place and return the same array. */\n shuffle<T>(arr: T[]): T[];\n /** Return the seed this generator was constructed (or last reseeded) with. */\n getSeed(): number;\n}\n\n/**\n * Internal extension that exposes mid-stream reseeding. The Inspector uses\n * this to enforce deterministic E2E mode without leaking the foot-gun\n * (game code calling `setSeed` would corrupt other consumers' sequences in\n * the same scene).\n *\n * @internal\n */\nexport interface InternalRandomService extends RandomService {\n setSeed(seed: number): void;\n}\n\n/** Scene-scoped key for the active scene's deterministic RNG. */\nexport const RandomKey = new ServiceKey<RandomService>(\"random\", {\n scope: \"scene\",\n});\n\nconst UINT32_MAX = 0x1_0000_0000;\n\n/** Normalize arbitrary numbers into the uint32 seed space. */\nexport function normalizeSeed(seed: number): number {\n return seed >>> 0;\n}\n\n/** Default seed for explicitly non-deterministic paths. */\nexport function createDefaultRandomSeed(): number {\n return normalizeSeed(Date.now() ^ Math.floor(Math.random() * 1e9));\n}\n\nclass Mulberry32Random implements InternalRandomService {\n private seed: number;\n private state: number;\n\n constructor(seed: number) {\n const normalized = normalizeSeed(seed);\n this.seed = normalized;\n this.state = normalized;\n }\n\n float(): number {\n let t = (this.state += 0x6d2b79f5);\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / UINT32_MAX;\n }\n\n range(min: number, max: number): number {\n return min + this.float() * (max - min);\n }\n\n int(min: number, max: number): number {\n return Math.floor(this.range(min, max + 1));\n }\n\n pick<T>(arr: readonly T[]): T {\n if (arr.length === 0) {\n throw new Error(\"RandomService.pick() requires a non-empty array.\");\n }\n return arr[this.int(0, arr.length - 1)]!;\n }\n\n shuffle<T>(arr: T[]): T[] {\n for (let i = arr.length - 1; i > 0; i--) {\n const j = this.int(0, i);\n const tmp = arr[i]!;\n arr[i] = arr[j]!;\n arr[j] = tmp;\n }\n return arr;\n }\n\n setSeed(seed: number): void {\n const normalized = normalizeSeed(seed);\n this.seed = normalized;\n this.state = normalized;\n }\n\n getSeed(): number {\n return this.seed;\n }\n}\n\n/** Create a deterministic random service. */\nexport function createRandomService(\n seed = createDefaultRandomSeed(),\n): RandomService {\n return new Mulberry32Random(seed);\n}\n\n/**\n * Explicitly non-deterministic global RNG for boot-time or cross-scene code.\n * Inspector seed control never touches this instance.\n */\nexport const globalRandom = createRandomService();\n","import type { Component } from \"./Component.js\";\nimport type { ComponentClass } from \"./types.js\";\nimport type { SceneTransitionKind } from \"./SceneTransition.js\";\nimport type { Scene } from \"./Scene.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 \"scene:transition:started\": {\n kind: SceneTransitionKind;\n fromScene: SceneRef | undefined;\n toScene: SceneRef | undefined;\n };\n \"scene:transition:ended\": {\n kind: SceneTransitionKind;\n fromScene: SceneRef | undefined;\n toScene: SceneRef | undefined;\n };\n // Full Scene (not SceneRef) — subscribers typically compare by identity\n // against a Scene reference and may cast to LoadingScene to call\n // continue()/progress. Widening here avoids forcing casts at every site.\n \"scene:loading:progress\": { scene: Scene; ratio: number };\n \"scene:loading:done\": { scene: Scene };\n \"engine:started\": undefined;\n \"engine:stopped\": undefined;\n // Viewport / device events. Emitted by RendererPlugin when the canvas\n // host element enters/exits fullscreen and when the device orientation\n // changes. `OrientationType` is the built-in DOM lib union.\n \"screen:fullscreen\": { active: boolean };\n \"screen:orientation\": { type: OrientationType };\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 private observers = new Set<(event: keyof E, data: E[keyof E]) => 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 if (this.observers.size > 0) {\n const observers = [...this.observers];\n for (const observer of observers) {\n observer(event, data);\n }\n }\n\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 /**\n * Observe every emitted event without affecting handler order or control\n * flow. Used by tooling such as the Inspector event log.\n */\n tap(observer: (event: keyof E, data: E[keyof E]) => void): () => void {\n this.observers.add(observer);\n return () => {\n this.observers.delete(observer);\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","import type { Scene } from \"./Scene.js\";\nimport { ServiceKey, LoggerKey } from \"./EngineContext.js\";\nimport type { Logger } from \"./Logger.js\";\n\n/**\n * Plugin hooks invoked by the SceneManager at scene lifecycle points.\n * Plugins register hooks via `engine.registerSceneHooks(hooks)` to set up or\n * tear down per-scene state (e.g. render containers, physics worlds).\n */\nexport interface SceneHooks {\n /**\n * Runs after the scene's context is bound but before preload / `onEnter`.\n * Awaited serially so scoped services registered here are ready when the\n * scene's own code runs. Fires on `push`, `replace`, and `_mountDetached`.\n */\n beforeEnter?(scene: Scene): void | Promise<void>;\n\n /**\n * Runs after `onExit` + `_destroyAllEntities` and before the scene's\n * scoped-service map is cleared. Fires on `pop`, `replace`, `clear`, and\n * `_unmountDetached`.\n */\n afterExit?(scene: Scene): void;\n}\n\n/**\n * Registry of scene hooks. Held by the engine, consumed by the SceneManager.\n * @internal\n */\nexport class SceneHookRegistry {\n private readonly hooks: SceneHooks[] = [];\n\n register(hooks: SceneHooks): () => void {\n this.hooks.push(hooks);\n return () => {\n const idx = this.hooks.indexOf(hooks);\n if (idx !== -1) this.hooks.splice(idx, 1);\n };\n }\n\n /** Run all `beforeEnter` hooks serially. */\n async runBeforeEnter(scene: Scene): Promise<void> {\n for (const h of this.hooks) {\n await h.beforeEnter?.(scene);\n }\n }\n\n runAfterExit(scene: Scene): void {\n for (const h of this.hooks) {\n try {\n h.afterExit?.(scene);\n } catch (err) {\n // Swallow so one failing plugin doesn't block teardown of the rest.\n const logger = scene.context.tryResolve(LoggerKey) as\n | Logger\n | undefined;\n if (logger) {\n logger.error(\"core\", \"Scene afterExit hook threw\", {\n scene: scene.name,\n error: err,\n });\n } else {\n console.error(\n `[yage] Scene afterExit hook threw for scene \"${scene.name}\":`,\n err,\n );\n }\n }\n }\n }\n}\n\n/** DI key for the scene-hook registry. @internal */\nexport const SceneHookRegistryKey = new ServiceKey<SceneHookRegistry>(\n \"sceneHookRegistry\",\n);\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 *\n * @deprecated Prefer Entity subclasses with `setup()` for entity types.\n * Blueprints still work for parametric factories but are no longer the\n * recommended pattern for new code.\n */\nexport interface Blueprint<P = void> {\n readonly name: string;\n build(entity: Entity, params: P): void;\n}\n\n/**\n * Create a blueprint from a name and a build function.\n *\n * @deprecated Prefer Entity subclasses with `setup()` for entity types.\n */\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\nimport type { Entity } from \"./Entity.js\";\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): 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 { Logger } from \"./Logger.js\";\nimport type { Scene } from \"./Scene.js\";\nimport type { SnapshotResolver } from \"./Serializable.js\";\nimport type { ComponentClass } from \"./types.js\";\nimport { LoggerKey } from \"./EngineContext.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!: 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 threading through `this.entity.scene` in component\n * code.\n */\n get scene(): Scene {\n const scene = this.entity.tryScene;\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 /**\n * Resolve a service by key, cached after first lookup. Scene-scoped values\n * (registered via `scene._registerScoped`) take precedence over engine\n * scope. A key declared with `scope: \"scene\"` that falls back to engine\n * scope emits a one-shot dev warning — almost always signals a missed\n * `beforeEnter` hook.\n */\n protected use<T>(key: ServiceKey<T>): T {\n this._serviceCache ??= new Map();\n const cached = this._serviceCache.get(key.id);\n if (cached !== undefined) return cached as T;\n\n const scene = this.entity.tryScene;\n const scoped = scene?._resolveScoped(key);\n if (scoped !== undefined) {\n this._serviceCache.set(key.id, scoped);\n return scoped;\n }\n\n const value = this.context.resolve(key);\n if (key.scope === \"scene\") {\n // Don't cache: a later scoped registration should take precedence,\n // and the warning should keep firing until the plugin wiring is\n // fixed — caching would silence it after one hit.\n this._warnScopedFallback(key);\n return value;\n }\n this._serviceCache.set(key.id, value);\n return value;\n }\n\n private _warnScopedFallback<T>(key: ServiceKey<T>): void {\n const logger = this.context.tryResolve(LoggerKey) as Logger | undefined;\n logger?.warn(\n \"core\",\n `Scoped key \"${key.id}\" fell back to engine scope — did a plugin forget to register a beforeEnter hook?`,\n { component: this.constructor.name },\n );\n }\n\n /**\n * Lazy proxy-based service resolution. Can be used at field-declaration time:\n * ```ts\n * readonly input = this.service(InputManagerKey);\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 { Blueprint } from \"./Blueprint.js\";\nimport type { SnapshotResolver } from \"./Serializable.js\";\nimport type { Scene } from \"./Scene.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: 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 /**\n * The scene this entity belongs to. Throws if the entity is not attached\n * to a scene — which in practice only happens before `scene.spawn` /\n * `addChild` wires it up, or after `destroy()` tears it down. Inside\n * lifecycle methods (`setup`, component `onAdd`, `update`, etc.) this is\n * always safe to access.\n *\n * For the rare case where you genuinely need to inspect whether an\n * entity has a scene (e.g. defensive code in systems iterating a query\n * result), use `tryScene` instead.\n */\n get scene(): Scene {\n if (!this._scene) {\n throw new Error(\n `Entity \"${this.name}\" is not attached to a scene. Use \\`tryScene\\` if you need to check.`,\n );\n }\n return this._scene;\n }\n\n /** The scene this entity belongs to, or `null` if detached. */\n get tryScene(): 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 /**\n * Spawn a new entity in this entity's scene and add it as a named child.\n * Combines `scene.spawn(...)` + `this.addChild(name, ...)` in one call —\n * the idiomatic way to compose entity trees (logical root + visual body\n * + UI sibling + ...).\n *\n * Mirrors the overload shape of `Scene.spawn`: pass an Entity subclass\n * (with optional setup params), a `Blueprint`, or omit for an anonymous\n * base Entity.\n *\n * ```ts\n * this.spawnChild(\"body\", EnemyBody, { color: 0xff6b6b });\n * this.spawnChild(\"hp\", EnemyHealthBar);\n * ```\n */\n spawnChild(name: string): Entity;\n spawnChild<E extends Entity>(name: string, Class: new () => E): E;\n spawnChild<E extends Entity, P>(\n name: string,\n Class: new () => E & { setup(params: P): void },\n params: P,\n ): E;\n spawnChild<P>(\n name: string,\n blueprint: Blueprint<P>,\n params: P,\n ): Entity;\n // eslint-disable-next-line @typescript-eslint/unified-signatures -- preserves Class return-type narrowing on the overload above\n spawnChild(name: string, blueprint: Blueprint<void>): Entity;\n spawnChild(\n name: string,\n classOrBlueprint?: (new () => Entity) | Blueprint<unknown>,\n params?: unknown,\n ): Entity {\n const scene = this.scene;\n // Validate before spawning so we don't leave an orphan entity in the\n // scene if addChild would reject the name. addChild also throws on\n // this, but by then the spawn side-effects (scene.entities insert,\n // `entity:created` emit, setup() / blueprint.build()) have all run.\n if (this._children?.has(name)) {\n throw new Error(\n `Entity \"${this.name}\" already has a child named \"${name}\".`,\n );\n }\n // The public overloads above keep callsites type-safe. The\n // implementation signature is intentionally loose so it can funnel\n // into `Scene.spawn`'s matching overloads without per-variant\n // branches. When no class/blueprint is provided, forward `name` as\n // the entity's own name so `child.name` matches the child-map key.\n const child =\n classOrBlueprint === undefined\n ? scene.spawn(name)\n : (scene.spawn as (a?: unknown, b?: unknown) => Entity)(\n classOrBlueprint,\n params,\n );\n this.addChild(name, child);\n return child;\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 this._scene?._observeEntityEvent(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: 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.running || !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 { Transform } from \"./Transform.js\";\nimport type { Entity } from \"./Entity.js\";\nimport type { Component } from \"./Component.js\";\nimport type { Scene } from \"./Scene.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport type { GameLoop } from \"./GameLoop.js\";\nimport type { EventBus, EngineEvents } from \"./EventBus.js\";\nimport {\n EngineContext,\n ErrorBoundaryKey,\n ServiceKey,\n SystemSchedulerKey,\n} from \"./EngineContext.js\";\nimport {\n RandomKey,\n createDefaultRandomSeed,\n createRandomService,\n normalizeSeed,\n type InternalRandomService,\n type RandomService,\n} from \"./Random.js\";\n\n// Duplicate service keys locally to avoid runtime deps on optional packages.\nconst InputManagerRuntimeKey = new ServiceKey<InputManagerLike>(\"inputManager\");\nconst PhysicsWorldManagerRuntimeKey = new ServiceKey<PhysicsWorldManagerLike>(\n \"physicsWorldManager\",\n);\nconst RendererRuntimeKey = new ServiceKey<RendererLike>(\"renderer\");\n\n/**\n * Mirrors `GamepadAxisKey` from `@yagejs/input` as a local union so the\n * Inspector contract gets compile-time literal checking without taking a\n * runtime dependency on the input package.\n */\ntype InspectorGamepadAxisKey =\n | \"leftX\"\n | \"leftY\"\n | \"rightX\"\n | \"rightY\"\n | \"leftTrigger\"\n | \"rightTrigger\";\n\n/**\n * Options for synthetic pointer injection. Pass `id` / `type` / `isPrimary`\n * to drive a non-primary, touch, or pen pointer in deterministic tests. All\n * fields are optional and default to a primary mouse pointer with `id: 1`.\n */\ninterface InspectorPointerOpts {\n id?: number;\n type?: \"mouse\" | \"pen\" | \"touch\";\n isPrimary?: boolean;\n}\n\ninterface InputManagerLike {\n fireKeyDown(code: string): void;\n fireKeyUp(code: string): void;\n firePointerMove(x: number, y: number, opts?: InspectorPointerOpts): void;\n firePointerDown(button?: 0 | 1 | 2, opts?: InspectorPointerOpts): void;\n firePointerUp(button?: 0 | 1 | 2, opts?: { id?: number }): void;\n /** `code` is a gamepad code string (e.g. `\"GamepadA\"`, `\"GamepadLT\"`). */\n fireGamepadButton(code: string, pressed: boolean): void;\n fireGamepadAxis(side: InspectorGamepadAxisKey, value: number): void;\n fireAction(name: string): void;\n clearAll(): void;\n snapshotState(): InputStateSnapshot;\n}\n\ninterface PhysicsWorldManagerLike {\n getContext(scene: Scene): { world: PhysicsWorldLike } | undefined;\n}\n\ninterface PhysicsWorldLike {\n snapshot(): PhysicsSnapshot;\n}\n\ninterface RendererLike {\n application: {\n stage: unknown;\n renderer: {\n extract: {\n canvas(stage: unknown): HTMLCanvasElement;\n };\n };\n };\n}\n\ninterface CameraComponentLike {\n enabled: boolean;\n position: { x: number; y: number };\n zoom: number;\n rotation: number;\n priority?: number;\n cameraName?: string;\n}\n\ninterface UIElementLike {\n constructor: { name: string };\n children?: readonly UIElementLike[];\n yogaNode?: {\n getComputedLayout(): {\n left: number;\n top: number;\n width: number;\n height: number;\n };\n };\n}\n\n/** Backward-compatible summary snapshot returned by query helpers. */\nexport interface EntitySnapshot {\n id: number;\n name: string;\n tags: string[];\n components: string[];\n position?: { x: number; y: number };\n}\n\n/** Backward-compatible scene stack summary. */\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\nexport interface ComponentStateSnapshot {\n type: string;\n state: unknown | null;\n}\n\nexport interface WorldEntitySnapshot {\n id: string;\n type: string;\n parent: string | null;\n transform: {\n x: number;\n y: number;\n rotation: number;\n scaleX: number;\n scaleY: number;\n };\n components: ComponentStateSnapshot[];\n}\n\nexport interface UINodeSnapshot {\n id: string;\n type: string;\n layout: { x: number; y: number; width: number; height: number };\n children: UINodeSnapshot[];\n state: unknown | null;\n}\n\nexport interface UITreeSnapshot {\n root: UINodeSnapshot;\n}\n\nexport interface PhysicsSnapshot {\n bodies: Array<{\n entityId: string;\n type: \"dynamic\" | \"kinematic\" | \"static\";\n position: { x: number; y: number };\n rotation: number;\n linvel: { x: number; y: number };\n angvel: number;\n }>;\n contacts: Array<{ a: string; b: string }>;\n}\n\nexport interface EventLogEntry {\n frame: number;\n source: \"bus\" | \"entity\";\n type: string;\n targetId?: string;\n payload: unknown | null;\n}\n\nexport interface WorldSceneSnapshot {\n id: string;\n name: string;\n paused: boolean;\n timeScale: number;\n seed: number;\n entities: WorldEntitySnapshot[];\n ui: UITreeSnapshot | null;\n physics: PhysicsSnapshot;\n events: EventLogEntry[];\n}\n\nexport interface CameraSnapshot {\n sceneId: string;\n sceneName: string;\n name: string | null;\n priority: number;\n position: { x: number; y: number };\n zoom: number;\n rotation: number;\n}\n\n/**\n * Per-pointer entry in {@link InputStateSnapshot.pointers}. Mirrors the runtime\n * `PointerInfo` shape from `@yagejs/input`. Touch pointers vanish from the\n * array once their last button releases; mouse pointers persist.\n */\nexport interface PointerSnapshot {\n /** `PointerEvent.pointerId`, or the synthetic id passed via `firePointer*`. */\n id: number;\n x: number;\n y: number;\n type: \"mouse\" | \"pen\" | \"touch\";\n isPrimary: boolean;\n buttons: number[];\n down: boolean;\n}\n\nexport interface InputStateSnapshot {\n keys: string[];\n actions: string[];\n /**\n * Aggregate / primary-pointer view, retained for back-compat. `x` / `y` track\n * the primary pointer's screen position; `buttons` / `down` reflect the\n * any-pointer aggregate that drives the `MouseLeft`/`Middle`/`Right` action codes.\n *\n * For multi-touch state, read {@link InputStateSnapshot.pointers}.\n */\n mouse: {\n x: number;\n y: number;\n buttons: number[];\n down: boolean;\n };\n /** All currently-tracked pointers (one per active mouse, pen, or finger). */\n pointers: PointerSnapshot[];\n gamepad: {\n /** Currently-held gamepad codes (e.g. `\"GamepadA\"`, `\"GamepadLT\"`). */\n buttons: string[];\n /**\n * Axis state keyed by `${padIndex}:${axisName}` (axisName is a\n * `GamepadAxisKey` from `@yagejs/input`).\n */\n axes: Array<{ key: string; value: number }>;\n };\n}\n\n/** Full deterministic inspector snapshot. */\nexport interface EngineSnapshot {\n version: 1;\n frame: number;\n sceneStack: SceneSnapshot[];\n entityCount: number;\n systemCount: number;\n errors: ErrorSnapshot;\n scenes: WorldSceneSnapshot[];\n camera: CameraSnapshot | null;\n input: InputStateSnapshot;\n}\n\nexport interface InspectorTimeController {\n readonly isFrozen: boolean;\n freeze(): void;\n thaw(): void;\n stepFrames(count: number): void;\n setDelta(ms: number): void;\n getFrame(): number;\n}\n\ninterface LoggedEvent {\n entry: EventLogEntry;\n sceneId: string | undefined;\n}\n\ninterface EventWaiter {\n pattern: string | RegExp;\n source: \"bus\" | \"entity\" | undefined;\n withinFrames: number | undefined;\n deadlineFrame: number | undefined;\n resolve: (entry: EventLogEntry) => void;\n reject: (error: Error) => void;\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 readonly events?: EventBus<EngineEvents>;\n}\n\n/**\n * Programmatic runtime control and state queries for testing and debugging.\n * Exposed on `window.__yage__` in debug mode.\n */\nexport class Inspector {\n private readonly engine: EngineRef;\n private readonly extensions = new Map<string, object>();\n private readonly sceneIds = new WeakMap<Scene, string>();\n private nextSceneId = 0;\n private defaultSceneSeed: number | undefined;\n private sceneSeedOverride: number | undefined;\n private timeController: InspectorTimeController | null = null;\n private eventLogEnabled = false;\n private eventCapacity = 500;\n /**\n * Ring buffer of recent events. `eventLogHead` points at the oldest slot;\n * a full ring contains exactly `eventCapacity` entries. We avoid `splice` to\n * keep `appendEvent` O(1) — the previous shift-on-overflow approach was\n * O(n) per event once the buffer was full.\n */\n private eventLog: LoggedEvent[] = [];\n private eventLogHead = 0;\n private eventWaiters = new Set<EventWaiter>();\n private detachBusTap: (() => void) | null = null;\n private readonly busEventObserver = (\n event: keyof EngineEvents,\n data: EngineEvents[keyof EngineEvents],\n ): void => {\n this.recordBusEvent(String(event), data);\n };\n private readonly sceneEventObserver = (\n eventName: string,\n data: unknown,\n entity: Entity,\n ): void => {\n this.recordEntityEvent(eventName, data, entity);\n };\n\n readonly time = {\n freeze: (): void => {\n this.requireTimeController().freeze();\n },\n thaw: (): void => {\n this.requireTimeController().thaw();\n },\n step: (frames = 1): void => {\n this.assertNonNegativeInteger(frames, \"Inspector.time.step(frames)\");\n if (frames === 0) return;\n this.requireTimeController().stepFrames(frames);\n // Event matching happens inside appendEvent during the step. A trailing\n // pass here only needs to expire deadline waiters whose time ran out.\n this.expireDeadlineWaiters();\n },\n setDelta: (ms: number): void => {\n if (!Number.isFinite(ms) || ms <= 0) {\n throw new Error(\"Inspector.time.setDelta(ms) requires a positive number.\");\n }\n this.requireTimeController().setDelta(ms);\n },\n isFrozen: (): boolean => this.timeController?.isFrozen ?? false,\n getFrame: (): number =>\n this.timeController?.getFrame() ?? this.engine.loop.frameCount,\n };\n\n readonly input = {\n keyDown: (code: string): void => {\n this.requireInputManager().fireKeyDown(code);\n },\n keyUp: (code: string): void => {\n this.requireInputManager().fireKeyUp(code);\n },\n mouseMove: (x: number, y: number): void => {\n this.requireInputManager().firePointerMove(x, y);\n },\n mouseDown: (button: 0 | 1 | 2 = 0): void => {\n this.requireInputManager().firePointerDown(button);\n },\n mouseUp: (button: 0 | 1 | 2 = 0): void => {\n this.requireInputManager().firePointerUp(button);\n },\n /**\n * Inject a synthetic pointer-move with full pointer addressing. Pass `opts`\n * with `id` / `type: \"touch\"` to drive a specific finger; defaults match\n * the primary mouse pointer (same as `mouseMove`).\n */\n pointerMove: (\n x: number,\n y: number,\n opts?: InspectorPointerOpts,\n ): void => {\n this.requireInputManager().firePointerMove(x, y, opts);\n },\n /**\n * Inject a synthetic pointer-down. With `opts.id` and `opts.type: \"touch\"`\n * this drives a multi-touch contact, exercising `getPointers()`,\n * per-pointer event hooks, and the any-pointer aggregate for `MouseLeft`.\n */\n pointerDown: (\n button: 0 | 1 | 2 = 0,\n opts?: InspectorPointerOpts,\n ): void => {\n this.requireInputManager().firePointerDown(button, opts);\n },\n pointerUp: (\n button: 0 | 1 | 2 = 0,\n opts?: { id?: number },\n ): void => {\n this.requireInputManager().firePointerUp(button, opts);\n },\n gamepadButton: (code: string, pressed: boolean): void => {\n this.requireInputManager().fireGamepadButton(code, pressed);\n },\n gamepadAxis: (\n side: InspectorGamepadAxisKey,\n value: number,\n ): void => {\n this.requireInputManager().fireGamepadAxis(side, value);\n },\n tap: (code: string, frames = 1): void => {\n this.assertNonNegativeInteger(frames, \"Inspector.input.tap(frames)\");\n const input = this.requireInputManager();\n input.fireKeyDown(code);\n try {\n this.time.step(frames);\n } finally {\n input.fireKeyUp(code);\n }\n },\n hold: (code: string, frames: number): void => {\n this.assertNonNegativeInteger(frames, \"Inspector.input.hold(frames)\");\n const input = this.requireInputManager();\n input.fireKeyDown(code);\n try {\n this.time.step(frames);\n } finally {\n input.fireKeyUp(code);\n }\n },\n fireAction: (name: string, frames = 1): void => {\n this.assertNonNegativeInteger(\n frames,\n \"Inspector.input.fireAction(frames)\",\n );\n const input = this.requireInputManager();\n for (let i = 0; i < frames; i++) {\n input.fireAction(name);\n this.time.step(1);\n }\n },\n clearAll: (): void => {\n this.requireInputManager().clearAll();\n },\n };\n\n readonly events = {\n getLog: (): EventLogEntry[] =>\n this.iterateLog().map(({ entry }) => ({ ...entry })),\n clearLog: (): void => {\n this.eventLog.length = 0;\n this.eventLogHead = 0;\n },\n setCapacity: (n: number): void => {\n this.assertNonNegativeInteger(\n n,\n \"Inspector.events.setCapacity(capacity)\",\n );\n // `slice(-0)` is `slice(0)` (returns the whole array), so guard zero\n // explicitly — otherwise setCapacity(0) would leave stale entries.\n const ordered = n === 0 ? [] : this.iterateLog().slice(-n);\n this.eventCapacity = n;\n this.eventLog = ordered;\n this.eventLogHead = 0;\n },\n waitFor: (\n pattern: string | RegExp,\n options?: {\n withinFrames?: number;\n source?: \"bus\" | \"entity\";\n },\n ): Promise<EventLogEntry> => {\n const existing = this.findMatchingEvent(pattern, options?.source);\n if (existing) return Promise.resolve(existing);\n\n const withinFrames = options?.withinFrames;\n if (\n withinFrames !== undefined &&\n (!Number.isInteger(withinFrames) || withinFrames < 0)\n ) {\n throw new Error(\n \"Inspector.events.waitFor(withinFrames) requires a non-negative integer.\",\n );\n }\n\n return new Promise<EventLogEntry>((resolve, reject) => {\n const waiter: EventWaiter = {\n pattern,\n source: options?.source,\n withinFrames,\n deadlineFrame:\n withinFrames !== undefined\n ? this.time.getFrame() + withinFrames\n : undefined,\n resolve,\n reject,\n };\n this.eventWaiters.add(waiter);\n });\n },\n };\n\n readonly capture = {\n png: async (): Promise<Uint8Array> => {\n const base64 = await this.capture.pngBase64();\n return decodeBase64(base64);\n },\n dataURL: async (): Promise<string> => {\n const renderer = this.engine.context.tryResolve(RendererRuntimeKey);\n if (!renderer) {\n throw new Error(\n \"Inspector.capture requires RendererPlugin to be active.\",\n );\n }\n const canvas = renderer.application.renderer.extract.canvas(\n renderer.application.stage,\n );\n return canvas.toDataURL(\"image/png\");\n },\n pngBase64: async (): Promise<string> => {\n const dataUrl = await this.capture.dataURL();\n const comma = dataUrl.indexOf(\",\");\n return comma === -1 ? dataUrl : dataUrl.slice(comma + 1);\n },\n };\n\n constructor(engine: EngineRef) {\n this.engine = engine;\n }\n\n /** Register a namespaced extension API for plugin-specific debug helpers. */\n addExtension<T extends object>(namespace: string, api: T): T {\n this.assertNonEmptyString(\n namespace,\n \"Inspector.addExtension(namespace)\",\n );\n if (!api || typeof api !== \"object\") {\n throw new Error(\"Inspector.addExtension(api) requires an object.\");\n }\n if (this.extensions.has(namespace)) {\n throw new Error(\n `Inspector.addExtension(): namespace \"${namespace}\" is already registered.`,\n );\n }\n this.extensions.set(namespace, api);\n return api;\n }\n\n /** Look up a previously registered extension API by namespace. */\n getExtension<T extends object>(namespace: string): T | undefined {\n this.assertNonEmptyString(\n namespace,\n \"Inspector.getExtension(namespace)\",\n );\n return this.extensions.get(namespace) as T | undefined;\n }\n\n /** Remove a previously registered extension namespace. */\n removeExtension(namespace: string): void {\n this.assertNonEmptyString(\n namespace,\n \"Inspector.removeExtension(namespace)\",\n );\n this.extensions.delete(namespace);\n }\n\n /** Full deterministic state snapshot (stable ordering, serializable). */\n snapshot(): EngineSnapshot {\n const scenes = this.engine.scenes.all.map((scene) =>\n this.sceneToWorldSnapshot(scene),\n );\n return {\n version: 1,\n frame: this.time.getFrame(),\n sceneStack: this.getSceneStack(),\n entityCount: this.countEntities(),\n systemCount: this.getSystems().length,\n errors: this.getErrors(),\n scenes,\n camera: this.buildCameraSnapshot(),\n input: this.buildInputSnapshot(),\n };\n }\n\n /** Stable JSON form of {@link snapshot}. */\n snapshotJSON(): string {\n return stableStringify(this.snapshot());\n }\n\n /** Snapshot one scene by inspector scene id. */\n snapshotScene(id: string): WorldSceneSnapshot {\n const scene = this.engine.scenes.all.find(\n (candidate) => this.getSceneId(candidate) === id,\n );\n if (!scene) {\n throw new Error(`Inspector.snapshotScene(): unknown scene id \"${id}\".`);\n }\n return this.sceneToWorldSnapshot(scene);\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.entityToQuerySnapshot(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 if (typeof comp.serialize === \"function\") {\n const data = trySerialize(comp);\n if (data !== undefined) return data;\n }\n return this.serializeComponentOwnProperties(comp);\n }\n\n /** Get all entities in the active scene as lightweight 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.entityToQuerySnapshot(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 /** Create a new scene-scoped RNG instance using the current inspector seed policy. */\n createSceneRandom(): RandomService {\n const seed =\n this.sceneSeedOverride ?? this.defaultSceneSeed ?? createDefaultRandomSeed();\n return createRandomService(seed);\n }\n\n /** Force every current and future scene RNG to the provided seed. */\n setSeed(seed: number): void {\n const normalized = normalizeSeed(seed);\n this.sceneSeedOverride = normalized;\n for (const scene of this.engine.scenes.all) {\n this.resolveInternalRandom(scene)?.setSeed(normalized);\n }\n }\n\n /** @internal DebugPlugin installs a deterministic default seed through this hook. */\n setDefaultSceneSeed(seed: number | undefined): void {\n this.defaultSceneSeed =\n seed === undefined ? undefined : normalizeSeed(seed);\n if (this.sceneSeedOverride !== undefined || this.defaultSceneSeed === undefined) {\n return;\n }\n for (const scene of this.engine.scenes.all) {\n this.resolveInternalRandom(scene)?.setSeed(this.defaultSceneSeed);\n }\n }\n\n private resolveInternalRandom(scene: Scene): InternalRandomService | undefined {\n return scene._resolveScoped(RandomKey) as\n | InternalRandomService\n | undefined;\n }\n\n /** @internal DebugPlugin attaches the frozen-time controller through this hook. */\n attachTimeController(controller: InspectorTimeController): void {\n this.timeController = controller;\n }\n\n /** @internal Clear a previously attached time controller. */\n detachTimeController(controller?: InspectorTimeController): void {\n if (!controller || this.timeController === controller) {\n this.timeController = null;\n }\n }\n\n /** @internal Enable or disable event log recording. */\n setEventLogEnabled(enabled: boolean): void {\n if (this.eventLogEnabled === enabled) return;\n this.eventLogEnabled = enabled;\n\n if (enabled) {\n if (!this.detachBusTap && this.engine.events?.tap) {\n this.detachBusTap = this.engine.events.tap(this.busEventObserver);\n }\n } else {\n this.detachBusTap?.();\n this.detachBusTap = null;\n }\n\n for (const scene of this.engine.scenes.all) {\n if (enabled) {\n this.attachSceneEventObserver(scene);\n } else {\n this.detachSceneEventObserver(scene);\n }\n }\n }\n\n /** @internal Install entity-event observation for one scene. No-op if disabled. */\n attachSceneEventObserver(scene: Scene): void {\n if (!this.eventLogEnabled) return;\n scene._setEntityEventObserver(this.sceneEventObserver);\n }\n\n /** @internal Clear entity-event observation for one scene. */\n detachSceneEventObserver(scene: Scene): void {\n scene._setEntityEventObserver(undefined);\n }\n\n /** @internal Scene hooks forward entity events through this method. */\n recordEntityEvent(eventName: string, data: unknown, entity: Entity): void {\n if (!this.eventLogEnabled) return;\n const scene = entity.tryScene;\n this.appendEvent(\n {\n frame: this.time.getFrame(),\n source: \"entity\",\n type: eventName,\n targetId: String(entity.id),\n payload: serializeEventPayload(data),\n },\n scene ? this.getSceneId(scene) : undefined,\n );\n }\n\n /** @internal Engine teardown releases the event-bus tap through this hook. */\n dispose(): void {\n this.detachBusTap?.();\n this.detachBusTap = null;\n for (const scene of this.engine.scenes.all) {\n scene._setEntityEventObserver(undefined);\n }\n this.extensions.clear();\n }\n\n private requireTimeController(): InspectorTimeController {\n if (!this.timeController) {\n throw new Error(\n \"Inspector.time requires DebugPlugin to be active.\",\n );\n }\n return this.timeController;\n }\n\n private requireInputManager(): InputManagerLike {\n const input = this.engine.context.tryResolve(InputManagerRuntimeKey);\n if (!input) {\n throw new Error(\n \"Inspector.input requires InputPlugin to be active.\",\n );\n }\n return input;\n }\n\n private recordBusEvent(type: string, data: unknown): void {\n if (!this.eventLogEnabled) return;\n this.appendEvent(\n {\n frame: this.time.getFrame(),\n source: \"bus\",\n type,\n payload: serializeEventPayload(data),\n },\n this.inferSceneIdFromPayload(data),\n );\n }\n\n private appendEvent(entry: EventLogEntry, sceneId: string | undefined): void {\n if (this.eventCapacity === 0) {\n this.flushMatchingWaiter(entry);\n return;\n }\n const logged: LoggedEvent = { entry, sceneId };\n if (this.eventLog.length < this.eventCapacity) {\n this.eventLog.push(logged);\n } else {\n // Ring full: overwrite the oldest slot in O(1) and advance the head.\n this.eventLog[this.eventLogHead] = logged;\n this.eventLogHead =\n (this.eventLogHead + 1) % this.eventCapacity;\n }\n this.flushMatchingWaiter(entry);\n }\n\n /** Resolve waiters whose deadline has passed without a match. */\n private expireDeadlineWaiters(): void {\n if (this.eventWaiters.size === 0) return;\n const frame = this.time.getFrame();\n for (const waiter of [...this.eventWaiters]) {\n if (\n waiter.deadlineFrame !== undefined &&\n frame > waiter.deadlineFrame\n ) {\n this.eventWaiters.delete(waiter);\n waiter.reject(\n new Error(\n `Inspector.events.waitFor() timed out after ${waiter.withinFrames} frames.`,\n ),\n );\n }\n }\n }\n\n /** Resolve any waiter that matches the just-appended entry. */\n private flushMatchingWaiter(entry: EventLogEntry): void {\n if (this.eventWaiters.size === 0) return;\n for (const waiter of [...this.eventWaiters]) {\n if (this.eventMatches(entry, waiter.pattern, waiter.source)) {\n this.eventWaiters.delete(waiter);\n waiter.resolve(entry);\n }\n }\n }\n\n /**\n * Walk the ring buffer in chronological order. We avoid materializing the\n * ordered array on every event append; instead, every consumer that needs\n * order calls this helper.\n */\n private iterateLog(): LoggedEvent[] {\n if (this.eventLog.length < this.eventCapacity || this.eventLogHead === 0) {\n return this.eventLog;\n }\n return [\n ...this.eventLog.slice(this.eventLogHead),\n ...this.eventLog.slice(0, this.eventLogHead),\n ];\n }\n\n private findMatchingEvent(\n pattern: string | RegExp,\n source: \"bus\" | \"entity\" | undefined,\n ): EventLogEntry | undefined {\n for (const { entry } of this.iterateLog()) {\n if (this.eventMatches(entry, pattern, source)) {\n return { ...entry };\n }\n }\n return undefined;\n }\n\n private eventMatches(\n entry: EventLogEntry,\n pattern: string | RegExp,\n source: \"bus\" | \"entity\" | undefined,\n ): boolean {\n if (source && entry.source !== source) return false;\n return typeof pattern === \"string\"\n ? entry.type === pattern\n : pattern.test(entry.type);\n }\n\n private sceneToWorldSnapshot(scene: Scene): WorldSceneSnapshot {\n const random = scene._resolveScoped(RandomKey);\n const physicsManager = this.engine.context.tryResolve(\n PhysicsWorldManagerRuntimeKey,\n );\n return {\n id: this.getSceneId(scene),\n name: scene.name,\n paused: scene.isPaused,\n timeScale: scene.timeScale,\n seed: random?.getSeed() ?? 0,\n entities: this.getSceneEntities(scene),\n ui: this.buildUISnapshot(scene),\n physics:\n physicsManager?.getContext(scene)?.world.snapshot() ?? {\n bodies: [],\n contacts: [],\n },\n events: this.getSceneEvents(scene),\n };\n }\n\n private getSceneEntities(scene: Scene): WorldEntitySnapshot[] {\n return [...scene.getEntities()]\n .filter((entity) => !entity.isDestroyed)\n .sort((a, b) => a.id - b.id)\n .map((entity) => this.entityToWorldSnapshot(entity));\n }\n\n private entityToWorldSnapshot(entity: Entity): WorldEntitySnapshot {\n const transform = entity.has(Transform) ? entity.get(Transform) : undefined;\n const worldPosition = transform?.worldPosition;\n const worldScale = transform?.worldScale;\n const components = [...entity.getAll()]\n .map((component) => this.componentToSnapshot(component))\n .sort((a, b) => (a.type < b.type ? -1 : a.type > b.type ? 1 : 0));\n\n return {\n id: String(entity.id),\n type: entity.constructor.name,\n parent: entity.parent ? String(entity.parent.id) : null,\n transform: {\n x: worldPosition?.x ?? 0,\n y: worldPosition?.y ?? 0,\n rotation: transform?.worldRotation ?? 0,\n scaleX: worldScale?.x ?? 1,\n scaleY: worldScale?.y ?? 1,\n },\n components,\n };\n }\n\n private componentToSnapshot(component: Component): ComponentStateSnapshot {\n return {\n type: component.constructor.name,\n state:\n typeof component.serialize === \"function\"\n ? trySerialize(component) ?? null\n : null,\n };\n }\n\n private buildUISnapshot(scene: Scene): UITreeSnapshot | null {\n const roots = [...scene.getEntities()]\n .filter((entity) => !entity.isDestroyed)\n .flatMap((entity) =>\n [...entity.getAll()]\n .filter(\n (component) =>\n component.constructor.name === \"UIPanel\" &&\n \"_node\" in (component as object),\n )\n .map((component, index) =>\n this.buildUINodeSnapshot(\n (component as Component & { _node: UIElementLike })._node,\n `entity-${entity.id}:UIPanel:${index}`,\n ),\n ),\n );\n\n if (roots.length === 0) return null;\n if (roots.length === 1) {\n return { root: roots[0]! };\n }\n\n return {\n root: {\n id: `scene-${this.getSceneId(scene)}:ui`,\n type: \"UIRoot\",\n layout: { x: 0, y: 0, width: 0, height: 0 },\n children: roots,\n state: null,\n },\n };\n }\n\n private buildUINodeSnapshot(\n node: UIElementLike,\n id: string,\n ): UINodeSnapshot {\n const layout = node.yogaNode?.getComputedLayout();\n const children = (node.children ?? []).map((child, index) =>\n this.buildUINodeSnapshot(child, `${id}/${index}`),\n );\n return {\n id,\n type: node.constructor.name,\n layout: {\n x: layout?.left ?? 0,\n y: layout?.top ?? 0,\n width: layout?.width ?? 0,\n height: layout?.height ?? 0,\n },\n children,\n state: null,\n };\n }\n\n private buildCameraSnapshot(): CameraSnapshot | null {\n const match = this.findTopmostCamera();\n if (!match) return null;\n const { scene, camera } = match;\n return {\n sceneId: this.getSceneId(scene),\n sceneName: scene.name,\n name: camera.cameraName ?? null,\n priority: camera.priority ?? 0,\n position: {\n x: camera.position.x,\n y: camera.position.y,\n },\n zoom: camera.zoom,\n rotation: camera.rotation,\n };\n }\n\n private findTopmostCamera():\n | { scene: Scene; camera: CameraComponentLike }\n | undefined {\n const stack = this.engine.scenes.all;\n for (let i = stack.length - 1; i >= 0; i--) {\n const scene = stack[i];\n if (!scene) continue;\n\n let highest: CameraComponentLike | undefined;\n for (const entity of scene.getEntities()) {\n if (entity.isDestroyed) continue;\n for (const component of entity.getAll()) {\n if (component.constructor.name !== \"CameraComponent\") continue;\n const camera = component as unknown as CameraComponentLike;\n if (\n camera.enabled &&\n (!highest || (camera.priority ?? 0) > (highest.priority ?? 0))\n ) {\n highest = camera;\n }\n }\n }\n\n if (highest) {\n return { scene, camera: highest };\n }\n }\n\n return undefined;\n }\n\n private buildInputSnapshot(): InputStateSnapshot {\n const input = this.engine.context.tryResolve(InputManagerRuntimeKey);\n return (\n input?.snapshotState() ?? {\n keys: [],\n actions: [],\n mouse: { x: 0, y: 0, buttons: [], down: false },\n pointers: [],\n gamepad: { buttons: [], axes: [] },\n }\n );\n }\n\n private getSceneEvents(scene: Scene): EventLogEntry[] {\n const sceneId = this.getSceneId(scene);\n return this.iterateLog()\n .filter((entry) => entry.sceneId === sceneId)\n .map(({ entry }) => ({ ...entry }));\n }\n\n private inferSceneIdFromPayload(data: unknown): string | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n const record = data as Record<string, unknown>;\n\n const scene =\n this.extractScene(record[\"scene\"]) ??\n this.extractSceneFromEntity(record[\"entity\"]) ??\n this.extractSceneFromEntity(record[\"oldScene\"]) ??\n this.extractSceneFromEntity(record[\"newScene\"]);\n\n return scene ? this.getSceneId(scene) : undefined;\n }\n\n private extractScene(value: unknown): Scene | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n return this.engine.scenes.all.find((scene) => scene === value);\n }\n\n private extractSceneFromEntity(value: unknown): Scene | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const maybeEntity = value as { tryScene?: Scene | null };\n return maybeEntity.tryScene ?? this.extractScene(value);\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 entityToQuerySnapshot(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].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),\n components: [...entity.getAll()]\n .map((component) => component.constructor.name)\n .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),\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 serializeComponentOwnProperties(comp: Component): unknown {\n const result: Record<string, unknown> = {};\n for (const key of Object.getOwnPropertyNames(comp)) {\n if (key === \"entity\") continue;\n // Skip private-by-convention fields. Components hold pixi/rapier handles\n // (e.g. _node, _body) on underscore-prefixed slots; exposing them in\n // snapshots would either crash JSON.stringify on cycles or leak\n // meaningless object identities.\n if (key.startsWith(\"_\")) continue;\n const value = (comp as unknown as Record<string, unknown>)[key];\n if (!isSerializableValue(value)) continue;\n result[key] = value;\n }\n return result;\n }\n\n private countEntities(): number {\n let count = 0;\n for (const scene of this.engine.scenes.all) {\n for (const entity of scene.getEntities()) {\n if (!entity.isDestroyed) count++;\n }\n }\n return count;\n }\n\n private getSceneId(scene: Scene): string {\n let id = this.sceneIds.get(scene);\n if (!id) {\n this.nextSceneId++;\n id = `scene-${this.nextSceneId}`;\n this.sceneIds.set(scene, id);\n }\n return id;\n }\n\n private assertNonNegativeInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`${name} requires a non-negative integer.`);\n }\n }\n\n private assertNonEmptyString(value: string, name: string): void {\n if (value.trim().length === 0) {\n throw new Error(`${name} requires a non-empty string.`);\n }\n }\n}\n\nfunction isSerializableValue(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n const t = typeof value;\n if (t === \"function\") return false;\n if (t !== \"object\") return true;\n if (Array.isArray(value)) return true;\n // Plain objects pass; class instances (Pixi, Rapier, Yoga, etc.) don't.\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nfunction safeClone(value: unknown): unknown | undefined {\n try {\n return JSON.parse(JSON.stringify(value)) as unknown;\n } catch {\n return undefined;\n }\n}\n\nfunction trySerialize(component: Component): unknown | undefined {\n try {\n return safeClone(component.serialize?.());\n } catch {\n return undefined;\n }\n}\n\nfunction serializeEventPayload(payload: unknown): unknown | null {\n if (payload === undefined) return null;\n const cloned = safeClone(payload);\n return cloned === undefined ? { _unserializable: true } : cloned;\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortJsonValue(value));\n}\n\nfunction sortJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => sortJsonValue(item));\n }\n\n if (value && typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>).sort(\n ([left], [right]) => (left < right ? -1 : left > right ? 1 : 0),\n );\n const result: Record<string, unknown> = {};\n for (const [key, child] of entries) {\n result[key] = sortJsonValue(child);\n }\n return result;\n }\n\n return value;\n}\n\nfunction decodeBase64(base64: string): Uint8Array {\n if (typeof atob === \"function\") {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n\n const bufferCtor = (globalThis as {\n Buffer?: {\n from(value: string, encoding: \"base64\"): Uint8Array;\n };\n }).Buffer;\n if (bufferCtor) {\n return bufferCtor.from(base64, \"base64\");\n }\n\n throw new Error(\"Inspector.capture.png() is not supported in this environment.\");\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 type { SceneTransition } from \"./SceneTransition.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 /** Default transition used when this scene is the destination of a push/pop/replace. */\n readonly defaultTransition?: SceneTransition;\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 private _entityEventObserver?:\n | ((eventName: string, data: unknown, entity: Entity) => void)\n | undefined;\n private _scopedServices?: Map<string, unknown>;\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 /** Whether a scene transition is currently running. */\n get isTransitioning(): boolean {\n const sm = this._context?.tryResolve(SceneManagerKey);\n return sm?.isTransitioning ?? 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 /**\n * Observe entity-scoped event emissions after they dispatch locally and\n * bubble to the scene. Tooling only; game code should keep using `on()`.\n * @internal\n */\n _observeEntityEvent(eventName: string, data: unknown, entity: Entity): void {\n this._entityEventObserver?.(eventName, data, entity);\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 * Register a scene-scoped service. Called from a plugin's `beforeEnter`\n * hook to make per-scene state (render tree, physics world) resolvable via\n * `Component.use(key)`.\n * @internal\n */\n _registerScoped<T>(key: ServiceKey<T>, value: T): void {\n this._scopedServices ??= new Map();\n this._scopedServices.set(key.id, value);\n }\n\n /**\n * Install or clear a tooling-only observer for bubbled entity events.\n * @internal\n */\n _setEntityEventObserver(\n observer?: (eventName: string, data: unknown, entity: Entity) => void,\n ): void {\n this._entityEventObserver = observer;\n }\n\n /**\n * Resolve a scene-scoped service, or `undefined` if none was registered.\n * @internal\n */\n _resolveScoped<T>(key: ServiceKey<T>): T | undefined {\n return this._scopedServices?.get(key.id) as T | undefined;\n }\n\n /**\n * Clear all scene-scoped services. Called by the SceneManager after\n * `afterExit` hooks run, so plugin cleanup code still sees scoped state.\n * @internal\n */\n _clearScopedServices(): void {\n this._scopedServices?.clear();\n }\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 { 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 { Scene } from \"./Scene.js\";\nimport {\n EventBusKey,\n LoggerKey,\n ProcessSystemKey,\n SceneManagerKey,\n} from \"./EngineContext.js\";\nimport type { SceneTransition } from \"./SceneTransition.js\";\nimport { Process } from \"./Process.js\";\n\n/**\n * Base class for a progress-bar style loading screen.\n *\n * Preloads the target scene's assets through the `AssetManager`, exposes\n * `progress` and emits `scene:loading:progress` / `scene:loading:done` on\n * the engine event bus, enforces `minDuration` to prevent flicker on cached\n * loads, then replaces itself with `target` — optionally through a\n * transition.\n *\n * LoadingScene owns orchestration only. It does not render anything. To show\n * a progress UI, spawn an entity that subscribes to the loading events (the\n * canonical default is `LoadingSceneProgressBar` in `@yagejs/ui`, or any\n * custom component). The loading scene is a normal Scene, so you can use\n * `onEnter` to spawn whatever you want.\n *\n * ```ts\n * class Boot extends LoadingScene {\n * readonly target = new GameScene();\n * readonly minDuration = 500;\n * readonly transition = fade({ duration: 300 });\n * override onEnter() {\n * this.spawn(LoadingSceneProgressBar);\n * this.startLoading();\n * }\n * }\n *\n * await engine.scenes.replace(new Boot());\n * ```\n *\n * Set `autoContinue = false` to gate the handoff behind a `continue()` call\n * — useful for \"press any key to continue\" flows. `scene:loading:done`\n * still fires so UI can react (show a prompt), and whoever eventually\n * calls `this.continue()` triggers the transition.\n */\nexport abstract class LoadingScene extends Scene {\n override readonly name: string = \"loading\";\n\n /**\n * Scene to load and transition to. Accepts an instance or a factory —\n * use a factory when target construction should be deferred until\n * loading starts (heavy constructors, side effects). The factory runs\n * before `assets.loadAll` so `target.preload` can be inspected.\n */\n abstract readonly target: Scene | (() => Scene);\n\n /**\n * Minimum wall-clock ms the scene stays visible before handing off.\n * Prevents flicker on cached loads. Default 0.\n */\n readonly minDuration: number = 0;\n\n /** Transition used for the loading → target handoff. */\n readonly transition?: SceneTransition;\n\n /**\n * When true (default), the handoff fires automatically after loading and\n * `minDuration`. Set false to gate it behind `continue()` — useful when\n * the loading scene also asks the player to press a key or click.\n */\n readonly autoContinue: boolean = true;\n\n /**\n * Optional hook; fires if asset loading rejects. The scene stays mounted\n * whether or not this is set. When set, the hook is the recovery channel:\n * draw a retry UI, push an error scene, or call `this.startLoading()`\n * again to retry the load. When unset, the error is logged via the engine\n * logger and the scene remains mounted in a failed state with no\n * automatic recovery.\n *\n * The hook may still be running when the scene is replaced externally —\n * don't assume the scene is live (check `this.context.tryResolve` rather\n * than `this.service` before touching engine services, and avoid spawning\n * new entities after an `await`).\n */\n onLoadError?(error: Error): void | Promise<void>;\n\n private _progress = 0;\n private _started = false;\n private _active = true;\n private _continueRequested = false;\n private _continueGate?: () => void;\n private _pendingWaits = new Set<Process>();\n // Bumped on every `_run` attempt. `AssetManager.loadAll` uses `Promise.all`\n // under the hood, so individual loaders from a failed attempt can still\n // resolve and fire `onProgress` after the attempt rejects. Without this\n // guard, a retry kicked off from `onLoadError` would see stale progress\n // callbacks mutate `_progress` and emit `scene:loading:progress` events\n // attributed to the current attempt.\n private _attempt = 0;\n\n /** Current load progress, 0 → 1. Updated as the AssetManager reports progress. */\n get progress(): number {\n return this._progress;\n }\n\n /**\n * Kick off asset loading. While a load is in flight, subsequent calls\n * are no-ops. After a load failure the guard is released, so calling\n * `startLoading()` from `onLoadError` (or from a retry button) kicks off\n * a fresh load against the same target.\n *\n * Usually called once from `onEnter` after spawning the loading UI:\n * ```ts\n * override onEnter() {\n * this.spawn(LoadingSceneProgressBar);\n * this.startLoading();\n * }\n * ```\n *\n * Deferring the call lets you gate the start of the load behind a\n * title screen, \"press any key\" prompt, intro animation, etc.\n */\n startLoading(): void {\n if (this._started) return;\n this._started = true;\n // `_run` is fire-and-forget — the scene is already mounted, so there's\n // no `push`/`replace` caller to propagate errors to. The catch is the\n // final terminus for anything `_run` rethrows (target factory failure,\n // `scenes.replace` failure, or a load error with no `onLoadError`\n // override). Log it so the failure doesn't vanish into the browser's\n // unhandled-rejection channel.\n this._run().catch((err) => {\n if (!this._active) return;\n const logger = this.context.tryResolve(LoggerKey);\n if (logger) {\n logger.error(\"LoadingScene\", \"loading failed\", { error: err });\n } else {\n console.error(\"[LoadingScene] loading failed:\", err);\n }\n });\n }\n\n /**\n * Trigger the handoff to `target`. No-op if already called or if\n * `autoContinue` already fired it. If called before loading finishes,\n * the handoff runs as soon as loading + `minDuration` complete.\n */\n continue(): void {\n if (this._continueRequested) return;\n this._continueRequested = true;\n this._continueGate?.();\n }\n\n override onExit(): void {\n // Flip the run-guard so any in-flight _run() resumption short-circuits\n // instead of firing events or scheduling scenes.replace on a stack\n // that has already moved on. Also unblocks an autoContinue=false gate\n // so the promise resolves and the async function can terminate.\n this._active = false;\n this._continueGate?.();\n for (const wait of this._pendingWaits) {\n wait.cancel();\n }\n this._pendingWaits.clear();\n }\n\n private async _run(): Promise<void> {\n // Yield past the push-mutation window onEnter runs inside. Without\n // this, a target with empty or cached preload resumes the handoff\n // while SceneManager is still mid-mutation, and scenes.replace\n // would reject as reentrant.\n await Promise.resolve();\n if (!this._active) return;\n\n const attempt = ++this._attempt;\n const target =\n typeof this.target === \"function\" ? this.target() : this.target;\n const bus = this.context.resolve(EventBusKey);\n const minDuration = this._createEngineTimeDelay(this.minDuration);\n\n // `onLoadError` is specifically for asset-load failures. Narrow the\n // try/catch to the load phase so target-factory errors and\n // scenes.replace errors aren't silently swallowed through it.\n try {\n await this.assets.loadAll(target.preload ?? [], (ratio) => {\n if (!this._active || attempt !== this._attempt) return;\n this._progress = ratio;\n bus.emit(\"scene:loading:progress\", { scene: this, ratio });\n });\n if (!this._active || attempt !== this._attempt) {\n minDuration.cancel();\n return;\n }\n await minDuration.promise;\n if (!this._active || attempt !== this._attempt) return;\n } catch (err) {\n minDuration.cancel();\n // Scene exited mid-await → thrown error is incidental. Swallow.\n if (!this._active || attempt !== this._attempt) return;\n const error = err instanceof Error ? err : new Error(String(err));\n // Release the start guard so the hook (or anyone with a reference)\n // can call startLoading() again to retry. Bumping `_attempt` here\n // invalidates any still-in-flight progress callbacks from this\n // failed attempt before the retry's `onProgress` can fire.\n this._started = false;\n this._attempt++;\n if (this.onLoadError) {\n await this.onLoadError(error);\n return;\n }\n throw error;\n }\n\n bus.emit(\"scene:loading:done\", { scene: this });\n\n if (!this.autoContinue && !this._continueRequested) {\n await new Promise<void>((resolve) => {\n this._continueGate = resolve;\n });\n if (!this._active || attempt !== this._attempt) return;\n }\n\n const scenes = this.context.resolve(SceneManagerKey);\n await scenes.replace(\n target,\n this.transition ? { transition: this.transition } : undefined,\n );\n }\n\n private _createEngineTimeDelay(ms: number): {\n promise: Promise<void>;\n cancel: () => void;\n } {\n if (ms <= 0) {\n return {\n promise: Promise.resolve(),\n cancel: () => {},\n };\n }\n\n const wait = Process.delay(ms);\n this._pendingWaits.add(wait);\n this.context.resolve(ProcessSystemKey).add(wait);\n return {\n promise: wait.toPromise().finally(() => {\n this._pendingWaits.delete(wait);\n }),\n cancel: () => {\n wait.cancel();\n },\n };\n }\n}\n","import type { Scene } from \"./Scene.js\";\nimport type { EngineContext } from \"./EngineContext.js\";\n\n/** Which scene op triggered this transition. */\nexport type SceneTransitionKind = \"push\" | \"pop\" | \"replace\";\n\n/** Context passed to a transition each frame. */\nexport interface SceneTransitionContext {\n /** Wall-clock ms elapsed since begin(). */\n readonly elapsed: number;\n readonly kind: SceneTransitionKind;\n readonly engineContext: EngineContext;\n /** The scene being left or removed (undefined on first push). */\n readonly fromScene: Scene | undefined;\n /** The scene being entered or revealed (undefined on last pop). */\n readonly toScene: Scene | undefined;\n}\n\n/**\n * A scene transition animates the handoff between scene stack states.\n *\n * `SceneManager` keeps both the outgoing and incoming scenes on the stack\n * for the transition's duration, then removes the outgoing scene afterward.\n * Transitions use raw wall-clock dt and ignore engine + scene `timeScale`.\n */\nexport interface SceneTransition {\n /** Total duration in wall-clock ms. */\n readonly duration: number;\n /** Called once when the transition starts. Set up resources here. */\n begin?(ctx: SceneTransitionContext): void;\n /** Called each frame with frame dt in ms. `ctx.elapsed` is clamped to `duration`. */\n tick(dt: number, ctx: SceneTransitionContext): void;\n /** Called when the transition ends. Tear down resources here. */\n end?(ctx: SceneTransitionContext): void;\n}\n\n/** Options accepted by `SceneManager.push/pop/replace`. */\nexport interface SceneTransitionOptions {\n transition?: SceneTransition;\n}\n\n/**\n * Resolve the effective transition for a scene op.\n * Precedence: call-site option → destination's `defaultTransition` → undefined.\n */\nexport function resolveTransition(\n callSite: SceneTransition | undefined,\n destination: Scene | undefined,\n): SceneTransition | undefined {\n if (callSite) return callSite;\n return destination?.defaultTransition;\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, LoggerKey } from \"./EngineContext.js\";\nimport type { SceneHookRegistry } from \"./SceneHooks.js\";\nimport { SceneHookRegistryKey } from \"./SceneHooks.js\";\nimport type { Logger } from \"./Logger.js\";\nimport {\n resolveTransition,\n type SceneTransition,\n type SceneTransitionContext,\n type SceneTransitionKind,\n type SceneTransitionOptions,\n} from \"./SceneTransition.js\";\n\ninterface TransitionRun {\n kind: SceneTransitionKind;\n transition: SceneTransition;\n elapsed: number;\n fromScene: Scene | undefined;\n toScene: Scene | undefined;\n resolve: () => void;\n}\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 private hookRegistry: SceneHookRegistry | undefined;\n private logger: Logger | undefined;\n private _currentRun: TransitionRun | undefined;\n private _pendingChain: Promise<void> = Promise.resolve();\n private _mutationDepth = 0;\n private _destroyed = false;\n\n private _autoPauseOnBlur = false;\n private _isBlurred = false;\n private readonly _visibilityPausedScenes = new Set<Scene>();\n private _visibilityListenerCleanup: (() => void) | undefined;\n\n /**\n * Pause all non-paused scenes when `document.hidden` becomes `true`; restore\n * them on focus. Default: `false`. Only scenes paused by this mechanism are\n * restored — user-paused scenes (manual `scene.paused = true` or `pauseBelow`\n * cascade) are never touched.\n */\n get autoPauseOnBlur(): boolean {\n return this._autoPauseOnBlur;\n }\n\n set autoPauseOnBlur(value: boolean) {\n if (this._autoPauseOnBlur === value) return;\n this._autoPauseOnBlur = value;\n if (!this._isBlurred) return;\n if (value) {\n this._applyBlurPause();\n } else if (this._visibilityPausedScenes.size > 0) {\n this._restoreBlurPause();\n }\n }\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 this.hookRegistry = context.tryResolve(SceneHookRegistryKey);\n this.logger = context.tryResolve(LoggerKey);\n\n if (this._visibilityListenerCleanup || typeof document === \"undefined\") {\n return;\n }\n const onVisibilityChange = (): void => {\n this._handleVisibilityChange(document.hidden);\n };\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n this._visibilityListenerCleanup = () =>\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n }\n\n /**\n * React to a visibility change. Parameterised on `hidden` so unit tests can\n * drive it without a real `document`.\n * @internal\n */\n _handleVisibilityChange(hidden: boolean): void {\n if (hidden && !this._isBlurred) {\n this._isBlurred = true;\n if (this._autoPauseOnBlur) this._applyBlurPause();\n } else if (!hidden && this._isBlurred) {\n this._isBlurred = false;\n if (this._visibilityPausedScenes.size > 0) this._restoreBlurPause();\n }\n }\n\n private _applyBlurPause(): void {\n for (const scene of this.activeScenes) {\n scene.paused = true;\n this._visibilityPausedScenes.add(scene);\n }\n }\n\n private _restoreBlurPause(): void {\n for (const scene of this._visibilityPausedScenes) {\n scene.paused = false;\n }\n this._visibilityPausedScenes.clear();\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((scene) => !scene.isPaused);\n }\n\n /** Whether a scene transition is currently running. */\n get isTransitioning(): boolean {\n return this._currentRun !== undefined;\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 */\n async push(scene: Scene, opts?: SceneTransitionOptions): Promise<void> {\n this._assertNotMutating(\"push\");\n await this._enqueue(async () => {\n const fromScene = this.active;\n await this._pushScene(scene);\n\n const transition = resolveTransition(opts?.transition, scene);\n if (!transition) return;\n\n await this._runTransition(\"push\", transition, fromScene, scene);\n });\n }\n\n /** Pop the top scene. Scenes below may receive onResume(). */\n async pop(opts?: SceneTransitionOptions): Promise<Scene | undefined> {\n this._assertNotMutating(\"pop\");\n return this._enqueue(async () => {\n if (this.stack.length === 0) return undefined;\n\n const fromScene = this.active;\n const destination =\n this.stack.length > 1 ? this.stack[this.stack.length - 2] : undefined;\n const transition = resolveTransition(opts?.transition, destination);\n\n if (transition) {\n await this._runTransition(\"pop\", transition, fromScene, destination);\n }\n\n return this._popScene();\n });\n }\n\n /**\n * Replace the top scene. Without a transition the old scene exits first,\n * then the new scene enters. With a transition the new scene is pushed\n * first, both scenes coexist for the transition duration, then the old\n * scene is removed at the end.\n */\n async replace(scene: Scene, opts?: SceneTransitionOptions): Promise<void> {\n this._assertNotMutating(\"replace\");\n await this._enqueue(async () => {\n const transition = resolveTransition(opts?.transition, scene);\n\n if (!transition) {\n await this._replaceScene(scene);\n return;\n }\n\n const old = this.active;\n await this._pushScene(scene, true);\n await this._runTransition(\"replace\", transition, old, scene);\n\n if (old) {\n this._removeScene(old, true);\n }\n this.bus?.emit(\"scene:replaced\", {\n oldScene: old ?? scene,\n newScene: scene,\n });\n });\n }\n\n /**\n * Pop every scene on the stack, top to bottom. Each receives onExit().\n * Queued like push/pop/replace — runs after any in-flight transition.\n * Use for \"restart from menu\"-style flows. Does not run transitions.\n */\n async popAll(): Promise<void> {\n this._assertNotMutating(\"popAll\");\n await this._enqueue(async () => {\n this._withMutationSync(() => {\n while (this.stack.length > 0) {\n const scene = this.stack.pop();\n if (!scene) break;\n this._teardownScene(scene);\n this.bus?.emit(\"scene:popped\", { scene });\n }\n });\n });\n }\n\n /**\n * Run the full scene-enter lifecycle (beforeEnter hooks, preload, onEnter)\n * for a scene that is NOT placed on the stack. Used by infrastructure\n * plugins like DebugPlugin that render a scene off-stack.\n * @internal\n */\n async _mountDetached(scene: Scene): Promise<void> {\n await this._withMutation(async () => {\n scene._setContext(this._context);\n await this.hookRegistry?.runBeforeEnter(scene);\n await this._preloadScene(scene);\n scene.onEnter?.();\n });\n }\n\n /**\n * Run the scene-exit lifecycle (onExit, entity destruction, afterExit\n * hooks, scoped-service clear) for a detached scene.\n * @internal\n */\n _unmountDetached(scene: Scene): void {\n this._withMutationSync(() => {\n this._teardownScene(scene);\n });\n }\n\n /**\n * Mark the manager destroyed and synchronously tear down every scene.\n * Called by Engine.destroy(). Any queued async work short-circuits on\n * resume; in-flight transitions' pending promises are resolved via\n * _cleanupRun so they don't leak.\n * @internal\n */\n _destroy(): void {\n this._destroyed = true;\n if (this._currentRun) {\n this._cleanupRun(this._currentRun);\n }\n this._pendingChain = Promise.resolve();\n\n this._visibilityListenerCleanup?.();\n this._visibilityListenerCleanup = undefined;\n this._visibilityPausedScenes.clear();\n\n this._withMutationSync(() => {\n while (this.stack.length > 0) {\n const scene = this.stack.pop();\n if (!scene) break;\n this._teardownScene(scene);\n this.bus?.emit(\"scene:popped\", { scene });\n }\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 /**\n * Advance the active transition by `dt` ms. Called by Engine's earlyUpdate\n * callback with raw (unscaled) wall-clock dt.\n * @internal\n */\n _tickTransition(dt: number): void {\n const run = this._currentRun;\n if (!run) return;\n\n const remaining = run.transition.duration - run.elapsed;\n const consume = Math.min(dt, remaining);\n run.elapsed += consume;\n this._safeTick(run, consume);\n\n if (run.elapsed >= run.transition.duration) {\n this._cleanupRun(run);\n }\n }\n\n // ---- Private helpers ----\n\n private _enqueue<T>(work: () => Promise<T>): Promise<T | undefined> {\n if (this._destroyed) return Promise.resolve(undefined);\n const next = this._pendingChain.then(async () => {\n if (this._destroyed) return undefined;\n return work();\n });\n\n this._pendingChain = next.then(\n () => undefined,\n () => undefined,\n );\n\n return next;\n }\n\n private async _pushScene(\n scene: Scene,\n suppressEvent = false,\n ): Promise<void> {\n const wasPaused = this._snapshotPauseStates();\n\n await this._withMutation(async () => {\n scene._setContext(this._context);\n await this.hookRegistry?.runBeforeEnter(scene);\n // Preload before pushing so a failed asset load doesn't leave an\n // un-entered scene on the stack.\n await this._preloadScene(scene);\n this.stack.push(scene);\n scene.onEnter?.();\n this._firePauseTransitions(wasPaused);\n if (!suppressEvent) {\n this.bus?.emit(\"scene:pushed\", { scene });\n }\n });\n }\n\n private _popScene(suppressEvent = false): Scene | undefined {\n const wasPaused = this._snapshotPauseStates();\n\n return this._withMutationSync(() => {\n const removed = this.stack.pop();\n if (!removed) return undefined;\n\n this._teardownScene(removed);\n this._fireResumeTransitions(wasPaused);\n if (!suppressEvent) {\n this.bus?.emit(\"scene:popped\", { scene: removed });\n }\n return removed;\n });\n }\n\n private async _replaceScene(scene: Scene): Promise<void> {\n const wasPaused = this._snapshotPauseStates();\n\n await this._withMutation(async () => {\n scene._setContext(this._context);\n await this.hookRegistry?.runBeforeEnter(scene);\n // Preload before mutating the stack so a failed asset load doesn't\n // tear down the old scene without a working replacement.\n await this._preloadScene(scene);\n\n const old = this.stack.pop();\n if (old) this._teardownScene(old);\n this.stack.push(scene);\n scene.onEnter?.();\n\n this._firePauseTransitions(wasPaused);\n this._fireResumeTransitions(wasPaused);\n this.bus?.emit(\"scene:replaced\", {\n oldScene: old ?? scene,\n newScene: scene,\n });\n });\n }\n\n private _removeScene(scene: Scene, suppressEvent = false): void {\n this._withMutationSync(() => {\n const idx = this.stack.indexOf(scene);\n if (idx === -1) return;\n\n const wasPaused = this._snapshotPauseStates();\n this.stack.splice(idx, 1);\n this._teardownScene(scene);\n this._firePauseTransitions(wasPaused);\n this._fireResumeTransitions(wasPaused);\n if (!suppressEvent) {\n this.bus?.emit(\"scene:popped\", { scene });\n }\n });\n }\n\n private async _preloadScene(scene: Scene): Promise<void> {\n if (!scene.preload?.length || !this.assetManager) return;\n await this.assetManager.loadAll(\n scene.preload,\n scene.onProgress?.bind(scene),\n );\n }\n\n private _teardownScene(scene: Scene): void {\n scene.onExit?.();\n scene._destroyAllEntities();\n this.hookRegistry?.runAfterExit(scene);\n scene._clearScopedServices();\n this._visibilityPausedScenes.delete(scene);\n }\n\n private async _runTransition(\n kind: SceneTransitionKind,\n transition: SceneTransition,\n fromScene: Scene | undefined,\n toScene: Scene | undefined,\n ): Promise<void> {\n // If destroy() landed between this op's prior await and here, bail\n // before registering a _currentRun whose promise would never resolve\n // (the loop is stopped, so _tickTransition won't fire).\n if (this._destroyed) return;\n\n let resolveRun!: () => void;\n const promise = new Promise<void>((resolve) => {\n resolveRun = resolve;\n });\n\n const run: TransitionRun = {\n kind,\n transition,\n elapsed: 0,\n fromScene,\n toScene,\n resolve: resolveRun,\n };\n this._currentRun = run;\n this.bus?.emit(\"scene:transition:started\", {\n kind,\n fromScene,\n toScene,\n });\n\n // Fire begin synchronously so the transition can paint its start state\n // before any render happens. For push/replace this lets built-ins hide\n // the incoming scene before a frame could show it covering the old one.\n this._safeCall(run, \"begin\");\n\n // Reject NaN and Infinity (Infinity > 0 is true, so the naive check\n // lets it through and _tickTransition would loop forever without ever\n // reaching elapsed >= duration, hanging the _pendingChain).\n if (!Number.isFinite(transition.duration) || transition.duration <= 0) {\n this._cleanupRun(run);\n return;\n }\n\n await promise;\n }\n\n private _cleanupRun(run: TransitionRun): void {\n if (this._currentRun !== run) return;\n\n this._safeCall(run, \"end\");\n this._currentRun = undefined;\n this.bus?.emit(\"scene:transition:ended\", {\n kind: run.kind,\n fromScene: run.fromScene,\n toScene: run.toScene,\n });\n run.resolve();\n }\n\n private _safeTick(run: TransitionRun, dt: number): void {\n try {\n run.transition.tick(dt, this._makeContext(run));\n } catch (err: unknown) {\n this.logger?.warn(\n \"SceneManager\",\n `Transition tick error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private _safeCall(run: TransitionRun, method: \"begin\" | \"end\"): void {\n try {\n run.transition[method]?.(this._makeContext(run));\n } catch (err: unknown) {\n this.logger?.warn(\n \"SceneManager\",\n `Transition ${method} error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private _makeContext(run: TransitionRun): SceneTransitionContext {\n return {\n elapsed: run.elapsed,\n kind: run.kind,\n engineContext: this._context,\n fromScene: run.fromScene,\n toScene: run.toScene,\n };\n }\n\n private _snapshotPauseStates(): Map<Scene, boolean> {\n return new Map(\n this.stack.map((scene) => [scene, scene.isPaused] as const),\n );\n }\n\n private _assertNotMutating(method: string): void {\n if (this._mutationDepth === 0) return;\n throw new Error(\n `SceneManager.${method}() called reentrantly from a scene lifecycle hook ` +\n \"(onEnter/onExit/onPause/onResume or a beforeEnter/afterExit hook). \" +\n \"Defer the call outside the hook, e.g. via queueMicrotask() or from a component update().\",\n );\n }\n\n private async _withMutation<T>(work: () => Promise<T>): Promise<T> {\n this._mutationDepth++;\n try {\n return await work();\n } finally {\n this._mutationDepth--;\n }\n }\n\n private _withMutationSync<T>(work: () => T): T {\n this._mutationDepth++;\n try {\n return work();\n } finally {\n this._mutationDepth--;\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 scene of this.stack) {\n const was = wasPaused.get(scene) ?? false;\n if (scene.isPaused && !was) {\n scene.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 scene of this.stack) {\n const was = wasPaused.get(scene) ?? false;\n if (!scene.isPaused && was) {\n scene.onResume?.();\n }\n }\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 { ProcessOptions } from \"./Process.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: 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\";\nimport { serializable } from \"./Serializable.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 */\n@serializable\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 serialize(): null {\n return null;\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\";\nimport { serializable } from \"./Serializable.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 */\n@serializable\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 serialize(): null {\n return null;\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 { Scene } from \"./Scene.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport type { Process } from \"./Process.js\";\nimport { ProcessComponent } from \"./ProcessComponent.js\";\nimport { SceneManagerKey } from \"./EngineContext.js\";\nimport { SceneHookRegistryKey } from \"./SceneHooks.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 globalProcesses = new Set<Process>();\n private scenePools = new Map<Scene, Set<Process>>();\n private _unregisterSceneHook: (() => void) | null = null;\n\n override onRegister(context: EngineContext): void {\n this.sceneManager = context.resolve(SceneManagerKey);\n // Drop the scene's pool on exit so cancelled processes (e.g. effect\n // fades torn down with the scene) don't keep the dead Scene key\n // alive in the pool map. Hold onto the unregister callback so engine\n // teardown releases the hook — without this, a re-created Engine\n // sharing a SceneHookRegistry would accumulate dead callbacks.\n const hooks = context.tryResolve(SceneHookRegistryKey);\n this._unregisterSceneHook =\n hooks?.register({\n afterExit: (scene) => this.cancelForScene(scene),\n }) ?? null;\n }\n\n override onUnregister(): void {\n this._unregisterSceneHook?.();\n this._unregisterSceneHook = null;\n // Drain pools so cancelled processes don't keep Scene refs alive.\n for (const p of this.globalProcesses) {\n if (!p.completed) p.cancel();\n }\n this.globalProcesses.clear();\n for (const pool of this.scenePools.values()) {\n for (const p of pool) {\n if (!p.completed) p.cancel();\n }\n }\n this.scenePools.clear();\n }\n\n /**\n * Add an engine-global process. Ticked under the global timeScale only;\n * NOT gated by per-scene pause or scaled by per-scene timeScale. Use this\n * for cross-scene effects (e.g. screen-scope filter fades on `app.stage`)\n * or processes that have no owning scene.\n */\n add(process: Process): Process {\n this.globalProcesses.add(process);\n return process;\n }\n\n /**\n * Add a process bound to a specific scene's lifecycle. Ticked only while\n * the scene is active (not paused) and scaled by the scene's `timeScale`,\n * exactly like an entity-owned `ProcessComponent`. Use this for layer or\n * scene-scope effect fades that should pause with the scene.\n */\n addForScene(scene: Scene, process: Process): Process {\n let pool = this.scenePools.get(scene);\n if (!pool) {\n pool = new Set();\n this.scenePools.set(scene, pool);\n }\n pool.add(process);\n return process;\n }\n\n /** Cancel engine-global processes, optionally by tag. */\n cancel(tag?: string): void {\n for (const p of this.globalProcesses) {\n if (tag === undefined || p.tags.includes(tag)) {\n p.cancel();\n this.globalProcesses.delete(p);\n }\n }\n }\n\n /** Cancel every scene-bound process for `scene`, optionally by tag. */\n cancelForScene(scene: Scene, tag?: string): void {\n const pool = this.scenePools.get(scene);\n if (!pool) return;\n for (const p of pool) {\n if (tag === undefined || p.tags.includes(tag)) {\n p.cancel();\n pool.delete(p);\n }\n }\n if (pool.size === 0) this.scenePools.delete(scene);\n }\n\n update(dt: number): void {\n const globalScaledDt = dt * this.timeScale;\n\n // Engine-global processes — global timeScale only, not scene-bound.\n for (const p of this.globalProcesses) {\n p._update(globalScaledDt);\n if (p.completed) {\n this.globalProcesses.delete(p);\n }\n }\n\n // Per-scene work: entity ProcessComponents AND scene-scoped processes.\n // Both share the same activeScenes gating + per-scene timeScale, so a\n // layer-scope fade pauses with the scene exactly like an entity fade.\n for (const scene of this.sceneManager.activeScenes) {\n const effectiveDt = globalScaledDt * scene.timeScale;\n\n const pool = this.scenePools.get(scene);\n if (pool) {\n for (const p of pool) {\n p._update(effectiveDt);\n if (p.completed) pool.delete(p);\n }\n if (pool.size === 0) this.scenePools.delete(scene);\n }\n\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 type { Entity } from \"./Entity.js\";\nimport type { Process } from \"./Process.js\";\nimport { ProcessComponent } from \"./ProcessComponent.js\";\nimport type { ProcessSystem } from \"./ProcessSystem.js\";\nimport type { Scene } from \"./Scene.js\";\n\n/**\n * A scoped queue for `Process` instances. Tracks the processes it enqueued so\n * `cancelAll()` can tear them down without touching unrelated processes that\n * happen to share the same underlying pool (entity `ProcessComponent` or\n * engine-level `ProcessSystem`).\n *\n * Use one of the `make*ScopedQueue` factories to construct one — each picks\n * the right routing strategy and lifetime semantics for its scope.\n */\nexport interface ScopedProcessQueue {\n /** Enqueue a process. Returned for chaining. */\n run(p: Process): Process;\n /** Cancel every process this queue enqueued. Idempotent. */\n cancelAll(): void;\n}\n\n/**\n * Build a `ScopedProcessQueue` over a routing function. The three public\n * factories below differ only in WHERE they route the process (entity\n * ProcessComponent / scene-bound pool / engine-global pool); the tracking,\n * lazy-prune-on-run, and isolated-cancelAll behavior is identical.\n *\n * Lazy O(n) sweep on each `run()` is bounded by how many processes the\n * queue has accumulated; cheap and avoids holding refs to completed Process\n * instances for the queue's lifetime.\n */\nfunction makeQueue(route: (p: Process) => void): ScopedProcessQueue {\n const ours = new Set<Process>();\n return {\n run(p) {\n for (const old of ours) {\n if (old.completed) ours.delete(old);\n }\n route(p);\n ours.add(p);\n return p;\n },\n cancelAll() {\n for (const p of ours) {\n if (!p.completed) p.cancel();\n }\n ours.clear();\n },\n };\n}\n\n/**\n * Scoped queue that routes through the entity's `ProcessComponent`. Auto-adds\n * one if the entity doesn't already have it. `cancelAll()` only cancels the\n * processes this queue enqueued, so sharing the underlying ProcessComponent\n * with user code stays safe.\n */\nexport function makeEntityScopedQueue(entity: Entity): ScopedProcessQueue {\n return makeQueue((p) => {\n let pc = entity.tryGet(ProcessComponent);\n if (!pc) {\n pc = entity.add(new ProcessComponent());\n }\n pc.run(p);\n });\n}\n\n/**\n * Scoped queue bound to a specific scene's lifecycle. Routes through\n * `ProcessSystem.addForScene`, so processes pause with the scene and are\n * scaled by its `timeScale` — matching the behaviour of entity-owned\n * `ProcessComponent` processes.\n */\nexport function makeSceneScopedQueue(\n processSystem: ProcessSystem,\n scene: Scene,\n): ScopedProcessQueue {\n return makeQueue((p) => processSystem.addForScene(scene, p));\n}\n\n/**\n * Engine-global scoped queue. Routes through `ProcessSystem.add` — ticked\n * under the global timeScale only, NOT gated by per-scene pause or scaled\n * by per-scene timeScale. Right for cross-scene work that should keep\n * playing during scene transitions and across paused scenes.\n */\nexport function makeGlobalScopedQueue(\n processSystem: ProcessSystem,\n): ScopedProcessQueue {\n return makeQueue((p) => processSystem.add(p));\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\";\nimport { SceneHookRegistry, SceneHookRegistryKey } from \"./SceneHooks.js\";\nimport type { SceneHooks } from \"./SceneHooks.js\";\nimport { RandomKey } from \"./Random.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 private readonly sceneHooks: SceneHookRegistry;\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 this.sceneHooks = new SceneHookRegistry();\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 this.context.register(SceneHookRegistryKey, this.sceneHooks);\n\n this.sceneHooks.register({\n beforeEnter: (scene) => {\n scene._registerScoped(RandomKey, this.inspector.createSceneRandom());\n this.inspector.attachSceneEventObserver(scene);\n },\n afterExit: (scene) => {\n this.inspector.detachSceneEventObserver(scene);\n },\n });\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.scenes._tickTransition(dt);\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 /**\n * Register scene lifecycle hooks. The returned function unregisters the\n * hooks. Infrastructure plugins (renderer, physics, debug) register hooks\n * in their `install` or `onStart` to set up and tear down per-scene state.\n */\n registerSceneHooks(hooks: SceneHooks): () => void {\n return this.sceneHooks.register(hooks);\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. Awaited so users can reliably call scenes.push()\n // right after `await engine.start()` without racing plugin init\n // (e.g. DebugPlugin mounts a detached debug scene in onStart).\n for (const plugin of sorted) {\n await 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 // Tear down scenes synchronously; also short-circuits any queued async work.\n this.scenes._destroy();\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.inspector.dispose();\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 { ServiceKey } from \"./EngineContext.js\";\n\n/**\n * Cross-package contract for \"something that owns a canvas and can map\n * canvas-relative CSS pixels into virtual-space pixels\".\n *\n * Implemented by `@yagejs/renderer`'s `RendererPlugin` and consumed by\n * `@yagejs/input` for pointer-event targeting and coordinate mapping under\n * responsive fit. Foreign renderers can implement this interface and register\n * under `RendererAdapterKey` to integrate with the input plugin without\n * importing `@yagejs/renderer`.\n */\nexport interface RendererAdapter {\n readonly canvas: HTMLCanvasElement;\n /**\n * Convert CSS pixels relative to the canvas into virtual-space pixels.\n * Optional — when absent, consumers fall back to raw CSS pixels (correct\n * only when canvas CSS size equals virtual size).\n */\n canvasToVirtual?(x: number, y: number): { x: number; y: number };\n /**\n * Hit-test at virtual-space coordinates and return `true` when the topmost\n * interactive container under `(x, y)` is parented (directly or through any\n * ancestor) to a container marked via {@link markPointerConsumeContainer}.\n * Optional — when absent, the input plugin's UI auto-consume fallback is a\n * no-op.\n *\n * Implemented by `@yagejs/renderer` over Pixi's `EventBoundary`. The input\n * plugin calls this on `pointerdown` drains to auto-claim presses that land\n * on UI surfaces (UIPanel backgrounds, decorative UIText, etc.) without\n * requiring per-component handler boilerplate.\n */\n hitTestUI?(x: number, y: number): boolean;\n}\n\n/**\n * Well-known service key for the current renderer's pointer-input adapter.\n * The canonical `@yagejs/renderer` plugin registers itself here; consumers\n * (notably `@yagejs/input`) resolve this key to auto-wire canvas targeting\n * and coordinate mapping.\n */\nexport const RendererAdapterKey = new ServiceKey<RendererAdapter>(\n \"rendererAdapter\",\n);\n","/**\n * Cross-package WeakSet for marking display containers (Pixi `Container`s in\n * the canonical setup) as \"swallow pointer input.\" The `@yagejs/input`\n * package's drain step consults this set via the renderer's optional\n * `hitTestUI(x, y)` — when the topmost interactive container under a\n * `pointerdown` is parented to a marked container, the pointer is auto-claimed\n * (`consumePointer`-equivalent), so the press never propagates to gameplay\n * action-map edges like `MouseLeft`.\n *\n * Lives in `@yagejs/core` so the renderer (read side) and the UI / sprite\n * components (write side) can both reach it without circular imports.\n *\n * Untyped on `Container` to keep `@yagejs/core` free of any Pixi dependency.\n * Callers pass their `Pixi.Container` instances directly; `WeakSet` accepts\n * any object reference.\n */\n\nconst registry = new WeakSet<object>();\n\n/**\n * Mark a display container as a UI-input surface. Idempotent. Call from a\n * component's `onAdd` (or equivalent) after the underlying Pixi container is\n * created.\n */\nexport function markPointerConsumeContainer(container: object): void {\n registry.add(container);\n}\n\n/**\n * Remove the mark. Call from a component's `onDestroy` for symmetry, or to\n * implement an opt-out (`consumeInput: false`) escape hatch on UI primitives.\n */\nexport function unmarkPointerConsumeContainer(container: object): void {\n registry.delete(container);\n}\n\n/** Whether a container has been marked as a UI-input surface. */\nexport function isPointerConsumeContainer(container: object): boolean {\n return registry.has(container);\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\";\nimport { RandomKey, createRandomService } from \"./Random.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 scene._registerScoped(RandomKey, createRandomService(1234));\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","_init","_a","_init","_a","registry"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/Vec2.ts","../src/MathUtils.ts","../src/EngineContext.ts","../src/Random.ts","../src/EventBus.ts","../src/Logger.ts","../src/SceneHooks.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/Inspector.ts","../src/Scene.ts","../src/Process.ts","../src/LoadingScene.ts","../src/SceneTransition.ts","../src/SceneManager.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/ProcessQueue.ts","../src/Engine.ts","../src/RendererAdapter.ts","../src/ui-consume-registry.ts","../src/test-utils.ts","../src/state/Atom.ts","../src/state/Store.ts","../src/state/codecs.ts","../src/state/persistent.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\";\nexport type { SmoothDampResult } from \"./MathUtils.js\";\n\nexport {\n RandomKey,\n createRandomService,\n createDefaultRandomSeed,\n globalRandom,\n normalizeSeed,\n} from \"./Random.js\";\nexport type { RandomService } from \"./Random.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\";\nexport type { ServiceScope, ServiceKeyOptions } from \"./EngineContext.js\";\n\nexport type { SceneHooks } from \"./SceneHooks.js\";\nexport { SceneHookRegistry, SceneHookRegistryKey } from \"./SceneHooks.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 { Inspector } from \"./Inspector.js\";\nexport type {\n EntitySnapshot,\n SceneSnapshot,\n SystemSnapshot,\n ErrorSnapshot,\n ComponentStateSnapshot,\n WorldEntitySnapshot,\n UINodeSnapshot,\n UITreeSnapshot,\n PhysicsSnapshot,\n EventLogEntry,\n WorldSceneSnapshot,\n CameraSnapshot,\n InputStateSnapshot,\n PointerSnapshot,\n EngineSnapshot,\n InspectorTimeController,\n} from \"./Inspector.js\";\n\nexport { Scene } from \"./Scene.js\";\nexport type { SpawnOptions } from \"./Scene.js\";\n\nexport { LoadingScene } from \"./LoadingScene.js\";\n\nexport { SceneManager } from \"./SceneManager.js\";\n\nexport type {\n SceneTransition,\n SceneTransitionContext,\n SceneTransitionKind,\n SceneTransitionOptions,\n} from \"./SceneTransition.js\";\nexport { resolveTransition } from \"./SceneTransition.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 {\n makeEntityScopedQueue,\n makeGlobalScopedQueue,\n makeSceneScopedQueue,\n} from \"./ProcessQueue.js\";\nexport type { ScopedProcessQueue } from \"./ProcessQueue.js\";\n\nexport { Engine } from \"./Engine.js\";\nexport type { EngineConfig } from \"./Engine.js\";\n\nexport { RendererAdapterKey } from \"./RendererAdapter.js\";\nexport type { RendererAdapter } from \"./RendererAdapter.js\";\n\nexport {\n markPointerConsumeContainer,\n unmarkPointerConsumeContainer,\n isPointerConsumeContainer,\n} from \"./ui-consume-registry.js\";\n\nexport {\n createTestEngine,\n createMockScene,\n createMockEntity,\n advanceFrames,\n} from \"./test-utils.js\";\n\nexport {\n createAtom,\n createStore,\n defineStore,\n defineSet,\n defineMap,\n defineCounter,\n StoreVersionTooNewError,\n StoreMigrationMissingError,\n jsonCodec,\n setCodec,\n mapCodec,\n dateCodec,\n _resetAllStoresForTesting,\n _clearStoreRegistryForTesting,\n} from \"./state/index.js\";\nexport type {\n Atom,\n Store,\n Codec,\n PersistentLike,\n PersistentStore,\n PersistentSet,\n PersistentMap,\n PersistentCounter,\n DefineStoreOptions,\n DefineSetOptions,\n DefineMapOptions,\n DefineCounterOptions,\n} from \"./state/index.js\";\n","import type { Component } from \"./Component.js\";\nimport type { EngineContext } from \"./EngineContext.js\";\nimport type { SystemScheduler } from \"./SystemScheduler.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: EngineContext): void | Promise<void>;\n /** Register systems with the scheduler. Called after install. */\n registerSystems?(scheduler: SystemScheduler): void;\n /** Called after all plugins are installed and the engine has started. */\n onStart?(): void | Promise<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 /** Move current toward target by at most maxDelta without overshooting. */\n static moveTowards(\n current: Vec2Like,\n target: Vec2Like,\n maxDelta: number,\n ): Vec2 {\n const dx = target.x - current.x;\n const dy = target.y - current.y;\n const distanceSq = dx * dx + dy * dy;\n\n if (distanceSq < EPSILON * EPSILON) {\n return new Vec2(target.x, target.y);\n }\n\n if (maxDelta <= 0) {\n return new Vec2(current.x, current.y);\n }\n\n const distance = Math.sqrt(distanceSq);\n if (distance <= maxDelta) {\n return new Vec2(target.x, target.y);\n }\n\n const scale = maxDelta / distance;\n return new Vec2(current.x + dx * scale, current.y + dy * scale);\n }\n}\n","const TAU = Math.PI * 2;\nconst MIN_SMOOTH_TIME = 0.0001;\n\nexport interface SmoothDampResult {\n /** Smoothed value after this step. */\n readonly value: number;\n /** Velocity to pass into the next smoothDamp step. */\n readonly velocity: number;\n}\n\nfunction normalizeAngle(radians: number): number {\n const wrapped = ((((radians + Math.PI) % TAU) + TAU) % TAU) - Math.PI;\n // Preserve sign at +/-PI so direction survives the half-turn.\n return wrapped === -Math.PI && radians > 0 ? Math.PI : wrapped;\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 /** Return the clamped interpolation factor that produces v between a and b. */\n inverseLerp(a: number, b: number, v: number): number {\n if (a === b) return 0;\n return MathUtils.clamp((v - a) / (b - a), 0, 1);\n },\n\n /** Interpolate between angles in radians along the shortest path. */\n lerpAngle(a: number, b: number, t: number): number {\n return normalizeAngle(a + MathUtils.shortestAngleBetween(a, b) * t);\n },\n\n /** Signed shortest angular delta from a to b, in radians. */\n shortestAngleBetween(a: number, b: number): number {\n return normalizeAngle(b - a);\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 /** Bounce t between 0 and length. */\n pingPong(t: number, length: number): number {\n if (length <= 0) return 0;\n const wrapped = MathUtils.wrap(t, 0, length * 2);\n return length - Math.abs(wrapped - length);\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 /**\n * Smoothly damp current toward target without overshooting.\n * Pass the returned velocity back into the next call.\n */\n smoothDamp(\n current: number,\n target: number,\n velocity: number,\n smoothTime: number,\n deltaTime: number,\n maxSpeed: number = Infinity,\n ): SmoothDampResult {\n if (deltaTime <= 0) {\n return { value: current, velocity };\n }\n\n const safeSmoothTime = Math.max(MIN_SMOOTH_TIME, smoothTime);\n const omega = 2 / safeSmoothTime;\n const x = omega * deltaTime;\n const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x);\n const originalTarget = target;\n const maxChange = maxSpeed * safeSmoothTime;\n const change = MathUtils.clamp(current - target, -maxChange, maxChange);\n const adjustedTarget = current - change;\n const temp = (velocity + omega * change) * deltaTime;\n const nextVelocity = (velocity - omega * temp) * exp;\n let value = adjustedTarget + (change + temp) * exp;\n let resultVelocity = nextVelocity;\n const targetIsAboveCurrent = originalTarget - current > 0;\n const valuePassedTarget = targetIsAboveCurrent\n ? value > originalTarget\n : value < originalTarget;\n\n if (valuePassedTarget) {\n value = originalTarget;\n resultVelocity = 0;\n }\n\n return { value, velocity: resultVelocity };\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 { AssetManager } from \"./AssetManager.js\";\nimport type { Engine } from \"./Engine.js\";\nimport type { ErrorBoundary } from \"./ErrorBoundary.js\";\nimport type { EngineEvents, EventBus } from \"./EventBus.js\";\nimport type { GameLoop } from \"./GameLoop.js\";\nimport type { Inspector } from \"./Inspector.js\";\nimport type { Logger } from \"./Logger.js\";\nimport type { ProcessSystem } from \"./ProcessSystem.js\";\nimport type { QueryCache } from \"./QueryCache.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport type { SystemScheduler } from \"./SystemScheduler.js\";\n\n/** The resolution scope for a service. */\nexport type ServiceScope = \"engine\" | \"scene\";\n\n/** Options passed to `new ServiceKey(id, options)`. */\nexport interface ServiceKeyOptions {\n /**\n * Declared scope. `\"scene\"` keys are expected to be registered per-scene\n * via a `beforeEnter` hook; `Component.use` will check scene scope first\n * and warn if it falls back to engine scope.\n * Default: `\"engine\"`.\n */\n scope?: ServiceScope;\n}\n\n/** A typed key for service registration and resolution. */\nexport class ServiceKey<T> {\n /** Declared scope (engine or scene). Defaults to `\"engine\"`. */\n readonly scope: ServiceScope;\n\n constructor(\n /** Unique string identifier for this service. */\n public readonly id: string,\n options?: ServiceKeyOptions,\n ) {\n this.scope = options?.scope ?? \"engine\";\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 type-only imports to avoid circular imports. The generic parameter\n// documents the expected service type. Consumers import both the key and the\n// type.\n\n/** Key for the Engine instance. */\nexport const EngineKey = new ServiceKey<Engine>(\"engine\");\n\n/** Key for the EventBus instance. */\nexport const EventBusKey = new ServiceKey<EventBus<EngineEvents>>(\"eventBus\");\n\n/** Key for the SceneManager instance. */\nexport const SceneManagerKey = new ServiceKey<SceneManager>(\"sceneManager\");\n\n/** Key for the Logger instance. */\nexport const LoggerKey = new ServiceKey<Logger>(\"logger\");\n\n/** Key for the Inspector instance. */\nexport const InspectorKey = new ServiceKey<Inspector>(\"inspector\");\n\n/** Key for the QueryCache instance. */\nexport const QueryCacheKey = new ServiceKey<QueryCache>(\"queryCache\");\n\n/** Key for the ErrorBoundary instance. */\nexport const ErrorBoundaryKey = new ServiceKey<ErrorBoundary>(\"errorBoundary\");\n\n/** Key for the GameLoop instance. */\nexport const GameLoopKey = new ServiceKey<GameLoop>(\"gameLoop\");\n\n/** Key for the SystemScheduler instance. */\nexport const SystemSchedulerKey = new ServiceKey<SystemScheduler>(\n \"systemScheduler\",\n);\n\n/** Key for the ProcessSystem instance. */\nexport const ProcessSystemKey = new ServiceKey<ProcessSystem>(\"processSystem\");\n\n/** Key for the AssetManager instance. */\nexport const AssetManagerKey = new ServiceKey<AssetManager>(\"assetManager\");\n","import { ServiceKey } from \"./EngineContext.js\";\n\n/** Seeded random service used by runtime systems that must be deterministic. */\nexport interface RandomService {\n /** Random float in the range [0, 1). */\n float(): number;\n /** Random float in the range [min, max). */\n range(min: number, max: number): number;\n /** Random integer in the range [min, max] (inclusive). */\n int(min: number, max: number): number;\n /** Pick a random element from a non-empty array. */\n pick<T>(arr: readonly T[]): T;\n /** Shuffle an array in place and return the same array. */\n shuffle<T>(arr: T[]): T[];\n /** Return the seed this generator was constructed (or last reseeded) with. */\n getSeed(): number;\n}\n\n/**\n * Internal extension that exposes mid-stream reseeding. The Inspector uses\n * this to enforce deterministic E2E mode without leaking the foot-gun\n * (game code calling `setSeed` would corrupt other consumers' sequences in\n * the same scene).\n *\n * @internal\n */\nexport interface InternalRandomService extends RandomService {\n setSeed(seed: number): void;\n}\n\n/** Scene-scoped key for the active scene's deterministic RNG. */\nexport const RandomKey = new ServiceKey<RandomService>(\"random\", {\n scope: \"scene\",\n});\n\nconst UINT32_MAX = 0x1_0000_0000;\n\n/** Normalize arbitrary numbers into the uint32 seed space. */\nexport function normalizeSeed(seed: number): number {\n return seed >>> 0;\n}\n\n/** Default seed for explicitly non-deterministic paths. */\nexport function createDefaultRandomSeed(): number {\n return normalizeSeed(Date.now() ^ Math.floor(Math.random() * 1e9));\n}\n\nclass Mulberry32Random implements InternalRandomService {\n private seed: number;\n private state: number;\n\n constructor(seed: number) {\n const normalized = normalizeSeed(seed);\n this.seed = normalized;\n this.state = normalized;\n }\n\n float(): number {\n let t = (this.state += 0x6d2b79f5);\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / UINT32_MAX;\n }\n\n range(min: number, max: number): number {\n return min + this.float() * (max - min);\n }\n\n int(min: number, max: number): number {\n return Math.floor(this.range(min, max + 1));\n }\n\n pick<T>(arr: readonly T[]): T {\n if (arr.length === 0) {\n throw new Error(\"RandomService.pick() requires a non-empty array.\");\n }\n return arr[this.int(0, arr.length - 1)]!;\n }\n\n shuffle<T>(arr: T[]): T[] {\n for (let i = arr.length - 1; i > 0; i--) {\n const j = this.int(0, i);\n const tmp = arr[i]!;\n arr[i] = arr[j]!;\n arr[j] = tmp;\n }\n return arr;\n }\n\n setSeed(seed: number): void {\n const normalized = normalizeSeed(seed);\n this.seed = normalized;\n this.state = normalized;\n }\n\n getSeed(): number {\n return this.seed;\n }\n}\n\n/** Create a deterministic random service. */\nexport function createRandomService(\n seed = createDefaultRandomSeed(),\n): RandomService {\n return new Mulberry32Random(seed);\n}\n\n/**\n * Explicitly non-deterministic global RNG for boot-time or cross-scene code.\n * Inspector seed control never touches this instance.\n */\nexport const globalRandom = createRandomService();\n","import type { Component } from \"./Component.js\";\nimport type { ComponentClass } from \"./types.js\";\nimport type { SceneTransitionKind } from \"./SceneTransition.js\";\nimport type { Scene } from \"./Scene.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 \"scene:transition:started\": {\n kind: SceneTransitionKind;\n fromScene: SceneRef | undefined;\n toScene: SceneRef | undefined;\n };\n \"scene:transition:ended\": {\n kind: SceneTransitionKind;\n fromScene: SceneRef | undefined;\n toScene: SceneRef | undefined;\n };\n // Full Scene (not SceneRef) — subscribers typically compare by identity\n // against a Scene reference and may cast to LoadingScene to call\n // continue()/progress. Widening here avoids forcing casts at every site.\n \"scene:loading:progress\": { scene: Scene; ratio: number };\n \"scene:loading:done\": { scene: Scene };\n \"engine:started\": undefined;\n \"engine:stopped\": undefined;\n // Viewport / device events. Emitted by RendererPlugin when the canvas\n // host element enters/exits fullscreen and when the device orientation\n // changes. `OrientationType` is the built-in DOM lib union.\n \"screen:fullscreen\": { active: boolean };\n \"screen:orientation\": { type: OrientationType };\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 private observers = new Set<(event: keyof E, data: E[keyof E]) => 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 if (this.observers.size > 0) {\n const observers = [...this.observers];\n for (const observer of observers) {\n observer(event, data);\n }\n }\n\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 /**\n * Observe every emitted event without affecting handler order or control\n * flow. Used by tooling such as the Inspector event log.\n */\n tap(observer: (event: keyof E, data: E[keyof E]) => void): () => void {\n this.observers.add(observer);\n return () => {\n this.observers.delete(observer);\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","import type { Scene } from \"./Scene.js\";\nimport { ServiceKey, LoggerKey } from \"./EngineContext.js\";\nimport type { Logger } from \"./Logger.js\";\n\n/**\n * Plugin hooks invoked by the SceneManager at scene lifecycle points.\n * Plugins register hooks via `engine.registerSceneHooks(hooks)` to set up or\n * tear down per-scene state (e.g. render containers, physics worlds).\n */\nexport interface SceneHooks {\n /**\n * Runs after the scene's context is bound but before preload / `onEnter`.\n * Awaited serially so scoped services registered here are ready when the\n * scene's own code runs. Fires on `push`, `replace`, and `_mountDetached`.\n */\n beforeEnter?(scene: Scene): void | Promise<void>;\n\n /**\n * Runs after `onExit` + `_destroyAllEntities` and before the scene's\n * scoped-service map is cleared. Fires on `pop`, `replace`, `clear`, and\n * `_unmountDetached`.\n */\n afterExit?(scene: Scene): void;\n}\n\n/**\n * Registry of scene hooks. Held by the engine, consumed by the SceneManager.\n * @internal\n */\nexport class SceneHookRegistry {\n private readonly hooks: SceneHooks[] = [];\n\n register(hooks: SceneHooks): () => void {\n this.hooks.push(hooks);\n return () => {\n const idx = this.hooks.indexOf(hooks);\n if (idx !== -1) this.hooks.splice(idx, 1);\n };\n }\n\n /** Run all `beforeEnter` hooks serially. */\n async runBeforeEnter(scene: Scene): Promise<void> {\n for (const h of this.hooks) {\n await h.beforeEnter?.(scene);\n }\n }\n\n runAfterExit(scene: Scene): void {\n for (const h of this.hooks) {\n try {\n h.afterExit?.(scene);\n } catch (err) {\n // Swallow so one failing plugin doesn't block teardown of the rest.\n const logger = scene.context.tryResolve(LoggerKey) as\n | Logger\n | undefined;\n if (logger) {\n logger.error(\"core\", \"Scene afterExit hook threw\", {\n scene: scene.name,\n error: err,\n });\n } else {\n console.error(\n `[yage] Scene afterExit hook threw for scene \"${scene.name}\":`,\n err,\n );\n }\n }\n }\n }\n}\n\n/** DI key for the scene-hook registry. @internal */\nexport const SceneHookRegistryKey = new ServiceKey<SceneHookRegistry>(\n \"sceneHookRegistry\",\n);\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 *\n * @deprecated Prefer Entity subclasses with `setup()` for entity types.\n * Blueprints still work for parametric factories but are no longer the\n * recommended pattern for new code.\n */\nexport interface Blueprint<P = void> {\n readonly name: string;\n build(entity: Entity, params: P): void;\n}\n\n/**\n * Create a blueprint from a name and a build function.\n *\n * @deprecated Prefer Entity subclasses with `setup()` for entity types.\n */\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\nimport type { Entity } from \"./Entity.js\";\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): 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 { Logger } from \"./Logger.js\";\nimport type { Scene } from \"./Scene.js\";\nimport type { SnapshotResolver } from \"./Serializable.js\";\nimport type { ComponentClass } from \"./types.js\";\nimport { LoggerKey } from \"./EngineContext.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!: 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 threading through `this.entity.scene` in component\n * code.\n */\n get scene(): Scene {\n const scene = this.entity.tryScene;\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 /**\n * Resolve a service by key, cached after first lookup. Scene-scoped values\n * (registered via `scene._registerScoped`) take precedence over engine\n * scope. A key declared with `scope: \"scene\"` that falls back to engine\n * scope emits a one-shot dev warning — almost always signals a missed\n * `beforeEnter` hook.\n */\n protected use<T>(key: ServiceKey<T>): T {\n this._serviceCache ??= new Map();\n const cached = this._serviceCache.get(key.id);\n if (cached !== undefined) return cached as T;\n\n const scene = this.entity.tryScene;\n const scoped = scene?._resolveScoped(key);\n if (scoped !== undefined) {\n this._serviceCache.set(key.id, scoped);\n return scoped;\n }\n\n const value = this.context.resolve(key);\n if (key.scope === \"scene\") {\n // Don't cache: a later scoped registration should take precedence,\n // and the warning should keep firing until the plugin wiring is\n // fixed — caching would silence it after one hit.\n this._warnScopedFallback(key);\n return value;\n }\n this._serviceCache.set(key.id, value);\n return value;\n }\n\n private _warnScopedFallback<T>(key: ServiceKey<T>): void {\n const logger = this.context.tryResolve(LoggerKey) as Logger | undefined;\n logger?.warn(\n \"core\",\n `Scoped key \"${key.id}\" fell back to engine scope — did a plugin forget to register a beforeEnter hook?`,\n { component: this.constructor.name },\n );\n }\n\n /**\n * Lazy proxy-based service resolution. Can be used at field-declaration time:\n * ```ts\n * readonly input = this.service(InputManagerKey);\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 { Blueprint } from \"./Blueprint.js\";\nimport type { SnapshotResolver } from \"./Serializable.js\";\nimport type { Scene, SpawnOptions } from \"./Scene.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 * Stable identity key, scene-scoped. Set at spawn-time when\n * `options.key` is passed to `scene.spawn` / `entity.spawnChild`;\n * `undefined` otherwise. Used with `scene.findByKey` and as a stable\n * id in persistent stores (e.g. `defineSet<string>(\"world.opened\")`).\n */\n readonly key?: string;\n\n private components = new Map<ComponentClass, Component>();\n private _destroyed = false;\n private _scene: 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 /**\n * The scene this entity belongs to. Throws if the entity is not attached\n * to a scene — which in practice only happens before `scene.spawn` /\n * `addChild` wires it up, or after `destroy()` tears it down. Inside\n * lifecycle methods (`setup`, component `onAdd`, `update`, etc.) this is\n * always safe to access.\n *\n * For the rare case where you genuinely need to inspect whether an\n * entity has a scene (e.g. defensive code in systems iterating a query\n * result), use `tryScene` instead.\n */\n get scene(): Scene {\n if (!this._scene) {\n throw new Error(\n `Entity \"${this.name}\" is not attached to a scene. Use \\`tryScene\\` if you need to check.`,\n );\n }\n return this._scene;\n }\n\n /** The scene this entity belongs to, or `null` if detached. */\n get tryScene(): 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 /**\n * Spawn a new entity in this entity's scene and add it as a named child.\n * Combines `scene.spawn(...)` + `this.addChild(name, ...)` in one call —\n * the idiomatic way to compose entity trees (logical root + visual body\n * + UI sibling + ...).\n *\n * Mirrors the overload shape of `Scene.spawn`: pass an Entity subclass\n * (with optional setup params), a `Blueprint`, or omit for an anonymous\n * base Entity.\n *\n * ```ts\n * this.spawnChild(\"body\", EnemyBody, { color: 0xff6b6b });\n * this.spawnChild(\"hp\", EnemyHealthBar);\n * ```\n */\n spawnChild(name: string, options?: SpawnOptions): Entity;\n spawnChild<E extends Entity>(\n name: string,\n Class: new () => E,\n options?: SpawnOptions,\n ): E;\n spawnChild<E extends Entity, P>(\n name: string,\n Class: new () => E & { setup(params: P): void },\n params: P,\n options?: SpawnOptions,\n ): E;\n spawnChild<P>(\n name: string,\n blueprint: Blueprint<P>,\n params: P,\n options?: SpawnOptions,\n ): Entity;\n // eslint-disable-next-line @typescript-eslint/unified-signatures -- preserves Class return-type narrowing on the overload above\n spawnChild(\n name: string,\n blueprint: Blueprint<void>,\n options?: SpawnOptions,\n ): Entity;\n spawnChild(\n name: string,\n classOrBlueprintOrOptions?:\n | (new () => Entity)\n | Blueprint<unknown>\n | SpawnOptions,\n paramsOrOptions?: unknown,\n maybeOptions?: SpawnOptions,\n ): Entity {\n const scene = this.scene;\n // Validate before spawning so we don't leave an orphan entity in the\n // scene if addChild would reject the name. addChild also throws on\n // this, but by then the spawn side-effects (scene.entities insert,\n // `entity:created` emit, setup() / blueprint.build()) have all run.\n if (this._children?.has(name)) {\n throw new Error(\n `Entity \"${this.name}\" already has a child named \"${name}\".`,\n );\n }\n // The public overloads above keep callsites type-safe. The\n // implementation signature is intentionally loose so it can funnel\n // into `Scene.spawn`'s matching overloads without per-variant\n // branches. When no class/blueprint is provided, forward `name` as\n // the entity's own name so `child.name` matches the child-map key.\n let child: Entity;\n if (classOrBlueprintOrOptions === undefined) {\n child = scene.spawn(name);\n } else if (\n typeof classOrBlueprintOrOptions === \"object\" &&\n !(\"build\" in classOrBlueprintOrOptions)\n ) {\n // spawnChild(name, options)\n child = scene.spawn(name, classOrBlueprintOrOptions as SpawnOptions);\n } else {\n child = (\n scene.spawn as (a?: unknown, b?: unknown, c?: unknown) => Entity\n )(classOrBlueprintOrOptions, paramsOrOptions, maybeOptions);\n }\n this.addChild(name, child);\n return child;\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 this._scene?._observeEntityEvent(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 * Return the stable key, or throw if this entity was spawned without one.\n * Use inside component `setup()` when the component depends on identity\n * (e.g. reading from a `defineSet` keyed by entity id).\n */\n requireKey(): string {\n if (this.key === undefined) {\n throw new Error(\n `Entity \"${this.name}\" (id=${this.id}) has no stable key. ` +\n `Pass { key: \"...\" } to scene.spawn(...) or entity.spawnChild(...).`,\n );\n }\n return this.key;\n }\n\n /**\n * Internal: set the scene and callbacks. Called by Scene.spawn().\n * @internal\n */\n _setScene(\n scene: Scene | null,\n callbacks: EntityCallbacks | null,\n ): void {\n this._scene = scene;\n this.callbacks = callbacks;\n }\n\n /**\n * Internal: assign the stable identity key. Called by `Scene._registerKey`\n * during spawn. Throws if the entity already has a key — keys are\n * immutable for an entity's lifetime.\n * @internal\n */\n _setKey(key: string): void {\n if (this.key !== undefined) {\n throw new Error(\n `Entity \"${this.name}\" already has key \"${this.key}\".`,\n );\n }\n (this as { key?: string }).key = key;\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.running || !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 { Transform } from \"./Transform.js\";\nimport type { Entity } from \"./Entity.js\";\nimport type { Component } from \"./Component.js\";\nimport type { Scene } from \"./Scene.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport type { GameLoop } from \"./GameLoop.js\";\nimport type { EventBus, EngineEvents } from \"./EventBus.js\";\nimport {\n EngineContext,\n ErrorBoundaryKey,\n ServiceKey,\n SystemSchedulerKey,\n} from \"./EngineContext.js\";\nimport {\n RandomKey,\n createDefaultRandomSeed,\n createRandomService,\n normalizeSeed,\n type InternalRandomService,\n type RandomService,\n} from \"./Random.js\";\n\n// Duplicate service keys locally to avoid runtime deps on optional packages.\nconst InputManagerRuntimeKey = new ServiceKey<InputManagerLike>(\"inputManager\");\nconst PhysicsWorldManagerRuntimeKey = new ServiceKey<PhysicsWorldManagerLike>(\n \"physicsWorldManager\",\n);\nconst RendererRuntimeKey = new ServiceKey<RendererLike>(\"renderer\");\n\n/**\n * Mirrors `GamepadAxisKey` from `@yagejs/input` as a local union so the\n * Inspector contract gets compile-time literal checking without taking a\n * runtime dependency on the input package.\n */\ntype InspectorGamepadAxisKey =\n | \"leftX\"\n | \"leftY\"\n | \"rightX\"\n | \"rightY\"\n | \"leftTrigger\"\n | \"rightTrigger\";\n\n/**\n * Options for synthetic pointer injection. Pass `id` / `type` / `isPrimary`\n * to drive a non-primary, touch, or pen pointer in deterministic tests. All\n * fields are optional and default to a primary mouse pointer with `id: 1`.\n */\ninterface InspectorPointerOpts {\n id?: number;\n type?: \"mouse\" | \"pen\" | \"touch\";\n isPrimary?: boolean;\n}\n\ninterface InputManagerLike {\n fireKeyDown(code: string): void;\n fireKeyUp(code: string): void;\n firePointerMove(x: number, y: number, opts?: InspectorPointerOpts): void;\n firePointerDown(button?: 0 | 1 | 2, opts?: InspectorPointerOpts): void;\n firePointerUp(button?: 0 | 1 | 2, opts?: { id?: number }): void;\n /** `code` is a gamepad code string (e.g. `\"GamepadA\"`, `\"GamepadLT\"`). */\n fireGamepadButton(code: string, pressed: boolean): void;\n fireGamepadAxis(side: InspectorGamepadAxisKey, value: number): void;\n fireAction(name: string): void;\n clearAll(): void;\n snapshotState(): InputStateSnapshot;\n}\n\ninterface PhysicsWorldManagerLike {\n getContext(scene: Scene): { world: PhysicsWorldLike } | undefined;\n}\n\ninterface PhysicsWorldLike {\n snapshot(): PhysicsSnapshot;\n}\n\ninterface RendererLike {\n application: {\n stage: unknown;\n renderer: {\n extract: {\n canvas(stage: unknown): HTMLCanvasElement;\n };\n };\n };\n}\n\ninterface CameraComponentLike {\n enabled: boolean;\n position: { x: number; y: number };\n zoom: number;\n rotation: number;\n priority?: number;\n cameraName?: string;\n}\n\ninterface UIElementLike {\n constructor: { name: string };\n children?: readonly UIElementLike[];\n yogaNode?: {\n getComputedLayout(): {\n left: number;\n top: number;\n width: number;\n height: number;\n };\n };\n}\n\n/** Backward-compatible summary snapshot returned by query helpers. */\nexport interface EntitySnapshot {\n id: number;\n name: string;\n tags: string[];\n components: string[];\n position?: { x: number; y: number };\n}\n\n/** Backward-compatible scene stack summary. */\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\nexport interface ComponentStateSnapshot {\n type: string;\n state: unknown | null;\n}\n\nexport interface WorldEntitySnapshot {\n id: string;\n type: string;\n parent: string | null;\n transform: {\n x: number;\n y: number;\n rotation: number;\n scaleX: number;\n scaleY: number;\n };\n components: ComponentStateSnapshot[];\n}\n\nexport interface UINodeSnapshot {\n id: string;\n type: string;\n layout: { x: number; y: number; width: number; height: number };\n children: UINodeSnapshot[];\n state: unknown | null;\n}\n\nexport interface UITreeSnapshot {\n root: UINodeSnapshot;\n}\n\nexport interface PhysicsSnapshot {\n bodies: Array<{\n entityId: string;\n type: \"dynamic\" | \"kinematic\" | \"static\";\n position: { x: number; y: number };\n rotation: number;\n linvel: { x: number; y: number };\n angvel: number;\n }>;\n contacts: Array<{ a: string; b: string }>;\n}\n\nexport interface EventLogEntry {\n frame: number;\n source: \"bus\" | \"entity\";\n type: string;\n targetId?: string;\n payload: unknown | null;\n}\n\nexport interface WorldSceneSnapshot {\n id: string;\n name: string;\n paused: boolean;\n timeScale: number;\n seed: number;\n entities: WorldEntitySnapshot[];\n ui: UITreeSnapshot | null;\n physics: PhysicsSnapshot;\n events: EventLogEntry[];\n}\n\nexport interface CameraSnapshot {\n sceneId: string;\n sceneName: string;\n name: string | null;\n priority: number;\n position: { x: number; y: number };\n zoom: number;\n rotation: number;\n}\n\n/**\n * Per-pointer entry in {@link InputStateSnapshot.pointers}. Mirrors the runtime\n * `PointerInfo` shape from `@yagejs/input`. Touch pointers vanish from the\n * array once their last button releases; mouse pointers persist.\n */\nexport interface PointerSnapshot {\n /** `PointerEvent.pointerId`, or the synthetic id passed via `firePointer*`. */\n id: number;\n x: number;\n y: number;\n type: \"mouse\" | \"pen\" | \"touch\";\n isPrimary: boolean;\n buttons: number[];\n down: boolean;\n}\n\nexport interface InputStateSnapshot {\n keys: string[];\n actions: string[];\n /**\n * Aggregate / primary-pointer view, retained for back-compat. `x` / `y` track\n * the primary pointer's screen position; `buttons` / `down` reflect the\n * any-pointer aggregate that drives the `MouseLeft`/`Middle`/`Right` action codes.\n *\n * For multi-touch state, read {@link InputStateSnapshot.pointers}.\n */\n mouse: {\n x: number;\n y: number;\n buttons: number[];\n down: boolean;\n };\n /** All currently-tracked pointers (one per active mouse, pen, or finger). */\n pointers: PointerSnapshot[];\n gamepad: {\n /** Currently-held gamepad codes (e.g. `\"GamepadA\"`, `\"GamepadLT\"`). */\n buttons: string[];\n /**\n * Axis state keyed by `${padIndex}:${axisName}` (axisName is a\n * `GamepadAxisKey` from `@yagejs/input`).\n */\n axes: Array<{ key: string; value: number }>;\n };\n}\n\n/** Full deterministic inspector snapshot. */\nexport interface EngineSnapshot {\n version: 1;\n frame: number;\n sceneStack: SceneSnapshot[];\n entityCount: number;\n systemCount: number;\n errors: ErrorSnapshot;\n scenes: WorldSceneSnapshot[];\n camera: CameraSnapshot | null;\n input: InputStateSnapshot;\n}\n\nexport interface InspectorTimeController {\n readonly isFrozen: boolean;\n freeze(): void;\n thaw(): void;\n stepFrames(count: number): void;\n setDelta(ms: number): void;\n getFrame(): number;\n}\n\ninterface LoggedEvent {\n entry: EventLogEntry;\n sceneId: string | undefined;\n}\n\ninterface EventWaiter {\n pattern: string | RegExp;\n source: \"bus\" | \"entity\" | undefined;\n withinFrames: number | undefined;\n deadlineFrame: number | undefined;\n resolve: (entry: EventLogEntry) => void;\n reject: (error: Error) => void;\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 readonly events?: EventBus<EngineEvents>;\n}\n\n/**\n * Programmatic runtime control and state queries for testing and debugging.\n * Exposed on `window.__yage__` in debug mode.\n */\nexport class Inspector {\n private readonly engine: EngineRef;\n private readonly extensions = new Map<string, object>();\n private readonly sceneIds = new WeakMap<Scene, string>();\n private nextSceneId = 0;\n private defaultSceneSeed: number | undefined;\n private sceneSeedOverride: number | undefined;\n private timeController: InspectorTimeController | null = null;\n private eventLogEnabled = false;\n private eventCapacity = 500;\n /**\n * Ring buffer of recent events. `eventLogHead` points at the oldest slot;\n * a full ring contains exactly `eventCapacity` entries. We avoid `splice` to\n * keep `appendEvent` O(1) — the previous shift-on-overflow approach was\n * O(n) per event once the buffer was full.\n */\n private eventLog: LoggedEvent[] = [];\n private eventLogHead = 0;\n private eventWaiters = new Set<EventWaiter>();\n private detachBusTap: (() => void) | null = null;\n private readonly busEventObserver = (\n event: keyof EngineEvents,\n data: EngineEvents[keyof EngineEvents],\n ): void => {\n this.recordBusEvent(String(event), data);\n };\n private readonly sceneEventObserver = (\n eventName: string,\n data: unknown,\n entity: Entity,\n ): void => {\n this.recordEntityEvent(eventName, data, entity);\n };\n\n readonly time = {\n freeze: (): void => {\n this.requireTimeController().freeze();\n },\n thaw: (): void => {\n this.requireTimeController().thaw();\n },\n step: (frames = 1): void => {\n this.assertNonNegativeInteger(frames, \"Inspector.time.step(frames)\");\n if (frames === 0) return;\n this.requireTimeController().stepFrames(frames);\n // Event matching happens inside appendEvent during the step. A trailing\n // pass here only needs to expire deadline waiters whose time ran out.\n this.expireDeadlineWaiters();\n },\n setDelta: (ms: number): void => {\n if (!Number.isFinite(ms) || ms <= 0) {\n throw new Error(\"Inspector.time.setDelta(ms) requires a positive number.\");\n }\n this.requireTimeController().setDelta(ms);\n },\n isFrozen: (): boolean => this.timeController?.isFrozen ?? false,\n getFrame: (): number =>\n this.timeController?.getFrame() ?? this.engine.loop.frameCount,\n };\n\n readonly input = {\n keyDown: (code: string): void => {\n this.requireInputManager().fireKeyDown(code);\n },\n keyUp: (code: string): void => {\n this.requireInputManager().fireKeyUp(code);\n },\n mouseMove: (x: number, y: number): void => {\n this.requireInputManager().firePointerMove(x, y);\n },\n mouseDown: (button: 0 | 1 | 2 = 0): void => {\n this.requireInputManager().firePointerDown(button);\n },\n mouseUp: (button: 0 | 1 | 2 = 0): void => {\n this.requireInputManager().firePointerUp(button);\n },\n /**\n * Inject a synthetic pointer-move with full pointer addressing. Pass `opts`\n * with `id` / `type: \"touch\"` to drive a specific finger; defaults match\n * the primary mouse pointer (same as `mouseMove`).\n */\n pointerMove: (\n x: number,\n y: number,\n opts?: InspectorPointerOpts,\n ): void => {\n this.requireInputManager().firePointerMove(x, y, opts);\n },\n /**\n * Inject a synthetic pointer-down. With `opts.id` and `opts.type: \"touch\"`\n * this drives a multi-touch contact, exercising `getPointers()`,\n * per-pointer event hooks, and the any-pointer aggregate for `MouseLeft`.\n */\n pointerDown: (\n button: 0 | 1 | 2 = 0,\n opts?: InspectorPointerOpts,\n ): void => {\n this.requireInputManager().firePointerDown(button, opts);\n },\n pointerUp: (\n button: 0 | 1 | 2 = 0,\n opts?: { id?: number },\n ): void => {\n this.requireInputManager().firePointerUp(button, opts);\n },\n gamepadButton: (code: string, pressed: boolean): void => {\n this.requireInputManager().fireGamepadButton(code, pressed);\n },\n gamepadAxis: (\n side: InspectorGamepadAxisKey,\n value: number,\n ): void => {\n this.requireInputManager().fireGamepadAxis(side, value);\n },\n tap: (code: string, frames = 1): void => {\n this.assertNonNegativeInteger(frames, \"Inspector.input.tap(frames)\");\n const input = this.requireInputManager();\n input.fireKeyDown(code);\n try {\n this.time.step(frames);\n } finally {\n input.fireKeyUp(code);\n }\n },\n hold: (code: string, frames: number): void => {\n this.assertNonNegativeInteger(frames, \"Inspector.input.hold(frames)\");\n const input = this.requireInputManager();\n input.fireKeyDown(code);\n try {\n this.time.step(frames);\n } finally {\n input.fireKeyUp(code);\n }\n },\n fireAction: (name: string, frames = 1): void => {\n this.assertNonNegativeInteger(\n frames,\n \"Inspector.input.fireAction(frames)\",\n );\n const input = this.requireInputManager();\n for (let i = 0; i < frames; i++) {\n input.fireAction(name);\n this.time.step(1);\n }\n },\n clearAll: (): void => {\n this.requireInputManager().clearAll();\n },\n };\n\n readonly events = {\n getLog: (): EventLogEntry[] =>\n this.iterateLog().map(({ entry }) => ({ ...entry })),\n clearLog: (): void => {\n this.eventLog.length = 0;\n this.eventLogHead = 0;\n },\n setCapacity: (n: number): void => {\n this.assertNonNegativeInteger(\n n,\n \"Inspector.events.setCapacity(capacity)\",\n );\n // `slice(-0)` is `slice(0)` (returns the whole array), so guard zero\n // explicitly — otherwise setCapacity(0) would leave stale entries.\n const ordered = n === 0 ? [] : this.iterateLog().slice(-n);\n this.eventCapacity = n;\n this.eventLog = ordered;\n this.eventLogHead = 0;\n },\n waitFor: (\n pattern: string | RegExp,\n options?: {\n withinFrames?: number;\n source?: \"bus\" | \"entity\";\n },\n ): Promise<EventLogEntry> => {\n const existing = this.findMatchingEvent(pattern, options?.source);\n if (existing) return Promise.resolve(existing);\n\n const withinFrames = options?.withinFrames;\n if (\n withinFrames !== undefined &&\n (!Number.isInteger(withinFrames) || withinFrames < 0)\n ) {\n throw new Error(\n \"Inspector.events.waitFor(withinFrames) requires a non-negative integer.\",\n );\n }\n\n return new Promise<EventLogEntry>((resolve, reject) => {\n const waiter: EventWaiter = {\n pattern,\n source: options?.source,\n withinFrames,\n deadlineFrame:\n withinFrames !== undefined\n ? this.time.getFrame() + withinFrames\n : undefined,\n resolve,\n reject,\n };\n this.eventWaiters.add(waiter);\n });\n },\n };\n\n readonly capture = {\n png: async (): Promise<Uint8Array> => {\n const base64 = await this.capture.pngBase64();\n return decodeBase64(base64);\n },\n dataURL: async (): Promise<string> => {\n const renderer = this.engine.context.tryResolve(RendererRuntimeKey);\n if (!renderer) {\n throw new Error(\n \"Inspector.capture requires RendererPlugin to be active.\",\n );\n }\n const canvas = renderer.application.renderer.extract.canvas(\n renderer.application.stage,\n );\n return canvas.toDataURL(\"image/png\");\n },\n pngBase64: async (): Promise<string> => {\n const dataUrl = await this.capture.dataURL();\n const comma = dataUrl.indexOf(\",\");\n return comma === -1 ? dataUrl : dataUrl.slice(comma + 1);\n },\n };\n\n constructor(engine: EngineRef) {\n this.engine = engine;\n }\n\n /** Register a namespaced extension API for plugin-specific debug helpers. */\n addExtension<T extends object>(namespace: string, api: T): T {\n this.assertNonEmptyString(\n namespace,\n \"Inspector.addExtension(namespace)\",\n );\n if (!api || typeof api !== \"object\") {\n throw new Error(\"Inspector.addExtension(api) requires an object.\");\n }\n if (this.extensions.has(namespace)) {\n throw new Error(\n `Inspector.addExtension(): namespace \"${namespace}\" is already registered.`,\n );\n }\n this.extensions.set(namespace, api);\n return api;\n }\n\n /** Look up a previously registered extension API by namespace. */\n getExtension<T extends object>(namespace: string): T | undefined {\n this.assertNonEmptyString(\n namespace,\n \"Inspector.getExtension(namespace)\",\n );\n return this.extensions.get(namespace) as T | undefined;\n }\n\n /** Remove a previously registered extension namespace. */\n removeExtension(namespace: string): void {\n this.assertNonEmptyString(\n namespace,\n \"Inspector.removeExtension(namespace)\",\n );\n this.extensions.delete(namespace);\n }\n\n /** Full deterministic state snapshot (stable ordering, serializable). */\n snapshot(): EngineSnapshot {\n const scenes = this.engine.scenes.all.map((scene) =>\n this.sceneToWorldSnapshot(scene),\n );\n return {\n version: 1,\n frame: this.time.getFrame(),\n sceneStack: this.getSceneStack(),\n entityCount: this.countEntities(),\n systemCount: this.getSystems().length,\n errors: this.getErrors(),\n scenes,\n camera: this.buildCameraSnapshot(),\n input: this.buildInputSnapshot(),\n };\n }\n\n /** Stable JSON form of {@link snapshot}. */\n snapshotJSON(): string {\n return stableStringify(this.snapshot());\n }\n\n /** Snapshot one scene by inspector scene id. */\n snapshotScene(id: string): WorldSceneSnapshot {\n const scene = this.engine.scenes.all.find(\n (candidate) => this.getSceneId(candidate) === id,\n );\n if (!scene) {\n throw new Error(`Inspector.snapshotScene(): unknown scene id \"${id}\".`);\n }\n return this.sceneToWorldSnapshot(scene);\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.entityToQuerySnapshot(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 if (typeof comp.serialize === \"function\") {\n const data = trySerialize(comp);\n if (data !== undefined) return data;\n }\n return this.serializeComponentOwnProperties(comp);\n }\n\n /** Get all entities in the active scene as lightweight 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.entityToQuerySnapshot(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 /** Create a new scene-scoped RNG instance using the current inspector seed policy. */\n createSceneRandom(): RandomService {\n const seed =\n this.sceneSeedOverride ?? this.defaultSceneSeed ?? createDefaultRandomSeed();\n return createRandomService(seed);\n }\n\n /** Force every current and future scene RNG to the provided seed. */\n setSeed(seed: number): void {\n const normalized = normalizeSeed(seed);\n this.sceneSeedOverride = normalized;\n for (const scene of this.engine.scenes.all) {\n this.resolveInternalRandom(scene)?.setSeed(normalized);\n }\n }\n\n /** @internal DebugPlugin installs a deterministic default seed through this hook. */\n setDefaultSceneSeed(seed: number | undefined): void {\n this.defaultSceneSeed =\n seed === undefined ? undefined : normalizeSeed(seed);\n if (this.sceneSeedOverride !== undefined || this.defaultSceneSeed === undefined) {\n return;\n }\n for (const scene of this.engine.scenes.all) {\n this.resolveInternalRandom(scene)?.setSeed(this.defaultSceneSeed);\n }\n }\n\n private resolveInternalRandom(scene: Scene): InternalRandomService | undefined {\n return scene._resolveScoped(RandomKey) as\n | InternalRandomService\n | undefined;\n }\n\n /** @internal DebugPlugin attaches the frozen-time controller through this hook. */\n attachTimeController(controller: InspectorTimeController): void {\n this.timeController = controller;\n }\n\n /** @internal Clear a previously attached time controller. */\n detachTimeController(controller?: InspectorTimeController): void {\n if (!controller || this.timeController === controller) {\n this.timeController = null;\n }\n }\n\n /** @internal Enable or disable event log recording. */\n setEventLogEnabled(enabled: boolean): void {\n if (this.eventLogEnabled === enabled) return;\n this.eventLogEnabled = enabled;\n\n if (enabled) {\n if (!this.detachBusTap && this.engine.events?.tap) {\n this.detachBusTap = this.engine.events.tap(this.busEventObserver);\n }\n } else {\n this.detachBusTap?.();\n this.detachBusTap = null;\n }\n\n for (const scene of this.engine.scenes.all) {\n if (enabled) {\n this.attachSceneEventObserver(scene);\n } else {\n this.detachSceneEventObserver(scene);\n }\n }\n }\n\n /** @internal Install entity-event observation for one scene. No-op if disabled. */\n attachSceneEventObserver(scene: Scene): void {\n if (!this.eventLogEnabled) return;\n scene._setEntityEventObserver(this.sceneEventObserver);\n }\n\n /** @internal Clear entity-event observation for one scene. */\n detachSceneEventObserver(scene: Scene): void {\n scene._setEntityEventObserver(undefined);\n }\n\n /** @internal Scene hooks forward entity events through this method. */\n recordEntityEvent(eventName: string, data: unknown, entity: Entity): void {\n if (!this.eventLogEnabled) return;\n const scene = entity.tryScene;\n this.appendEvent(\n {\n frame: this.time.getFrame(),\n source: \"entity\",\n type: eventName,\n targetId: String(entity.id),\n payload: serializeEventPayload(data),\n },\n scene ? this.getSceneId(scene) : undefined,\n );\n }\n\n /** @internal Engine teardown releases the event-bus tap through this hook. */\n dispose(): void {\n this.detachBusTap?.();\n this.detachBusTap = null;\n for (const scene of this.engine.scenes.all) {\n scene._setEntityEventObserver(undefined);\n }\n this.extensions.clear();\n }\n\n private requireTimeController(): InspectorTimeController {\n if (!this.timeController) {\n throw new Error(\n \"Inspector.time requires DebugPlugin to be active.\",\n );\n }\n return this.timeController;\n }\n\n private requireInputManager(): InputManagerLike {\n const input = this.engine.context.tryResolve(InputManagerRuntimeKey);\n if (!input) {\n throw new Error(\n \"Inspector.input requires InputPlugin to be active.\",\n );\n }\n return input;\n }\n\n private recordBusEvent(type: string, data: unknown): void {\n if (!this.eventLogEnabled) return;\n this.appendEvent(\n {\n frame: this.time.getFrame(),\n source: \"bus\",\n type,\n payload: serializeEventPayload(data),\n },\n this.inferSceneIdFromPayload(data),\n );\n }\n\n private appendEvent(entry: EventLogEntry, sceneId: string | undefined): void {\n if (this.eventCapacity === 0) {\n this.flushMatchingWaiter(entry);\n return;\n }\n const logged: LoggedEvent = { entry, sceneId };\n if (this.eventLog.length < this.eventCapacity) {\n this.eventLog.push(logged);\n } else {\n // Ring full: overwrite the oldest slot in O(1) and advance the head.\n this.eventLog[this.eventLogHead] = logged;\n this.eventLogHead =\n (this.eventLogHead + 1) % this.eventCapacity;\n }\n this.flushMatchingWaiter(entry);\n }\n\n /** Resolve waiters whose deadline has passed without a match. */\n private expireDeadlineWaiters(): void {\n if (this.eventWaiters.size === 0) return;\n const frame = this.time.getFrame();\n for (const waiter of [...this.eventWaiters]) {\n if (\n waiter.deadlineFrame !== undefined &&\n frame > waiter.deadlineFrame\n ) {\n this.eventWaiters.delete(waiter);\n waiter.reject(\n new Error(\n `Inspector.events.waitFor() timed out after ${waiter.withinFrames} frames.`,\n ),\n );\n }\n }\n }\n\n /** Resolve any waiter that matches the just-appended entry. */\n private flushMatchingWaiter(entry: EventLogEntry): void {\n if (this.eventWaiters.size === 0) return;\n for (const waiter of [...this.eventWaiters]) {\n if (this.eventMatches(entry, waiter.pattern, waiter.source)) {\n this.eventWaiters.delete(waiter);\n waiter.resolve(entry);\n }\n }\n }\n\n /**\n * Walk the ring buffer in chronological order. We avoid materializing the\n * ordered array on every event append; instead, every consumer that needs\n * order calls this helper.\n */\n private iterateLog(): LoggedEvent[] {\n if (this.eventLog.length < this.eventCapacity || this.eventLogHead === 0) {\n return this.eventLog;\n }\n return [\n ...this.eventLog.slice(this.eventLogHead),\n ...this.eventLog.slice(0, this.eventLogHead),\n ];\n }\n\n private findMatchingEvent(\n pattern: string | RegExp,\n source: \"bus\" | \"entity\" | undefined,\n ): EventLogEntry | undefined {\n for (const { entry } of this.iterateLog()) {\n if (this.eventMatches(entry, pattern, source)) {\n return { ...entry };\n }\n }\n return undefined;\n }\n\n private eventMatches(\n entry: EventLogEntry,\n pattern: string | RegExp,\n source: \"bus\" | \"entity\" | undefined,\n ): boolean {\n if (source && entry.source !== source) return false;\n return typeof pattern === \"string\"\n ? entry.type === pattern\n : pattern.test(entry.type);\n }\n\n private sceneToWorldSnapshot(scene: Scene): WorldSceneSnapshot {\n const random = scene._resolveScoped(RandomKey);\n const physicsManager = this.engine.context.tryResolve(\n PhysicsWorldManagerRuntimeKey,\n );\n return {\n id: this.getSceneId(scene),\n name: scene.name,\n paused: scene.isPaused,\n timeScale: scene.timeScale,\n seed: random?.getSeed() ?? 0,\n entities: this.getSceneEntities(scene),\n ui: this.buildUISnapshot(scene),\n physics:\n physicsManager?.getContext(scene)?.world.snapshot() ?? {\n bodies: [],\n contacts: [],\n },\n events: this.getSceneEvents(scene),\n };\n }\n\n private getSceneEntities(scene: Scene): WorldEntitySnapshot[] {\n return [...scene.getEntities()]\n .filter((entity) => !entity.isDestroyed)\n .sort((a, b) => a.id - b.id)\n .map((entity) => this.entityToWorldSnapshot(entity));\n }\n\n private entityToWorldSnapshot(entity: Entity): WorldEntitySnapshot {\n const transform = entity.has(Transform) ? entity.get(Transform) : undefined;\n const worldPosition = transform?.worldPosition;\n const worldScale = transform?.worldScale;\n const components = [...entity.getAll()]\n .map((component) => this.componentToSnapshot(component))\n .sort((a, b) => (a.type < b.type ? -1 : a.type > b.type ? 1 : 0));\n\n return {\n id: String(entity.id),\n type: entity.constructor.name,\n parent: entity.parent ? String(entity.parent.id) : null,\n transform: {\n x: worldPosition?.x ?? 0,\n y: worldPosition?.y ?? 0,\n rotation: transform?.worldRotation ?? 0,\n scaleX: worldScale?.x ?? 1,\n scaleY: worldScale?.y ?? 1,\n },\n components,\n };\n }\n\n private componentToSnapshot(component: Component): ComponentStateSnapshot {\n return {\n type: component.constructor.name,\n state:\n typeof component.serialize === \"function\"\n ? trySerialize(component) ?? null\n : null,\n };\n }\n\n private buildUISnapshot(scene: Scene): UITreeSnapshot | null {\n const roots = [...scene.getEntities()]\n .filter((entity) => !entity.isDestroyed)\n .flatMap((entity) =>\n [...entity.getAll()]\n .filter(\n (component) =>\n component.constructor.name === \"UIPanel\" &&\n \"_node\" in (component as object),\n )\n .map((component, index) =>\n this.buildUINodeSnapshot(\n (component as Component & { _node: UIElementLike })._node,\n `entity-${entity.id}:UIPanel:${index}`,\n ),\n ),\n );\n\n if (roots.length === 0) return null;\n if (roots.length === 1) {\n return { root: roots[0]! };\n }\n\n return {\n root: {\n id: `scene-${this.getSceneId(scene)}:ui`,\n type: \"UIRoot\",\n layout: { x: 0, y: 0, width: 0, height: 0 },\n children: roots,\n state: null,\n },\n };\n }\n\n private buildUINodeSnapshot(\n node: UIElementLike,\n id: string,\n ): UINodeSnapshot {\n const layout = node.yogaNode?.getComputedLayout();\n const children = (node.children ?? []).map((child, index) =>\n this.buildUINodeSnapshot(child, `${id}/${index}`),\n );\n return {\n id,\n type: node.constructor.name,\n layout: {\n x: layout?.left ?? 0,\n y: layout?.top ?? 0,\n width: layout?.width ?? 0,\n height: layout?.height ?? 0,\n },\n children,\n state: null,\n };\n }\n\n private buildCameraSnapshot(): CameraSnapshot | null {\n const match = this.findTopmostCamera();\n if (!match) return null;\n const { scene, camera } = match;\n return {\n sceneId: this.getSceneId(scene),\n sceneName: scene.name,\n name: camera.cameraName ?? null,\n priority: camera.priority ?? 0,\n position: {\n x: camera.position.x,\n y: camera.position.y,\n },\n zoom: camera.zoom,\n rotation: camera.rotation,\n };\n }\n\n private findTopmostCamera():\n | { scene: Scene; camera: CameraComponentLike }\n | undefined {\n const stack = this.engine.scenes.all;\n for (let i = stack.length - 1; i >= 0; i--) {\n const scene = stack[i];\n if (!scene) continue;\n\n let highest: CameraComponentLike | undefined;\n for (const entity of scene.getEntities()) {\n if (entity.isDestroyed) continue;\n for (const component of entity.getAll()) {\n if (component.constructor.name !== \"CameraComponent\") continue;\n const camera = component as unknown as CameraComponentLike;\n if (\n camera.enabled &&\n (!highest || (camera.priority ?? 0) > (highest.priority ?? 0))\n ) {\n highest = camera;\n }\n }\n }\n\n if (highest) {\n return { scene, camera: highest };\n }\n }\n\n return undefined;\n }\n\n private buildInputSnapshot(): InputStateSnapshot {\n const input = this.engine.context.tryResolve(InputManagerRuntimeKey);\n return (\n input?.snapshotState() ?? {\n keys: [],\n actions: [],\n mouse: { x: 0, y: 0, buttons: [], down: false },\n pointers: [],\n gamepad: { buttons: [], axes: [] },\n }\n );\n }\n\n private getSceneEvents(scene: Scene): EventLogEntry[] {\n const sceneId = this.getSceneId(scene);\n return this.iterateLog()\n .filter((entry) => entry.sceneId === sceneId)\n .map(({ entry }) => ({ ...entry }));\n }\n\n private inferSceneIdFromPayload(data: unknown): string | undefined {\n if (!data || typeof data !== \"object\") return undefined;\n const record = data as Record<string, unknown>;\n\n const scene =\n this.extractScene(record[\"scene\"]) ??\n this.extractSceneFromEntity(record[\"entity\"]) ??\n this.extractSceneFromEntity(record[\"oldScene\"]) ??\n this.extractSceneFromEntity(record[\"newScene\"]);\n\n return scene ? this.getSceneId(scene) : undefined;\n }\n\n private extractScene(value: unknown): Scene | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n return this.engine.scenes.all.find((scene) => scene === value);\n }\n\n private extractSceneFromEntity(value: unknown): Scene | undefined {\n if (!value || typeof value !== \"object\") return undefined;\n const maybeEntity = value as { tryScene?: Scene | null };\n return maybeEntity.tryScene ?? this.extractScene(value);\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 entityToQuerySnapshot(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].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),\n components: [...entity.getAll()]\n .map((component) => component.constructor.name)\n .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)),\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 serializeComponentOwnProperties(comp: Component): unknown {\n const result: Record<string, unknown> = {};\n for (const key of Object.getOwnPropertyNames(comp)) {\n if (key === \"entity\") continue;\n // Skip private-by-convention fields. Components hold pixi/rapier handles\n // (e.g. _node, _body) on underscore-prefixed slots; exposing them in\n // snapshots would either crash JSON.stringify on cycles or leak\n // meaningless object identities.\n if (key.startsWith(\"_\")) continue;\n const value = (comp as unknown as Record<string, unknown>)[key];\n if (!isSerializableValue(value)) continue;\n result[key] = value;\n }\n return result;\n }\n\n private countEntities(): number {\n let count = 0;\n for (const scene of this.engine.scenes.all) {\n for (const entity of scene.getEntities()) {\n if (!entity.isDestroyed) count++;\n }\n }\n return count;\n }\n\n private getSceneId(scene: Scene): string {\n let id = this.sceneIds.get(scene);\n if (!id) {\n this.nextSceneId++;\n id = `scene-${this.nextSceneId}`;\n this.sceneIds.set(scene, id);\n }\n return id;\n }\n\n private assertNonNegativeInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`${name} requires a non-negative integer.`);\n }\n }\n\n private assertNonEmptyString(value: string, name: string): void {\n if (value.trim().length === 0) {\n throw new Error(`${name} requires a non-empty string.`);\n }\n }\n}\n\nfunction isSerializableValue(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n const t = typeof value;\n if (t === \"function\") return false;\n if (t !== \"object\") return true;\n if (Array.isArray(value)) return true;\n // Plain objects pass; class instances (Pixi, Rapier, Yoga, etc.) don't.\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nfunction safeClone(value: unknown): unknown | undefined {\n try {\n return JSON.parse(JSON.stringify(value)) as unknown;\n } catch {\n return undefined;\n }\n}\n\nfunction trySerialize(component: Component): unknown | undefined {\n try {\n return safeClone(component.serialize?.());\n } catch {\n return undefined;\n }\n}\n\nfunction serializeEventPayload(payload: unknown): unknown | null {\n if (payload === undefined) return null;\n const cloned = safeClone(payload);\n return cloned === undefined ? { _unserializable: true } : cloned;\n}\n\nfunction stableStringify(value: unknown): string {\n return JSON.stringify(sortJsonValue(value));\n}\n\nfunction sortJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => sortJsonValue(item));\n }\n\n if (value && typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>).sort(\n ([left], [right]) => (left < right ? -1 : left > right ? 1 : 0),\n );\n const result: Record<string, unknown> = {};\n for (const [key, child] of entries) {\n result[key] = sortJsonValue(child);\n }\n return result;\n }\n\n return value;\n}\n\nfunction decodeBase64(base64: string): Uint8Array {\n if (typeof atob === \"function\") {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n\n const bufferCtor = (globalThis as {\n Buffer?: {\n from(value: string, encoding: \"base64\"): Uint8Array;\n };\n }).Buffer;\n if (bufferCtor) {\n return bufferCtor.from(base64, \"base64\");\n }\n\n throw new Error(\"Inspector.capture.png() is not supported in this environment.\");\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 type { SceneTransition } from \"./SceneTransition.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 * Options accepted by the trailing argument of `Scene.spawn` and\n * `Entity.spawnChild`.\n */\nexport interface SpawnOptions {\n /**\n * Stable per-scene identity key. Looked up via `Scene.findByKey` and used\n * as a stable id in persistent stores (e.g. `defineSet<string>(\"world.opened\")`).\n *\n * Identity is opt-in — most entities (bullets, particles, transient enemies)\n * never need a key. Pass one only for entities whose state should persist\n * across save/load or cross-scene navigation, or that game code looks up\n * by name (chests, doors, named NPCs).\n *\n * Heads-up: don't name a top-level setup-params field `key`. The 2-arg\n * `spawn(Class, X)` form looks at `X`'s shape to disambiguate params from\n * options — an `X` whose only own keys are SpawnOptions fields routes\n * to options. If your params shape clashes (e.g. `setup(p: { key: number })`),\n * use the explicit 3-arg form `spawn(Class, params, options)`.\n */\n key?: string;\n}\n\n/**\n * Heuristic: is this object exactly the shape of `SpawnOptions`? Used by the\n * runtime to disambiguate the 2-arg `spawn(Class, X)` / `spawn(Blueprint, X)`\n * forms when both params and options are plausible.\n *\n * Rule: a plain object whose only own keys are SpawnOptions fields. As of\n * today, that's just `key`. If `SpawnOptions` grows, extend the allow-list.\n *\n * Trade-off: a params shape with a top-level `key` and nothing else is\n * misrouted to options — the \"reserved-keys-in-options\" footgun called out\n * in the design memo. Mitigation: don't name a top-level setup-params field\n * `key`. Use the 3-arg form (`spawn(Class, params, options)`) when in doubt.\n */\nconst _SPAWN_OPTION_KEYS: ReadonlySet<string> = new Set([\"key\"]);\nfunction _looksLikeSpawnOptions(v: unknown): v is SpawnOptions {\n if (typeof v !== \"object\" || v === null || Array.isArray(v)) return false;\n const keys = Object.keys(v);\n if (keys.length === 0) return false;\n for (const k of keys) {\n if (!_SPAWN_OPTION_KEYS.has(k)) return false;\n }\n return true;\n}\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 /** Default transition used when this scene is the destination of a push/pop/replace. */\n readonly defaultTransition?: SceneTransition;\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 private _entityEventObserver?:\n | ((eventName: string, data: unknown, entity: Entity) => void)\n | undefined;\n private _scopedServices?: Map<string, unknown>;\n private _identityIndex?: Map<string, Entity>;\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 /** Whether a scene transition is currently running. */\n get isTransitioning(): boolean {\n const sm = this._context?.tryResolve(SceneManagerKey);\n return sm?.isTransitioning ?? 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 /**\n * Spawn a new entity in this scene.\n *\n * Pass `{ key }` in the trailing options to register a stable per-scene\n * identity key, looked up later via `scene.findByKey`. The key is assigned\n * before `setup()` runs, so `entity.requireKey()` is safe inside it.\n *\n * Runtime routing for the 2-arg class form (`spawn(Class, X)`):\n * - If the class doesn't declare `setup` → `X` is options.\n * - Else if `X`'s own keys are exactly SpawnOptions fields (`{ key }`) →\n * `X` is options. Covers both `setup(params = {})` keyed without\n * params and `setup()` (no real params) keyed.\n * - Else → `X` is params (forwarded to `setup`).\n * The 3-arg form is always unambiguous: `spawn(Class, params, options)`.\n *\n * Don't name a top-level setup-params field `key` — the shape check would\n * misroute it. If you must, use the 3-arg form.\n */\n spawn(name?: string, options?: SpawnOptions): Entity;\n /**\n * Spawn from a blueprint. **Note**: blueprint params must not include a\n * top-level `key: string` field — the runtime can't disambiguate it from\n * `SpawnOptions`. If your params do, use the explicit 3-arg form\n * (`spawn(bp, params, { key })`) so options arrives in the trailing slot.\n */\n spawn<P>(blueprint: Blueprint<P>, params: P, options?: SpawnOptions): Entity;\n spawn(blueprint: Blueprint<void>, options?: SpawnOptions): 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 options?: SpawnOptions,\n ): E;\n /** Spawn an entity subclass without setup params. */\n spawn<E extends Entity>(Class: new () => E, options?: SpawnOptions): E;\n spawn(\n nameOrBlueprintOrClass?: string | Blueprint<unknown> | (new () => Entity),\n paramsOrOptions?: unknown,\n maybeOptions?: SpawnOptions,\n ): Entity {\n // Class-based spawn: argument is a constructor function for an Entity subclass\n if (typeof nameOrBlueprintOrClass === \"function\") {\n const Ctor = nameOrBlueprintOrClass;\n const hasSetup =\n typeof (Ctor.prototype as { setup?: unknown }).setup === \"function\";\n\n let params: unknown;\n let options: SpawnOptions | undefined;\n if (maybeOptions !== undefined) {\n // 3-arg: explicit. paramsOrOptions = params, maybeOptions = options.\n params = paramsOrOptions;\n options = maybeOptions;\n } else if (paramsOrOptions === undefined) {\n // 1-arg: nothing to route.\n } else if (!hasSetup) {\n // No setup → 2nd arg can only be options.\n options = paramsOrOptions as SpawnOptions;\n } else if (_looksLikeSpawnOptions(paramsOrOptions)) {\n // Setup exists, but the 2nd arg is options-shaped (only `key`).\n // This covers two cases that arity alone gets wrong:\n // - setup(params = {}) with `spawn(Class, { key })` → options ✓\n // - setup() with `spawn(Class, { key })` → options ✓\n // For setup-bearing classes whose params type happens to have ONLY\n // a top-level `key` field, the user must use the 3-arg form.\n options = paramsOrOptions;\n } else {\n // Setup exists and 2nd arg has params-shaped content (e.g.\n // `{ position, zoom }`). Forward to setup.\n params = paramsOrOptions;\n }\n\n const entity = new Ctor();\n entity._setScene(this, this.entityCallbacks);\n // Register key BEFORE adding to entities/emitting created — a duplicate\n // key throw must not leave a half-spawned entity in the scene.\n if (options?.key !== undefined) this._registerKey(entity, options.key);\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 // Routing for non-class forms:\n // spawn(name, options?) → paramsOrOptions = options\n // spawn(blueprint, params, options?) → paramsOrOptions = params, maybeOptions = options\n // spawn(blueprint, options?) (Blueprint<void>) → paramsOrOptions = options\n // For blueprints we can't introspect arity reliably (build is user code);\n // disambiguate via a 3-arg call (always passes options as the third arg)\n // vs 2-arg (where the second slot is options for void blueprints, or params\n // for parameterised ones — which is fine because params for a `Blueprint<void>`\n // doesn't typecheck either way).\n let blueprintParams: unknown;\n let options: SpawnOptions | undefined;\n if (isBlueprint) {\n if (maybeOptions !== undefined) {\n blueprintParams = paramsOrOptions;\n options = maybeOptions;\n } else if (\n paramsOrOptions !== undefined &&\n _looksLikeSpawnOptions(paramsOrOptions)\n ) {\n options = paramsOrOptions;\n } else {\n blueprintParams = paramsOrOptions;\n }\n } else {\n // spawn(name, options?)\n options = paramsOrOptions as SpawnOptions | undefined;\n }\n\n const entity = new Entity(name);\n entity._setScene(this, this.entityCallbacks);\n if (options?.key !== undefined) this._registerKey(entity, options.key);\n this.entities.add(entity);\n this.bus?.emit(\"entity:created\", { entity });\n\n if (isBlueprint) {\n (nameOrBlueprintOrClass as Blueprint<unknown>).build(\n entity,\n blueprintParams,\n );\n }\n\n return entity;\n }\n\n /**\n * Look up an entity by its stable identity key, scoped to this scene.\n * Returns `undefined` for unknown or already-destroyed entities.\n */\n findByKey<E extends Entity = Entity>(key: string): E | undefined {\n const entity = this._identityIndex?.get(key);\n if (!entity || entity.isDestroyed) return undefined;\n return entity as E;\n }\n\n /**\n * Internal: register a key on a freshly spawned entity. Throws on\n * duplicate so callers (Scene.spawn) can abort before adding to\n * `this.entities` or emitting `entity:created`.\n * @internal\n */\n _registerKey(entity: Entity, key: string): void {\n this._identityIndex ??= new Map();\n const existing = this._identityIndex.get(key);\n if (existing && !existing.isDestroyed) {\n throw new Error(\n `Scene \"${this.name}\" already has an entity with key \"${key}\". ` +\n `Destroy it before spawning a duplicate.`,\n );\n }\n entity._setKey(key);\n this._identityIndex.set(key, 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 /**\n * Observe entity-scoped event emissions after they dispatch locally and\n * bubble to the scene. Tooling only; game code should keep using `on()`.\n * @internal\n */\n _observeEntityEvent(eventName: string, data: unknown, entity: Entity): void {\n this._entityEventObserver?.(eventName, data, entity);\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 * Register a scene-scoped service. Called from a plugin's `beforeEnter`\n * hook to make per-scene state (render tree, physics world) resolvable via\n * `Component.use(key)`.\n * @internal\n */\n _registerScoped<T>(key: ServiceKey<T>, value: T): void {\n this._scopedServices ??= new Map();\n this._scopedServices.set(key.id, value);\n }\n\n /**\n * Install or clear a tooling-only observer for bubbled entity events.\n * @internal\n */\n _setEntityEventObserver(\n observer?: (eventName: string, data: unknown, entity: Entity) => void,\n ): void {\n this._entityEventObserver = observer;\n }\n\n /**\n * Resolve a scene-scoped service, or `undefined` if none was registered.\n * @internal\n */\n _resolveScoped<T>(key: ServiceKey<T>): T | undefined {\n return this._scopedServices?.get(key.id) as T | undefined;\n }\n\n /**\n * Clear all scene-scoped services. Called by the SceneManager after\n * `afterExit` hooks run, so plugin cleanup code still sees scoped state.\n * @internal\n */\n _clearScopedServices(): void {\n this._scopedServices?.clear();\n }\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 if (\n entity.key !== undefined &&\n this._identityIndex?.get(entity.key) === entity\n ) {\n // Only evict if the slot still points to *this* entity. A\n // same-frame destroy + respawn with the same key replaces the\n // map entry inside `_registerKey`; we must not delete the\n // replacement here.\n this._identityIndex.delete(entity.key);\n }\n this.bus?.emit(\"entity:destroyed\", { entity });\n }\n this.destroyQueue.length = 0;\n }\n\n /**\n * Destroy all entities — used during scene exit. Clears the identity\n * index in bulk; per-entity key removal in `_flushDestroyQueue` is the\n * in-game path.\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 this._identityIndex?.clear();\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 { Scene } from \"./Scene.js\";\nimport {\n EventBusKey,\n LoggerKey,\n ProcessSystemKey,\n SceneManagerKey,\n} from \"./EngineContext.js\";\nimport type { SceneTransition } from \"./SceneTransition.js\";\nimport { Process } from \"./Process.js\";\n\n/**\n * Base class for a progress-bar style loading screen.\n *\n * Preloads the target scene's assets through the `AssetManager`, exposes\n * `progress` and emits `scene:loading:progress` / `scene:loading:done` on\n * the engine event bus, enforces `minDuration` to prevent flicker on cached\n * loads, then replaces itself with `target` — optionally through a\n * transition.\n *\n * LoadingScene owns orchestration only. It does not render anything. To show\n * a progress UI, spawn an entity that subscribes to the loading events (the\n * canonical default is `LoadingSceneProgressBar` in `@yagejs/ui`, or any\n * custom component). The loading scene is a normal Scene, so you can use\n * `onEnter` to spawn whatever you want.\n *\n * ```ts\n * class Boot extends LoadingScene {\n * readonly target = new GameScene();\n * readonly minDuration = 500;\n * readonly transition = fade({ duration: 300 });\n * override onEnter() {\n * this.spawn(LoadingSceneProgressBar);\n * this.startLoading();\n * }\n * }\n *\n * await engine.scenes.replace(new Boot());\n * ```\n *\n * Set `autoContinue = false` to gate the handoff behind a `continue()` call\n * — useful for \"press any key to continue\" flows. `scene:loading:done`\n * still fires so UI can react (show a prompt), and whoever eventually\n * calls `this.continue()` triggers the transition.\n */\nexport abstract class LoadingScene extends Scene {\n override readonly name: string = \"loading\";\n\n /**\n * Scene to load and transition to. Accepts an instance or a factory —\n * use a factory when target construction should be deferred until\n * loading starts (heavy constructors, side effects). The factory runs\n * before `assets.loadAll` so `target.preload` can be inspected.\n */\n abstract readonly target: Scene | (() => Scene);\n\n /**\n * Minimum wall-clock ms the scene stays visible before handing off.\n * Prevents flicker on cached loads. Default 0.\n */\n readonly minDuration: number = 0;\n\n /** Transition used for the loading → target handoff. */\n readonly transition?: SceneTransition;\n\n /**\n * When true (default), the handoff fires automatically after loading and\n * `minDuration`. Set false to gate it behind `continue()` — useful when\n * the loading scene also asks the player to press a key or click.\n */\n readonly autoContinue: boolean = true;\n\n /**\n * Optional hook; fires if asset loading rejects. The scene stays mounted\n * whether or not this is set. When set, the hook is the recovery channel:\n * draw a retry UI, push an error scene, or call `this.startLoading()`\n * again to retry the load. When unset, the error is logged via the engine\n * logger and the scene remains mounted in a failed state with no\n * automatic recovery.\n *\n * The hook may still be running when the scene is replaced externally —\n * don't assume the scene is live (check `this.context.tryResolve` rather\n * than `this.service` before touching engine services, and avoid spawning\n * new entities after an `await`).\n */\n onLoadError?(error: Error): void | Promise<void>;\n\n private _progress = 0;\n private _started = false;\n private _active = true;\n private _continueRequested = false;\n private _continueGate?: () => void;\n private _pendingWaits = new Set<Process>();\n // Bumped on every `_run` attempt. `AssetManager.loadAll` uses `Promise.all`\n // under the hood, so individual loaders from a failed attempt can still\n // resolve and fire `onProgress` after the attempt rejects. Without this\n // guard, a retry kicked off from `onLoadError` would see stale progress\n // callbacks mutate `_progress` and emit `scene:loading:progress` events\n // attributed to the current attempt.\n private _attempt = 0;\n\n /** Current load progress, 0 → 1. Updated as the AssetManager reports progress. */\n get progress(): number {\n return this._progress;\n }\n\n /**\n * Kick off asset loading. While a load is in flight, subsequent calls\n * are no-ops. After a load failure the guard is released, so calling\n * `startLoading()` from `onLoadError` (or from a retry button) kicks off\n * a fresh load against the same target.\n *\n * Usually called once from `onEnter` after spawning the loading UI:\n * ```ts\n * override onEnter() {\n * this.spawn(LoadingSceneProgressBar);\n * this.startLoading();\n * }\n * ```\n *\n * Deferring the call lets you gate the start of the load behind a\n * title screen, \"press any key\" prompt, intro animation, etc.\n */\n startLoading(): void {\n if (this._started) return;\n this._started = true;\n // `_run` is fire-and-forget — the scene is already mounted, so there's\n // no `push`/`replace` caller to propagate errors to. The catch is the\n // final terminus for anything `_run` rethrows (target factory failure,\n // `scenes.replace` failure, or a load error with no `onLoadError`\n // override). Log it so the failure doesn't vanish into the browser's\n // unhandled-rejection channel.\n this._run().catch((err) => {\n if (!this._active) return;\n const logger = this.context.tryResolve(LoggerKey);\n if (logger) {\n logger.error(\"LoadingScene\", \"loading failed\", { error: err });\n } else {\n console.error(\"[LoadingScene] loading failed:\", err);\n }\n });\n }\n\n /**\n * Trigger the handoff to `target`. No-op if already called or if\n * `autoContinue` already fired it. If called before loading finishes,\n * the handoff runs as soon as loading + `minDuration` complete.\n */\n continue(): void {\n if (this._continueRequested) return;\n this._continueRequested = true;\n this._continueGate?.();\n }\n\n override onExit(): void {\n // Flip the run-guard so any in-flight _run() resumption short-circuits\n // instead of firing events or scheduling scenes.replace on a stack\n // that has already moved on. Also unblocks an autoContinue=false gate\n // so the promise resolves and the async function can terminate.\n this._active = false;\n this._continueGate?.();\n for (const wait of this._pendingWaits) {\n wait.cancel();\n }\n this._pendingWaits.clear();\n }\n\n private async _run(): Promise<void> {\n // Yield past the push-mutation window onEnter runs inside. Without\n // this, a target with empty or cached preload resumes the handoff\n // while SceneManager is still mid-mutation, and scenes.replace\n // would reject as reentrant.\n await Promise.resolve();\n if (!this._active) return;\n\n const attempt = ++this._attempt;\n const target =\n typeof this.target === \"function\" ? this.target() : this.target;\n const bus = this.context.resolve(EventBusKey);\n const minDuration = this._createEngineTimeDelay(this.minDuration);\n\n // `onLoadError` is specifically for asset-load failures. Narrow the\n // try/catch to the load phase so target-factory errors and\n // scenes.replace errors aren't silently swallowed through it.\n try {\n await this.assets.loadAll(target.preload ?? [], (ratio) => {\n if (!this._active || attempt !== this._attempt) return;\n this._progress = ratio;\n bus.emit(\"scene:loading:progress\", { scene: this, ratio });\n });\n if (!this._active || attempt !== this._attempt) {\n minDuration.cancel();\n return;\n }\n await minDuration.promise;\n if (!this._active || attempt !== this._attempt) return;\n } catch (err) {\n minDuration.cancel();\n // Scene exited mid-await → thrown error is incidental. Swallow.\n if (!this._active || attempt !== this._attempt) return;\n const error = err instanceof Error ? err : new Error(String(err));\n // Release the start guard so the hook (or anyone with a reference)\n // can call startLoading() again to retry. Bumping `_attempt` here\n // invalidates any still-in-flight progress callbacks from this\n // failed attempt before the retry's `onProgress` can fire.\n this._started = false;\n this._attempt++;\n if (this.onLoadError) {\n await this.onLoadError(error);\n return;\n }\n throw error;\n }\n\n bus.emit(\"scene:loading:done\", { scene: this });\n\n if (!this.autoContinue && !this._continueRequested) {\n await new Promise<void>((resolve) => {\n this._continueGate = resolve;\n });\n if (!this._active || attempt !== this._attempt) return;\n }\n\n const scenes = this.context.resolve(SceneManagerKey);\n await scenes.replace(\n target,\n this.transition ? { transition: this.transition } : undefined,\n );\n }\n\n private _createEngineTimeDelay(ms: number): {\n promise: Promise<void>;\n cancel: () => void;\n } {\n if (ms <= 0) {\n return {\n promise: Promise.resolve(),\n cancel: () => {},\n };\n }\n\n const wait = Process.delay(ms);\n this._pendingWaits.add(wait);\n this.context.resolve(ProcessSystemKey).add(wait);\n return {\n promise: wait.toPromise().finally(() => {\n this._pendingWaits.delete(wait);\n }),\n cancel: () => {\n wait.cancel();\n },\n };\n }\n}\n","import type { Scene } from \"./Scene.js\";\nimport type { EngineContext } from \"./EngineContext.js\";\n\n/** Which scene op triggered this transition. */\nexport type SceneTransitionKind = \"push\" | \"pop\" | \"replace\";\n\n/** Context passed to a transition each frame. */\nexport interface SceneTransitionContext {\n /** Wall-clock ms elapsed since begin(). */\n readonly elapsed: number;\n readonly kind: SceneTransitionKind;\n readonly engineContext: EngineContext;\n /** The scene being left or removed (undefined on first push). */\n readonly fromScene: Scene | undefined;\n /** The scene being entered or revealed (undefined on last pop). */\n readonly toScene: Scene | undefined;\n}\n\n/**\n * A scene transition animates the handoff between scene stack states.\n *\n * `SceneManager` keeps both the outgoing and incoming scenes on the stack\n * for the transition's duration, then removes the outgoing scene afterward.\n * Transitions use raw wall-clock dt and ignore engine + scene `timeScale`.\n */\nexport interface SceneTransition {\n /** Total duration in wall-clock ms. */\n readonly duration: number;\n /** Called once when the transition starts. Set up resources here. */\n begin?(ctx: SceneTransitionContext): void;\n /** Called each frame with frame dt in ms. `ctx.elapsed` is clamped to `duration`. */\n tick(dt: number, ctx: SceneTransitionContext): void;\n /** Called when the transition ends. Tear down resources here. */\n end?(ctx: SceneTransitionContext): void;\n}\n\n/** Options accepted by `SceneManager.push/pop/replace`. */\nexport interface SceneTransitionOptions {\n transition?: SceneTransition;\n}\n\n/**\n * Resolve the effective transition for a scene op.\n * Precedence: call-site option → destination's `defaultTransition` → undefined.\n */\nexport function resolveTransition(\n callSite: SceneTransition | undefined,\n destination: Scene | undefined,\n): SceneTransition | undefined {\n if (callSite) return callSite;\n return destination?.defaultTransition;\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, LoggerKey } from \"./EngineContext.js\";\nimport type { SceneHookRegistry } from \"./SceneHooks.js\";\nimport { SceneHookRegistryKey } from \"./SceneHooks.js\";\nimport type { Logger } from \"./Logger.js\";\nimport {\n resolveTransition,\n type SceneTransition,\n type SceneTransitionContext,\n type SceneTransitionKind,\n type SceneTransitionOptions,\n} from \"./SceneTransition.js\";\n\ninterface TransitionRun {\n kind: SceneTransitionKind;\n transition: SceneTransition;\n elapsed: number;\n fromScene: Scene | undefined;\n toScene: Scene | undefined;\n resolve: () => void;\n}\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 private hookRegistry: SceneHookRegistry | undefined;\n private logger: Logger | undefined;\n private _currentRun: TransitionRun | undefined;\n private _pendingChain: Promise<void> = Promise.resolve();\n private _mutationDepth = 0;\n private _destroyed = false;\n\n private _autoPauseOnBlur = false;\n private _isBlurred = false;\n private readonly _visibilityPausedScenes = new Set<Scene>();\n private _visibilityListenerCleanup: (() => void) | undefined;\n\n /**\n * Pause all non-paused scenes when `document.hidden` becomes `true`; restore\n * them on focus. Default: `false`. Only scenes paused by this mechanism are\n * restored — user-paused scenes (manual `scene.paused = true` or `pauseBelow`\n * cascade) are never touched.\n */\n get autoPauseOnBlur(): boolean {\n return this._autoPauseOnBlur;\n }\n\n set autoPauseOnBlur(value: boolean) {\n if (this._autoPauseOnBlur === value) return;\n this._autoPauseOnBlur = value;\n if (!this._isBlurred) return;\n if (value) {\n this._applyBlurPause();\n } else if (this._visibilityPausedScenes.size > 0) {\n this._restoreBlurPause();\n }\n }\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 this.hookRegistry = context.tryResolve(SceneHookRegistryKey);\n this.logger = context.tryResolve(LoggerKey);\n\n if (this._visibilityListenerCleanup || typeof document === \"undefined\") {\n return;\n }\n const onVisibilityChange = (): void => {\n this._handleVisibilityChange(document.hidden);\n };\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n this._visibilityListenerCleanup = () =>\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n }\n\n /**\n * React to a visibility change. Parameterised on `hidden` so unit tests can\n * drive it without a real `document`.\n * @internal\n */\n _handleVisibilityChange(hidden: boolean): void {\n if (hidden && !this._isBlurred) {\n this._isBlurred = true;\n if (this._autoPauseOnBlur) this._applyBlurPause();\n } else if (!hidden && this._isBlurred) {\n this._isBlurred = false;\n if (this._visibilityPausedScenes.size > 0) this._restoreBlurPause();\n }\n }\n\n private _applyBlurPause(): void {\n for (const scene of this.activeScenes) {\n scene.paused = true;\n this._visibilityPausedScenes.add(scene);\n }\n }\n\n private _restoreBlurPause(): void {\n for (const scene of this._visibilityPausedScenes) {\n scene.paused = false;\n }\n this._visibilityPausedScenes.clear();\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((scene) => !scene.isPaused);\n }\n\n /** Whether a scene transition is currently running. */\n get isTransitioning(): boolean {\n return this._currentRun !== undefined;\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 */\n async push(scene: Scene, opts?: SceneTransitionOptions): Promise<void> {\n this._assertNotMutating(\"push\");\n await this._enqueue(async () => {\n const fromScene = this.active;\n await this._pushScene(scene);\n\n const transition = resolveTransition(opts?.transition, scene);\n if (!transition) return;\n\n await this._runTransition(\"push\", transition, fromScene, scene);\n });\n }\n\n /** Pop the top scene. Scenes below may receive onResume(). */\n async pop(opts?: SceneTransitionOptions): Promise<Scene | undefined> {\n this._assertNotMutating(\"pop\");\n return this._enqueue(async () => {\n if (this.stack.length === 0) return undefined;\n\n const fromScene = this.active;\n const destination =\n this.stack.length > 1 ? this.stack[this.stack.length - 2] : undefined;\n const transition = resolveTransition(opts?.transition, destination);\n\n if (transition) {\n await this._runTransition(\"pop\", transition, fromScene, destination);\n }\n\n return this._popScene();\n });\n }\n\n /**\n * Replace the top scene. Without a transition the old scene exits first,\n * then the new scene enters. With a transition the new scene is pushed\n * first, both scenes coexist for the transition duration, then the old\n * scene is removed at the end.\n */\n async replace(scene: Scene, opts?: SceneTransitionOptions): Promise<void> {\n this._assertNotMutating(\"replace\");\n await this._enqueue(async () => {\n const transition = resolveTransition(opts?.transition, scene);\n\n if (!transition) {\n await this._replaceScene(scene);\n return;\n }\n\n const old = this.active;\n await this._pushScene(scene, true);\n await this._runTransition(\"replace\", transition, old, scene);\n\n if (old) {\n this._removeScene(old, true);\n }\n this.bus?.emit(\"scene:replaced\", {\n oldScene: old ?? scene,\n newScene: scene,\n });\n });\n }\n\n /**\n * Pop every scene on the stack, top to bottom. Each receives onExit().\n * Queued like push/pop/replace — runs after any in-flight transition.\n * Use for \"restart from menu\"-style flows. Does not run transitions.\n */\n async popAll(): Promise<void> {\n this._assertNotMutating(\"popAll\");\n await this._enqueue(async () => {\n this._withMutationSync(() => {\n while (this.stack.length > 0) {\n const scene = this.stack.pop();\n if (!scene) break;\n this._teardownScene(scene);\n this.bus?.emit(\"scene:popped\", { scene });\n }\n });\n });\n }\n\n /**\n * Run the full scene-enter lifecycle (beforeEnter hooks, preload, onEnter)\n * for a scene that is NOT placed on the stack. Used by infrastructure\n * plugins like DebugPlugin that render a scene off-stack.\n * @internal\n */\n async _mountDetached(scene: Scene): Promise<void> {\n await this._withMutation(async () => {\n scene._setContext(this._context);\n await this.hookRegistry?.runBeforeEnter(scene);\n await this._preloadScene(scene);\n scene.onEnter?.();\n });\n }\n\n /**\n * Run the scene-exit lifecycle (onExit, entity destruction, afterExit\n * hooks, scoped-service clear) for a detached scene.\n * @internal\n */\n _unmountDetached(scene: Scene): void {\n this._withMutationSync(() => {\n this._teardownScene(scene);\n });\n }\n\n /**\n * Mark the manager destroyed and synchronously tear down every scene.\n * Called by Engine.destroy(). Any queued async work short-circuits on\n * resume; in-flight transitions' pending promises are resolved via\n * _cleanupRun so they don't leak.\n * @internal\n */\n _destroy(): void {\n this._destroyed = true;\n if (this._currentRun) {\n this._cleanupRun(this._currentRun);\n }\n this._pendingChain = Promise.resolve();\n\n this._visibilityListenerCleanup?.();\n this._visibilityListenerCleanup = undefined;\n this._visibilityPausedScenes.clear();\n\n this._withMutationSync(() => {\n while (this.stack.length > 0) {\n const scene = this.stack.pop();\n if (!scene) break;\n this._teardownScene(scene);\n this.bus?.emit(\"scene:popped\", { scene });\n }\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 /**\n * Advance the active transition by `dt` ms. Called by Engine's earlyUpdate\n * callback with raw (unscaled) wall-clock dt.\n * @internal\n */\n _tickTransition(dt: number): void {\n const run = this._currentRun;\n if (!run) return;\n\n const remaining = run.transition.duration - run.elapsed;\n const consume = Math.min(dt, remaining);\n run.elapsed += consume;\n this._safeTick(run, consume);\n\n if (run.elapsed >= run.transition.duration) {\n this._cleanupRun(run);\n }\n }\n\n // ---- Private helpers ----\n\n private _enqueue<T>(work: () => Promise<T>): Promise<T | undefined> {\n if (this._destroyed) return Promise.resolve(undefined);\n const next = this._pendingChain.then(async () => {\n if (this._destroyed) return undefined;\n return work();\n });\n\n this._pendingChain = next.then(\n () => undefined,\n () => undefined,\n );\n\n return next;\n }\n\n private async _pushScene(\n scene: Scene,\n suppressEvent = false,\n ): Promise<void> {\n const wasPaused = this._snapshotPauseStates();\n\n await this._withMutation(async () => {\n scene._setContext(this._context);\n await this.hookRegistry?.runBeforeEnter(scene);\n // Preload before pushing so a failed asset load doesn't leave an\n // un-entered scene on the stack.\n await this._preloadScene(scene);\n this.stack.push(scene);\n scene.onEnter?.();\n this._firePauseTransitions(wasPaused);\n if (!suppressEvent) {\n this.bus?.emit(\"scene:pushed\", { scene });\n }\n });\n }\n\n private _popScene(suppressEvent = false): Scene | undefined {\n const wasPaused = this._snapshotPauseStates();\n\n return this._withMutationSync(() => {\n const removed = this.stack.pop();\n if (!removed) return undefined;\n\n this._teardownScene(removed);\n this._fireResumeTransitions(wasPaused);\n if (!suppressEvent) {\n this.bus?.emit(\"scene:popped\", { scene: removed });\n }\n return removed;\n });\n }\n\n private async _replaceScene(scene: Scene): Promise<void> {\n const wasPaused = this._snapshotPauseStates();\n\n await this._withMutation(async () => {\n scene._setContext(this._context);\n await this.hookRegistry?.runBeforeEnter(scene);\n // Preload before mutating the stack so a failed asset load doesn't\n // tear down the old scene without a working replacement.\n await this._preloadScene(scene);\n\n const old = this.stack.pop();\n if (old) this._teardownScene(old);\n this.stack.push(scene);\n scene.onEnter?.();\n\n this._firePauseTransitions(wasPaused);\n this._fireResumeTransitions(wasPaused);\n this.bus?.emit(\"scene:replaced\", {\n oldScene: old ?? scene,\n newScene: scene,\n });\n });\n }\n\n private _removeScene(scene: Scene, suppressEvent = false): void {\n this._withMutationSync(() => {\n const idx = this.stack.indexOf(scene);\n if (idx === -1) return;\n\n const wasPaused = this._snapshotPauseStates();\n this.stack.splice(idx, 1);\n this._teardownScene(scene);\n this._firePauseTransitions(wasPaused);\n this._fireResumeTransitions(wasPaused);\n if (!suppressEvent) {\n this.bus?.emit(\"scene:popped\", { scene });\n }\n });\n }\n\n private async _preloadScene(scene: Scene): Promise<void> {\n if (!scene.preload?.length || !this.assetManager) return;\n await this.assetManager.loadAll(\n scene.preload,\n scene.onProgress?.bind(scene),\n );\n }\n\n private _teardownScene(scene: Scene): void {\n scene.onExit?.();\n scene._destroyAllEntities();\n this.hookRegistry?.runAfterExit(scene);\n scene._clearScopedServices();\n this._visibilityPausedScenes.delete(scene);\n }\n\n private async _runTransition(\n kind: SceneTransitionKind,\n transition: SceneTransition,\n fromScene: Scene | undefined,\n toScene: Scene | undefined,\n ): Promise<void> {\n // If destroy() landed between this op's prior await and here, bail\n // before registering a _currentRun whose promise would never resolve\n // (the loop is stopped, so _tickTransition won't fire).\n if (this._destroyed) return;\n\n let resolveRun!: () => void;\n const promise = new Promise<void>((resolve) => {\n resolveRun = resolve;\n });\n\n const run: TransitionRun = {\n kind,\n transition,\n elapsed: 0,\n fromScene,\n toScene,\n resolve: resolveRun,\n };\n this._currentRun = run;\n this.bus?.emit(\"scene:transition:started\", {\n kind,\n fromScene,\n toScene,\n });\n\n // Fire begin synchronously so the transition can paint its start state\n // before any render happens. For push/replace this lets built-ins hide\n // the incoming scene before a frame could show it covering the old one.\n this._safeCall(run, \"begin\");\n\n // Reject NaN and Infinity (Infinity > 0 is true, so the naive check\n // lets it through and _tickTransition would loop forever without ever\n // reaching elapsed >= duration, hanging the _pendingChain).\n if (!Number.isFinite(transition.duration) || transition.duration <= 0) {\n this._cleanupRun(run);\n return;\n }\n\n await promise;\n }\n\n private _cleanupRun(run: TransitionRun): void {\n if (this._currentRun !== run) return;\n\n this._safeCall(run, \"end\");\n this._currentRun = undefined;\n this.bus?.emit(\"scene:transition:ended\", {\n kind: run.kind,\n fromScene: run.fromScene,\n toScene: run.toScene,\n });\n run.resolve();\n }\n\n private _safeTick(run: TransitionRun, dt: number): void {\n try {\n run.transition.tick(dt, this._makeContext(run));\n } catch (err: unknown) {\n this.logger?.warn(\n \"SceneManager\",\n `Transition tick error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private _safeCall(run: TransitionRun, method: \"begin\" | \"end\"): void {\n try {\n run.transition[method]?.(this._makeContext(run));\n } catch (err: unknown) {\n this.logger?.warn(\n \"SceneManager\",\n `Transition ${method} error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n private _makeContext(run: TransitionRun): SceneTransitionContext {\n return {\n elapsed: run.elapsed,\n kind: run.kind,\n engineContext: this._context,\n fromScene: run.fromScene,\n toScene: run.toScene,\n };\n }\n\n private _snapshotPauseStates(): Map<Scene, boolean> {\n return new Map(\n this.stack.map((scene) => [scene, scene.isPaused] as const),\n );\n }\n\n private _assertNotMutating(method: string): void {\n if (this._mutationDepth === 0) return;\n throw new Error(\n `SceneManager.${method}() called reentrantly from a scene lifecycle hook ` +\n \"(onEnter/onExit/onPause/onResume or a beforeEnter/afterExit hook). \" +\n \"Defer the call outside the hook, e.g. via queueMicrotask() or from a component update().\",\n );\n }\n\n private async _withMutation<T>(work: () => Promise<T>): Promise<T> {\n this._mutationDepth++;\n try {\n return await work();\n } finally {\n this._mutationDepth--;\n }\n }\n\n private _withMutationSync<T>(work: () => T): T {\n this._mutationDepth++;\n try {\n return work();\n } finally {\n this._mutationDepth--;\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 scene of this.stack) {\n const was = wasPaused.get(scene) ?? false;\n if (scene.isPaused && !was) {\n scene.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 scene of this.stack) {\n const was = wasPaused.get(scene) ?? false;\n if (!scene.isPaused && was) {\n scene.onResume?.();\n }\n }\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 { ProcessOptions } from \"./Process.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: 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\";\nimport { serializable } from \"./Serializable.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 */\n@serializable\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 serialize(): null {\n return null;\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\";\nimport { serializable } from \"./Serializable.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 */\n@serializable\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 serialize(): null {\n return null;\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 { Scene } from \"./Scene.js\";\nimport type { SceneManager } from \"./SceneManager.js\";\nimport type { Process } from \"./Process.js\";\nimport { ProcessComponent } from \"./ProcessComponent.js\";\nimport { SceneManagerKey } from \"./EngineContext.js\";\nimport { SceneHookRegistryKey } from \"./SceneHooks.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 globalProcesses = new Set<Process>();\n private scenePools = new Map<Scene, Set<Process>>();\n private _unregisterSceneHook: (() => void) | null = null;\n\n override onRegister(context: EngineContext): void {\n this.sceneManager = context.resolve(SceneManagerKey);\n // Drop the scene's pool on exit so cancelled processes (e.g. effect\n // fades torn down with the scene) don't keep the dead Scene key\n // alive in the pool map. Hold onto the unregister callback so engine\n // teardown releases the hook — without this, a re-created Engine\n // sharing a SceneHookRegistry would accumulate dead callbacks.\n const hooks = context.tryResolve(SceneHookRegistryKey);\n this._unregisterSceneHook =\n hooks?.register({\n afterExit: (scene) => this.cancelForScene(scene),\n }) ?? null;\n }\n\n override onUnregister(): void {\n this._unregisterSceneHook?.();\n this._unregisterSceneHook = null;\n // Drain pools so cancelled processes don't keep Scene refs alive.\n for (const p of this.globalProcesses) {\n if (!p.completed) p.cancel();\n }\n this.globalProcesses.clear();\n for (const pool of this.scenePools.values()) {\n for (const p of pool) {\n if (!p.completed) p.cancel();\n }\n }\n this.scenePools.clear();\n }\n\n /**\n * Add an engine-global process. Ticked under the global timeScale only;\n * NOT gated by per-scene pause or scaled by per-scene timeScale. Use this\n * for cross-scene effects (e.g. screen-scope filter fades on `app.stage`)\n * or processes that have no owning scene.\n */\n add(process: Process): Process {\n this.globalProcesses.add(process);\n return process;\n }\n\n /**\n * Add a process bound to a specific scene's lifecycle. Ticked only while\n * the scene is active (not paused) and scaled by the scene's `timeScale`,\n * exactly like an entity-owned `ProcessComponent`. Use this for layer or\n * scene-scope effect fades that should pause with the scene.\n */\n addForScene(scene: Scene, process: Process): Process {\n let pool = this.scenePools.get(scene);\n if (!pool) {\n pool = new Set();\n this.scenePools.set(scene, pool);\n }\n pool.add(process);\n return process;\n }\n\n /** Cancel engine-global processes, optionally by tag. */\n cancel(tag?: string): void {\n for (const p of this.globalProcesses) {\n if (tag === undefined || p.tags.includes(tag)) {\n p.cancel();\n this.globalProcesses.delete(p);\n }\n }\n }\n\n /** Cancel every scene-bound process for `scene`, optionally by tag. */\n cancelForScene(scene: Scene, tag?: string): void {\n const pool = this.scenePools.get(scene);\n if (!pool) return;\n for (const p of pool) {\n if (tag === undefined || p.tags.includes(tag)) {\n p.cancel();\n pool.delete(p);\n }\n }\n if (pool.size === 0) this.scenePools.delete(scene);\n }\n\n update(dt: number): void {\n const globalScaledDt = dt * this.timeScale;\n\n // Engine-global processes — global timeScale only, not scene-bound.\n for (const p of this.globalProcesses) {\n p._update(globalScaledDt);\n if (p.completed) {\n this.globalProcesses.delete(p);\n }\n }\n\n // Per-scene work: entity ProcessComponents AND scene-scoped processes.\n // Both share the same activeScenes gating + per-scene timeScale, so a\n // layer-scope fade pauses with the scene exactly like an entity fade.\n for (const scene of this.sceneManager.activeScenes) {\n const effectiveDt = globalScaledDt * scene.timeScale;\n\n const pool = this.scenePools.get(scene);\n if (pool) {\n for (const p of pool) {\n p._update(effectiveDt);\n if (p.completed) pool.delete(p);\n }\n if (pool.size === 0) this.scenePools.delete(scene);\n }\n\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 type { Entity } from \"./Entity.js\";\nimport type { Process } from \"./Process.js\";\nimport { ProcessComponent } from \"./ProcessComponent.js\";\nimport type { ProcessSystem } from \"./ProcessSystem.js\";\nimport type { Scene } from \"./Scene.js\";\n\n/**\n * A scoped queue for `Process` instances. Tracks the processes it enqueued so\n * `cancelAll()` can tear them down without touching unrelated processes that\n * happen to share the same underlying pool (entity `ProcessComponent` or\n * engine-level `ProcessSystem`).\n *\n * Use one of the `make*ScopedQueue` factories to construct one — each picks\n * the right routing strategy and lifetime semantics for its scope.\n */\nexport interface ScopedProcessQueue {\n /** Enqueue a process. Returned for chaining. */\n run(p: Process): Process;\n /** Cancel every process this queue enqueued. Idempotent. */\n cancelAll(): void;\n}\n\n/**\n * Build a `ScopedProcessQueue` over a routing function. The three public\n * factories below differ only in WHERE they route the process (entity\n * ProcessComponent / scene-bound pool / engine-global pool); the tracking,\n * lazy-prune-on-run, and isolated-cancelAll behavior is identical.\n *\n * Lazy O(n) sweep on each `run()` is bounded by how many processes the\n * queue has accumulated; cheap and avoids holding refs to completed Process\n * instances for the queue's lifetime.\n */\nfunction makeQueue(route: (p: Process) => void): ScopedProcessQueue {\n const ours = new Set<Process>();\n return {\n run(p) {\n for (const old of ours) {\n if (old.completed) ours.delete(old);\n }\n route(p);\n ours.add(p);\n return p;\n },\n cancelAll() {\n for (const p of ours) {\n if (!p.completed) p.cancel();\n }\n ours.clear();\n },\n };\n}\n\n/**\n * Scoped queue that routes through the entity's `ProcessComponent`. Auto-adds\n * one if the entity doesn't already have it. `cancelAll()` only cancels the\n * processes this queue enqueued, so sharing the underlying ProcessComponent\n * with user code stays safe.\n */\nexport function makeEntityScopedQueue(entity: Entity): ScopedProcessQueue {\n return makeQueue((p) => {\n let pc = entity.tryGet(ProcessComponent);\n if (!pc) {\n pc = entity.add(new ProcessComponent());\n }\n pc.run(p);\n });\n}\n\n/**\n * Scoped queue bound to a specific scene's lifecycle. Routes through\n * `ProcessSystem.addForScene`, so processes pause with the scene and are\n * scaled by its `timeScale` — matching the behaviour of entity-owned\n * `ProcessComponent` processes.\n */\nexport function makeSceneScopedQueue(\n processSystem: ProcessSystem,\n scene: Scene,\n): ScopedProcessQueue {\n return makeQueue((p) => processSystem.addForScene(scene, p));\n}\n\n/**\n * Engine-global scoped queue. Routes through `ProcessSystem.add` — ticked\n * under the global timeScale only, NOT gated by per-scene pause or scaled\n * by per-scene timeScale. Right for cross-scene work that should keep\n * playing during scene transitions and across paused scenes.\n */\nexport function makeGlobalScopedQueue(\n processSystem: ProcessSystem,\n): ScopedProcessQueue {\n return makeQueue((p) => processSystem.add(p));\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\";\nimport { SceneHookRegistry, SceneHookRegistryKey } from \"./SceneHooks.js\";\nimport type { SceneHooks } from \"./SceneHooks.js\";\nimport { RandomKey } from \"./Random.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 private readonly sceneHooks: SceneHookRegistry;\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 this.sceneHooks = new SceneHookRegistry();\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 this.context.register(SceneHookRegistryKey, this.sceneHooks);\n\n this.sceneHooks.register({\n beforeEnter: (scene) => {\n scene._registerScoped(RandomKey, this.inspector.createSceneRandom());\n this.inspector.attachSceneEventObserver(scene);\n },\n afterExit: (scene) => {\n this.inspector.detachSceneEventObserver(scene);\n },\n });\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.scenes._tickTransition(dt);\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 /**\n * Register scene lifecycle hooks. The returned function unregisters the\n * hooks. Infrastructure plugins (renderer, physics, debug) register hooks\n * in their `install` or `onStart` to set up and tear down per-scene state.\n */\n registerSceneHooks(hooks: SceneHooks): () => void {\n return this.sceneHooks.register(hooks);\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. Awaited so users can reliably call scenes.push()\n // right after `await engine.start()` without racing plugin init\n // (e.g. DebugPlugin mounts a detached debug scene in onStart).\n for (const plugin of sorted) {\n await 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 // Tear down scenes synchronously; also short-circuits any queued async work.\n this.scenes._destroy();\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.inspector.dispose();\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 { ServiceKey } from \"./EngineContext.js\";\n\n/**\n * Cross-package contract for \"something that owns a canvas and can map\n * canvas-relative CSS pixels into virtual-space pixels\".\n *\n * Implemented by `@yagejs/renderer`'s `RendererPlugin` and consumed by\n * `@yagejs/input` for pointer-event targeting and coordinate mapping under\n * responsive fit. Foreign renderers can implement this interface and register\n * under `RendererAdapterKey` to integrate with the input plugin without\n * importing `@yagejs/renderer`.\n */\nexport interface RendererAdapter {\n readonly canvas: HTMLCanvasElement;\n /**\n * Convert CSS pixels relative to the canvas into virtual-space pixels.\n * Optional — when absent, consumers fall back to raw CSS pixels (correct\n * only when canvas CSS size equals virtual size).\n */\n canvasToVirtual?(x: number, y: number): { x: number; y: number };\n /**\n * Hit-test at virtual-space coordinates and return `true` when the topmost\n * interactive container under `(x, y)` is parented (directly or through any\n * ancestor) to a container marked via {@link markPointerConsumeContainer}.\n * Optional — when absent, the input plugin's UI auto-consume fallback is a\n * no-op.\n *\n * Implemented by `@yagejs/renderer` over Pixi's `EventBoundary`. The input\n * plugin calls this on `pointerdown` drains to auto-claim presses that land\n * on UI surfaces (UIPanel backgrounds, decorative UIText, etc.) without\n * requiring per-component handler boilerplate.\n */\n hitTestUI?(x: number, y: number): boolean;\n}\n\n/**\n * Well-known service key for the current renderer's pointer-input adapter.\n * The canonical `@yagejs/renderer` plugin registers itself here; consumers\n * (notably `@yagejs/input`) resolve this key to auto-wire canvas targeting\n * and coordinate mapping.\n */\nexport const RendererAdapterKey = new ServiceKey<RendererAdapter>(\n \"rendererAdapter\",\n);\n","/**\n * Cross-package WeakSet for marking display containers (Pixi `Container`s in\n * the canonical setup) as \"swallow pointer input.\" The `@yagejs/input`\n * package's drain step consults this set via the renderer's optional\n * `hitTestUI(x, y)` — when the topmost interactive container under a\n * `pointerdown` is parented to a marked container, the pointer is auto-claimed\n * (`consumePointer`-equivalent), so the press never propagates to gameplay\n * action-map edges like `MouseLeft`.\n *\n * Lives in `@yagejs/core` so the renderer (read side) and the UI / sprite\n * components (write side) can both reach it without circular imports.\n *\n * Untyped on `Container` to keep `@yagejs/core` free of any Pixi dependency.\n * Callers pass their `Pixi.Container` instances directly; `WeakSet` accepts\n * any object reference.\n */\n\nconst registry = new WeakSet<object>();\n\n/**\n * Mark a display container as a UI-input surface. Idempotent. Call from a\n * component's `onAdd` (or equivalent) after the underlying Pixi container is\n * created.\n */\nexport function markPointerConsumeContainer(container: object): void {\n registry.add(container);\n}\n\n/**\n * Remove the mark. Call from a component's `onDestroy` for symmetry, or to\n * implement an opt-out (`consumeInput: false`) escape hatch on UI primitives.\n */\nexport function unmarkPointerConsumeContainer(container: object): void {\n registry.delete(container);\n}\n\n/** Whether a container has been marked as a UI-input surface. */\nexport function isPointerConsumeContainer(container: object): boolean {\n return registry.has(container);\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\";\nimport { RandomKey, createRandomService } from \"./Random.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 scene._registerScoped(RandomKey, createRandomService(1234));\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","/**\n * Atom — minimal reactive cell.\n *\n * Signal-shaped: `get`, `set`, `subscribe`. Identity-based change detection\n * (`Object.is`); subscribers are notified only when the value actually changes.\n */\nexport interface Atom<T> {\n get(): T;\n set(next: T): void;\n subscribe(listener: (value: T) => void): () => void;\n}\n\nexport function createAtom<T>(initial: T): Atom<T> {\n let value: T = initial;\n const listeners = new Set<(value: T) => void>();\n\n return {\n get(): T {\n return value;\n },\n set(next: T): void {\n if (Object.is(value, next)) return;\n value = next;\n for (const fn of listeners) fn(value);\n },\n subscribe(listener: (value: T) => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n","/**\n * Store — object-shaped reactive store with shallow merge.\n *\n * `get()` returns a `Readonly<T>` whose reference is stable between sets.\n * `set(partial)` merges keys via spread and notifies only when at least one key\n * changed (Object.is per key). Mutation through the snapshot bypasses\n * subscribers — TypeScript's `Readonly<T>` enforces the contract; do not reach\n * into nested objects to mutate them, use `set` instead.\n */\nexport interface Store<T extends object> {\n get(): Readonly<T>;\n set(partial: Partial<T>): void;\n subscribe(listener: () => void): () => void;\n}\n\nexport function createStore<T extends object>(initial: T): Store<T> {\n let snapshot: T = { ...initial };\n const listeners = new Set<() => void>();\n\n return {\n get(): Readonly<T> {\n return snapshot;\n },\n set(partial: Partial<T>): void {\n let changed = false;\n for (const key of Object.keys(partial) as Array<keyof T>) {\n if (!Object.is(snapshot[key], partial[key])) {\n changed = true;\n break;\n }\n }\n if (!changed) return;\n\n snapshot = { ...snapshot, ...partial };\n for (const fn of listeners) fn();\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n","/**\n * A codec converts a value between its in-memory representation and a JSON-safe\n * representation that adapters can stringify. Codecs are pure functions; they\n * don't read or write storage.\n */\nexport interface Codec<T> {\n encode(value: T): unknown;\n decode(raw: unknown): T;\n}\n\n/** Identity codec — pass-through for plain JSON-serializable values. */\nexport function jsonCodec<T>(): Codec<T> {\n return {\n encode: (value) => value,\n decode: (raw) => raw as T,\n };\n}\n\n/** Set ↔ array. */\nexport function setCodec<K>(): Codec<Set<K>> {\n return {\n encode: (value) => Array.from(value),\n decode: (raw) => {\n if (!Array.isArray(raw)) {\n throw new Error(\"setCodec.decode: expected an array\");\n }\n return new Set(raw as K[]);\n },\n };\n}\n\n/** Map ↔ entries array. */\nexport function mapCodec<K, V>(): Codec<Map<K, V>> {\n return {\n encode: (value) => Array.from(value.entries()),\n decode: (raw) => {\n if (!Array.isArray(raw)) {\n throw new Error(\"mapCodec.decode: expected an array of entries\");\n }\n return new Map(raw as Array<[K, V]>);\n },\n };\n}\n\n/** Date ↔ ISO string. */\nexport function dateCodec(): Codec<Date> {\n return {\n encode: (value) => value.toISOString(),\n decode: (raw) => {\n if (typeof raw !== \"string\") {\n throw new Error(\"dateCodec.decode: expected an ISO string\");\n }\n const d = new Date(raw);\n if (Number.isNaN(d.getTime())) {\n throw new Error(`dateCodec.decode: invalid ISO string ${JSON.stringify(raw)}`);\n }\n return d;\n },\n };\n}\n","import { createAtom, type Atom } from \"./Atom.js\";\nimport { createStore, type Store } from \"./Store.js\";\nimport { jsonCodec, setCodec, mapCodec, type Codec } from \"./codecs.js\";\n\n/**\n * Common persistence shape implemented by every defineX output. The save layer\n * accepts anything matching this structural type — stores don't depend on the\n * save layer.\n */\nexport interface PersistentLike {\n readonly id: string;\n readonly version: number;\n serialize(): { version: number; data: unknown };\n hydrate(payload: { version: number; data: unknown }): void;\n subscribe(listener: () => void): () => void;\n}\n\n// ---------------------------------------------------------------------------\n// Internal registry — tracks every defined store so tests can reset them all.\n// ---------------------------------------------------------------------------\n\ninterface RegisteredEntry {\n readonly id: string;\n reset(): void;\n}\n\n// Keyed by id so a subsequent re-evaluation of the same module (e.g. a\n// dev-server hot reload) replaces the entry transparently rather than\n// throwing on the second `defineX` call.\nconst registry = new Map<string, RegisteredEntry>();\n\nfunction register(entry: RegisteredEntry): void {\n registry.set(entry.id, entry);\n}\n\n/**\n * Reset every persistent store created by defineStore / defineSet / defineMap /\n * defineCounter back to its defaults. Test-only.\n *\n * @internal\n */\nexport function _resetAllStoresForTesting(): void {\n for (const entry of registry.values()) entry.reset();\n}\n\n/**\n * Drop every persistent store from the internal registry. Use only when you\n * intend to redefine stores with the same ids (e.g. between test files that\n * share a module namespace via Vitest's module cache).\n *\n * @internal\n */\nexport function _clearStoreRegistryForTesting(): void {\n registry.clear();\n}\n\n// ---------------------------------------------------------------------------\n// defineStore — object-shaped persistent store\n// ---------------------------------------------------------------------------\n\nexport interface DefineStoreOptions<T> {\n /** Schema version. Defaults to 1. Bump when shape changes; provide `migrate`. */\n version?: number;\n /** Factory producing the default value. Called on creation and on `reset()`. */\n defaults: () => T;\n /** Codec for `T`. Defaults to identity (jsonCodec). */\n codec?: Codec<T>;\n /**\n * Migrate previously-stored data to the current version. Receives the raw\n * decoded payload and the version it was written at. Called when\n * `payload.version < version` during `hydrate`.\n */\n migrate?: (old: unknown, fromVersion: number) => T;\n}\n\nexport interface PersistentStore<T extends object>\n extends Store<T>,\n PersistentLike {\n reset(): void;\n}\n\n/** Thrown by `hydrate` when stored data is from a newer version than this build. */\nexport class StoreVersionTooNewError extends Error {\n readonly storeId: string;\n readonly storedVersion: number;\n readonly currentVersion: number;\n constructor(storeId: string, storedVersion: number, currentVersion: number) {\n super(\n `Store \"${storeId}\" was saved at version ${storedVersion}, ` +\n `but this build is at version ${currentVersion}. Cannot downgrade.`,\n );\n this.name = \"StoreVersionTooNewError\";\n this.storeId = storeId;\n this.storedVersion = storedVersion;\n this.currentVersion = currentVersion;\n }\n}\n\n/** Thrown by `hydrate` when stored data is older than the current version and no `migrate` is configured. */\nexport class StoreMigrationMissingError extends Error {\n readonly storeId: string;\n readonly storedVersion: number;\n readonly currentVersion: number;\n constructor(storeId: string, storedVersion: number, currentVersion: number) {\n super(\n `Store \"${storeId}\" needs migration from version ${storedVersion} ` +\n `to ${currentVersion}, but no migrate() was provided.`,\n );\n this.name = \"StoreMigrationMissingError\";\n this.storeId = storeId;\n this.storedVersion = storedVersion;\n this.currentVersion = currentVersion;\n }\n}\n\nexport function defineStore<T extends object>(\n id: string,\n opts: DefineStoreOptions<T>,\n): PersistentStore<T> {\n const version = opts.version ?? 1;\n const codec: Codec<T> = opts.codec ?? jsonCodec<T>();\n const defaults = opts.defaults;\n\n const inner = createStore<T>(defaults());\n\n const replaceAll = (next: T): void => {\n inner.set({ ...next });\n };\n\n const store: PersistentStore<T> = {\n id,\n version,\n\n get: inner.get,\n set: inner.set,\n subscribe: inner.subscribe,\n\n reset(): void {\n replaceAll(defaults());\n },\n\n serialize(): { version: number; data: unknown } {\n return { version, data: codec.encode(inner.get() as T) };\n },\n\n hydrate(payload: { version: number; data: unknown }): void {\n if (payload.version > version) {\n throw new StoreVersionTooNewError(id, payload.version, version);\n }\n let next: T;\n if (payload.version < version) {\n if (!opts.migrate) {\n throw new StoreMigrationMissingError(id, payload.version, version);\n }\n next = opts.migrate(payload.data, payload.version);\n } else {\n next = codec.decode(payload.data);\n }\n replaceAll(next);\n },\n };\n\n register({ id, reset: () => store.reset() });\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// defineSet — persistent set of keys\n// ---------------------------------------------------------------------------\n\nexport interface PersistentSet<K> extends PersistentLike {\n has(key: K): boolean;\n add(key: K): void;\n remove(key: K): void;\n clear(): void;\n size(): number;\n values(): IterableIterator<K>;\n reset(): void;\n}\n\nexport interface DefineSetOptions<K> {\n version?: number;\n defaults?: () => Iterable<K>;\n /**\n * Migrate older stored data to the current version. Receives the raw decoded\n * payload (a `K[]` from setCodec) and the version it was written at. Required\n * when bumping `version`; otherwise older payloads throw at hydrate.\n */\n migrate?: (old: unknown, fromVersion: number) => Set<K>;\n}\n\nexport function defineSet<K>(\n id: string,\n opts?: DefineSetOptions<K>,\n): PersistentSet<K> {\n const version = opts?.version ?? 1;\n const defaults = (): Set<K> => new Set<K>(opts?.defaults?.() ?? []);\n const codec = setCodec<K>();\n const atom: Atom<Set<K>> = createAtom<Set<K>>(defaults());\n\n const replace = (next: Set<K>): void => {\n atom.set(next);\n };\n\n const store: PersistentSet<K> = {\n id,\n version,\n\n has(key) {\n return atom.get().has(key);\n },\n add(key) {\n const current = atom.get();\n if (current.has(key)) return;\n const next = new Set(current);\n next.add(key);\n replace(next);\n },\n remove(key) {\n const current = atom.get();\n if (!current.has(key)) return;\n const next = new Set(current);\n next.delete(key);\n replace(next);\n },\n clear() {\n if (atom.get().size === 0) return;\n replace(new Set());\n },\n size() {\n return atom.get().size;\n },\n values() {\n return atom.get().values();\n },\n\n subscribe(listener) {\n return atom.subscribe(() => listener());\n },\n\n reset() {\n replace(defaults());\n },\n\n serialize() {\n return { version, data: codec.encode(atom.get()) };\n },\n hydrate(payload) {\n if (payload.version > version) {\n throw new StoreVersionTooNewError(id, payload.version, version);\n }\n if (payload.version < version) {\n if (!opts?.migrate) {\n throw new StoreMigrationMissingError(id, payload.version, version);\n }\n replace(opts.migrate(payload.data, payload.version));\n return;\n }\n replace(codec.decode(payload.data));\n },\n };\n\n register({ id, reset: () => store.reset() });\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// defineMap — persistent key→value map\n// ---------------------------------------------------------------------------\n\nexport interface PersistentMap<K, V> extends PersistentLike {\n has(key: K): boolean;\n get(key: K): V | undefined;\n set(key: K, value: V): void;\n remove(key: K): void;\n clear(): void;\n size(): number;\n entries(): IterableIterator<[K, V]>;\n reset(): void;\n}\n\nexport interface DefineMapOptions<K, V> {\n version?: number;\n defaults?: () => Iterable<[K, V]>;\n /**\n * Migrate older stored data to the current version. Receives the raw decoded\n * payload (a `[K, V][]` from mapCodec) and the version it was written at.\n * Required when bumping `version`; otherwise older payloads throw at hydrate.\n */\n migrate?: (old: unknown, fromVersion: number) => Map<K, V>;\n}\n\nexport function defineMap<K, V>(\n id: string,\n opts?: DefineMapOptions<K, V>,\n): PersistentMap<K, V> {\n const version = opts?.version ?? 1;\n const defaults = (): Map<K, V> => new Map<K, V>(opts?.defaults?.() ?? []);\n const codec = mapCodec<K, V>();\n const atom = createAtom<Map<K, V>>(defaults());\n\n const replace = (next: Map<K, V>): void => {\n atom.set(next);\n };\n\n const store: PersistentMap<K, V> = {\n id,\n version,\n\n has(key) {\n return atom.get().has(key);\n },\n get(key) {\n return atom.get().get(key);\n },\n set(key, value) {\n const current = atom.get();\n if (current.has(key) && Object.is(current.get(key), value)) return;\n const next = new Map(current);\n next.set(key, value);\n replace(next);\n },\n remove(key) {\n const current = atom.get();\n if (!current.has(key)) return;\n const next = new Map(current);\n next.delete(key);\n replace(next);\n },\n clear() {\n if (atom.get().size === 0) return;\n replace(new Map());\n },\n size() {\n return atom.get().size;\n },\n entries() {\n return atom.get().entries();\n },\n\n subscribe(listener) {\n return atom.subscribe(() => listener());\n },\n\n reset() {\n replace(defaults());\n },\n\n serialize() {\n return { version, data: codec.encode(atom.get()) };\n },\n hydrate(payload) {\n if (payload.version > version) {\n throw new StoreVersionTooNewError(id, payload.version, version);\n }\n if (payload.version < version) {\n if (!opts?.migrate) {\n throw new StoreMigrationMissingError(id, payload.version, version);\n }\n replace(opts.migrate(payload.data, payload.version));\n return;\n }\n replace(codec.decode(payload.data));\n },\n };\n\n register({ id, reset: () => store.reset() });\n return store;\n}\n\n// ---------------------------------------------------------------------------\n// defineCounter — persistent integer counter\n// ---------------------------------------------------------------------------\n\nexport interface PersistentCounter extends PersistentLike {\n value(): number;\n set(n: number): void;\n increment(by?: number): void;\n decrement(by?: number): void;\n reset(): void;\n}\n\nexport interface DefineCounterOptions {\n version?: number;\n defaults?: () => number;\n /**\n * Migrate older stored data to the current version. Receives the raw decoded\n * payload (a number) and the version it was written at. Required when\n * bumping `version`; otherwise older payloads throw at hydrate.\n */\n migrate?: (old: unknown, fromVersion: number) => number;\n}\n\nexport function defineCounter(\n id: string,\n opts?: DefineCounterOptions,\n): PersistentCounter {\n const version = opts?.version ?? 1;\n const defaults = (): number => opts?.defaults?.() ?? 0;\n const atom = createAtom<number>(defaults());\n\n const store: PersistentCounter = {\n id,\n version,\n\n value() {\n return atom.get();\n },\n set(n) {\n atom.set(n);\n },\n increment(by = 1) {\n atom.set(atom.get() + by);\n },\n decrement(by = 1) {\n atom.set(atom.get() - by);\n },\n\n subscribe(listener) {\n return atom.subscribe(() => listener());\n },\n\n reset() {\n atom.set(defaults());\n },\n\n serialize() {\n return { version, data: atom.get() };\n },\n hydrate(payload) {\n if (payload.version > version) {\n throw new StoreVersionTooNewError(id, payload.version, version);\n }\n if (payload.version < version) {\n if (!opts?.migrate) {\n throw new StoreMigrationMissingError(id, payload.version, version);\n }\n const migrated = opts.migrate(payload.data, payload.version);\n if (typeof migrated !== \"number\") {\n throw new Error(\n `defineCounter \"${id}\".hydrate: migrate returned non-number ${typeof migrated}`,\n );\n }\n atom.set(migrated);\n return;\n }\n if (typeof payload.data !== \"number\") {\n throw new Error(\n `defineCounter \"${id}\".hydrate: expected number, got ${typeof payload.data}`,\n );\n }\n atom.set(payload.data);\n },\n };\n\n register({ id, reset: () => store.reset() });\n return store;\n}\n"],"mappings":"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","names":["Phase","LogLevel","options","entity","result","_init","_a","_init","_a","registry","registry"]}
|