@yagejs/debug 0.3.0 → 0.5.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
@@ -40,42 +40,55 @@ var import_renderer3 = require("@yagejs/renderer");
40
40
 
41
41
  // src/DebugClock.ts
42
42
  var DebugClock = class {
43
- constructor(gameLoop, stopTicker, startTicker, render) {
44
- this.gameLoop = gameLoop;
45
- this.stopTicker = stopTicker;
46
- this.startTicker = startTicker;
47
- this.render = render;
48
- }
49
- gameLoop;
50
- stopTicker;
51
- startTicker;
52
- render;
43
+ constructor(host) {
44
+ this.host = host;
45
+ this.deltaMs = host.fixedTimestep;
46
+ }
47
+ host;
53
48
  static {
54
49
  __name(this, "DebugClock");
55
50
  }
56
- _isManual = false;
57
- get isManual() {
58
- return this._isManual;
51
+ _isFrozen = false;
52
+ deltaMs;
53
+ frame = 0;
54
+ get isFrozen() {
55
+ return this._isFrozen;
59
56
  }
60
57
  startAuto() {
61
- if (!this._isManual) return;
62
- this.startTicker();
63
- this._isManual = false;
58
+ if (!this._isFrozen) return;
59
+ this.host.thaw();
60
+ this._isFrozen = false;
64
61
  }
65
62
  stopAuto() {
66
- if (this._isManual) return;
67
- this.stopTicker();
68
- this._isManual = true;
63
+ if (this._isFrozen) return;
64
+ this.host.freeze();
65
+ this._isFrozen = true;
66
+ }
67
+ freeze() {
68
+ this.stopAuto();
69
+ }
70
+ thaw() {
71
+ this.startAuto();
72
+ }
73
+ setDelta(ms) {
74
+ if (!Number.isFinite(ms) || ms <= 0) {
75
+ throw new Error("DebugClock.setDelta(ms) requires a positive number.");
76
+ }
77
+ this.deltaMs = ms;
78
+ }
79
+ getFrame() {
80
+ return this.frame;
69
81
  }
70
82
  step(dtMs) {
71
- if (!this._isManual) {
72
- throw new Error(
73
- "Manual clock is not active. Call clock.stopAuto() first."
74
- );
83
+ if (!this._isFrozen) {
84
+ throw new Error("DebugClock is not frozen. Call clock.freeze() first.");
85
+ }
86
+ const dt = dtMs ?? this.deltaMs;
87
+ if (!Number.isFinite(dt) || dt <= 0) {
88
+ throw new Error("DebugClock.step(dtMs) requires a positive number.");
75
89
  }
76
- const dt = dtMs ?? this.gameLoop.fixedTimestep;
77
- this.gameLoop.tick(dt);
78
- this.render();
90
+ this.host.advance(dt);
91
+ this.frame++;
79
92
  }
80
93
  stepFrames(count, dtMs) {
81
94
  if (!Number.isInteger(count) || count < 0) {
@@ -87,16 +100,6 @@ var DebugClock = class {
87
100
  this.step(dtMs);
88
101
  }
89
102
  }
90
- /** Enter or exit manual mode. Used by DebugPlugin for config-driven init. */
91
- setManual(enabled) {
92
- if (enabled === this._isManual) return;
93
- if (enabled) {
94
- this.stopTicker();
95
- } else {
96
- this.startTicker();
97
- }
98
- this._isManual = enabled;
99
- }
100
103
  };
101
104
 
102
105
  // src/DebugRegistryImpl.ts
@@ -578,6 +581,12 @@ var DebugPlugin = class {
578
581
  install(context) {
579
582
  this.context = context;
580
583
  this.renderer = context.resolve(import_renderer2.RendererKey);
584
+ if (this.config.deterministicSeed !== void 0) {
585
+ context.resolve(import_core4.InspectorKey).setDefaultSceneSeed(this.config.deterministicSeed);
586
+ }
587
+ if (this.config.startFrozen) {
588
+ this.renderer.application.stop();
589
+ }
581
590
  this.registry = new DebugRegistryImpl();
582
591
  this.registry.enabled = this.config.startEnabled ?? false;
583
592
  if (this.config.flags) {
@@ -604,7 +613,7 @@ var DebugPlugin = class {
604
613
  this.registry.toggle();
605
614
  return;
606
615
  }
607
- if (e.code === stepKey && this.clock?.isManual) {
616
+ if (e.code === stepKey && this.clock?.isFrozen) {
608
617
  e.preventDefault();
609
618
  this.clock.step();
610
619
  }
@@ -629,18 +638,15 @@ var DebugPlugin = class {
629
638
  this.registry.register(new SystemTimingContributor(this.systemTimings));
630
639
  const gameLoop = this.context.resolve(import_core4.GameLoopKey);
631
640
  const app = this.renderer.application;
632
- this.clock = new DebugClock(
633
- gameLoop,
634
- () => app.stop(),
635
- () => app.start(),
636
- () => app.render()
637
- );
638
- if (this.config.manualClock) {
639
- this.clock.setManual(true);
640
- }
641
+ this.clock = new DebugClock(createPixiTickerHost(app, gameLoop.fixedTimestep));
642
+ inspector.attachTimeController(this.clock);
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
- this.attachInspectorDiagnostics(inspector);
649
+ this.registerInspectorDiagnostics();
644
650
  await this.materializeDebugScene();
645
651
  const bringToFront = /* @__PURE__ */ __name(() => {
646
652
  if (this.debugScene && this.provider?.bringSceneToFront) {
@@ -665,6 +671,15 @@ var DebugPlugin = class {
665
671
  this.keyListener = null;
666
672
  }
667
673
  this.detachFromGlobal();
674
+ const inspector = this.context.resolve(import_core4.InspectorKey);
675
+ inspector.removeExtension("debug");
676
+ if (this.clock) {
677
+ inspector.detachTimeController(this.clock);
678
+ }
679
+ inspector.setEventLogEnabled(false);
680
+ if (this.config.deterministicSeed !== void 0) {
681
+ inspector.setDefaultSceneSeed(void 0);
682
+ }
668
683
  this.clock = null;
669
684
  for (const contributor of this.registry.contributors.values()) {
670
685
  contributor.dispose?.();
@@ -738,44 +753,42 @@ var DebugPlugin = class {
738
753
  this.worldApi = null;
739
754
  this.hudApi = null;
740
755
  }
741
- attachInspectorDiagnostics(inspector) {
742
- const g = globalThis["__yage__"];
743
- if (!g || typeof g !== "object") return;
744
- const debugSurface = g;
745
- const diagnostics = inspector;
746
- debugSurface["inspector"] = inspector;
747
- diagnostics.getLayerTransform = (sceneName, layerName) => {
748
- const scene = this.sceneManager.all.find(
749
- (candidate) => candidate.name === sceneName
750
- );
751
- if (!scene) return void 0;
752
- const layer = this.provider?.getTree(scene)?.tryGet(layerName);
753
- if (!layer) return void 0;
754
- const container = layer.container;
755
- return {
756
- x: container.position.x,
757
- y: container.position.y,
758
- scaleX: container.scale.x,
759
- scaleY: container.scale.y,
760
- rotation: container.rotation
761
- };
762
- };
763
- diagnostics.getCameraStack = () => {
764
- const cameras = [];
765
- for (const scene of this.sceneManager.all) {
766
- for (const entity of scene.getEntities()) {
767
- const cam = entity.tryGet(import_renderer2.CameraComponent);
768
- if (!cam) continue;
769
- cameras.push({
770
- scene: scene.name,
771
- name: cam.cameraName,
772
- priority: cam.priority,
773
- enabled: cam.enabled
774
- });
756
+ registerInspectorDiagnostics() {
757
+ const diagnostics = {
758
+ getLayerTransform: /* @__PURE__ */ __name((sceneName, layerName) => {
759
+ const scene = this.sceneManager.all.find(
760
+ (candidate) => candidate.name === sceneName
761
+ );
762
+ if (!scene) return void 0;
763
+ const layer = this.provider?.getTree(scene)?.tryGet(layerName);
764
+ if (!layer) return void 0;
765
+ const container = layer.container;
766
+ return {
767
+ x: container.position.x,
768
+ y: container.position.y,
769
+ scaleX: container.scale.x,
770
+ scaleY: container.scale.y,
771
+ rotation: container.rotation
772
+ };
773
+ }, "getLayerTransform"),
774
+ getCameraStack: /* @__PURE__ */ __name(() => {
775
+ const cameras = [];
776
+ for (const scene of this.sceneManager.all) {
777
+ for (const entity of scene.getEntities()) {
778
+ const cam = entity.tryGet(import_renderer2.CameraComponent);
779
+ if (!cam) continue;
780
+ cameras.push({
781
+ scene: scene.name,
782
+ name: cam.cameraName,
783
+ priority: cam.priority,
784
+ enabled: cam.enabled
785
+ });
786
+ }
775
787
  }
776
- }
777
- return cameras;
788
+ return cameras;
789
+ }, "getCameraStack")
778
790
  };
791
+ this.context.resolve(import_core4.InspectorKey).addExtension("debug", diagnostics);
779
792
  }
780
793
  attachToGlobal(clock) {
781
794
  const g = globalThis["__yage__"];
@@ -790,6 +803,32 @@ var DebugPlugin = class {
790
803
  }
791
804
  }
792
805
  };
806
+ function createPixiTickerHost(app, fixedTimestep) {
807
+ let syntheticTime = 0;
808
+ let savedMinFPS = null;
809
+ return {
810
+ fixedTimestep,
811
+ freeze() {
812
+ app.stop();
813
+ syntheticTime = 0;
814
+ app.ticker.lastTime = 0;
815
+ savedMinFPS = app.ticker.minFPS;
816
+ app.ticker.minFPS = 0;
817
+ },
818
+ thaw() {
819
+ if (savedMinFPS !== null) {
820
+ app.ticker.minFPS = savedMinFPS;
821
+ savedMinFPS = null;
822
+ }
823
+ app.start();
824
+ },
825
+ advance(dtMs) {
826
+ syntheticTime += dtMs;
827
+ app.ticker.update(syntheticTime);
828
+ }
829
+ };
830
+ }
831
+ __name(createPixiTickerHost, "createPixiTickerHost");
793
832
  function findTopmostCamera(sceneManager) {
794
833
  const stack = sceneManager.all;
795
834
  for (let i = stack.length - 1; i >= 0; i--) {
@@ -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 { DebugConfig } 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 Inspector,\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 { Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { 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 /** When true, stop the renderer ticker and advance simulation manually via `window.__yage__.clock`. */\n manualClock?: boolean;\n /** Key code to advance one fixed-timestep frame while manual clock mode is active. 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\ninterface LayerTransformSnapshot {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n rotation: number;\n}\n\ninterface CameraStackSnapshot {\n scene: string;\n name: string | undefined;\n priority: number;\n enabled: boolean;\n}\n\ninterface InspectorDiagnostics {\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\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?.isManual) {\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\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n this.clock = new DebugClock(\n gameLoop,\n () => app.stop(),\n () => app.start(),\n () => app.render(),\n );\n if (this.config.manualClock) {\n this.clock.setManual(true);\n }\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.attachInspectorDiagnostics(inspector);\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 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 attachInspectorDiagnostics(inspector: Inspector): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (!g || typeof g !== \"object\") return;\n\n const debugSurface = g as Record<string, unknown>;\n const diagnostics = inspector as Inspector & InspectorDiagnostics;\n debugSurface[\"inspector\"] = inspector;\n\n diagnostics.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\n diagnostics.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\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 * 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 isManual: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n}\n\n/** Minimal view of a game loop needed by the debug clock. */\ninterface GameLoopLike {\n tick(dtMs: number): void;\n readonly fixedTimestep: number;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * When manual mode is active the renderer ticker is paused and frames\n * advance only via explicit `step()` / `stepFrames()` calls.\n */\nexport class DebugClock implements IDebugClock {\n private _isManual = false;\n\n constructor(\n private readonly gameLoop: GameLoopLike,\n private readonly stopTicker: () => void,\n private readonly startTicker: () => void,\n private readonly render: () => void,\n ) {}\n\n get isManual(): boolean {\n return this._isManual;\n }\n\n startAuto(): void {\n if (!this._isManual) return;\n this.startTicker();\n this._isManual = false;\n }\n\n stopAuto(): void {\n if (this._isManual) return;\n this.stopTicker();\n this._isManual = true;\n }\n\n step(dtMs?: number): void {\n if (!this._isManual) {\n throw new Error(\n \"Manual clock is not active. Call clock.stopAuto() first.\",\n );\n }\n const dt = dtMs ?? this.gameLoop.fixedTimestep;\n this.gameLoop.tick(dt);\n this.render();\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 /** Enter or exit manual mode. Used by DebugPlugin for config-driven init. */\n setManual(enabled: boolean): void {\n if (enabled === this._isManual) return;\n if (enabled) {\n this.stopTicker();\n } else {\n this.startTicker();\n }\n this._isManual = enabled;\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
@@ -5,9 +5,7 @@ import { DebugRegistry, DebugContributor, StatsApi } from './api.cjs';
5
5
  interface DebugConfig {
6
6
  /** Key code to toggle debug overlay. Default: "Backquote" */
7
7
  toggleKey?: string;
8
- /** When true, stop the renderer ticker and advance simulation manually via `window.__yage__.clock`. */
9
- manualClock?: boolean;
10
- /** Key code to advance one fixed-timestep frame while manual clock mode is active. Default: "Period" */
8
+ /** Key code to advance one fixed-timestep frame while the debug clock is frozen. Default: "Period" */
11
9
  stepKey?: string;
12
10
  /** Max pooled Graphics objects. Default: 256 */
13
11
  maxGraphics?: number;
@@ -17,6 +15,46 @@ interface DebugConfig {
17
15
  startEnabled?: boolean;
18
16
  /** Initial flag overrides, keyed by "contributorName.flagName". */
19
17
  flags?: Record<string, boolean>;
18
+ /**
19
+ * If set, every scene's RNG is initialized with this seed instead of an
20
+ * unspecified default. Use for deterministic E2E runs. Leave undefined for
21
+ * normal debug builds so randomness behaves the same as in production.
22
+ */
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;
35
+ }
36
+ interface LayerTransformSnapshot {
37
+ x: number;
38
+ y: number;
39
+ scaleX: number;
40
+ scaleY: number;
41
+ rotation: number;
42
+ }
43
+ interface CameraStackSnapshot {
44
+ scene: string;
45
+ name: string | undefined;
46
+ priority: number;
47
+ enabled: boolean;
48
+ }
49
+ /**
50
+ * Renderer-aware diagnostics exposed through the inspector extension
51
+ * namespace `debug`. Kept out of the core Inspector surface so the core
52
+ * package stays renderer-agnostic while plugins can still publish optional
53
+ * runtime helpers in a uniform way.
54
+ */
55
+ interface DebugDiagnostics {
56
+ getLayerTransform(sceneName: string, layerName: string): LayerTransformSnapshot | undefined;
57
+ getCameraStack(): CameraStackSnapshot[];
20
58
  }
21
59
  /**
22
60
  * Debug overlay plugin. Mounts a private `DebugScene` through
@@ -57,18 +95,22 @@ declare class DebugPlugin implements Plugin {
57
95
  private findActiveCamera;
58
96
  private setUpDebugInfra;
59
97
  private tearDownDebugInfra;
60
- private attachInspectorDiagnostics;
98
+ private registerInspectorDiagnostics;
61
99
  private attachToGlobal;
62
100
  private detachFromGlobal;
63
101
  }
64
102
 
65
103
  /** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */
66
104
  interface IDebugClock {
67
- readonly isManual: boolean;
105
+ readonly isFrozen: boolean;
68
106
  startAuto(): void;
69
107
  stopAuto(): void;
70
108
  step(dtMs?: number): void;
71
109
  stepFrames(count: number, dtMs?: number): void;
110
+ freeze(): void;
111
+ thaw(): void;
112
+ setDelta(ms: number): void;
113
+ getFrame(): number;
72
114
  }
73
115
 
74
116
  /** Concrete implementation of the DebugRegistry interface. */
@@ -94,4 +136,4 @@ declare class StatsStore implements StatsApi {
94
136
  max(key: string): number;
95
137
  }
96
138
 
97
- export { type DebugConfig, DebugPlugin, DebugRegistryImpl, type IDebugClock, StatsStore };
139
+ export { type CameraStackSnapshot, type DebugConfig, type DebugDiagnostics, DebugPlugin, DebugRegistryImpl, type IDebugClock, type LayerTransformSnapshot, StatsStore };
package/dist/index.d.ts CHANGED
@@ -5,9 +5,7 @@ import { DebugRegistry, DebugContributor, StatsApi } from './api.js';
5
5
  interface DebugConfig {
6
6
  /** Key code to toggle debug overlay. Default: "Backquote" */
7
7
  toggleKey?: string;
8
- /** When true, stop the renderer ticker and advance simulation manually via `window.__yage__.clock`. */
9
- manualClock?: boolean;
10
- /** Key code to advance one fixed-timestep frame while manual clock mode is active. Default: "Period" */
8
+ /** Key code to advance one fixed-timestep frame while the debug clock is frozen. Default: "Period" */
11
9
  stepKey?: string;
12
10
  /** Max pooled Graphics objects. Default: 256 */
13
11
  maxGraphics?: number;
@@ -17,6 +15,46 @@ interface DebugConfig {
17
15
  startEnabled?: boolean;
18
16
  /** Initial flag overrides, keyed by "contributorName.flagName". */
19
17
  flags?: Record<string, boolean>;
18
+ /**
19
+ * If set, every scene's RNG is initialized with this seed instead of an
20
+ * unspecified default. Use for deterministic E2E runs. Leave undefined for
21
+ * normal debug builds so randomness behaves the same as in production.
22
+ */
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;
35
+ }
36
+ interface LayerTransformSnapshot {
37
+ x: number;
38
+ y: number;
39
+ scaleX: number;
40
+ scaleY: number;
41
+ rotation: number;
42
+ }
43
+ interface CameraStackSnapshot {
44
+ scene: string;
45
+ name: string | undefined;
46
+ priority: number;
47
+ enabled: boolean;
48
+ }
49
+ /**
50
+ * Renderer-aware diagnostics exposed through the inspector extension
51
+ * namespace `debug`. Kept out of the core Inspector surface so the core
52
+ * package stays renderer-agnostic while plugins can still publish optional
53
+ * runtime helpers in a uniform way.
54
+ */
55
+ interface DebugDiagnostics {
56
+ getLayerTransform(sceneName: string, layerName: string): LayerTransformSnapshot | undefined;
57
+ getCameraStack(): CameraStackSnapshot[];
20
58
  }
21
59
  /**
22
60
  * Debug overlay plugin. Mounts a private `DebugScene` through
@@ -57,18 +95,22 @@ declare class DebugPlugin implements Plugin {
57
95
  private findActiveCamera;
58
96
  private setUpDebugInfra;
59
97
  private tearDownDebugInfra;
60
- private attachInspectorDiagnostics;
98
+ private registerInspectorDiagnostics;
61
99
  private attachToGlobal;
62
100
  private detachFromGlobal;
63
101
  }
64
102
 
65
103
  /** Public interface for the manual debug clock, accessible via `window.__yage__.clock`. */
66
104
  interface IDebugClock {
67
- readonly isManual: boolean;
105
+ readonly isFrozen: boolean;
68
106
  startAuto(): void;
69
107
  stopAuto(): void;
70
108
  step(dtMs?: number): void;
71
109
  stepFrames(count: number, dtMs?: number): void;
110
+ freeze(): void;
111
+ thaw(): void;
112
+ setDelta(ms: number): void;
113
+ getFrame(): number;
72
114
  }
73
115
 
74
116
  /** Concrete implementation of the DebugRegistry interface. */
@@ -94,4 +136,4 @@ declare class StatsStore implements StatsApi {
94
136
  max(key: string): number;
95
137
  }
96
138
 
97
- export { type DebugConfig, DebugPlugin, DebugRegistryImpl, type IDebugClock, StatsStore };
139
+ export { type CameraStackSnapshot, type DebugConfig, type DebugDiagnostics, DebugPlugin, DebugRegistryImpl, type IDebugClock, type LayerTransformSnapshot, StatsStore };
package/dist/index.js CHANGED
@@ -15,42 +15,55 @@ import { SceneRenderTreeProviderKey } from "@yagejs/renderer";
15
15
 
16
16
  // src/DebugClock.ts
17
17
  var DebugClock = class {
18
- constructor(gameLoop, stopTicker, startTicker, render) {
19
- this.gameLoop = gameLoop;
20
- this.stopTicker = stopTicker;
21
- this.startTicker = startTicker;
22
- this.render = render;
23
- }
24
- gameLoop;
25
- stopTicker;
26
- startTicker;
27
- render;
18
+ constructor(host) {
19
+ this.host = host;
20
+ this.deltaMs = host.fixedTimestep;
21
+ }
22
+ host;
28
23
  static {
29
24
  __name(this, "DebugClock");
30
25
  }
31
- _isManual = false;
32
- get isManual() {
33
- return this._isManual;
26
+ _isFrozen = false;
27
+ deltaMs;
28
+ frame = 0;
29
+ get isFrozen() {
30
+ return this._isFrozen;
34
31
  }
35
32
  startAuto() {
36
- if (!this._isManual) return;
37
- this.startTicker();
38
- this._isManual = false;
33
+ if (!this._isFrozen) return;
34
+ this.host.thaw();
35
+ this._isFrozen = false;
39
36
  }
40
37
  stopAuto() {
41
- if (this._isManual) return;
42
- this.stopTicker();
43
- this._isManual = true;
38
+ if (this._isFrozen) return;
39
+ this.host.freeze();
40
+ this._isFrozen = true;
41
+ }
42
+ freeze() {
43
+ this.stopAuto();
44
+ }
45
+ thaw() {
46
+ this.startAuto();
47
+ }
48
+ setDelta(ms) {
49
+ if (!Number.isFinite(ms) || ms <= 0) {
50
+ throw new Error("DebugClock.setDelta(ms) requires a positive number.");
51
+ }
52
+ this.deltaMs = ms;
53
+ }
54
+ getFrame() {
55
+ return this.frame;
44
56
  }
45
57
  step(dtMs) {
46
- if (!this._isManual) {
47
- throw new Error(
48
- "Manual clock is not active. Call clock.stopAuto() first."
49
- );
58
+ if (!this._isFrozen) {
59
+ throw new Error("DebugClock is not frozen. Call clock.freeze() first.");
60
+ }
61
+ const dt = dtMs ?? this.deltaMs;
62
+ if (!Number.isFinite(dt) || dt <= 0) {
63
+ throw new Error("DebugClock.step(dtMs) requires a positive number.");
50
64
  }
51
- const dt = dtMs ?? this.gameLoop.fixedTimestep;
52
- this.gameLoop.tick(dt);
53
- this.render();
65
+ this.host.advance(dt);
66
+ this.frame++;
54
67
  }
55
68
  stepFrames(count, dtMs) {
56
69
  if (!Number.isInteger(count) || count < 0) {
@@ -62,16 +75,6 @@ var DebugClock = class {
62
75
  this.step(dtMs);
63
76
  }
64
77
  }
65
- /** Enter or exit manual mode. Used by DebugPlugin for config-driven init. */
66
- setManual(enabled) {
67
- if (enabled === this._isManual) return;
68
- if (enabled) {
69
- this.stopTicker();
70
- } else {
71
- this.startTicker();
72
- }
73
- this._isManual = enabled;
74
- }
75
78
  };
76
79
 
77
80
  // src/DebugRegistryImpl.ts
@@ -553,6 +556,12 @@ var DebugPlugin = class {
553
556
  install(context) {
554
557
  this.context = context;
555
558
  this.renderer = context.resolve(RendererKey);
559
+ if (this.config.deterministicSeed !== void 0) {
560
+ context.resolve(InspectorKey).setDefaultSceneSeed(this.config.deterministicSeed);
561
+ }
562
+ if (this.config.startFrozen) {
563
+ this.renderer.application.stop();
564
+ }
556
565
  this.registry = new DebugRegistryImpl();
557
566
  this.registry.enabled = this.config.startEnabled ?? false;
558
567
  if (this.config.flags) {
@@ -579,7 +588,7 @@ var DebugPlugin = class {
579
588
  this.registry.toggle();
580
589
  return;
581
590
  }
582
- if (e.code === stepKey && this.clock?.isManual) {
591
+ if (e.code === stepKey && this.clock?.isFrozen) {
583
592
  e.preventDefault();
584
593
  this.clock.step();
585
594
  }
@@ -604,18 +613,15 @@ var DebugPlugin = class {
604
613
  this.registry.register(new SystemTimingContributor(this.systemTimings));
605
614
  const gameLoop = this.context.resolve(GameLoopKey);
606
615
  const app = this.renderer.application;
607
- this.clock = new DebugClock(
608
- gameLoop,
609
- () => app.stop(),
610
- () => app.start(),
611
- () => app.render()
612
- );
613
- if (this.config.manualClock) {
614
- this.clock.setManual(true);
615
- }
616
+ this.clock = new DebugClock(createPixiTickerHost(app, gameLoop.fixedTimestep));
617
+ inspector.attachTimeController(this.clock);
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
- this.attachInspectorDiagnostics(inspector);
624
+ this.registerInspectorDiagnostics();
619
625
  await this.materializeDebugScene();
620
626
  const bringToFront = /* @__PURE__ */ __name(() => {
621
627
  if (this.debugScene && this.provider?.bringSceneToFront) {
@@ -640,6 +646,15 @@ var DebugPlugin = class {
640
646
  this.keyListener = null;
641
647
  }
642
648
  this.detachFromGlobal();
649
+ const inspector = this.context.resolve(InspectorKey);
650
+ inspector.removeExtension("debug");
651
+ if (this.clock) {
652
+ inspector.detachTimeController(this.clock);
653
+ }
654
+ inspector.setEventLogEnabled(false);
655
+ if (this.config.deterministicSeed !== void 0) {
656
+ inspector.setDefaultSceneSeed(void 0);
657
+ }
643
658
  this.clock = null;
644
659
  for (const contributor of this.registry.contributors.values()) {
645
660
  contributor.dispose?.();
@@ -713,44 +728,42 @@ var DebugPlugin = class {
713
728
  this.worldApi = null;
714
729
  this.hudApi = null;
715
730
  }
716
- attachInspectorDiagnostics(inspector) {
717
- const g = globalThis["__yage__"];
718
- if (!g || typeof g !== "object") return;
719
- const debugSurface = g;
720
- const diagnostics = inspector;
721
- debugSurface["inspector"] = inspector;
722
- diagnostics.getLayerTransform = (sceneName, layerName) => {
723
- const scene = this.sceneManager.all.find(
724
- (candidate) => candidate.name === sceneName
725
- );
726
- if (!scene) return void 0;
727
- const layer = this.provider?.getTree(scene)?.tryGet(layerName);
728
- if (!layer) return void 0;
729
- const container = layer.container;
730
- return {
731
- x: container.position.x,
732
- y: container.position.y,
733
- scaleX: container.scale.x,
734
- scaleY: container.scale.y,
735
- rotation: container.rotation
736
- };
737
- };
738
- diagnostics.getCameraStack = () => {
739
- const cameras = [];
740
- for (const scene of this.sceneManager.all) {
741
- for (const entity of scene.getEntities()) {
742
- const cam = entity.tryGet(CameraComponent);
743
- if (!cam) continue;
744
- cameras.push({
745
- scene: scene.name,
746
- name: cam.cameraName,
747
- priority: cam.priority,
748
- enabled: cam.enabled
749
- });
731
+ registerInspectorDiagnostics() {
732
+ const diagnostics = {
733
+ getLayerTransform: /* @__PURE__ */ __name((sceneName, layerName) => {
734
+ const scene = this.sceneManager.all.find(
735
+ (candidate) => candidate.name === sceneName
736
+ );
737
+ if (!scene) return void 0;
738
+ const layer = this.provider?.getTree(scene)?.tryGet(layerName);
739
+ if (!layer) return void 0;
740
+ const container = layer.container;
741
+ return {
742
+ x: container.position.x,
743
+ y: container.position.y,
744
+ scaleX: container.scale.x,
745
+ scaleY: container.scale.y,
746
+ rotation: container.rotation
747
+ };
748
+ }, "getLayerTransform"),
749
+ getCameraStack: /* @__PURE__ */ __name(() => {
750
+ const cameras = [];
751
+ for (const scene of this.sceneManager.all) {
752
+ for (const entity of scene.getEntities()) {
753
+ const cam = entity.tryGet(CameraComponent);
754
+ if (!cam) continue;
755
+ cameras.push({
756
+ scene: scene.name,
757
+ name: cam.cameraName,
758
+ priority: cam.priority,
759
+ enabled: cam.enabled
760
+ });
761
+ }
750
762
  }
751
- }
752
- return cameras;
763
+ return cameras;
764
+ }, "getCameraStack")
753
765
  };
766
+ this.context.resolve(InspectorKey).addExtension("debug", diagnostics);
754
767
  }
755
768
  attachToGlobal(clock) {
756
769
  const g = globalThis["__yage__"];
@@ -765,6 +778,32 @@ var DebugPlugin = class {
765
778
  }
766
779
  }
767
780
  };
781
+ function createPixiTickerHost(app, fixedTimestep) {
782
+ let syntheticTime = 0;
783
+ let savedMinFPS = null;
784
+ return {
785
+ fixedTimestep,
786
+ freeze() {
787
+ app.stop();
788
+ syntheticTime = 0;
789
+ app.ticker.lastTime = 0;
790
+ savedMinFPS = app.ticker.minFPS;
791
+ app.ticker.minFPS = 0;
792
+ },
793
+ thaw() {
794
+ if (savedMinFPS !== null) {
795
+ app.ticker.minFPS = savedMinFPS;
796
+ savedMinFPS = null;
797
+ }
798
+ app.start();
799
+ },
800
+ advance(dtMs) {
801
+ syntheticTime += dtMs;
802
+ app.ticker.update(syntheticTime);
803
+ }
804
+ };
805
+ }
806
+ __name(createPixiTickerHost, "createPixiTickerHost");
768
807
  function findTopmostCamera(sceneManager) {
769
808
  const stack = sceneManager.all;
770
809
  for (let i = stack.length - 1; i >= 0; i--) {
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 Inspector,\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 { Container } from \"pixi.js\";\nimport { DebugClock } from \"./DebugClock.js\";\nimport type { 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 /** When true, stop the renderer ticker and advance simulation manually via `window.__yage__.clock`. */\n manualClock?: boolean;\n /** Key code to advance one fixed-timestep frame while manual clock mode is active. 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\ninterface LayerTransformSnapshot {\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n rotation: number;\n}\n\ninterface CameraStackSnapshot {\n scene: string;\n name: string | undefined;\n priority: number;\n enabled: boolean;\n}\n\ninterface InspectorDiagnostics {\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\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?.isManual) {\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\n const gameLoop = this.context.resolve(GameLoopKey);\n const app = this.renderer.application;\n this.clock = new DebugClock(\n gameLoop,\n () => app.stop(),\n () => app.start(),\n () => app.render(),\n );\n if (this.config.manualClock) {\n this.clock.setManual(true);\n }\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.attachInspectorDiagnostics(inspector);\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 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 attachInspectorDiagnostics(inspector: Inspector): void {\n const g = (globalThis as Record<string, unknown>)[\"__yage__\"];\n if (!g || typeof g !== \"object\") return;\n\n const debugSurface = g as Record<string, unknown>;\n const diagnostics = inspector as Inspector & InspectorDiagnostics;\n debugSurface[\"inspector\"] = inspector;\n\n diagnostics.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\n diagnostics.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\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 * 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 isManual: boolean;\n startAuto(): void;\n stopAuto(): void;\n step(dtMs?: number): void;\n stepFrames(count: number, dtMs?: number): void;\n}\n\n/** Minimal view of a game loop needed by the debug clock. */\ninterface GameLoopLike {\n tick(dtMs: number): void;\n readonly fixedTimestep: number;\n}\n\n/**\n * Controls engine time-stepping for deterministic E2E tests.\n *\n * When manual mode is active the renderer ticker is paused and frames\n * advance only via explicit `step()` / `stepFrames()` calls.\n */\nexport class DebugClock implements IDebugClock {\n private _isManual = false;\n\n constructor(\n private readonly gameLoop: GameLoopLike,\n private readonly stopTicker: () => void,\n private readonly startTicker: () => void,\n private readonly render: () => void,\n ) {}\n\n get isManual(): boolean {\n return this._isManual;\n }\n\n startAuto(): void {\n if (!this._isManual) return;\n this.startTicker();\n this._isManual = false;\n }\n\n stopAuto(): void {\n if (this._isManual) return;\n this.stopTicker();\n this._isManual = true;\n }\n\n step(dtMs?: number): void {\n if (!this._isManual) {\n throw new Error(\n \"Manual clock is not active. Call clock.stopAuto() first.\",\n );\n }\n const dt = dtMs ?? this.gameLoop.fixedTimestep;\n this.gameLoop.tick(dt);\n this.render();\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 /** Enter or exit manual mode. Used by DebugPlugin for config-driven init. */\n setManual(enabled: boolean): void {\n if (enabled === this._isManual) return;\n if (enabled) {\n this.stopTicker();\n } else {\n this.startTicker();\n }\n this._isManual = enabled;\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.3.0",
3
+ "version": "0.5.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.3.0",
62
- "@yagejs/renderer": "^0.3.0",
61
+ "@yagejs/core": "^0.5.0",
62
+ "@yagejs/renderer": "^0.5.0",
63
63
  "pixi.js": "^8.5.0"
64
64
  }
65
65
  }