@yagejs/debug 0.4.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 CHANGED
@@ -584,6 +584,9 @@ var DebugPlugin = class {
584
584
  if (this.config.deterministicSeed !== void 0) {
585
585
  context.resolve(import_core4.InspectorKey).setDefaultSceneSeed(this.config.deterministicSeed);
586
586
  }
587
+ if (this.config.startFrozen) {
588
+ this.renderer.application.stop();
589
+ }
587
590
  this.registry = new DebugRegistryImpl();
588
591
  this.registry.enabled = this.config.startEnabled ?? false;
589
592
  if (this.config.flags) {
@@ -639,6 +642,9 @@ var DebugPlugin = class {
639
642
  inspector.attachTimeController(this.clock);
640
643
  inspector.setEventLogEnabled(true);
641
644
  this.attachToGlobal(this.clock);
645
+ if (this.config.startFrozen) {
646
+ this.clock.freeze();
647
+ }
642
648
  this.provider = this.context.tryResolve(import_renderer3.SceneRenderTreeProviderKey) ?? null;
643
649
  this.registerInspectorDiagnostics();
644
650
  await this.materializeDebugScene();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/DebugPlugin.ts","../src/types.ts","../src/DebugClock.ts","../src/DebugRegistryImpl.ts","../src/DebugScene.ts","../src/StatsStore.ts","../src/GraphicsPool.ts","../src/TextPool.ts","../src/WorldDebugApiImpl.ts","../src/HudDebugApiImpl.ts","../src/DebugRenderSystem.ts","../src/contributors/FpsContributor.ts","../src/contributors/EntityCountContributor.ts","../src/contributors/SystemTimingContributor.ts"],"sourcesContent":["export { DebugPlugin } from \"./DebugPlugin.js\";\nexport type {\n DebugConfig,\n DebugDiagnostics,\n LayerTransformSnapshot,\n CameraStackSnapshot,\n} from \"./DebugPlugin.js\";\nexport type { IDebugClock } from \"./DebugClock.js\";\nexport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nexport { StatsStore } from \"./StatsStore.js\";\n","import {\n EventBusKey,\n GameLoopKey,\n InspectorKey,\n SceneManagerKey,\n} from \"@yagejs/core\";\nimport type {\n EngineContext,\n EventBus,\n EngineEvents,\n Plugin,\n SceneManager,\n System,\n SystemScheduler,\n} from \"@yagejs/core\";\nimport { DebugRegistryKey } from \"./types.js\";\nimport { CameraComponent, RendererKey } from \"@yagejs/renderer\";\nimport type { RendererPlugin, SceneRenderTreeProvider } from \"@yagejs/renderer\";\nimport { SceneRenderTreeProviderKey } from \"@yagejs/renderer\";\nimport type { Application, Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { DebugClockHost, IDebugClock } from \"./DebugClock.js\";\nimport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport { DebugScene } from \"./DebugScene.js\";\nimport { StatsStore } from \"./StatsStore.js\";\nimport { GraphicsPool } from \"./GraphicsPool.js\";\nimport { TextPool } from \"./TextPool.js\";\nimport { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport { DebugRenderSystem } from \"./DebugRenderSystem.js\";\nimport { FpsContributor } from \"./contributors/FpsContributor.js\";\nimport { EntityCountContributor } from \"./contributors/EntityCountContributor.js\";\nimport { SystemTimingContributor } from \"./contributors/SystemTimingContributor.js\";\n\n/** Configuration for the DebugPlugin. */\nexport interface DebugConfig {\n /** Key code to toggle debug overlay. Default: \"Backquote\" */\n toggleKey?: string;\n /** Key code to advance one fixed-timestep frame while the debug clock is frozen. Default: \"Period\" */\n stepKey?: string;\n /** Max pooled Graphics objects. Default: 256 */\n maxGraphics?: number;\n /** Max HUD text lines. Default: 32 */\n maxHudLines?: number;\n /** Whether the overlay starts enabled. Default: false */\n startEnabled?: boolean;\n /** Initial flag overrides, keyed by \"contributorName.flagName\". */\n flags?: Record<string, boolean>;\n /**\n * If set, every scene's RNG is initialized with this seed instead of an\n * unspecified default. Use for deterministic E2E runs. Leave undefined for\n * normal debug builds so randomness behaves the same as in production.\n */\n deterministicSeed?: number;\n}\n\nexport interface LayerTransformSnapshot {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n rotation: number;\n}\n\nexport interface CameraStackSnapshot {\n scene: string;\n name: string | undefined;\n priority: number;\n enabled: boolean;\n}\n\n/**\n * Renderer-aware diagnostics exposed through the inspector extension\n * namespace `debug`. Kept out of the core Inspector surface so the core\n * package stays renderer-agnostic while plugins can still publish optional\n * runtime helpers in a uniform way.\n */\nexport interface DebugDiagnostics {\n getLayerTransform(\n sceneName: string,\n layerName: string,\n ): LayerTransformSnapshot | undefined;\n getCameraStack(): CameraStackSnapshot[];\n}\n\n/**\n * Debug overlay plugin. Mounts a private `DebugScene` through\n * `SceneManager._mountDetached` so it goes through the same scoped-DI\n * lifecycle as stacked scenes (the renderer's `beforeEnter` hook creates\n * its render tree) while staying off the user-visible scene stack.\n */\nexport class DebugPlugin implements Plugin {\n readonly name = \"debug\";\n readonly version = \"3.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n private readonly config: DebugConfig;\n private registry!: DebugRegistryImpl;\n private stats!: StatsStore;\n private graphicsPool: GraphicsPool | null = null;\n private textPool: TextPool | null = null;\n private worldApi: WorldDebugApiImpl | null = null;\n private hudApi: HudDebugApiImpl | null = null;\n private renderSystem: DebugRenderSystem | null = null;\n private systemTimings = new Map<string, number>();\n private originalUpdates = new Map<System, (dt: number) => void>();\n private keyListener: ((e: KeyboardEvent) => void) | null = null;\n private context!: EngineContext;\n private renderer!: RendererPlugin;\n private scheduler!: SystemScheduler;\n private sceneManager!: SceneManager;\n private debugScene: DebugScene | null = null;\n private provider: SceneRenderTreeProvider | null = null;\n private eventUnsubs: Array<() => void> = [];\n private clock: DebugClock | null = null;\n\n constructor(config?: DebugConfig) {\n this.config = config ?? {};\n }\n\n install(context: EngineContext): void {\n this.context = context;\n this.renderer = context.resolve(RendererKey);\n if (this.config.deterministicSeed !== undefined) {\n context\n .resolve(InspectorKey)\n .setDefaultSceneSeed(this.config.deterministicSeed);\n }\n\n this.registry = new DebugRegistryImpl();\n this.registry.enabled = this.config.startEnabled ?? false;\n\n if (this.config.flags) {\n for (const [key, value] of Object.entries(this.config.flags)) {\n const dot = key.indexOf(\".\");\n if (dot > 0) {\n this.registry.setFlag(key.slice(0, dot), key.slice(dot + 1), value);\n }\n }\n }\n\n this.stats = new StatsStore();\n\n context.register(DebugRegistryKey, this.registry);\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n // DebugRenderSystem is registered lazily once the debug scene is ready —\n // its constructor needs the scene's layer containers.\n this.scheduler = scheduler;\n }\n\n async onStart(): Promise<void> {\n this.sceneManager = this.context.resolve(SceneManagerKey);\n const bus = this.context.resolve(EventBusKey) as EventBus<EngineEvents>;\n\n // Key listeners (toggle, manual-clock step)\n const toggleKey = this.config.toggleKey ?? \"Backquote\";\n const stepKey = this.config.stepKey ?? \"Period\";\n this.keyListener = (e: KeyboardEvent) => {\n if (e.code === toggleKey) {\n this.registry.toggle();\n return;\n }\n if (e.code === stepKey && this.clock?.isFrozen) {\n e.preventDefault();\n this.clock.step();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.keyListener);\n }\n\n // Instrument system timings — reuse the scheduler captured in\n // `registerSystems`, which ran before `onStart`.\n for (const system of this.scheduler.getAllSystems()) {\n if (system instanceof DebugRenderSystem) continue;\n const name = system.constructor.name;\n const original = system.update.bind(system);\n this.originalUpdates.set(system, original);\n system.update = (dt: number) => {\n const t0 = performance.now();\n original(dt);\n this.systemTimings.set(name, performance.now() - t0);\n };\n }\n\n // Built-in contributors\n const inspector = this.context.resolve(InspectorKey);\n this.registry.register(new FpsContributor());\n this.registry.register(new EntityCountContributor(inspector));\n this.registry.register(new SystemTimingContributor(this.systemTimings));\n\n // Manual clock for deterministic stepping. The host drives `app.ticker`\n // directly so a manual `step()` fires every ticker subscriber\n // (AnimatedSprite, pixi-filters, render, user `app.ticker.add` callbacks)\n // with the same synthetic dt as gameplay state.\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n this.clock = new DebugClock(createPixiTickerHost(app, gameLoop.fixedTimestep));\n inspector.attachTimeController(this.clock);\n inspector.setEventLogEnabled(true);\n this.attachToGlobal(this.clock);\n\n // Materialize the debug scene off-stack. `_mountDetached` routes through\n // the same beforeEnter hooks as `push`, so the renderer materializes the\n // debug scene's tree and registers SceneRenderTreeKey on its scope.\n this.provider = this.context.tryResolve(SceneRenderTreeProviderKey) ?? null;\n this.registerInspectorDiagnostics();\n await this.materializeDebugScene();\n\n // Keep the debug scene visually on top of the user stack after any\n // push/pop/replace by reordering its root containers.\n const bringToFront = () => {\n if (this.debugScene && this.provider?.bringSceneToFront) {\n this.provider.bringSceneToFront(this.debugScene);\n }\n };\n this.eventUnsubs.push(bus.on(\"scene:pushed\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:popped\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:replaced\", bringToFront));\n }\n\n onDestroy(): void {\n for (const unsub of this.eventUnsubs) unsub();\n this.eventUnsubs.length = 0;\n\n for (const [system, original] of this.originalUpdates) {\n system.update = original;\n }\n this.originalUpdates.clear();\n\n if (this.keyListener) {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.keyListener);\n }\n this.keyListener = null;\n }\n\n this.detachFromGlobal();\n const inspector = this.context.resolve(InspectorKey);\n inspector.removeExtension(\"debug\");\n // Only detach our own clock — passing undefined would clear whatever\n // controller is registered, which could belong to another plugin if\n // onDestroy runs after a failed onStart.\n if (this.clock) {\n inspector.detachTimeController(this.clock);\n }\n inspector.setEventLogEnabled(false);\n if (this.config.deterministicSeed !== undefined) {\n inspector.setDefaultSceneSeed(undefined);\n }\n this.clock = null;\n\n for (const contributor of this.registry.contributors.values()) {\n contributor.dispose?.();\n }\n this.registry.contributors.clear();\n\n this.tearDownDebugInfra();\n this.teardownDebugScene();\n }\n\n private async materializeDebugScene(): Promise<void> {\n const scene = new DebugScene();\n scene.onReady = (worldContainer, hudContainer) =>\n this.setUpDebugInfra(worldContainer, hudContainer);\n scene.onTearDown = () => this.tearDownDebugInfra();\n await this.sceneManager._mountDetached(scene);\n this.debugScene = scene;\n }\n\n private teardownDebugScene(): void {\n // If destroy is called while `_mountDetached` is still pending, we don't\n // yet hold a reference to the partially-mounted scene. Skipping unmount\n // here is safe: onDestroy still runs `tearDownDebugInfra` below, and the\n // engine teardown tears down the renderer next which destroys any\n // half-created provider entries.\n if (!this.debugScene) return;\n this.sceneManager._unmountDetached(this.debugScene);\n this.debugScene = null;\n this.provider = null;\n }\n\n private findActiveCamera(): CameraComponent | undefined {\n return findTopmostCamera(this.sceneManager);\n }\n\n private setUpDebugInfra(\n worldContainer: Container,\n hudContainer: Container,\n ): void {\n const vw = this.renderer.virtualSize.width;\n const vh = this.renderer.virtualSize.height;\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n // Lazy camera accessor — reads from whichever stacked scene has a camera\n const cameraProxy = {\n get zoom() {\n return self.findActiveCamera()?.zoom ?? 1;\n },\n };\n\n this.graphicsPool = new GraphicsPool(\n worldContainer,\n this.config.maxGraphics,\n );\n this.textPool = new TextPool(hudContainer, this.config.maxHudLines);\n\n this.worldApi = new WorldDebugApiImpl(\n this.graphicsPool,\n this.registry,\n cameraProxy,\n );\n this.hudApi = new HudDebugApiImpl(this.textPool, this.registry, vw, vh);\n\n this.renderSystem = new DebugRenderSystem(\n this.registry,\n this.graphicsPool,\n this.textPool,\n this.worldApi,\n this.hudApi,\n this.stats,\n worldContainer,\n hudContainer,\n {\n findCamera: () => self.findActiveCamera(),\n viewportWidth: vw,\n viewportHeight: vh,\n },\n );\n this.scheduler.add(this.renderSystem);\n }\n\n private tearDownDebugInfra(): void {\n if (this.renderSystem) {\n this.scheduler.remove(this.renderSystem);\n this.renderSystem = null;\n }\n this.graphicsPool?.destroy();\n this.textPool?.destroy();\n this.graphicsPool = null;\n this.textPool = null;\n this.worldApi = null;\n this.hudApi = null;\n }\n\n private registerInspectorDiagnostics(): void {\n const diagnostics: DebugDiagnostics = {\n getLayerTransform: (sceneName, layerName) => {\n const scene = this.sceneManager.all.find(\n (candidate) => candidate.name === sceneName,\n );\n if (!scene) return undefined;\n\n const layer = this.provider?.getTree(scene)?.tryGet(layerName);\n if (!layer) return undefined;\n\n const container = layer.container;\n return {\n x: container.position.x,\n y: container.position.y,\n scaleX: container.scale.x,\n scaleY: container.scale.y,\n rotation: container.rotation,\n };\n },\n getCameraStack: () => {\n const cameras: CameraStackSnapshot[] = [];\n for (const scene of this.sceneManager.all) {\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (!cam) continue;\n cameras.push({\n scene: scene.name,\n name: cam.cameraName,\n priority: cam.priority,\n enabled: cam.enabled,\n });\n }\n }\n return cameras;\n },\n };\n this.context.resolve(InspectorKey).addExtension(\"debug\", diagnostics);\n }\n\n private attachToGlobal(clock: IDebugClock): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (g && typeof g === \"object\") {\n (g as Record<string, unknown>)[\"clock\"] = clock;\n }\n }\n\n private detachFromGlobal(): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (\n g &&\n typeof g === \"object\" &&\n (g as Record<string, unknown>)[\"clock\"] === this.clock\n ) {\n delete (g as Record<string, unknown>)[\"clock\"];\n }\n }\n}\n\n/**\n * Wire a `DebugClockHost` against a Pixi v8 `Application`. Driving\n * `app.ticker.update(syntheticTime)` while the ticker is stopped fires every\n * subscriber — Pixi's `Ticker.update` doesn't gate on `started`, only the\n * rAF-driven `_tick` does — so a single advance replaces the old\n * `gameLoop.tick(dt)` + `app.render()` quad and along the way fixes the\n * AnimatedSprite / pixi-filters / `app.ticker.add` subscriber freeze.\n */\nfunction createPixiTickerHost(\n app: Application,\n fixedTimestep: number,\n): DebugClockHost {\n let syntheticTime = 0;\n let savedMinFPS: number | null = null;\n return {\n fixedTimestep,\n freeze(): void {\n app.stop();\n // Reset both to zero so synthetic time starts from a clean origin\n // and `(syntheticTime + dt) - syntheticTime` stays an exact `dt`\n // — keeps deltaMS deterministic regardless of how long the page\n // ran in auto mode before the freeze.\n syntheticTime = 0;\n app.ticker.lastTime = 0;\n // Default minFPS=10 clamps deltaMS at 100ms — `step(200)` would\n // silently see deltaMS=100. Disable for the duration of the freeze.\n savedMinFPS = app.ticker.minFPS;\n app.ticker.minFPS = 0;\n },\n thaw(): void {\n if (savedMinFPS !== null) {\n app.ticker.minFPS = savedMinFPS;\n savedMinFPS = null;\n }\n // `app.start()` calls `Ticker._requestIfNeeded` which resets\n // `lastTime` to `performance.now()` itself, so the next rAF\n // doesn't see `realNow - 0` as a giant first-frame delta. No\n // need to set it manually here.\n app.start();\n },\n advance(dtMs: number): void {\n syntheticTime += dtMs;\n app.ticker.update(syntheticTime);\n },\n };\n}\n\n/**\n * Find the highest-priority enabled camera on the topmost scene that has one.\n * `sceneManager.all` is bottom→top, so we walk in reverse — a pause/HUD\n * scene's camera wins over a frozen scene beneath it.\n */\nexport function findTopmostCamera(\n sceneManager: SceneManager,\n): CameraComponent | undefined {\n const stack = sceneManager.all;\n for (let i = stack.length - 1; i >= 0; i--) {\n const scene = stack[i];\n if (!scene) continue;\n let highestPriorityCamera: CameraComponent | undefined;\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (\n cam &&\n cam.enabled &&\n (!highestPriorityCamera ||\n cam.priority > highestPriorityCamera.priority)\n ) {\n highestPriorityCamera = cam;\n }\n }\n if (highestPriorityCamera) return highestPriorityCamera;\n }\n return undefined;\n}\n","import { ServiceKey } from \"@yagejs/core\";\n\n/**\n * Minimal subset of PixiJS Graphics used by debug drawing.\n * Avoids a runtime pixi.js dependency in the ./api subpath.\n */\nexport interface DebugGraphics {\n position: { x: number; y: number };\n rotation: number;\n visible: boolean;\n clear(): DebugGraphics;\n rect(x: number, y: number, width: number, height: number): DebugGraphics;\n circle(x: number, y: number, radius: number): DebugGraphics;\n moveTo(x: number, y: number): DebugGraphics;\n lineTo(x: number, y: number): DebugGraphics;\n stroke(style: { width: number; color: number; alpha?: number }): DebugGraphics;\n fill(style: { color: number; alpha?: number }): DebugGraphics;\n}\n\n/** Camera-space drawing API passed to contributors. */\nexport interface WorldDebugApi {\n acquireGraphics(): DebugGraphics | undefined;\n isFlagEnabled(flag: string): boolean;\n readonly cameraZoom: number;\n}\n\n/** Screen-space HUD API passed to contributors. */\nexport interface HudDebugApi {\n addLine(text: string): void;\n isFlagEnabled(flag: string): boolean;\n readonly screenWidth: number;\n readonly screenHeight: number;\n}\n\n/** Rolling-window statistics collector. */\nexport interface StatsApi {\n push(key: string, value: number): void;\n average(key: string): number;\n latest(key: string): number;\n min(key: string): number;\n max(key: string): number;\n}\n\n/** A debug contributor that registers drawing/sampling callbacks. */\nexport interface DebugContributor {\n readonly name: string;\n readonly flags: readonly string[];\n drawWorld?(api: WorldDebugApi): void;\n drawHud?(api: HudDebugApi): void;\n sample?(stats: StatsApi, dt: number): void;\n dispose?(): void;\n}\n\n/** Service interface for the debug registry. */\nexport interface DebugRegistry {\n register(contributor: DebugContributor): void;\n isEnabled(): boolean;\n isFlagEnabled(contributorName: string, flag: string): boolean;\n}\n\n/** Service key for resolving the DebugRegistry via DI. */\nexport const DebugRegistryKey = new ServiceKey<DebugRegistry>(\"debugRegistry\");\n","/** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */\nexport interface IDebugClock {\n readonly isFrozen: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n freeze(): void;\n thaw(): void;\n setDelta(ms: number): void;\n getFrame(): number;\n}\n\n/**\n * Hooks the clock uses to drive the host. The host owns the synthetic-time\n * bookkeeping and the ticker plumbing — `DebugClock` stays a pure state\n * machine. Production wires this against Pixi's `app.ticker` so a manual\n * `step()` fires every ticker subscriber (GameLoop, AnimatedSprite,\n * pixi-filters, render) with the same synthetic dt.\n */\nexport interface DebugClockHost {\n readonly fixedTimestep: number;\n /** Advance one synthetic frame of `dtMs`. Fires every ticker subscriber. */\n advance(dtMs: number): void;\n /** Stop auto-advance. Capture state needed to make `advance` deterministic. */\n freeze(): void;\n /** Resume auto-advance. Restore captured state so the next rAF is sane. */\n thaw(): void;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * While frozen the renderer ticker is paused and frames advance only via\n * explicit `step()` / `stepFrames()` calls. `freeze()` / `thaw()` and\n * `startAuto()` / `stopAuto()` are equivalent verbs for the same toggle.\n */\nexport class DebugClock implements IDebugClock {\n private _isFrozen = false;\n private deltaMs: number;\n private frame = 0;\n\n constructor(private readonly host: DebugClockHost) {\n this.deltaMs = host.fixedTimestep;\n }\n\n get isFrozen(): boolean {\n return this._isFrozen;\n }\n\n startAuto(): void {\n if (!this._isFrozen) return;\n this.host.thaw();\n this._isFrozen = false;\n }\n\n stopAuto(): void {\n if (this._isFrozen) return;\n this.host.freeze();\n this._isFrozen = true;\n }\n\n freeze(): void {\n this.stopAuto();\n }\n\n thaw(): void {\n this.startAuto();\n }\n\n setDelta(ms: number): void {\n if (!Number.isFinite(ms) || ms <= 0) {\n throw new Error(\"DebugClock.setDelta(ms) requires a positive number.\");\n }\n this.deltaMs = ms;\n }\n\n getFrame(): number {\n return this.frame;\n }\n\n step(dtMs?: number): void {\n if (!this._isFrozen) {\n throw new Error(\"DebugClock is not frozen. Call clock.freeze() first.\");\n }\n const dt = dtMs ?? this.deltaMs;\n if (!Number.isFinite(dt) || dt <= 0) {\n throw new Error(\"DebugClock.step(dtMs) requires a positive number.\");\n }\n // Increment after a successful advance — if a ticker subscriber throws\n // (system exception, render failure) the frame counter shouldn't advance\n // ahead of state.\n this.host.advance(dt);\n this.frame++;\n }\n\n stepFrames(count: number, dtMs?: number): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n \"stepFrames(count) requires a non-negative integer count.\",\n );\n }\n for (let i = 0; i < count; i++) {\n this.step(dtMs);\n }\n }\n}\n","import type { DebugContributor, DebugRegistry } from \"./types.js\";\n\n/** Concrete implementation of the DebugRegistry interface. */\nexport class DebugRegistryImpl implements DebugRegistry {\n readonly contributors = new Map<string, DebugContributor>();\n enabled = false;\n private flags = new Map<string, boolean>();\n\n register(contributor: DebugContributor): void {\n if (this.contributors.has(contributor.name)) return;\n this.contributors.set(contributor.name, contributor);\n for (const flag of contributor.flags) {\n this.flags.set(`${contributor.name}.${flag}`, true);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n isFlagEnabled(contributorName: string, flag: string): boolean {\n return this.flags.get(`${contributorName}.${flag}`) ?? true;\n }\n\n toggle(): void {\n this.enabled = !this.enabled;\n }\n\n toggleFlag(contributorName: string, flag: string): void {\n const key = `${contributorName}.${flag}`;\n this.flags.set(key, !(this.flags.get(key) ?? true));\n }\n\n setFlag(contributorName: string, flag: string, value: boolean): void {\n this.flags.set(`${contributorName}.${flag}`, value);\n }\n}\n","import { LoggerKey, Scene } from \"@yagejs/core\";\nimport type { Logger } from \"@yagejs/core\";\nimport type { LayerDef } from \"@yagejs/renderer\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport type { Container } from \"pixi.js\";\n\n/**\n * Scene mounted by the debug plugin via `SceneManager._mountDetached`.\n * Declares two layers:\n * - `\"debug-world\"` — world-space, rides the camera (for collision shapes).\n * - `\"debug-hud\"` — screen-space, fixed overlay (text readouts).\n *\n * `pauseBelow: false` / `transparentBelow: true` so the underlying game\n * keeps running and rendering behind the overlay.\n */\nexport class DebugScene extends Scene {\n readonly name = \"__debug__\";\n override readonly pauseBelow = false;\n override readonly transparentBelow = true;\n readonly layers: readonly LayerDef[] = [\n { name: \"debug-world\", order: 999999 },\n { name: \"debug-hud\", order: 999999 },\n ];\n\n /** Called after `_mountDetached` has materialized the render tree. */\n onReady?: (worldContainer: Container, hudContainer: Container) => void;\n\n /** Called by the plugin when the scene is unmounted. */\n onTearDown?: () => void;\n\n onEnter(): void {\n const tree = this._resolveScoped(SceneRenderTreeKey);\n if (!tree) {\n // Shouldn't happen — DebugPlugin declares `renderer` as a dependency\n // so the renderer's `beforeEnter` hook should have materialized a\n // tree before this runs. Surface it rather than silently skipping\n // the overlay wiring.\n const logger = this.context.tryResolve(LoggerKey) as Logger | undefined;\n const msg =\n \"DebugScene.onEnter: SceneRenderTreeKey missing — debug overlay will not render. Is RendererPlugin registered?\";\n if (logger) logger.warn(\"debug\", msg);\n else console.warn(`[yage] ${msg}`);\n return;\n }\n const worldContainer = tree.get(\"debug-world\").container;\n const hudContainer = tree.get(\"debug-hud\").container;\n worldContainer.eventMode = \"none\";\n hudContainer.eventMode = \"none\";\n this.onReady?.(worldContainer, hudContainer);\n }\n\n onExit(): void {\n this.onTearDown?.();\n }\n}\n","import type { StatsApi } from \"./types.js\";\n\nconst WINDOW_SIZE = 120;\n\ninterface RingBuffer {\n data: Float64Array;\n count: number;\n index: number;\n}\n\n/** Rolling-window statistics store backed by Float64Array ring buffers. */\nexport class StatsStore implements StatsApi {\n private rings = new Map<string, RingBuffer>();\n\n push(key: string, value: number): void {\n let ring = this.rings.get(key);\n if (!ring) {\n ring = { data: new Float64Array(WINDOW_SIZE), count: 0, index: 0 };\n this.rings.set(key, ring);\n }\n ring.data[ring.index] = value;\n ring.index = (ring.index + 1) % WINDOW_SIZE;\n if (ring.count < WINDOW_SIZE) ring.count++;\n }\n\n average(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let sum = 0;\n for (let i = 0; i < count; i++) sum += data[i] ?? 0;\n return sum / count;\n }\n\n latest(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n return ring.data[(ring.index - 1 + WINDOW_SIZE) % WINDOW_SIZE] ?? 0;\n }\n\n min(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v < m) m = v;\n }\n return m;\n }\n\n max(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v > m) m = v;\n }\n return m;\n }\n}\n","import { Graphics, Container } from \"pixi.js\";\n\n/** Allocation-free pool of PixiJS Graphics objects for debug drawing. */\nexport class GraphicsPool {\n private pool: Graphics[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxSize: number;\n\n constructor(container: Container, maxSize = 256) {\n this.container = container;\n this.maxSize = maxSize;\n }\n\n /** Lazily create Graphics objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Graphics[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxSize; i++) {\n const g = new Graphics();\n g.visible = false;\n g.eventMode = \"none\";\n this.container.addChild(g);\n this.pool.push(g);\n }\n return this.pool;\n }\n\n /** Return the next available Graphics, or undefined if the pool is exhausted. */\n acquire(): Graphics | undefined {\n const pool = this.ensure();\n if (this.index >= pool.length) return undefined;\n const g = pool[this.index]!;\n g.visible = true;\n this.index++;\n return g;\n }\n\n /** Clear and hide all previously acquired graphics, reset index. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n const g = this.pool[i]!;\n g.clear();\n g.visible = false;\n g.position.set(0, 0);\n g.rotation = 0;\n g.scale.set(1, 1);\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const g of this.pool) {\n g.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import { Text, Container } from \"pixi.js\";\n\nconst LINE_HEIGHT = 16;\nconst FONT_SIZE = 14;\nconst PADDING = 4;\n\n/** Allocation-free pool of PixiJS Text objects for HUD debug lines. */\nexport class TextPool {\n private pool: Text[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxLines: number;\n\n constructor(container: Container, maxLines = 32) {\n this.container = container;\n this.maxLines = maxLines;\n }\n\n /** Lazily create Text objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Text[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxLines; i++) {\n const t = new Text({\n text: \"\",\n style: {\n fontFamily: \"monospace\",\n fontSize: FONT_SIZE,\n fill: 0xffffff,\n },\n });\n t.visible = false;\n t.eventMode = \"none\";\n this.container.addChild(t);\n this.pool.push(t);\n }\n return this.pool;\n }\n\n /** Show a text line at the next available slot. */\n addLine(text: string): void {\n const pool = this.ensure();\n if (this.index >= pool.length) return;\n const t = pool[this.index]!;\n t.text = text;\n t.visible = true;\n t.position.set(PADDING, PADDING + this.index * LINE_HEIGHT);\n this.index++;\n }\n\n /** Hide all lines and reset for the next frame. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n this.pool[i]!.visible = false;\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const t of this.pool) {\n t.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import type { WorldDebugApi, DebugGraphics } from \"./types.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** WorldDebugApi backed by a GraphicsPool. Contributor name is swapped per iteration. */\nexport class WorldDebugApiImpl implements WorldDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly pool: GraphicsPool,\n private readonly registry: DebugRegistryImpl,\n private readonly _camera: { zoom: number },\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawWorld). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n acquireGraphics(): DebugGraphics | undefined {\n return this.pool.acquire() as unknown as DebugGraphics | undefined;\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n\n get cameraZoom(): number {\n return this._camera.zoom;\n }\n}\n","import type { HudDebugApi } from \"./types.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** HudDebugApi backed by a TextPool. Contributor name is swapped per iteration. */\nexport class HudDebugApiImpl implements HudDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly textPool: TextPool,\n private readonly registry: DebugRegistryImpl,\n public readonly screenWidth: number,\n public readonly screenHeight: number,\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawHud). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n addLine(text: string): void {\n this.textPool.addLine(text);\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n}\n","import { System, Phase } from \"@yagejs/core\";\nimport type { Container } from \"pixi.js\";\nimport type { CameraComponent } from \"@yagejs/renderer\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport type { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport type { StatsStore } from \"./StatsStore.js\";\n\nexport interface DebugCameraAccessor {\n findCamera(): CameraComponent | undefined;\n viewportWidth: number;\n viewportHeight: number;\n}\n\n/** Renders all debug contributors. Runs after DisplaySystem in the Render phase. */\nexport class DebugRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = 9999;\n\n constructor(\n private readonly registry: DebugRegistryImpl,\n private readonly graphicsPool: GraphicsPool,\n private readonly textPool: TextPool,\n private readonly worldApi: WorldDebugApiImpl,\n private readonly hudApi: HudDebugApiImpl,\n private readonly stats: StatsStore,\n private readonly worldContainer: Container,\n private readonly hudContainer: Container,\n private readonly cameraAccessor: DebugCameraAccessor,\n ) {\n super();\n }\n\n update(dt: number): void {\n if (!this.registry.enabled) {\n this.worldContainer.visible = false;\n this.hudContainer.visible = false;\n return;\n }\n\n this.worldContainer.visible = true;\n this.hudContainer.visible = true;\n\n // Apply camera transform to the debug world container so that\n // world-space debug drawing (collision shapes, etc.) aligns with\n // the active scene's camera.\n this.syncWorldCamera();\n\n this.graphicsPool.resetFrame();\n this.textPool.resetFrame();\n\n for (const [name, contributor] of this.registry.contributors) {\n contributor.sample?.(this.stats, dt);\n\n if (contributor.drawWorld) {\n this.worldApi.setContributor(name);\n contributor.drawWorld(this.worldApi);\n }\n\n if (contributor.drawHud) {\n this.hudApi.setContributor(name);\n contributor.drawHud(this.hudApi);\n }\n }\n }\n\n private syncWorldCamera(): void {\n const cam = this.cameraAccessor.findCamera();\n if (!cam) {\n this.worldContainer.position.set(0, 0);\n this.worldContainer.scale.set(1, 1);\n this.worldContainer.rotation = 0;\n return;\n }\n\n const vw = this.cameraAccessor.viewportWidth;\n const vh = this.cameraAccessor.viewportHeight;\n const rotatedPos = cam.effectivePosition\n .scale(cam.zoom)\n .rotate(-cam.rotation);\n this.worldContainer.position.x = vw / 2 - rotatedPos.x;\n this.worldContainer.position.y = vh / 2 - rotatedPos.y;\n this.worldContainer.scale.set(cam.zoom);\n this.worldContainer.rotation = -cam.rotation;\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class FpsContributor implements DebugContributor {\n readonly name = \"fps\";\n readonly flags: readonly string[] = [];\n private stats: StatsApi | null = null;\n\n sample(stats: StatsApi, dt: number): void {\n this.stats = stats;\n if (dt > 0) stats.push(\"fps\", 1000 / dt);\n }\n\n drawHud(api: HudDebugApi): void {\n const avg = this.stats?.average(\"fps\") ?? 0;\n api.addLine(`FPS: ${Math.round(avg)}`);\n }\n}\n","import type { DebugContributor, HudDebugApi } from \"../types.js\";\nimport type { Inspector } from \"@yagejs/core\";\n\nexport class EntityCountContributor implements DebugContributor {\n readonly name = \"entities\";\n readonly flags: readonly string[] = [];\n\n constructor(private readonly inspector: Inspector) {}\n\n drawHud(api: HudDebugApi): void {\n const count = this.inspector.snapshot().entityCount;\n api.addLine(`Entities: ${count}`);\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class SystemTimingContributor implements DebugContributor {\n readonly name = \"timing\";\n readonly flags = [\"breakdown\"] as const;\n private stats: StatsApi | null = null;\n\n constructor(private readonly timings: Map<string, number>) {}\n\n sample(stats: StatsApi): void {\n this.stats = stats;\n for (const [name, ms] of this.timings) {\n stats.push(`system.${name}`, ms);\n }\n }\n\n drawHud(api: HudDebugApi): void {\n if (!this.stats) return;\n\n let total = 0;\n const entries: Array<[string, number]> = [];\n for (const name of this.timings.keys()) {\n const avg = this.stats.average(`system.${name}`);\n total += avg;\n entries.push([name, avg]);\n }\n\n api.addLine(`Systems: ${total.toFixed(2)}ms`);\n\n if (api.isFlagEnabled(\"breakdown\")) {\n entries.sort((a, b) => b[1] - a[1]);\n for (const [name, avg] of entries) {\n api.addLine(` ${name}: ${avg.toFixed(2)}ms`);\n }\n }\n }\n}\n"],"mappings":"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","names":["import_core","import_renderer","import_core","import_pixi","import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/DebugPlugin.ts","../src/types.ts","../src/DebugClock.ts","../src/DebugRegistryImpl.ts","../src/DebugScene.ts","../src/StatsStore.ts","../src/GraphicsPool.ts","../src/TextPool.ts","../src/WorldDebugApiImpl.ts","../src/HudDebugApiImpl.ts","../src/DebugRenderSystem.ts","../src/contributors/FpsContributor.ts","../src/contributors/EntityCountContributor.ts","../src/contributors/SystemTimingContributor.ts"],"sourcesContent":["export { DebugPlugin } from \"./DebugPlugin.js\";\nexport type {\n DebugConfig,\n DebugDiagnostics,\n LayerTransformSnapshot,\n CameraStackSnapshot,\n} from \"./DebugPlugin.js\";\nexport type { IDebugClock } from \"./DebugClock.js\";\nexport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nexport { StatsStore } from \"./StatsStore.js\";\n","import {\n EventBusKey,\n GameLoopKey,\n InspectorKey,\n SceneManagerKey,\n} from \"@yagejs/core\";\nimport type {\n EngineContext,\n EventBus,\n EngineEvents,\n Plugin,\n SceneManager,\n System,\n SystemScheduler,\n} from \"@yagejs/core\";\nimport { DebugRegistryKey } from \"./types.js\";\nimport { CameraComponent, RendererKey } from \"@yagejs/renderer\";\nimport type { RendererPlugin, SceneRenderTreeProvider } from \"@yagejs/renderer\";\nimport { SceneRenderTreeProviderKey } from \"@yagejs/renderer\";\nimport type { Application, Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { DebugClockHost, IDebugClock } from \"./DebugClock.js\";\nimport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport { DebugScene } from \"./DebugScene.js\";\nimport { StatsStore } from \"./StatsStore.js\";\nimport { GraphicsPool } from \"./GraphicsPool.js\";\nimport { TextPool } from \"./TextPool.js\";\nimport { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport { DebugRenderSystem } from \"./DebugRenderSystem.js\";\nimport { FpsContributor } from \"./contributors/FpsContributor.js\";\nimport { EntityCountContributor } from \"./contributors/EntityCountContributor.js\";\nimport { SystemTimingContributor } from \"./contributors/SystemTimingContributor.js\";\n\n/** Configuration for the DebugPlugin. */\nexport interface DebugConfig {\n /** Key code to toggle debug overlay. Default: \"Backquote\" */\n toggleKey?: string;\n /** Key code to advance one fixed-timestep frame while the debug clock is frozen. Default: \"Period\" */\n stepKey?: string;\n /** Max pooled Graphics objects. Default: 256 */\n maxGraphics?: number;\n /** Max HUD text lines. Default: 32 */\n maxHudLines?: number;\n /** Whether the overlay starts enabled. Default: false */\n startEnabled?: boolean;\n /** Initial flag overrides, keyed by \"contributorName.flagName\". */\n flags?: Record<string, boolean>;\n /**\n * If set, every scene's RNG is initialized with this seed instead of an\n * unspecified default. Use for deterministic E2E runs. Leave undefined for\n * normal debug builds so randomness behaves the same as in production.\n */\n deterministicSeed?: number;\n /**\n * If true, the engine boots with a paused Pixi ticker so no auto-frames\n * tick before user code can intervene — equivalent to calling\n * `inspector.time.freeze()` at frame zero, but applied during plugin\n * `install()` (before `loop.start()`). Use for deterministic E2E runs:\n * any later `engine.scenes.push(...)` resolves under frozen time, so\n * snapshots taken right after only depend on the explicit `time.step()`\n * calls — not on how many auto-frames slipped in between\n * `await engine.start()` and the test's first `freeze()`.\n */\n startFrozen?: boolean;\n}\n\nexport interface LayerTransformSnapshot {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n rotation: number;\n}\n\nexport interface CameraStackSnapshot {\n scene: string;\n name: string | undefined;\n priority: number;\n enabled: boolean;\n}\n\n/**\n * Renderer-aware diagnostics exposed through the inspector extension\n * namespace `debug`. Kept out of the core Inspector surface so the core\n * package stays renderer-agnostic while plugins can still publish optional\n * runtime helpers in a uniform way.\n */\nexport interface DebugDiagnostics {\n getLayerTransform(\n sceneName: string,\n layerName: string,\n ): LayerTransformSnapshot | undefined;\n getCameraStack(): CameraStackSnapshot[];\n}\n\n/**\n * Debug overlay plugin. Mounts a private `DebugScene` through\n * `SceneManager._mountDetached` so it goes through the same scoped-DI\n * lifecycle as stacked scenes (the renderer's `beforeEnter` hook creates\n * its render tree) while staying off the user-visible scene stack.\n */\nexport class DebugPlugin implements Plugin {\n readonly name = \"debug\";\n readonly version = \"3.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n private readonly config: DebugConfig;\n private registry!: DebugRegistryImpl;\n private stats!: StatsStore;\n private graphicsPool: GraphicsPool | null = null;\n private textPool: TextPool | null = null;\n private worldApi: WorldDebugApiImpl | null = null;\n private hudApi: HudDebugApiImpl | null = null;\n private renderSystem: DebugRenderSystem | null = null;\n private systemTimings = new Map<string, number>();\n private originalUpdates = new Map<System, (dt: number) => void>();\n private keyListener: ((e: KeyboardEvent) => void) | null = null;\n private context!: EngineContext;\n private renderer!: RendererPlugin;\n private scheduler!: SystemScheduler;\n private sceneManager!: SceneManager;\n private debugScene: DebugScene | null = null;\n private provider: SceneRenderTreeProvider | null = null;\n private eventUnsubs: Array<() => void> = [];\n private clock: DebugClock | null = null;\n\n constructor(config?: DebugConfig) {\n this.config = config ?? {};\n }\n\n install(context: EngineContext): void {\n this.context = context;\n this.renderer = context.resolve(RendererKey);\n if (this.config.deterministicSeed !== undefined) {\n context\n .resolve(InspectorKey)\n .setDefaultSceneSeed(this.config.deterministicSeed);\n }\n if (this.config.startFrozen) {\n // Stop Pixi's ticker before `loop.start()` runs, so no frames tick\n // between `app.init()` (which auto-starts the ticker) and the user's\n // first `inspector.time.freeze()`. Without this, even the few auto-\n // frames that slip in between RendererPlugin install and user-space\n // `await engine.start()` resolution mutate physics / input clocks,\n // breaking bit-identical replay snapshots. The DebugClock created in\n // `onStart` will pick this up via its own `freeze()` call.\n this.renderer.application.stop();\n }\n\n this.registry = new DebugRegistryImpl();\n this.registry.enabled = this.config.startEnabled ?? false;\n\n if (this.config.flags) {\n for (const [key, value] of Object.entries(this.config.flags)) {\n const dot = key.indexOf(\".\");\n if (dot > 0) {\n this.registry.setFlag(key.slice(0, dot), key.slice(dot + 1), value);\n }\n }\n }\n\n this.stats = new StatsStore();\n\n context.register(DebugRegistryKey, this.registry);\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n // DebugRenderSystem is registered lazily once the debug scene is ready —\n // its constructor needs the scene's layer containers.\n this.scheduler = scheduler;\n }\n\n async onStart(): Promise<void> {\n this.sceneManager = this.context.resolve(SceneManagerKey);\n const bus = this.context.resolve(EventBusKey) as EventBus<EngineEvents>;\n\n // Key listeners (toggle, manual-clock step)\n const toggleKey = this.config.toggleKey ?? \"Backquote\";\n const stepKey = this.config.stepKey ?? \"Period\";\n this.keyListener = (e: KeyboardEvent) => {\n if (e.code === toggleKey) {\n this.registry.toggle();\n return;\n }\n if (e.code === stepKey && this.clock?.isFrozen) {\n e.preventDefault();\n this.clock.step();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.keyListener);\n }\n\n // Instrument system timings — reuse the scheduler captured in\n // `registerSystems`, which ran before `onStart`.\n for (const system of this.scheduler.getAllSystems()) {\n if (system instanceof DebugRenderSystem) continue;\n const name = system.constructor.name;\n const original = system.update.bind(system);\n this.originalUpdates.set(system, original);\n system.update = (dt: number) => {\n const t0 = performance.now();\n original(dt);\n this.systemTimings.set(name, performance.now() - t0);\n };\n }\n\n // Built-in contributors\n const inspector = this.context.resolve(InspectorKey);\n this.registry.register(new FpsContributor());\n this.registry.register(new EntityCountContributor(inspector));\n this.registry.register(new SystemTimingContributor(this.systemTimings));\n\n // Manual clock for deterministic stepping. The host drives `app.ticker`\n // directly so a manual `step()` fires every ticker subscriber\n // (AnimatedSprite, pixi-filters, render, user `app.ticker.add` callbacks)\n // with the same synthetic dt as gameplay state.\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n this.clock = new DebugClock(createPixiTickerHost(app, gameLoop.fixedTimestep));\n inspector.attachTimeController(this.clock);\n inspector.setEventLogEnabled(true);\n this.attachToGlobal(this.clock);\n if (this.config.startFrozen) {\n // `install()` already called `app.stop()`. Run the clock's own\n // `freeze()` now to take ownership: it captures `minFPS`, zeroes\n // `syntheticTime` / `lastTime`, and flips `_isFrozen` so the public\n // `inspector.time.isFrozen()` reflects reality without a redundant\n // freeze cycle from the caller.\n this.clock.freeze();\n }\n\n // Materialize the debug scene off-stack. `_mountDetached` routes through\n // the same beforeEnter hooks as `push`, so the renderer materializes the\n // debug scene's tree and registers SceneRenderTreeKey on its scope.\n this.provider = this.context.tryResolve(SceneRenderTreeProviderKey) ?? null;\n this.registerInspectorDiagnostics();\n await this.materializeDebugScene();\n\n // Keep the debug scene visually on top of the user stack after any\n // push/pop/replace by reordering its root containers.\n const bringToFront = () => {\n if (this.debugScene && this.provider?.bringSceneToFront) {\n this.provider.bringSceneToFront(this.debugScene);\n }\n };\n this.eventUnsubs.push(bus.on(\"scene:pushed\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:popped\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:replaced\", bringToFront));\n }\n\n onDestroy(): void {\n for (const unsub of this.eventUnsubs) unsub();\n this.eventUnsubs.length = 0;\n\n for (const [system, original] of this.originalUpdates) {\n system.update = original;\n }\n this.originalUpdates.clear();\n\n if (this.keyListener) {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.keyListener);\n }\n this.keyListener = null;\n }\n\n this.detachFromGlobal();\n const inspector = this.context.resolve(InspectorKey);\n inspector.removeExtension(\"debug\");\n // Only detach our own clock — passing undefined would clear whatever\n // controller is registered, which could belong to another plugin if\n // onDestroy runs after a failed onStart.\n if (this.clock) {\n inspector.detachTimeController(this.clock);\n }\n inspector.setEventLogEnabled(false);\n if (this.config.deterministicSeed !== undefined) {\n inspector.setDefaultSceneSeed(undefined);\n }\n this.clock = null;\n\n for (const contributor of this.registry.contributors.values()) {\n contributor.dispose?.();\n }\n this.registry.contributors.clear();\n\n this.tearDownDebugInfra();\n this.teardownDebugScene();\n }\n\n private async materializeDebugScene(): Promise<void> {\n const scene = new DebugScene();\n scene.onReady = (worldContainer, hudContainer) =>\n this.setUpDebugInfra(worldContainer, hudContainer);\n scene.onTearDown = () => this.tearDownDebugInfra();\n await this.sceneManager._mountDetached(scene);\n this.debugScene = scene;\n }\n\n private teardownDebugScene(): void {\n // If destroy is called while `_mountDetached` is still pending, we don't\n // yet hold a reference to the partially-mounted scene. Skipping unmount\n // here is safe: onDestroy still runs `tearDownDebugInfra` below, and the\n // engine teardown tears down the renderer next which destroys any\n // half-created provider entries.\n if (!this.debugScene) return;\n this.sceneManager._unmountDetached(this.debugScene);\n this.debugScene = null;\n this.provider = null;\n }\n\n private findActiveCamera(): CameraComponent | undefined {\n return findTopmostCamera(this.sceneManager);\n }\n\n private setUpDebugInfra(\n worldContainer: Container,\n hudContainer: Container,\n ): void {\n const vw = this.renderer.virtualSize.width;\n const vh = this.renderer.virtualSize.height;\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n // Lazy camera accessor — reads from whichever stacked scene has a camera\n const cameraProxy = {\n get zoom() {\n return self.findActiveCamera()?.zoom ?? 1;\n },\n };\n\n this.graphicsPool = new GraphicsPool(\n worldContainer,\n this.config.maxGraphics,\n );\n this.textPool = new TextPool(hudContainer, this.config.maxHudLines);\n\n this.worldApi = new WorldDebugApiImpl(\n this.graphicsPool,\n this.registry,\n cameraProxy,\n );\n this.hudApi = new HudDebugApiImpl(this.textPool, this.registry, vw, vh);\n\n this.renderSystem = new DebugRenderSystem(\n this.registry,\n this.graphicsPool,\n this.textPool,\n this.worldApi,\n this.hudApi,\n this.stats,\n worldContainer,\n hudContainer,\n {\n findCamera: () => self.findActiveCamera(),\n viewportWidth: vw,\n viewportHeight: vh,\n },\n );\n this.scheduler.add(this.renderSystem);\n }\n\n private tearDownDebugInfra(): void {\n if (this.renderSystem) {\n this.scheduler.remove(this.renderSystem);\n this.renderSystem = null;\n }\n this.graphicsPool?.destroy();\n this.textPool?.destroy();\n this.graphicsPool = null;\n this.textPool = null;\n this.worldApi = null;\n this.hudApi = null;\n }\n\n private registerInspectorDiagnostics(): void {\n const diagnostics: DebugDiagnostics = {\n getLayerTransform: (sceneName, layerName) => {\n const scene = this.sceneManager.all.find(\n (candidate) => candidate.name === sceneName,\n );\n if (!scene) return undefined;\n\n const layer = this.provider?.getTree(scene)?.tryGet(layerName);\n if (!layer) return undefined;\n\n const container = layer.container;\n return {\n x: container.position.x,\n y: container.position.y,\n scaleX: container.scale.x,\n scaleY: container.scale.y,\n rotation: container.rotation,\n };\n },\n getCameraStack: () => {\n const cameras: CameraStackSnapshot[] = [];\n for (const scene of this.sceneManager.all) {\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (!cam) continue;\n cameras.push({\n scene: scene.name,\n name: cam.cameraName,\n priority: cam.priority,\n enabled: cam.enabled,\n });\n }\n }\n return cameras;\n },\n };\n this.context.resolve(InspectorKey).addExtension(\"debug\", diagnostics);\n }\n\n private attachToGlobal(clock: IDebugClock): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (g && typeof g === \"object\") {\n (g as Record<string, unknown>)[\"clock\"] = clock;\n }\n }\n\n private detachFromGlobal(): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (\n g &&\n typeof g === \"object\" &&\n (g as Record<string, unknown>)[\"clock\"] === this.clock\n ) {\n delete (g as Record<string, unknown>)[\"clock\"];\n }\n }\n}\n\n/**\n * Wire a `DebugClockHost` against a Pixi v8 `Application`. Driving\n * `app.ticker.update(syntheticTime)` while the ticker is stopped fires every\n * subscriber — Pixi's `Ticker.update` doesn't gate on `started`, only the\n * rAF-driven `_tick` does — so a single advance replaces the old\n * `gameLoop.tick(dt)` + `app.render()` quad and along the way fixes the\n * AnimatedSprite / pixi-filters / `app.ticker.add` subscriber freeze.\n */\nfunction createPixiTickerHost(\n app: Application,\n fixedTimestep: number,\n): DebugClockHost {\n let syntheticTime = 0;\n let savedMinFPS: number | null = null;\n return {\n fixedTimestep,\n freeze(): void {\n app.stop();\n // Reset both to zero so synthetic time starts from a clean origin\n // and `(syntheticTime + dt) - syntheticTime` stays an exact `dt`\n // — keeps deltaMS deterministic regardless of how long the page\n // ran in auto mode before the freeze.\n syntheticTime = 0;\n app.ticker.lastTime = 0;\n // Default minFPS=10 clamps deltaMS at 100ms — `step(200)` would\n // silently see deltaMS=100. Disable for the duration of the freeze.\n savedMinFPS = app.ticker.minFPS;\n app.ticker.minFPS = 0;\n },\n thaw(): void {\n if (savedMinFPS !== null) {\n app.ticker.minFPS = savedMinFPS;\n savedMinFPS = null;\n }\n // `app.start()` calls `Ticker._requestIfNeeded` which resets\n // `lastTime` to `performance.now()` itself, so the next rAF\n // doesn't see `realNow - 0` as a giant first-frame delta. No\n // need to set it manually here.\n app.start();\n },\n advance(dtMs: number): void {\n syntheticTime += dtMs;\n app.ticker.update(syntheticTime);\n },\n };\n}\n\n/**\n * Find the highest-priority enabled camera on the topmost scene that has one.\n * `sceneManager.all` is bottom→top, so we walk in reverse — a pause/HUD\n * scene's camera wins over a frozen scene beneath it.\n */\nexport function findTopmostCamera(\n sceneManager: SceneManager,\n): CameraComponent | undefined {\n const stack = sceneManager.all;\n for (let i = stack.length - 1; i >= 0; i--) {\n const scene = stack[i];\n if (!scene) continue;\n let highestPriorityCamera: CameraComponent | undefined;\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (\n cam &&\n cam.enabled &&\n (!highestPriorityCamera ||\n cam.priority > highestPriorityCamera.priority)\n ) {\n highestPriorityCamera = cam;\n }\n }\n if (highestPriorityCamera) return highestPriorityCamera;\n }\n return undefined;\n}\n","import { ServiceKey } from \"@yagejs/core\";\n\n/**\n * Minimal subset of PixiJS Graphics used by debug drawing.\n * Avoids a runtime pixi.js dependency in the ./api subpath.\n */\nexport interface DebugGraphics {\n position: { x: number; y: number };\n rotation: number;\n visible: boolean;\n clear(): DebugGraphics;\n rect(x: number, y: number, width: number, height: number): DebugGraphics;\n circle(x: number, y: number, radius: number): DebugGraphics;\n moveTo(x: number, y: number): DebugGraphics;\n lineTo(x: number, y: number): DebugGraphics;\n stroke(style: { width: number; color: number; alpha?: number }): DebugGraphics;\n fill(style: { color: number; alpha?: number }): DebugGraphics;\n}\n\n/** Camera-space drawing API passed to contributors. */\nexport interface WorldDebugApi {\n acquireGraphics(): DebugGraphics | undefined;\n isFlagEnabled(flag: string): boolean;\n readonly cameraZoom: number;\n}\n\n/** Screen-space HUD API passed to contributors. */\nexport interface HudDebugApi {\n addLine(text: string): void;\n isFlagEnabled(flag: string): boolean;\n readonly screenWidth: number;\n readonly screenHeight: number;\n}\n\n/** Rolling-window statistics collector. */\nexport interface StatsApi {\n push(key: string, value: number): void;\n average(key: string): number;\n latest(key: string): number;\n min(key: string): number;\n max(key: string): number;\n}\n\n/** A debug contributor that registers drawing/sampling callbacks. */\nexport interface DebugContributor {\n readonly name: string;\n readonly flags: readonly string[];\n drawWorld?(api: WorldDebugApi): void;\n drawHud?(api: HudDebugApi): void;\n sample?(stats: StatsApi, dt: number): void;\n dispose?(): void;\n}\n\n/** Service interface for the debug registry. */\nexport interface DebugRegistry {\n register(contributor: DebugContributor): void;\n isEnabled(): boolean;\n isFlagEnabled(contributorName: string, flag: string): boolean;\n}\n\n/** Service key for resolving the DebugRegistry via DI. */\nexport const DebugRegistryKey = new ServiceKey<DebugRegistry>(\"debugRegistry\");\n","/** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */\nexport interface IDebugClock {\n readonly isFrozen: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n freeze(): void;\n thaw(): void;\n setDelta(ms: number): void;\n getFrame(): number;\n}\n\n/**\n * Hooks the clock uses to drive the host. The host owns the synthetic-time\n * bookkeeping and the ticker plumbing — `DebugClock` stays a pure state\n * machine. Production wires this against Pixi's `app.ticker` so a manual\n * `step()` fires every ticker subscriber (GameLoop, AnimatedSprite,\n * pixi-filters, render) with the same synthetic dt.\n */\nexport interface DebugClockHost {\n readonly fixedTimestep: number;\n /** Advance one synthetic frame of `dtMs`. Fires every ticker subscriber. */\n advance(dtMs: number): void;\n /** Stop auto-advance. Capture state needed to make `advance` deterministic. */\n freeze(): void;\n /** Resume auto-advance. Restore captured state so the next rAF is sane. */\n thaw(): void;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * While frozen the renderer ticker is paused and frames advance only via\n * explicit `step()` / `stepFrames()` calls. `freeze()` / `thaw()` and\n * `startAuto()` / `stopAuto()` are equivalent verbs for the same toggle.\n */\nexport class DebugClock implements IDebugClock {\n private _isFrozen = false;\n private deltaMs: number;\n private frame = 0;\n\n constructor(private readonly host: DebugClockHost) {\n this.deltaMs = host.fixedTimestep;\n }\n\n get isFrozen(): boolean {\n return this._isFrozen;\n }\n\n startAuto(): void {\n if (!this._isFrozen) return;\n this.host.thaw();\n this._isFrozen = false;\n }\n\n stopAuto(): void {\n if (this._isFrozen) return;\n this.host.freeze();\n this._isFrozen = true;\n }\n\n freeze(): void {\n this.stopAuto();\n }\n\n thaw(): void {\n this.startAuto();\n }\n\n setDelta(ms: number): void {\n if (!Number.isFinite(ms) || ms <= 0) {\n throw new Error(\"DebugClock.setDelta(ms) requires a positive number.\");\n }\n this.deltaMs = ms;\n }\n\n getFrame(): number {\n return this.frame;\n }\n\n step(dtMs?: number): void {\n if (!this._isFrozen) {\n throw new Error(\"DebugClock is not frozen. Call clock.freeze() first.\");\n }\n const dt = dtMs ?? this.deltaMs;\n if (!Number.isFinite(dt) || dt <= 0) {\n throw new Error(\"DebugClock.step(dtMs) requires a positive number.\");\n }\n // Increment after a successful advance — if a ticker subscriber throws\n // (system exception, render failure) the frame counter shouldn't advance\n // ahead of state.\n this.host.advance(dt);\n this.frame++;\n }\n\n stepFrames(count: number, dtMs?: number): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n \"stepFrames(count) requires a non-negative integer count.\",\n );\n }\n for (let i = 0; i < count; i++) {\n this.step(dtMs);\n }\n }\n}\n","import type { DebugContributor, DebugRegistry } from \"./types.js\";\n\n/** Concrete implementation of the DebugRegistry interface. */\nexport class DebugRegistryImpl implements DebugRegistry {\n readonly contributors = new Map<string, DebugContributor>();\n enabled = false;\n private flags = new Map<string, boolean>();\n\n register(contributor: DebugContributor): void {\n if (this.contributors.has(contributor.name)) return;\n this.contributors.set(contributor.name, contributor);\n for (const flag of contributor.flags) {\n this.flags.set(`${contributor.name}.${flag}`, true);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n isFlagEnabled(contributorName: string, flag: string): boolean {\n return this.flags.get(`${contributorName}.${flag}`) ?? true;\n }\n\n toggle(): void {\n this.enabled = !this.enabled;\n }\n\n toggleFlag(contributorName: string, flag: string): void {\n const key = `${contributorName}.${flag}`;\n this.flags.set(key, !(this.flags.get(key) ?? true));\n }\n\n setFlag(contributorName: string, flag: string, value: boolean): void {\n this.flags.set(`${contributorName}.${flag}`, value);\n }\n}\n","import { LoggerKey, Scene } from \"@yagejs/core\";\nimport type { Logger } from \"@yagejs/core\";\nimport type { LayerDef } from \"@yagejs/renderer\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport type { Container } from \"pixi.js\";\n\n/**\n * Scene mounted by the debug plugin via `SceneManager._mountDetached`.\n * Declares two layers:\n * - `\"debug-world\"` — world-space, rides the camera (for collision shapes).\n * - `\"debug-hud\"` — screen-space, fixed overlay (text readouts).\n *\n * `pauseBelow: false` / `transparentBelow: true` so the underlying game\n * keeps running and rendering behind the overlay.\n */\nexport class DebugScene extends Scene {\n readonly name = \"__debug__\";\n override readonly pauseBelow = false;\n override readonly transparentBelow = true;\n readonly layers: readonly LayerDef[] = [\n { name: \"debug-world\", order: 999999 },\n { name: \"debug-hud\", order: 999999 },\n ];\n\n /** Called after `_mountDetached` has materialized the render tree. */\n onReady?: (worldContainer: Container, hudContainer: Container) => void;\n\n /** Called by the plugin when the scene is unmounted. */\n onTearDown?: () => void;\n\n onEnter(): void {\n const tree = this._resolveScoped(SceneRenderTreeKey);\n if (!tree) {\n // Shouldn't happen — DebugPlugin declares `renderer` as a dependency\n // so the renderer's `beforeEnter` hook should have materialized a\n // tree before this runs. Surface it rather than silently skipping\n // the overlay wiring.\n const logger = this.context.tryResolve(LoggerKey) as Logger | undefined;\n const msg =\n \"DebugScene.onEnter: SceneRenderTreeKey missing — debug overlay will not render. Is RendererPlugin registered?\";\n if (logger) logger.warn(\"debug\", msg);\n else console.warn(`[yage] ${msg}`);\n return;\n }\n const worldContainer = tree.get(\"debug-world\").container;\n const hudContainer = tree.get(\"debug-hud\").container;\n worldContainer.eventMode = \"none\";\n hudContainer.eventMode = \"none\";\n this.onReady?.(worldContainer, hudContainer);\n }\n\n onExit(): void {\n this.onTearDown?.();\n }\n}\n","import type { StatsApi } from \"./types.js\";\n\nconst WINDOW_SIZE = 120;\n\ninterface RingBuffer {\n data: Float64Array;\n count: number;\n index: number;\n}\n\n/** Rolling-window statistics store backed by Float64Array ring buffers. */\nexport class StatsStore implements StatsApi {\n private rings = new Map<string, RingBuffer>();\n\n push(key: string, value: number): void {\n let ring = this.rings.get(key);\n if (!ring) {\n ring = { data: new Float64Array(WINDOW_SIZE), count: 0, index: 0 };\n this.rings.set(key, ring);\n }\n ring.data[ring.index] = value;\n ring.index = (ring.index + 1) % WINDOW_SIZE;\n if (ring.count < WINDOW_SIZE) ring.count++;\n }\n\n average(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let sum = 0;\n for (let i = 0; i < count; i++) sum += data[i] ?? 0;\n return sum / count;\n }\n\n latest(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n return ring.data[(ring.index - 1 + WINDOW_SIZE) % WINDOW_SIZE] ?? 0;\n }\n\n min(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v < m) m = v;\n }\n return m;\n }\n\n max(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v > m) m = v;\n }\n return m;\n }\n}\n","import { Graphics, Container } from \"pixi.js\";\n\n/** Allocation-free pool of PixiJS Graphics objects for debug drawing. */\nexport class GraphicsPool {\n private pool: Graphics[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxSize: number;\n\n constructor(container: Container, maxSize = 256) {\n this.container = container;\n this.maxSize = maxSize;\n }\n\n /** Lazily create Graphics objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Graphics[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxSize; i++) {\n const g = new Graphics();\n g.visible = false;\n g.eventMode = \"none\";\n this.container.addChild(g);\n this.pool.push(g);\n }\n return this.pool;\n }\n\n /** Return the next available Graphics, or undefined if the pool is exhausted. */\n acquire(): Graphics | undefined {\n const pool = this.ensure();\n if (this.index >= pool.length) return undefined;\n const g = pool[this.index]!;\n g.visible = true;\n this.index++;\n return g;\n }\n\n /** Clear and hide all previously acquired graphics, reset index. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n const g = this.pool[i]!;\n g.clear();\n g.visible = false;\n g.position.set(0, 0);\n g.rotation = 0;\n g.scale.set(1, 1);\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const g of this.pool) {\n g.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import { Text, Container } from \"pixi.js\";\n\nconst LINE_HEIGHT = 16;\nconst FONT_SIZE = 14;\nconst PADDING = 4;\n\n/** Allocation-free pool of PixiJS Text objects for HUD debug lines. */\nexport class TextPool {\n private pool: Text[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxLines: number;\n\n constructor(container: Container, maxLines = 32) {\n this.container = container;\n this.maxLines = maxLines;\n }\n\n /** Lazily create Text objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Text[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxLines; i++) {\n const t = new Text({\n text: \"\",\n style: {\n fontFamily: \"monospace\",\n fontSize: FONT_SIZE,\n fill: 0xffffff,\n },\n });\n t.visible = false;\n t.eventMode = \"none\";\n this.container.addChild(t);\n this.pool.push(t);\n }\n return this.pool;\n }\n\n /** Show a text line at the next available slot. */\n addLine(text: string): void {\n const pool = this.ensure();\n if (this.index >= pool.length) return;\n const t = pool[this.index]!;\n t.text = text;\n t.visible = true;\n t.position.set(PADDING, PADDING + this.index * LINE_HEIGHT);\n this.index++;\n }\n\n /** Hide all lines and reset for the next frame. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n this.pool[i]!.visible = false;\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const t of this.pool) {\n t.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import type { WorldDebugApi, DebugGraphics } from \"./types.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** WorldDebugApi backed by a GraphicsPool. Contributor name is swapped per iteration. */\nexport class WorldDebugApiImpl implements WorldDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly pool: GraphicsPool,\n private readonly registry: DebugRegistryImpl,\n private readonly _camera: { zoom: number },\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawWorld). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n acquireGraphics(): DebugGraphics | undefined {\n return this.pool.acquire() as unknown as DebugGraphics | undefined;\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n\n get cameraZoom(): number {\n return this._camera.zoom;\n }\n}\n","import type { HudDebugApi } from \"./types.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** HudDebugApi backed by a TextPool. Contributor name is swapped per iteration. */\nexport class HudDebugApiImpl implements HudDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly textPool: TextPool,\n private readonly registry: DebugRegistryImpl,\n public readonly screenWidth: number,\n public readonly screenHeight: number,\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawHud). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n addLine(text: string): void {\n this.textPool.addLine(text);\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n}\n","import { System, Phase } from \"@yagejs/core\";\nimport type { Container } from \"pixi.js\";\nimport type { CameraComponent } from \"@yagejs/renderer\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport type { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport type { StatsStore } from \"./StatsStore.js\";\n\nexport interface DebugCameraAccessor {\n findCamera(): CameraComponent | undefined;\n viewportWidth: number;\n viewportHeight: number;\n}\n\n/** Renders all debug contributors. Runs after DisplaySystem in the Render phase. */\nexport class DebugRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = 9999;\n\n constructor(\n private readonly registry: DebugRegistryImpl,\n private readonly graphicsPool: GraphicsPool,\n private readonly textPool: TextPool,\n private readonly worldApi: WorldDebugApiImpl,\n private readonly hudApi: HudDebugApiImpl,\n private readonly stats: StatsStore,\n private readonly worldContainer: Container,\n private readonly hudContainer: Container,\n private readonly cameraAccessor: DebugCameraAccessor,\n ) {\n super();\n }\n\n update(dt: number): void {\n if (!this.registry.enabled) {\n this.worldContainer.visible = false;\n this.hudContainer.visible = false;\n return;\n }\n\n this.worldContainer.visible = true;\n this.hudContainer.visible = true;\n\n // Apply camera transform to the debug world container so that\n // world-space debug drawing (collision shapes, etc.) aligns with\n // the active scene's camera.\n this.syncWorldCamera();\n\n this.graphicsPool.resetFrame();\n this.textPool.resetFrame();\n\n for (const [name, contributor] of this.registry.contributors) {\n contributor.sample?.(this.stats, dt);\n\n if (contributor.drawWorld) {\n this.worldApi.setContributor(name);\n contributor.drawWorld(this.worldApi);\n }\n\n if (contributor.drawHud) {\n this.hudApi.setContributor(name);\n contributor.drawHud(this.hudApi);\n }\n }\n }\n\n private syncWorldCamera(): void {\n const cam = this.cameraAccessor.findCamera();\n if (!cam) {\n this.worldContainer.position.set(0, 0);\n this.worldContainer.scale.set(1, 1);\n this.worldContainer.rotation = 0;\n return;\n }\n\n const vw = this.cameraAccessor.viewportWidth;\n const vh = this.cameraAccessor.viewportHeight;\n const rotatedPos = cam.effectivePosition\n .scale(cam.zoom)\n .rotate(-cam.rotation);\n this.worldContainer.position.x = vw / 2 - rotatedPos.x;\n this.worldContainer.position.y = vh / 2 - rotatedPos.y;\n this.worldContainer.scale.set(cam.zoom);\n this.worldContainer.rotation = -cam.rotation;\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class FpsContributor implements DebugContributor {\n readonly name = \"fps\";\n readonly flags: readonly string[] = [];\n private stats: StatsApi | null = null;\n\n sample(stats: StatsApi, dt: number): void {\n this.stats = stats;\n if (dt > 0) stats.push(\"fps\", 1000 / dt);\n }\n\n drawHud(api: HudDebugApi): void {\n const avg = this.stats?.average(\"fps\") ?? 0;\n api.addLine(`FPS: ${Math.round(avg)}`);\n }\n}\n","import type { DebugContributor, HudDebugApi } from \"../types.js\";\nimport type { Inspector } from \"@yagejs/core\";\n\nexport class EntityCountContributor implements DebugContributor {\n readonly name = \"entities\";\n readonly flags: readonly string[] = [];\n\n constructor(private readonly inspector: Inspector) {}\n\n drawHud(api: HudDebugApi): void {\n const count = this.inspector.snapshot().entityCount;\n api.addLine(`Entities: ${count}`);\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class SystemTimingContributor implements DebugContributor {\n readonly name = \"timing\";\n readonly flags = [\"breakdown\"] as const;\n private stats: StatsApi | null = null;\n\n constructor(private readonly timings: Map<string, number>) {}\n\n sample(stats: StatsApi): void {\n this.stats = stats;\n for (const [name, ms] of this.timings) {\n stats.push(`system.${name}`, ms);\n }\n }\n\n drawHud(api: HudDebugApi): void {\n if (!this.stats) return;\n\n let total = 0;\n const entries: Array<[string, number]> = [];\n for (const name of this.timings.keys()) {\n const avg = this.stats.average(`system.${name}`);\n total += avg;\n entries.push([name, avg]);\n }\n\n api.addLine(`Systems: ${total.toFixed(2)}ms`);\n\n if (api.isFlagEnabled(\"breakdown\")) {\n entries.sort((a, b) => b[1] - a[1]);\n for (const [name, avg] of entries) {\n api.addLine(` ${name}: ${avg.toFixed(2)}ms`);\n }\n }\n }\n}\n"],"mappings":"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","names":["import_core","import_renderer","import_core","import_pixi","import_core"]}
package/dist/index.d.cts CHANGED
@@ -21,6 +21,17 @@ interface DebugConfig {
21
21
  * normal debug builds so randomness behaves the same as in production.
22
22
  */
23
23
  deterministicSeed?: number;
24
+ /**
25
+ * If true, the engine boots with a paused Pixi ticker so no auto-frames
26
+ * tick before user code can intervene — equivalent to calling
27
+ * `inspector.time.freeze()` at frame zero, but applied during plugin
28
+ * `install()` (before `loop.start()`). Use for deterministic E2E runs:
29
+ * any later `engine.scenes.push(...)` resolves under frozen time, so
30
+ * snapshots taken right after only depend on the explicit `time.step()`
31
+ * calls — not on how many auto-frames slipped in between
32
+ * `await engine.start()` and the test's first `freeze()`.
33
+ */
34
+ startFrozen?: boolean;
24
35
  }
25
36
  interface LayerTransformSnapshot {
26
37
  x: number;
package/dist/index.d.ts CHANGED
@@ -21,6 +21,17 @@ interface DebugConfig {
21
21
  * normal debug builds so randomness behaves the same as in production.
22
22
  */
23
23
  deterministicSeed?: number;
24
+ /**
25
+ * If true, the engine boots with a paused Pixi ticker so no auto-frames
26
+ * tick before user code can intervene — equivalent to calling
27
+ * `inspector.time.freeze()` at frame zero, but applied during plugin
28
+ * `install()` (before `loop.start()`). Use for deterministic E2E runs:
29
+ * any later `engine.scenes.push(...)` resolves under frozen time, so
30
+ * snapshots taken right after only depend on the explicit `time.step()`
31
+ * calls — not on how many auto-frames slipped in between
32
+ * `await engine.start()` and the test's first `freeze()`.
33
+ */
34
+ startFrozen?: boolean;
24
35
  }
25
36
  interface LayerTransformSnapshot {
26
37
  x: number;
package/dist/index.js CHANGED
@@ -559,6 +559,9 @@ var DebugPlugin = class {
559
559
  if (this.config.deterministicSeed !== void 0) {
560
560
  context.resolve(InspectorKey).setDefaultSceneSeed(this.config.deterministicSeed);
561
561
  }
562
+ if (this.config.startFrozen) {
563
+ this.renderer.application.stop();
564
+ }
562
565
  this.registry = new DebugRegistryImpl();
563
566
  this.registry.enabled = this.config.startEnabled ?? false;
564
567
  if (this.config.flags) {
@@ -614,6 +617,9 @@ var DebugPlugin = class {
614
617
  inspector.attachTimeController(this.clock);
615
618
  inspector.setEventLogEnabled(true);
616
619
  this.attachToGlobal(this.clock);
620
+ if (this.config.startFrozen) {
621
+ this.clock.freeze();
622
+ }
617
623
  this.provider = this.context.tryResolve(SceneRenderTreeProviderKey) ?? null;
618
624
  this.registerInspectorDiagnostics();
619
625
  await this.materializeDebugScene();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/DebugPlugin.ts","../src/DebugClock.ts","../src/DebugRegistryImpl.ts","../src/DebugScene.ts","../src/StatsStore.ts","../src/GraphicsPool.ts","../src/TextPool.ts","../src/WorldDebugApiImpl.ts","../src/HudDebugApiImpl.ts","../src/DebugRenderSystem.ts","../src/contributors/FpsContributor.ts","../src/contributors/EntityCountContributor.ts","../src/contributors/SystemTimingContributor.ts"],"sourcesContent":["import {\n EventBusKey,\n GameLoopKey,\n InspectorKey,\n SceneManagerKey,\n} from \"@yagejs/core\";\nimport type {\n EngineContext,\n EventBus,\n EngineEvents,\n Plugin,\n SceneManager,\n System,\n SystemScheduler,\n} from \"@yagejs/core\";\nimport { DebugRegistryKey } from \"./types.js\";\nimport { CameraComponent, RendererKey } from \"@yagejs/renderer\";\nimport type { RendererPlugin, SceneRenderTreeProvider } from \"@yagejs/renderer\";\nimport { SceneRenderTreeProviderKey } from \"@yagejs/renderer\";\nimport type { Application, Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { DebugClockHost, IDebugClock } from \"./DebugClock.js\";\nimport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport { DebugScene } from \"./DebugScene.js\";\nimport { StatsStore } from \"./StatsStore.js\";\nimport { GraphicsPool } from \"./GraphicsPool.js\";\nimport { TextPool } from \"./TextPool.js\";\nimport { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport { DebugRenderSystem } from \"./DebugRenderSystem.js\";\nimport { FpsContributor } from \"./contributors/FpsContributor.js\";\nimport { EntityCountContributor } from \"./contributors/EntityCountContributor.js\";\nimport { SystemTimingContributor } from \"./contributors/SystemTimingContributor.js\";\n\n/** Configuration for the DebugPlugin. */\nexport interface DebugConfig {\n /** Key code to toggle debug overlay. Default: \"Backquote\" */\n toggleKey?: string;\n /** Key code to advance one fixed-timestep frame while the debug clock is frozen. Default: \"Period\" */\n stepKey?: string;\n /** Max pooled Graphics objects. Default: 256 */\n maxGraphics?: number;\n /** Max HUD text lines. Default: 32 */\n maxHudLines?: number;\n /** Whether the overlay starts enabled. Default: false */\n startEnabled?: boolean;\n /** Initial flag overrides, keyed by \"contributorName.flagName\". */\n flags?: Record<string, boolean>;\n /**\n * If set, every scene's RNG is initialized with this seed instead of an\n * unspecified default. Use for deterministic E2E runs. Leave undefined for\n * normal debug builds so randomness behaves the same as in production.\n */\n deterministicSeed?: number;\n}\n\nexport interface LayerTransformSnapshot {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n rotation: number;\n}\n\nexport interface CameraStackSnapshot {\n scene: string;\n name: string | undefined;\n priority: number;\n enabled: boolean;\n}\n\n/**\n * Renderer-aware diagnostics exposed through the inspector extension\n * namespace `debug`. Kept out of the core Inspector surface so the core\n * package stays renderer-agnostic while plugins can still publish optional\n * runtime helpers in a uniform way.\n */\nexport interface DebugDiagnostics {\n getLayerTransform(\n sceneName: string,\n layerName: string,\n ): LayerTransformSnapshot | undefined;\n getCameraStack(): CameraStackSnapshot[];\n}\n\n/**\n * Debug overlay plugin. Mounts a private `DebugScene` through\n * `SceneManager._mountDetached` so it goes through the same scoped-DI\n * lifecycle as stacked scenes (the renderer's `beforeEnter` hook creates\n * its render tree) while staying off the user-visible scene stack.\n */\nexport class DebugPlugin implements Plugin {\n readonly name = \"debug\";\n readonly version = \"3.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n private readonly config: DebugConfig;\n private registry!: DebugRegistryImpl;\n private stats!: StatsStore;\n private graphicsPool: GraphicsPool | null = null;\n private textPool: TextPool | null = null;\n private worldApi: WorldDebugApiImpl | null = null;\n private hudApi: HudDebugApiImpl | null = null;\n private renderSystem: DebugRenderSystem | null = null;\n private systemTimings = new Map<string, number>();\n private originalUpdates = new Map<System, (dt: number) => void>();\n private keyListener: ((e: KeyboardEvent) => void) | null = null;\n private context!: EngineContext;\n private renderer!: RendererPlugin;\n private scheduler!: SystemScheduler;\n private sceneManager!: SceneManager;\n private debugScene: DebugScene | null = null;\n private provider: SceneRenderTreeProvider | null = null;\n private eventUnsubs: Array<() => void> = [];\n private clock: DebugClock | null = null;\n\n constructor(config?: DebugConfig) {\n this.config = config ?? {};\n }\n\n install(context: EngineContext): void {\n this.context = context;\n this.renderer = context.resolve(RendererKey);\n if (this.config.deterministicSeed !== undefined) {\n context\n .resolve(InspectorKey)\n .setDefaultSceneSeed(this.config.deterministicSeed);\n }\n\n this.registry = new DebugRegistryImpl();\n this.registry.enabled = this.config.startEnabled ?? false;\n\n if (this.config.flags) {\n for (const [key, value] of Object.entries(this.config.flags)) {\n const dot = key.indexOf(\".\");\n if (dot > 0) {\n this.registry.setFlag(key.slice(0, dot), key.slice(dot + 1), value);\n }\n }\n }\n\n this.stats = new StatsStore();\n\n context.register(DebugRegistryKey, this.registry);\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n // DebugRenderSystem is registered lazily once the debug scene is ready —\n // its constructor needs the scene's layer containers.\n this.scheduler = scheduler;\n }\n\n async onStart(): Promise<void> {\n this.sceneManager = this.context.resolve(SceneManagerKey);\n const bus = this.context.resolve(EventBusKey) as EventBus<EngineEvents>;\n\n // Key listeners (toggle, manual-clock step)\n const toggleKey = this.config.toggleKey ?? \"Backquote\";\n const stepKey = this.config.stepKey ?? \"Period\";\n this.keyListener = (e: KeyboardEvent) => {\n if (e.code === toggleKey) {\n this.registry.toggle();\n return;\n }\n if (e.code === stepKey && this.clock?.isFrozen) {\n e.preventDefault();\n this.clock.step();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.keyListener);\n }\n\n // Instrument system timings — reuse the scheduler captured in\n // `registerSystems`, which ran before `onStart`.\n for (const system of this.scheduler.getAllSystems()) {\n if (system instanceof DebugRenderSystem) continue;\n const name = system.constructor.name;\n const original = system.update.bind(system);\n this.originalUpdates.set(system, original);\n system.update = (dt: number) => {\n const t0 = performance.now();\n original(dt);\n this.systemTimings.set(name, performance.now() - t0);\n };\n }\n\n // Built-in contributors\n const inspector = this.context.resolve(InspectorKey);\n this.registry.register(new FpsContributor());\n this.registry.register(new EntityCountContributor(inspector));\n this.registry.register(new SystemTimingContributor(this.systemTimings));\n\n // Manual clock for deterministic stepping. The host drives `app.ticker`\n // directly so a manual `step()` fires every ticker subscriber\n // (AnimatedSprite, pixi-filters, render, user `app.ticker.add` callbacks)\n // with the same synthetic dt as gameplay state.\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n this.clock = new DebugClock(createPixiTickerHost(app, gameLoop.fixedTimestep));\n inspector.attachTimeController(this.clock);\n inspector.setEventLogEnabled(true);\n this.attachToGlobal(this.clock);\n\n // Materialize the debug scene off-stack. `_mountDetached` routes through\n // the same beforeEnter hooks as `push`, so the renderer materializes the\n // debug scene's tree and registers SceneRenderTreeKey on its scope.\n this.provider = this.context.tryResolve(SceneRenderTreeProviderKey) ?? null;\n this.registerInspectorDiagnostics();\n await this.materializeDebugScene();\n\n // Keep the debug scene visually on top of the user stack after any\n // push/pop/replace by reordering its root containers.\n const bringToFront = () => {\n if (this.debugScene && this.provider?.bringSceneToFront) {\n this.provider.bringSceneToFront(this.debugScene);\n }\n };\n this.eventUnsubs.push(bus.on(\"scene:pushed\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:popped\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:replaced\", bringToFront));\n }\n\n onDestroy(): void {\n for (const unsub of this.eventUnsubs) unsub();\n this.eventUnsubs.length = 0;\n\n for (const [system, original] of this.originalUpdates) {\n system.update = original;\n }\n this.originalUpdates.clear();\n\n if (this.keyListener) {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.keyListener);\n }\n this.keyListener = null;\n }\n\n this.detachFromGlobal();\n const inspector = this.context.resolve(InspectorKey);\n inspector.removeExtension(\"debug\");\n // Only detach our own clock — passing undefined would clear whatever\n // controller is registered, which could belong to another plugin if\n // onDestroy runs after a failed onStart.\n if (this.clock) {\n inspector.detachTimeController(this.clock);\n }\n inspector.setEventLogEnabled(false);\n if (this.config.deterministicSeed !== undefined) {\n inspector.setDefaultSceneSeed(undefined);\n }\n this.clock = null;\n\n for (const contributor of this.registry.contributors.values()) {\n contributor.dispose?.();\n }\n this.registry.contributors.clear();\n\n this.tearDownDebugInfra();\n this.teardownDebugScene();\n }\n\n private async materializeDebugScene(): Promise<void> {\n const scene = new DebugScene();\n scene.onReady = (worldContainer, hudContainer) =>\n this.setUpDebugInfra(worldContainer, hudContainer);\n scene.onTearDown = () => this.tearDownDebugInfra();\n await this.sceneManager._mountDetached(scene);\n this.debugScene = scene;\n }\n\n private teardownDebugScene(): void {\n // If destroy is called while `_mountDetached` is still pending, we don't\n // yet hold a reference to the partially-mounted scene. Skipping unmount\n // here is safe: onDestroy still runs `tearDownDebugInfra` below, and the\n // engine teardown tears down the renderer next which destroys any\n // half-created provider entries.\n if (!this.debugScene) return;\n this.sceneManager._unmountDetached(this.debugScene);\n this.debugScene = null;\n this.provider = null;\n }\n\n private findActiveCamera(): CameraComponent | undefined {\n return findTopmostCamera(this.sceneManager);\n }\n\n private setUpDebugInfra(\n worldContainer: Container,\n hudContainer: Container,\n ): void {\n const vw = this.renderer.virtualSize.width;\n const vh = this.renderer.virtualSize.height;\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n // Lazy camera accessor — reads from whichever stacked scene has a camera\n const cameraProxy = {\n get zoom() {\n return self.findActiveCamera()?.zoom ?? 1;\n },\n };\n\n this.graphicsPool = new GraphicsPool(\n worldContainer,\n this.config.maxGraphics,\n );\n this.textPool = new TextPool(hudContainer, this.config.maxHudLines);\n\n this.worldApi = new WorldDebugApiImpl(\n this.graphicsPool,\n this.registry,\n cameraProxy,\n );\n this.hudApi = new HudDebugApiImpl(this.textPool, this.registry, vw, vh);\n\n this.renderSystem = new DebugRenderSystem(\n this.registry,\n this.graphicsPool,\n this.textPool,\n this.worldApi,\n this.hudApi,\n this.stats,\n worldContainer,\n hudContainer,\n {\n findCamera: () => self.findActiveCamera(),\n viewportWidth: vw,\n viewportHeight: vh,\n },\n );\n this.scheduler.add(this.renderSystem);\n }\n\n private tearDownDebugInfra(): void {\n if (this.renderSystem) {\n this.scheduler.remove(this.renderSystem);\n this.renderSystem = null;\n }\n this.graphicsPool?.destroy();\n this.textPool?.destroy();\n this.graphicsPool = null;\n this.textPool = null;\n this.worldApi = null;\n this.hudApi = null;\n }\n\n private registerInspectorDiagnostics(): void {\n const diagnostics: DebugDiagnostics = {\n getLayerTransform: (sceneName, layerName) => {\n const scene = this.sceneManager.all.find(\n (candidate) => candidate.name === sceneName,\n );\n if (!scene) return undefined;\n\n const layer = this.provider?.getTree(scene)?.tryGet(layerName);\n if (!layer) return undefined;\n\n const container = layer.container;\n return {\n x: container.position.x,\n y: container.position.y,\n scaleX: container.scale.x,\n scaleY: container.scale.y,\n rotation: container.rotation,\n };\n },\n getCameraStack: () => {\n const cameras: CameraStackSnapshot[] = [];\n for (const scene of this.sceneManager.all) {\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (!cam) continue;\n cameras.push({\n scene: scene.name,\n name: cam.cameraName,\n priority: cam.priority,\n enabled: cam.enabled,\n });\n }\n }\n return cameras;\n },\n };\n this.context.resolve(InspectorKey).addExtension(\"debug\", diagnostics);\n }\n\n private attachToGlobal(clock: IDebugClock): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (g && typeof g === \"object\") {\n (g as Record<string, unknown>)[\"clock\"] = clock;\n }\n }\n\n private detachFromGlobal(): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (\n g &&\n typeof g === \"object\" &&\n (g as Record<string, unknown>)[\"clock\"] === this.clock\n ) {\n delete (g as Record<string, unknown>)[\"clock\"];\n }\n }\n}\n\n/**\n * Wire a `DebugClockHost` against a Pixi v8 `Application`. Driving\n * `app.ticker.update(syntheticTime)` while the ticker is stopped fires every\n * subscriber — Pixi's `Ticker.update` doesn't gate on `started`, only the\n * rAF-driven `_tick` does — so a single advance replaces the old\n * `gameLoop.tick(dt)` + `app.render()` quad and along the way fixes the\n * AnimatedSprite / pixi-filters / `app.ticker.add` subscriber freeze.\n */\nfunction createPixiTickerHost(\n app: Application,\n fixedTimestep: number,\n): DebugClockHost {\n let syntheticTime = 0;\n let savedMinFPS: number | null = null;\n return {\n fixedTimestep,\n freeze(): void {\n app.stop();\n // Reset both to zero so synthetic time starts from a clean origin\n // and `(syntheticTime + dt) - syntheticTime` stays an exact `dt`\n // — keeps deltaMS deterministic regardless of how long the page\n // ran in auto mode before the freeze.\n syntheticTime = 0;\n app.ticker.lastTime = 0;\n // Default minFPS=10 clamps deltaMS at 100ms — `step(200)` would\n // silently see deltaMS=100. Disable for the duration of the freeze.\n savedMinFPS = app.ticker.minFPS;\n app.ticker.minFPS = 0;\n },\n thaw(): void {\n if (savedMinFPS !== null) {\n app.ticker.minFPS = savedMinFPS;\n savedMinFPS = null;\n }\n // `app.start()` calls `Ticker._requestIfNeeded` which resets\n // `lastTime` to `performance.now()` itself, so the next rAF\n // doesn't see `realNow - 0` as a giant first-frame delta. No\n // need to set it manually here.\n app.start();\n },\n advance(dtMs: number): void {\n syntheticTime += dtMs;\n app.ticker.update(syntheticTime);\n },\n };\n}\n\n/**\n * Find the highest-priority enabled camera on the topmost scene that has one.\n * `sceneManager.all` is bottom→top, so we walk in reverse — a pause/HUD\n * scene's camera wins over a frozen scene beneath it.\n */\nexport function findTopmostCamera(\n sceneManager: SceneManager,\n): CameraComponent | undefined {\n const stack = sceneManager.all;\n for (let i = stack.length - 1; i >= 0; i--) {\n const scene = stack[i];\n if (!scene) continue;\n let highestPriorityCamera: CameraComponent | undefined;\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (\n cam &&\n cam.enabled &&\n (!highestPriorityCamera ||\n cam.priority > highestPriorityCamera.priority)\n ) {\n highestPriorityCamera = cam;\n }\n }\n if (highestPriorityCamera) return highestPriorityCamera;\n }\n return undefined;\n}\n","/** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */\nexport interface IDebugClock {\n readonly isFrozen: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n freeze(): void;\n thaw(): void;\n setDelta(ms: number): void;\n getFrame(): number;\n}\n\n/**\n * Hooks the clock uses to drive the host. The host owns the synthetic-time\n * bookkeeping and the ticker plumbing — `DebugClock` stays a pure state\n * machine. Production wires this against Pixi's `app.ticker` so a manual\n * `step()` fires every ticker subscriber (GameLoop, AnimatedSprite,\n * pixi-filters, render) with the same synthetic dt.\n */\nexport interface DebugClockHost {\n readonly fixedTimestep: number;\n /** Advance one synthetic frame of `dtMs`. Fires every ticker subscriber. */\n advance(dtMs: number): void;\n /** Stop auto-advance. Capture state needed to make `advance` deterministic. */\n freeze(): void;\n /** Resume auto-advance. Restore captured state so the next rAF is sane. */\n thaw(): void;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * While frozen the renderer ticker is paused and frames advance only via\n * explicit `step()` / `stepFrames()` calls. `freeze()` / `thaw()` and\n * `startAuto()` / `stopAuto()` are equivalent verbs for the same toggle.\n */\nexport class DebugClock implements IDebugClock {\n private _isFrozen = false;\n private deltaMs: number;\n private frame = 0;\n\n constructor(private readonly host: DebugClockHost) {\n this.deltaMs = host.fixedTimestep;\n }\n\n get isFrozen(): boolean {\n return this._isFrozen;\n }\n\n startAuto(): void {\n if (!this._isFrozen) return;\n this.host.thaw();\n this._isFrozen = false;\n }\n\n stopAuto(): void {\n if (this._isFrozen) return;\n this.host.freeze();\n this._isFrozen = true;\n }\n\n freeze(): void {\n this.stopAuto();\n }\n\n thaw(): void {\n this.startAuto();\n }\n\n setDelta(ms: number): void {\n if (!Number.isFinite(ms) || ms <= 0) {\n throw new Error(\"DebugClock.setDelta(ms) requires a positive number.\");\n }\n this.deltaMs = ms;\n }\n\n getFrame(): number {\n return this.frame;\n }\n\n step(dtMs?: number): void {\n if (!this._isFrozen) {\n throw new Error(\"DebugClock is not frozen. Call clock.freeze() first.\");\n }\n const dt = dtMs ?? this.deltaMs;\n if (!Number.isFinite(dt) || dt <= 0) {\n throw new Error(\"DebugClock.step(dtMs) requires a positive number.\");\n }\n // Increment after a successful advance — if a ticker subscriber throws\n // (system exception, render failure) the frame counter shouldn't advance\n // ahead of state.\n this.host.advance(dt);\n this.frame++;\n }\n\n stepFrames(count: number, dtMs?: number): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n \"stepFrames(count) requires a non-negative integer count.\",\n );\n }\n for (let i = 0; i < count; i++) {\n this.step(dtMs);\n }\n }\n}\n","import type { DebugContributor, DebugRegistry } from \"./types.js\";\n\n/** Concrete implementation of the DebugRegistry interface. */\nexport class DebugRegistryImpl implements DebugRegistry {\n readonly contributors = new Map<string, DebugContributor>();\n enabled = false;\n private flags = new Map<string, boolean>();\n\n register(contributor: DebugContributor): void {\n if (this.contributors.has(contributor.name)) return;\n this.contributors.set(contributor.name, contributor);\n for (const flag of contributor.flags) {\n this.flags.set(`${contributor.name}.${flag}`, true);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n isFlagEnabled(contributorName: string, flag: string): boolean {\n return this.flags.get(`${contributorName}.${flag}`) ?? true;\n }\n\n toggle(): void {\n this.enabled = !this.enabled;\n }\n\n toggleFlag(contributorName: string, flag: string): void {\n const key = `${contributorName}.${flag}`;\n this.flags.set(key, !(this.flags.get(key) ?? true));\n }\n\n setFlag(contributorName: string, flag: string, value: boolean): void {\n this.flags.set(`${contributorName}.${flag}`, value);\n }\n}\n","import { LoggerKey, Scene } from \"@yagejs/core\";\nimport type { Logger } from \"@yagejs/core\";\nimport type { LayerDef } from \"@yagejs/renderer\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport type { Container } from \"pixi.js\";\n\n/**\n * Scene mounted by the debug plugin via `SceneManager._mountDetached`.\n * Declares two layers:\n * - `\"debug-world\"` — world-space, rides the camera (for collision shapes).\n * - `\"debug-hud\"` — screen-space, fixed overlay (text readouts).\n *\n * `pauseBelow: false` / `transparentBelow: true` so the underlying game\n * keeps running and rendering behind the overlay.\n */\nexport class DebugScene extends Scene {\n readonly name = \"__debug__\";\n override readonly pauseBelow = false;\n override readonly transparentBelow = true;\n readonly layers: readonly LayerDef[] = [\n { name: \"debug-world\", order: 999999 },\n { name: \"debug-hud\", order: 999999 },\n ];\n\n /** Called after `_mountDetached` has materialized the render tree. */\n onReady?: (worldContainer: Container, hudContainer: Container) => void;\n\n /** Called by the plugin when the scene is unmounted. */\n onTearDown?: () => void;\n\n onEnter(): void {\n const tree = this._resolveScoped(SceneRenderTreeKey);\n if (!tree) {\n // Shouldn't happen — DebugPlugin declares `renderer` as a dependency\n // so the renderer's `beforeEnter` hook should have materialized a\n // tree before this runs. Surface it rather than silently skipping\n // the overlay wiring.\n const logger = this.context.tryResolve(LoggerKey) as Logger | undefined;\n const msg =\n \"DebugScene.onEnter: SceneRenderTreeKey missing — debug overlay will not render. Is RendererPlugin registered?\";\n if (logger) logger.warn(\"debug\", msg);\n else console.warn(`[yage] ${msg}`);\n return;\n }\n const worldContainer = tree.get(\"debug-world\").container;\n const hudContainer = tree.get(\"debug-hud\").container;\n worldContainer.eventMode = \"none\";\n hudContainer.eventMode = \"none\";\n this.onReady?.(worldContainer, hudContainer);\n }\n\n onExit(): void {\n this.onTearDown?.();\n }\n}\n","import type { StatsApi } from \"./types.js\";\n\nconst WINDOW_SIZE = 120;\n\ninterface RingBuffer {\n data: Float64Array;\n count: number;\n index: number;\n}\n\n/** Rolling-window statistics store backed by Float64Array ring buffers. */\nexport class StatsStore implements StatsApi {\n private rings = new Map<string, RingBuffer>();\n\n push(key: string, value: number): void {\n let ring = this.rings.get(key);\n if (!ring) {\n ring = { data: new Float64Array(WINDOW_SIZE), count: 0, index: 0 };\n this.rings.set(key, ring);\n }\n ring.data[ring.index] = value;\n ring.index = (ring.index + 1) % WINDOW_SIZE;\n if (ring.count < WINDOW_SIZE) ring.count++;\n }\n\n average(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let sum = 0;\n for (let i = 0; i < count; i++) sum += data[i] ?? 0;\n return sum / count;\n }\n\n latest(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n return ring.data[(ring.index - 1 + WINDOW_SIZE) % WINDOW_SIZE] ?? 0;\n }\n\n min(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v < m) m = v;\n }\n return m;\n }\n\n max(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v > m) m = v;\n }\n return m;\n }\n}\n","import { Graphics, Container } from \"pixi.js\";\n\n/** Allocation-free pool of PixiJS Graphics objects for debug drawing. */\nexport class GraphicsPool {\n private pool: Graphics[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxSize: number;\n\n constructor(container: Container, maxSize = 256) {\n this.container = container;\n this.maxSize = maxSize;\n }\n\n /** Lazily create Graphics objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Graphics[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxSize; i++) {\n const g = new Graphics();\n g.visible = false;\n g.eventMode = \"none\";\n this.container.addChild(g);\n this.pool.push(g);\n }\n return this.pool;\n }\n\n /** Return the next available Graphics, or undefined if the pool is exhausted. */\n acquire(): Graphics | undefined {\n const pool = this.ensure();\n if (this.index >= pool.length) return undefined;\n const g = pool[this.index]!;\n g.visible = true;\n this.index++;\n return g;\n }\n\n /** Clear and hide all previously acquired graphics, reset index. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n const g = this.pool[i]!;\n g.clear();\n g.visible = false;\n g.position.set(0, 0);\n g.rotation = 0;\n g.scale.set(1, 1);\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const g of this.pool) {\n g.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import { Text, Container } from \"pixi.js\";\n\nconst LINE_HEIGHT = 16;\nconst FONT_SIZE = 14;\nconst PADDING = 4;\n\n/** Allocation-free pool of PixiJS Text objects for HUD debug lines. */\nexport class TextPool {\n private pool: Text[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxLines: number;\n\n constructor(container: Container, maxLines = 32) {\n this.container = container;\n this.maxLines = maxLines;\n }\n\n /** Lazily create Text objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Text[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxLines; i++) {\n const t = new Text({\n text: \"\",\n style: {\n fontFamily: \"monospace\",\n fontSize: FONT_SIZE,\n fill: 0xffffff,\n },\n });\n t.visible = false;\n t.eventMode = \"none\";\n this.container.addChild(t);\n this.pool.push(t);\n }\n return this.pool;\n }\n\n /** Show a text line at the next available slot. */\n addLine(text: string): void {\n const pool = this.ensure();\n if (this.index >= pool.length) return;\n const t = pool[this.index]!;\n t.text = text;\n t.visible = true;\n t.position.set(PADDING, PADDING + this.index * LINE_HEIGHT);\n this.index++;\n }\n\n /** Hide all lines and reset for the next frame. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n this.pool[i]!.visible = false;\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const t of this.pool) {\n t.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import type { WorldDebugApi, DebugGraphics } from \"./types.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** WorldDebugApi backed by a GraphicsPool. Contributor name is swapped per iteration. */\nexport class WorldDebugApiImpl implements WorldDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly pool: GraphicsPool,\n private readonly registry: DebugRegistryImpl,\n private readonly _camera: { zoom: number },\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawWorld). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n acquireGraphics(): DebugGraphics | undefined {\n return this.pool.acquire() as unknown as DebugGraphics | undefined;\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n\n get cameraZoom(): number {\n return this._camera.zoom;\n }\n}\n","import type { HudDebugApi } from \"./types.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** HudDebugApi backed by a TextPool. Contributor name is swapped per iteration. */\nexport class HudDebugApiImpl implements HudDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly textPool: TextPool,\n private readonly registry: DebugRegistryImpl,\n public readonly screenWidth: number,\n public readonly screenHeight: number,\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawHud). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n addLine(text: string): void {\n this.textPool.addLine(text);\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n}\n","import { System, Phase } from \"@yagejs/core\";\nimport type { Container } from \"pixi.js\";\nimport type { CameraComponent } from \"@yagejs/renderer\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport type { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport type { StatsStore } from \"./StatsStore.js\";\n\nexport interface DebugCameraAccessor {\n findCamera(): CameraComponent | undefined;\n viewportWidth: number;\n viewportHeight: number;\n}\n\n/** Renders all debug contributors. Runs after DisplaySystem in the Render phase. */\nexport class DebugRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = 9999;\n\n constructor(\n private readonly registry: DebugRegistryImpl,\n private readonly graphicsPool: GraphicsPool,\n private readonly textPool: TextPool,\n private readonly worldApi: WorldDebugApiImpl,\n private readonly hudApi: HudDebugApiImpl,\n private readonly stats: StatsStore,\n private readonly worldContainer: Container,\n private readonly hudContainer: Container,\n private readonly cameraAccessor: DebugCameraAccessor,\n ) {\n super();\n }\n\n update(dt: number): void {\n if (!this.registry.enabled) {\n this.worldContainer.visible = false;\n this.hudContainer.visible = false;\n return;\n }\n\n this.worldContainer.visible = true;\n this.hudContainer.visible = true;\n\n // Apply camera transform to the debug world container so that\n // world-space debug drawing (collision shapes, etc.) aligns with\n // the active scene's camera.\n this.syncWorldCamera();\n\n this.graphicsPool.resetFrame();\n this.textPool.resetFrame();\n\n for (const [name, contributor] of this.registry.contributors) {\n contributor.sample?.(this.stats, dt);\n\n if (contributor.drawWorld) {\n this.worldApi.setContributor(name);\n contributor.drawWorld(this.worldApi);\n }\n\n if (contributor.drawHud) {\n this.hudApi.setContributor(name);\n contributor.drawHud(this.hudApi);\n }\n }\n }\n\n private syncWorldCamera(): void {\n const cam = this.cameraAccessor.findCamera();\n if (!cam) {\n this.worldContainer.position.set(0, 0);\n this.worldContainer.scale.set(1, 1);\n this.worldContainer.rotation = 0;\n return;\n }\n\n const vw = this.cameraAccessor.viewportWidth;\n const vh = this.cameraAccessor.viewportHeight;\n const rotatedPos = cam.effectivePosition\n .scale(cam.zoom)\n .rotate(-cam.rotation);\n this.worldContainer.position.x = vw / 2 - rotatedPos.x;\n this.worldContainer.position.y = vh / 2 - rotatedPos.y;\n this.worldContainer.scale.set(cam.zoom);\n this.worldContainer.rotation = -cam.rotation;\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class FpsContributor implements DebugContributor {\n readonly name = \"fps\";\n readonly flags: readonly string[] = [];\n private stats: StatsApi | null = null;\n\n sample(stats: StatsApi, dt: number): void {\n this.stats = stats;\n if (dt > 0) stats.push(\"fps\", 1000 / dt);\n }\n\n drawHud(api: HudDebugApi): void {\n const avg = this.stats?.average(\"fps\") ?? 0;\n api.addLine(`FPS: ${Math.round(avg)}`);\n }\n}\n","import type { DebugContributor, HudDebugApi } from \"../types.js\";\nimport type { Inspector } from \"@yagejs/core\";\n\nexport class EntityCountContributor implements DebugContributor {\n readonly name = \"entities\";\n readonly flags: readonly string[] = [];\n\n constructor(private readonly inspector: Inspector) {}\n\n drawHud(api: HudDebugApi): void {\n const count = this.inspector.snapshot().entityCount;\n api.addLine(`Entities: ${count}`);\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class SystemTimingContributor implements DebugContributor {\n readonly name = \"timing\";\n readonly flags = [\"breakdown\"] as const;\n private stats: StatsApi | null = null;\n\n constructor(private readonly timings: Map<string, number>) {}\n\n sample(stats: StatsApi): void {\n this.stats = stats;\n for (const [name, ms] of this.timings) {\n stats.push(`system.${name}`, ms);\n }\n }\n\n drawHud(api: HudDebugApi): void {\n if (!this.stats) return;\n\n let total = 0;\n const entries: Array<[string, number]> = [];\n for (const name of this.timings.keys()) {\n const avg = this.stats.average(`system.${name}`);\n total += avg;\n entries.push([name, avg]);\n }\n\n api.addLine(`Systems: ${total.toFixed(2)}ms`);\n\n if (api.isFlagEnabled(\"breakdown\")) {\n entries.sort((a, b) => b[1] - a[1]);\n for (const [name, avg] of entries) {\n api.addLine(` ${name}: ${avg.toFixed(2)}ms`);\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/DebugPlugin.ts","../src/DebugClock.ts","../src/DebugRegistryImpl.ts","../src/DebugScene.ts","../src/StatsStore.ts","../src/GraphicsPool.ts","../src/TextPool.ts","../src/WorldDebugApiImpl.ts","../src/HudDebugApiImpl.ts","../src/DebugRenderSystem.ts","../src/contributors/FpsContributor.ts","../src/contributors/EntityCountContributor.ts","../src/contributors/SystemTimingContributor.ts"],"sourcesContent":["import {\n EventBusKey,\n GameLoopKey,\n InspectorKey,\n SceneManagerKey,\n} from \"@yagejs/core\";\nimport type {\n EngineContext,\n EventBus,\n EngineEvents,\n Plugin,\n SceneManager,\n System,\n SystemScheduler,\n} from \"@yagejs/core\";\nimport { DebugRegistryKey } from \"./types.js\";\nimport { CameraComponent, RendererKey } from \"@yagejs/renderer\";\nimport type { RendererPlugin, SceneRenderTreeProvider } from \"@yagejs/renderer\";\nimport { SceneRenderTreeProviderKey } from \"@yagejs/renderer\";\nimport type { Application, Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { DebugClockHost, IDebugClock } from \"./DebugClock.js\";\nimport { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport { DebugScene } from \"./DebugScene.js\";\nimport { StatsStore } from \"./StatsStore.js\";\nimport { GraphicsPool } from \"./GraphicsPool.js\";\nimport { TextPool } from \"./TextPool.js\";\nimport { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport { DebugRenderSystem } from \"./DebugRenderSystem.js\";\nimport { FpsContributor } from \"./contributors/FpsContributor.js\";\nimport { EntityCountContributor } from \"./contributors/EntityCountContributor.js\";\nimport { SystemTimingContributor } from \"./contributors/SystemTimingContributor.js\";\n\n/** Configuration for the DebugPlugin. */\nexport interface DebugConfig {\n /** Key code to toggle debug overlay. Default: \"Backquote\" */\n toggleKey?: string;\n /** Key code to advance one fixed-timestep frame while the debug clock is frozen. Default: \"Period\" */\n stepKey?: string;\n /** Max pooled Graphics objects. Default: 256 */\n maxGraphics?: number;\n /** Max HUD text lines. Default: 32 */\n maxHudLines?: number;\n /** Whether the overlay starts enabled. Default: false */\n startEnabled?: boolean;\n /** Initial flag overrides, keyed by \"contributorName.flagName\". */\n flags?: Record<string, boolean>;\n /**\n * If set, every scene's RNG is initialized with this seed instead of an\n * unspecified default. Use for deterministic E2E runs. Leave undefined for\n * normal debug builds so randomness behaves the same as in production.\n */\n deterministicSeed?: number;\n /**\n * If true, the engine boots with a paused Pixi ticker so no auto-frames\n * tick before user code can intervene — equivalent to calling\n * `inspector.time.freeze()` at frame zero, but applied during plugin\n * `install()` (before `loop.start()`). Use for deterministic E2E runs:\n * any later `engine.scenes.push(...)` resolves under frozen time, so\n * snapshots taken right after only depend on the explicit `time.step()`\n * calls — not on how many auto-frames slipped in between\n * `await engine.start()` and the test's first `freeze()`.\n */\n startFrozen?: boolean;\n}\n\nexport interface LayerTransformSnapshot {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n rotation: number;\n}\n\nexport interface CameraStackSnapshot {\n scene: string;\n name: string | undefined;\n priority: number;\n enabled: boolean;\n}\n\n/**\n * Renderer-aware diagnostics exposed through the inspector extension\n * namespace `debug`. Kept out of the core Inspector surface so the core\n * package stays renderer-agnostic while plugins can still publish optional\n * runtime helpers in a uniform way.\n */\nexport interface DebugDiagnostics {\n getLayerTransform(\n sceneName: string,\n layerName: string,\n ): LayerTransformSnapshot | undefined;\n getCameraStack(): CameraStackSnapshot[];\n}\n\n/**\n * Debug overlay plugin. Mounts a private `DebugScene` through\n * `SceneManager._mountDetached` so it goes through the same scoped-DI\n * lifecycle as stacked scenes (the renderer's `beforeEnter` hook creates\n * its render tree) while staying off the user-visible scene stack.\n */\nexport class DebugPlugin implements Plugin {\n readonly name = \"debug\";\n readonly version = \"3.0.0\";\n readonly dependencies = [\"renderer\"] as const;\n\n private readonly config: DebugConfig;\n private registry!: DebugRegistryImpl;\n private stats!: StatsStore;\n private graphicsPool: GraphicsPool | null = null;\n private textPool: TextPool | null = null;\n private worldApi: WorldDebugApiImpl | null = null;\n private hudApi: HudDebugApiImpl | null = null;\n private renderSystem: DebugRenderSystem | null = null;\n private systemTimings = new Map<string, number>();\n private originalUpdates = new Map<System, (dt: number) => void>();\n private keyListener: ((e: KeyboardEvent) => void) | null = null;\n private context!: EngineContext;\n private renderer!: RendererPlugin;\n private scheduler!: SystemScheduler;\n private sceneManager!: SceneManager;\n private debugScene: DebugScene | null = null;\n private provider: SceneRenderTreeProvider | null = null;\n private eventUnsubs: Array<() => void> = [];\n private clock: DebugClock | null = null;\n\n constructor(config?: DebugConfig) {\n this.config = config ?? {};\n }\n\n install(context: EngineContext): void {\n this.context = context;\n this.renderer = context.resolve(RendererKey);\n if (this.config.deterministicSeed !== undefined) {\n context\n .resolve(InspectorKey)\n .setDefaultSceneSeed(this.config.deterministicSeed);\n }\n if (this.config.startFrozen) {\n // Stop Pixi's ticker before `loop.start()` runs, so no frames tick\n // between `app.init()` (which auto-starts the ticker) and the user's\n // first `inspector.time.freeze()`. Without this, even the few auto-\n // frames that slip in between RendererPlugin install and user-space\n // `await engine.start()` resolution mutate physics / input clocks,\n // breaking bit-identical replay snapshots. The DebugClock created in\n // `onStart` will pick this up via its own `freeze()` call.\n this.renderer.application.stop();\n }\n\n this.registry = new DebugRegistryImpl();\n this.registry.enabled = this.config.startEnabled ?? false;\n\n if (this.config.flags) {\n for (const [key, value] of Object.entries(this.config.flags)) {\n const dot = key.indexOf(\".\");\n if (dot > 0) {\n this.registry.setFlag(key.slice(0, dot), key.slice(dot + 1), value);\n }\n }\n }\n\n this.stats = new StatsStore();\n\n context.register(DebugRegistryKey, this.registry);\n }\n\n registerSystems(scheduler: SystemScheduler): void {\n // DebugRenderSystem is registered lazily once the debug scene is ready —\n // its constructor needs the scene's layer containers.\n this.scheduler = scheduler;\n }\n\n async onStart(): Promise<void> {\n this.sceneManager = this.context.resolve(SceneManagerKey);\n const bus = this.context.resolve(EventBusKey) as EventBus<EngineEvents>;\n\n // Key listeners (toggle, manual-clock step)\n const toggleKey = this.config.toggleKey ?? \"Backquote\";\n const stepKey = this.config.stepKey ?? \"Period\";\n this.keyListener = (e: KeyboardEvent) => {\n if (e.code === toggleKey) {\n this.registry.toggle();\n return;\n }\n if (e.code === stepKey && this.clock?.isFrozen) {\n e.preventDefault();\n this.clock.step();\n }\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.keyListener);\n }\n\n // Instrument system timings — reuse the scheduler captured in\n // `registerSystems`, which ran before `onStart`.\n for (const system of this.scheduler.getAllSystems()) {\n if (system instanceof DebugRenderSystem) continue;\n const name = system.constructor.name;\n const original = system.update.bind(system);\n this.originalUpdates.set(system, original);\n system.update = (dt: number) => {\n const t0 = performance.now();\n original(dt);\n this.systemTimings.set(name, performance.now() - t0);\n };\n }\n\n // Built-in contributors\n const inspector = this.context.resolve(InspectorKey);\n this.registry.register(new FpsContributor());\n this.registry.register(new EntityCountContributor(inspector));\n this.registry.register(new SystemTimingContributor(this.systemTimings));\n\n // Manual clock for deterministic stepping. The host drives `app.ticker`\n // directly so a manual `step()` fires every ticker subscriber\n // (AnimatedSprite, pixi-filters, render, user `app.ticker.add` callbacks)\n // with the same synthetic dt as gameplay state.\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n this.clock = new DebugClock(createPixiTickerHost(app, gameLoop.fixedTimestep));\n inspector.attachTimeController(this.clock);\n inspector.setEventLogEnabled(true);\n this.attachToGlobal(this.clock);\n if (this.config.startFrozen) {\n // `install()` already called `app.stop()`. Run the clock's own\n // `freeze()` now to take ownership: it captures `minFPS`, zeroes\n // `syntheticTime` / `lastTime`, and flips `_isFrozen` so the public\n // `inspector.time.isFrozen()` reflects reality without a redundant\n // freeze cycle from the caller.\n this.clock.freeze();\n }\n\n // Materialize the debug scene off-stack. `_mountDetached` routes through\n // the same beforeEnter hooks as `push`, so the renderer materializes the\n // debug scene's tree and registers SceneRenderTreeKey on its scope.\n this.provider = this.context.tryResolve(SceneRenderTreeProviderKey) ?? null;\n this.registerInspectorDiagnostics();\n await this.materializeDebugScene();\n\n // Keep the debug scene visually on top of the user stack after any\n // push/pop/replace by reordering its root containers.\n const bringToFront = () => {\n if (this.debugScene && this.provider?.bringSceneToFront) {\n this.provider.bringSceneToFront(this.debugScene);\n }\n };\n this.eventUnsubs.push(bus.on(\"scene:pushed\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:popped\", bringToFront));\n this.eventUnsubs.push(bus.on(\"scene:replaced\", bringToFront));\n }\n\n onDestroy(): void {\n for (const unsub of this.eventUnsubs) unsub();\n this.eventUnsubs.length = 0;\n\n for (const [system, original] of this.originalUpdates) {\n system.update = original;\n }\n this.originalUpdates.clear();\n\n if (this.keyListener) {\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.keyListener);\n }\n this.keyListener = null;\n }\n\n this.detachFromGlobal();\n const inspector = this.context.resolve(InspectorKey);\n inspector.removeExtension(\"debug\");\n // Only detach our own clock — passing undefined would clear whatever\n // controller is registered, which could belong to another plugin if\n // onDestroy runs after a failed onStart.\n if (this.clock) {\n inspector.detachTimeController(this.clock);\n }\n inspector.setEventLogEnabled(false);\n if (this.config.deterministicSeed !== undefined) {\n inspector.setDefaultSceneSeed(undefined);\n }\n this.clock = null;\n\n for (const contributor of this.registry.contributors.values()) {\n contributor.dispose?.();\n }\n this.registry.contributors.clear();\n\n this.tearDownDebugInfra();\n this.teardownDebugScene();\n }\n\n private async materializeDebugScene(): Promise<void> {\n const scene = new DebugScene();\n scene.onReady = (worldContainer, hudContainer) =>\n this.setUpDebugInfra(worldContainer, hudContainer);\n scene.onTearDown = () => this.tearDownDebugInfra();\n await this.sceneManager._mountDetached(scene);\n this.debugScene = scene;\n }\n\n private teardownDebugScene(): void {\n // If destroy is called while `_mountDetached` is still pending, we don't\n // yet hold a reference to the partially-mounted scene. Skipping unmount\n // here is safe: onDestroy still runs `tearDownDebugInfra` below, and the\n // engine teardown tears down the renderer next which destroys any\n // half-created provider entries.\n if (!this.debugScene) return;\n this.sceneManager._unmountDetached(this.debugScene);\n this.debugScene = null;\n this.provider = null;\n }\n\n private findActiveCamera(): CameraComponent | undefined {\n return findTopmostCamera(this.sceneManager);\n }\n\n private setUpDebugInfra(\n worldContainer: Container,\n hudContainer: Container,\n ): void {\n const vw = this.renderer.virtualSize.width;\n const vh = this.renderer.virtualSize.height;\n\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n // Lazy camera accessor — reads from whichever stacked scene has a camera\n const cameraProxy = {\n get zoom() {\n return self.findActiveCamera()?.zoom ?? 1;\n },\n };\n\n this.graphicsPool = new GraphicsPool(\n worldContainer,\n this.config.maxGraphics,\n );\n this.textPool = new TextPool(hudContainer, this.config.maxHudLines);\n\n this.worldApi = new WorldDebugApiImpl(\n this.graphicsPool,\n this.registry,\n cameraProxy,\n );\n this.hudApi = new HudDebugApiImpl(this.textPool, this.registry, vw, vh);\n\n this.renderSystem = new DebugRenderSystem(\n this.registry,\n this.graphicsPool,\n this.textPool,\n this.worldApi,\n this.hudApi,\n this.stats,\n worldContainer,\n hudContainer,\n {\n findCamera: () => self.findActiveCamera(),\n viewportWidth: vw,\n viewportHeight: vh,\n },\n );\n this.scheduler.add(this.renderSystem);\n }\n\n private tearDownDebugInfra(): void {\n if (this.renderSystem) {\n this.scheduler.remove(this.renderSystem);\n this.renderSystem = null;\n }\n this.graphicsPool?.destroy();\n this.textPool?.destroy();\n this.graphicsPool = null;\n this.textPool = null;\n this.worldApi = null;\n this.hudApi = null;\n }\n\n private registerInspectorDiagnostics(): void {\n const diagnostics: DebugDiagnostics = {\n getLayerTransform: (sceneName, layerName) => {\n const scene = this.sceneManager.all.find(\n (candidate) => candidate.name === sceneName,\n );\n if (!scene) return undefined;\n\n const layer = this.provider?.getTree(scene)?.tryGet(layerName);\n if (!layer) return undefined;\n\n const container = layer.container;\n return {\n x: container.position.x,\n y: container.position.y,\n scaleX: container.scale.x,\n scaleY: container.scale.y,\n rotation: container.rotation,\n };\n },\n getCameraStack: () => {\n const cameras: CameraStackSnapshot[] = [];\n for (const scene of this.sceneManager.all) {\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (!cam) continue;\n cameras.push({\n scene: scene.name,\n name: cam.cameraName,\n priority: cam.priority,\n enabled: cam.enabled,\n });\n }\n }\n return cameras;\n },\n };\n this.context.resolve(InspectorKey).addExtension(\"debug\", diagnostics);\n }\n\n private attachToGlobal(clock: IDebugClock): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (g && typeof g === \"object\") {\n (g as Record<string, unknown>)[\"clock\"] = clock;\n }\n }\n\n private detachFromGlobal(): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (\n g &&\n typeof g === \"object\" &&\n (g as Record<string, unknown>)[\"clock\"] === this.clock\n ) {\n delete (g as Record<string, unknown>)[\"clock\"];\n }\n }\n}\n\n/**\n * Wire a `DebugClockHost` against a Pixi v8 `Application`. Driving\n * `app.ticker.update(syntheticTime)` while the ticker is stopped fires every\n * subscriber — Pixi's `Ticker.update` doesn't gate on `started`, only the\n * rAF-driven `_tick` does — so a single advance replaces the old\n * `gameLoop.tick(dt)` + `app.render()` quad and along the way fixes the\n * AnimatedSprite / pixi-filters / `app.ticker.add` subscriber freeze.\n */\nfunction createPixiTickerHost(\n app: Application,\n fixedTimestep: number,\n): DebugClockHost {\n let syntheticTime = 0;\n let savedMinFPS: number | null = null;\n return {\n fixedTimestep,\n freeze(): void {\n app.stop();\n // Reset both to zero so synthetic time starts from a clean origin\n // and `(syntheticTime + dt) - syntheticTime` stays an exact `dt`\n // — keeps deltaMS deterministic regardless of how long the page\n // ran in auto mode before the freeze.\n syntheticTime = 0;\n app.ticker.lastTime = 0;\n // Default minFPS=10 clamps deltaMS at 100ms — `step(200)` would\n // silently see deltaMS=100. Disable for the duration of the freeze.\n savedMinFPS = app.ticker.minFPS;\n app.ticker.minFPS = 0;\n },\n thaw(): void {\n if (savedMinFPS !== null) {\n app.ticker.minFPS = savedMinFPS;\n savedMinFPS = null;\n }\n // `app.start()` calls `Ticker._requestIfNeeded` which resets\n // `lastTime` to `performance.now()` itself, so the next rAF\n // doesn't see `realNow - 0` as a giant first-frame delta. No\n // need to set it manually here.\n app.start();\n },\n advance(dtMs: number): void {\n syntheticTime += dtMs;\n app.ticker.update(syntheticTime);\n },\n };\n}\n\n/**\n * Find the highest-priority enabled camera on the topmost scene that has one.\n * `sceneManager.all` is bottom→top, so we walk in reverse — a pause/HUD\n * scene's camera wins over a frozen scene beneath it.\n */\nexport function findTopmostCamera(\n sceneManager: SceneManager,\n): CameraComponent | undefined {\n const stack = sceneManager.all;\n for (let i = stack.length - 1; i >= 0; i--) {\n const scene = stack[i];\n if (!scene) continue;\n let highestPriorityCamera: CameraComponent | undefined;\n for (const entity of scene.getEntities()) {\n const cam = entity.tryGet(CameraComponent);\n if (\n cam &&\n cam.enabled &&\n (!highestPriorityCamera ||\n cam.priority > highestPriorityCamera.priority)\n ) {\n highestPriorityCamera = cam;\n }\n }\n if (highestPriorityCamera) return highestPriorityCamera;\n }\n return undefined;\n}\n","/** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */\nexport interface IDebugClock {\n readonly isFrozen: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n freeze(): void;\n thaw(): void;\n setDelta(ms: number): void;\n getFrame(): number;\n}\n\n/**\n * Hooks the clock uses to drive the host. The host owns the synthetic-time\n * bookkeeping and the ticker plumbing — `DebugClock` stays a pure state\n * machine. Production wires this against Pixi's `app.ticker` so a manual\n * `step()` fires every ticker subscriber (GameLoop, AnimatedSprite,\n * pixi-filters, render) with the same synthetic dt.\n */\nexport interface DebugClockHost {\n readonly fixedTimestep: number;\n /** Advance one synthetic frame of `dtMs`. Fires every ticker subscriber. */\n advance(dtMs: number): void;\n /** Stop auto-advance. Capture state needed to make `advance` deterministic. */\n freeze(): void;\n /** Resume auto-advance. Restore captured state so the next rAF is sane. */\n thaw(): void;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * While frozen the renderer ticker is paused and frames advance only via\n * explicit `step()` / `stepFrames()` calls. `freeze()` / `thaw()` and\n * `startAuto()` / `stopAuto()` are equivalent verbs for the same toggle.\n */\nexport class DebugClock implements IDebugClock {\n private _isFrozen = false;\n private deltaMs: number;\n private frame = 0;\n\n constructor(private readonly host: DebugClockHost) {\n this.deltaMs = host.fixedTimestep;\n }\n\n get isFrozen(): boolean {\n return this._isFrozen;\n }\n\n startAuto(): void {\n if (!this._isFrozen) return;\n this.host.thaw();\n this._isFrozen = false;\n }\n\n stopAuto(): void {\n if (this._isFrozen) return;\n this.host.freeze();\n this._isFrozen = true;\n }\n\n freeze(): void {\n this.stopAuto();\n }\n\n thaw(): void {\n this.startAuto();\n }\n\n setDelta(ms: number): void {\n if (!Number.isFinite(ms) || ms <= 0) {\n throw new Error(\"DebugClock.setDelta(ms) requires a positive number.\");\n }\n this.deltaMs = ms;\n }\n\n getFrame(): number {\n return this.frame;\n }\n\n step(dtMs?: number): void {\n if (!this._isFrozen) {\n throw new Error(\"DebugClock is not frozen. Call clock.freeze() first.\");\n }\n const dt = dtMs ?? this.deltaMs;\n if (!Number.isFinite(dt) || dt <= 0) {\n throw new Error(\"DebugClock.step(dtMs) requires a positive number.\");\n }\n // Increment after a successful advance — if a ticker subscriber throws\n // (system exception, render failure) the frame counter shouldn't advance\n // ahead of state.\n this.host.advance(dt);\n this.frame++;\n }\n\n stepFrames(count: number, dtMs?: number): void {\n if (!Number.isInteger(count) || count < 0) {\n throw new Error(\n \"stepFrames(count) requires a non-negative integer count.\",\n );\n }\n for (let i = 0; i < count; i++) {\n this.step(dtMs);\n }\n }\n}\n","import type { DebugContributor, DebugRegistry } from \"./types.js\";\n\n/** Concrete implementation of the DebugRegistry interface. */\nexport class DebugRegistryImpl implements DebugRegistry {\n readonly contributors = new Map<string, DebugContributor>();\n enabled = false;\n private flags = new Map<string, boolean>();\n\n register(contributor: DebugContributor): void {\n if (this.contributors.has(contributor.name)) return;\n this.contributors.set(contributor.name, contributor);\n for (const flag of contributor.flags) {\n this.flags.set(`${contributor.name}.${flag}`, true);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n isFlagEnabled(contributorName: string, flag: string): boolean {\n return this.flags.get(`${contributorName}.${flag}`) ?? true;\n }\n\n toggle(): void {\n this.enabled = !this.enabled;\n }\n\n toggleFlag(contributorName: string, flag: string): void {\n const key = `${contributorName}.${flag}`;\n this.flags.set(key, !(this.flags.get(key) ?? true));\n }\n\n setFlag(contributorName: string, flag: string, value: boolean): void {\n this.flags.set(`${contributorName}.${flag}`, value);\n }\n}\n","import { LoggerKey, Scene } from \"@yagejs/core\";\nimport type { Logger } from \"@yagejs/core\";\nimport type { LayerDef } from \"@yagejs/renderer\";\nimport { SceneRenderTreeKey } from \"@yagejs/renderer\";\nimport type { Container } from \"pixi.js\";\n\n/**\n * Scene mounted by the debug plugin via `SceneManager._mountDetached`.\n * Declares two layers:\n * - `\"debug-world\"` — world-space, rides the camera (for collision shapes).\n * - `\"debug-hud\"` — screen-space, fixed overlay (text readouts).\n *\n * `pauseBelow: false` / `transparentBelow: true` so the underlying game\n * keeps running and rendering behind the overlay.\n */\nexport class DebugScene extends Scene {\n readonly name = \"__debug__\";\n override readonly pauseBelow = false;\n override readonly transparentBelow = true;\n readonly layers: readonly LayerDef[] = [\n { name: \"debug-world\", order: 999999 },\n { name: \"debug-hud\", order: 999999 },\n ];\n\n /** Called after `_mountDetached` has materialized the render tree. */\n onReady?: (worldContainer: Container, hudContainer: Container) => void;\n\n /** Called by the plugin when the scene is unmounted. */\n onTearDown?: () => void;\n\n onEnter(): void {\n const tree = this._resolveScoped(SceneRenderTreeKey);\n if (!tree) {\n // Shouldn't happen — DebugPlugin declares `renderer` as a dependency\n // so the renderer's `beforeEnter` hook should have materialized a\n // tree before this runs. Surface it rather than silently skipping\n // the overlay wiring.\n const logger = this.context.tryResolve(LoggerKey) as Logger | undefined;\n const msg =\n \"DebugScene.onEnter: SceneRenderTreeKey missing — debug overlay will not render. Is RendererPlugin registered?\";\n if (logger) logger.warn(\"debug\", msg);\n else console.warn(`[yage] ${msg}`);\n return;\n }\n const worldContainer = tree.get(\"debug-world\").container;\n const hudContainer = tree.get(\"debug-hud\").container;\n worldContainer.eventMode = \"none\";\n hudContainer.eventMode = \"none\";\n this.onReady?.(worldContainer, hudContainer);\n }\n\n onExit(): void {\n this.onTearDown?.();\n }\n}\n","import type { StatsApi } from \"./types.js\";\n\nconst WINDOW_SIZE = 120;\n\ninterface RingBuffer {\n data: Float64Array;\n count: number;\n index: number;\n}\n\n/** Rolling-window statistics store backed by Float64Array ring buffers. */\nexport class StatsStore implements StatsApi {\n private rings = new Map<string, RingBuffer>();\n\n push(key: string, value: number): void {\n let ring = this.rings.get(key);\n if (!ring) {\n ring = { data: new Float64Array(WINDOW_SIZE), count: 0, index: 0 };\n this.rings.set(key, ring);\n }\n ring.data[ring.index] = value;\n ring.index = (ring.index + 1) % WINDOW_SIZE;\n if (ring.count < WINDOW_SIZE) ring.count++;\n }\n\n average(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let sum = 0;\n for (let i = 0; i < count; i++) sum += data[i] ?? 0;\n return sum / count;\n }\n\n latest(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n return ring.data[(ring.index - 1 + WINDOW_SIZE) % WINDOW_SIZE] ?? 0;\n }\n\n min(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v < m) m = v;\n }\n return m;\n }\n\n max(key: string): number {\n const ring = this.rings.get(key);\n if (!ring || ring.count === 0) return 0;\n const { data, count } = ring;\n let m = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = data[i] ?? 0;\n if (v > m) m = v;\n }\n return m;\n }\n}\n","import { Graphics, Container } from \"pixi.js\";\n\n/** Allocation-free pool of PixiJS Graphics objects for debug drawing. */\nexport class GraphicsPool {\n private pool: Graphics[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxSize: number;\n\n constructor(container: Container, maxSize = 256) {\n this.container = container;\n this.maxSize = maxSize;\n }\n\n /** Lazily create Graphics objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Graphics[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxSize; i++) {\n const g = new Graphics();\n g.visible = false;\n g.eventMode = \"none\";\n this.container.addChild(g);\n this.pool.push(g);\n }\n return this.pool;\n }\n\n /** Return the next available Graphics, or undefined if the pool is exhausted. */\n acquire(): Graphics | undefined {\n const pool = this.ensure();\n if (this.index >= pool.length) return undefined;\n const g = pool[this.index]!;\n g.visible = true;\n this.index++;\n return g;\n }\n\n /** Clear and hide all previously acquired graphics, reset index. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n const g = this.pool[i]!;\n g.clear();\n g.visible = false;\n g.position.set(0, 0);\n g.rotation = 0;\n g.scale.set(1, 1);\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const g of this.pool) {\n g.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import { Text, Container } from \"pixi.js\";\n\nconst LINE_HEIGHT = 16;\nconst FONT_SIZE = 14;\nconst PADDING = 4;\n\n/** Allocation-free pool of PixiJS Text objects for HUD debug lines. */\nexport class TextPool {\n private pool: Text[] | null = null;\n private index = 0;\n private readonly container: Container;\n private readonly maxLines: number;\n\n constructor(container: Container, maxLines = 32) {\n this.container = container;\n this.maxLines = maxLines;\n }\n\n /** Lazily create Text objects on first use (ensures PixiJS is fully ready). */\n private ensure(): Text[] {\n if (this.pool) return this.pool;\n this.pool = [];\n for (let i = 0; i < this.maxLines; i++) {\n const t = new Text({\n text: \"\",\n style: {\n fontFamily: \"monospace\",\n fontSize: FONT_SIZE,\n fill: 0xffffff,\n },\n });\n t.visible = false;\n t.eventMode = \"none\";\n this.container.addChild(t);\n this.pool.push(t);\n }\n return this.pool;\n }\n\n /** Show a text line at the next available slot. */\n addLine(text: string): void {\n const pool = this.ensure();\n if (this.index >= pool.length) return;\n const t = pool[this.index]!;\n t.text = text;\n t.visible = true;\n t.position.set(PADDING, PADDING + this.index * LINE_HEIGHT);\n this.index++;\n }\n\n /** Hide all lines and reset for the next frame. */\n resetFrame(): void {\n if (!this.pool) return;\n for (let i = 0; i < this.index; i++) {\n this.pool[i]!.visible = false;\n }\n this.index = 0;\n }\n\n destroy(): void {\n if (!this.pool) return;\n for (const t of this.pool) {\n t.destroy();\n }\n this.pool.length = 0;\n }\n}\n","import type { WorldDebugApi, DebugGraphics } from \"./types.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** WorldDebugApi backed by a GraphicsPool. Contributor name is swapped per iteration. */\nexport class WorldDebugApiImpl implements WorldDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly pool: GraphicsPool,\n private readonly registry: DebugRegistryImpl,\n private readonly _camera: { zoom: number },\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawWorld). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n acquireGraphics(): DebugGraphics | undefined {\n return this.pool.acquire() as unknown as DebugGraphics | undefined;\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n\n get cameraZoom(): number {\n return this._camera.zoom;\n }\n}\n","import type { HudDebugApi } from \"./types.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\n\n/** HudDebugApi backed by a TextPool. Contributor name is swapped per iteration. */\nexport class HudDebugApiImpl implements HudDebugApi {\n private _contributorName = \"\";\n\n constructor(\n private readonly textPool: TextPool,\n private readonly registry: DebugRegistryImpl,\n public readonly screenWidth: number,\n public readonly screenHeight: number,\n ) {}\n\n /** Set the current contributor name (called before each contributor's drawHud). */\n setContributor(name: string): void {\n this._contributorName = name;\n }\n\n addLine(text: string): void {\n this.textPool.addLine(text);\n }\n\n isFlagEnabled(flag: string): boolean {\n return this.registry.isFlagEnabled(this._contributorName, flag);\n }\n}\n","import { System, Phase } from \"@yagejs/core\";\nimport type { Container } from \"pixi.js\";\nimport type { CameraComponent } from \"@yagejs/renderer\";\nimport type { DebugRegistryImpl } from \"./DebugRegistryImpl.js\";\nimport type { GraphicsPool } from \"./GraphicsPool.js\";\nimport type { TextPool } from \"./TextPool.js\";\nimport type { WorldDebugApiImpl } from \"./WorldDebugApiImpl.js\";\nimport type { HudDebugApiImpl } from \"./HudDebugApiImpl.js\";\nimport type { StatsStore } from \"./StatsStore.js\";\n\nexport interface DebugCameraAccessor {\n findCamera(): CameraComponent | undefined;\n viewportWidth: number;\n viewportHeight: number;\n}\n\n/** Renders all debug contributors. Runs after DisplaySystem in the Render phase. */\nexport class DebugRenderSystem extends System {\n readonly phase = Phase.Render;\n readonly priority = 9999;\n\n constructor(\n private readonly registry: DebugRegistryImpl,\n private readonly graphicsPool: GraphicsPool,\n private readonly textPool: TextPool,\n private readonly worldApi: WorldDebugApiImpl,\n private readonly hudApi: HudDebugApiImpl,\n private readonly stats: StatsStore,\n private readonly worldContainer: Container,\n private readonly hudContainer: Container,\n private readonly cameraAccessor: DebugCameraAccessor,\n ) {\n super();\n }\n\n update(dt: number): void {\n if (!this.registry.enabled) {\n this.worldContainer.visible = false;\n this.hudContainer.visible = false;\n return;\n }\n\n this.worldContainer.visible = true;\n this.hudContainer.visible = true;\n\n // Apply camera transform to the debug world container so that\n // world-space debug drawing (collision shapes, etc.) aligns with\n // the active scene's camera.\n this.syncWorldCamera();\n\n this.graphicsPool.resetFrame();\n this.textPool.resetFrame();\n\n for (const [name, contributor] of this.registry.contributors) {\n contributor.sample?.(this.stats, dt);\n\n if (contributor.drawWorld) {\n this.worldApi.setContributor(name);\n contributor.drawWorld(this.worldApi);\n }\n\n if (contributor.drawHud) {\n this.hudApi.setContributor(name);\n contributor.drawHud(this.hudApi);\n }\n }\n }\n\n private syncWorldCamera(): void {\n const cam = this.cameraAccessor.findCamera();\n if (!cam) {\n this.worldContainer.position.set(0, 0);\n this.worldContainer.scale.set(1, 1);\n this.worldContainer.rotation = 0;\n return;\n }\n\n const vw = this.cameraAccessor.viewportWidth;\n const vh = this.cameraAccessor.viewportHeight;\n const rotatedPos = cam.effectivePosition\n .scale(cam.zoom)\n .rotate(-cam.rotation);\n this.worldContainer.position.x = vw / 2 - rotatedPos.x;\n this.worldContainer.position.y = vh / 2 - rotatedPos.y;\n this.worldContainer.scale.set(cam.zoom);\n this.worldContainer.rotation = -cam.rotation;\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class FpsContributor implements DebugContributor {\n readonly name = \"fps\";\n readonly flags: readonly string[] = [];\n private stats: StatsApi | null = null;\n\n sample(stats: StatsApi, dt: number): void {\n this.stats = stats;\n if (dt > 0) stats.push(\"fps\", 1000 / dt);\n }\n\n drawHud(api: HudDebugApi): void {\n const avg = this.stats?.average(\"fps\") ?? 0;\n api.addLine(`FPS: ${Math.round(avg)}`);\n }\n}\n","import type { DebugContributor, HudDebugApi } from \"../types.js\";\nimport type { Inspector } from \"@yagejs/core\";\n\nexport class EntityCountContributor implements DebugContributor {\n readonly name = \"entities\";\n readonly flags: readonly string[] = [];\n\n constructor(private readonly inspector: Inspector) {}\n\n drawHud(api: HudDebugApi): void {\n const count = this.inspector.snapshot().entityCount;\n api.addLine(`Entities: ${count}`);\n }\n}\n","import type { DebugContributor, StatsApi, HudDebugApi } from \"../types.js\";\n\nexport class SystemTimingContributor implements DebugContributor {\n readonly name = \"timing\";\n readonly flags = [\"breakdown\"] as const;\n private stats: StatsApi | null = null;\n\n constructor(private readonly timings: Map<string, number>) {}\n\n sample(stats: StatsApi): void {\n this.stats = stats;\n for (const [name, ms] of this.timings) {\n stats.push(`system.${name}`, ms);\n }\n }\n\n drawHud(api: HudDebugApi): void {\n if (!this.stats) return;\n\n let total = 0;\n const entries: Array<[string, number]> = [];\n for (const name of this.timings.keys()) {\n const avg = this.stats.average(`system.${name}`);\n total += avg;\n entries.push([name, avg]);\n }\n\n api.addLine(`Systems: ${total.toFixed(2)}ms`);\n\n if (api.isFlagEnabled(\"breakdown\")) {\n entries.sort((a, b) => b[1] - a[1]);\n for (const [name, avg] of entries) {\n api.addLine(` ${name}: ${avg.toFixed(2)}ms`);\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yagejs/debug",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "FPS counter, entity inspector, and dev overlays for YAGE",
5
5
  "keywords": [
6
6
  "yage",
@@ -58,8 +58,8 @@
58
58
  "clean": "rm -rf dist"
59
59
  },
60
60
  "dependencies": {
61
- "@yagejs/core": "^0.4.0",
62
- "@yagejs/renderer": "^0.4.0",
61
+ "@yagejs/core": "^0.6.0",
62
+ "@yagejs/renderer": "^0.6.0",
63
63
  "pixi.js": "^8.5.0"
64
64
  }
65
65
  }