import { Scene, Entity, Vec2Like, ServiceKey } from '@yagejs/core'; /** * Minimal subset of PixiJS Graphics used by debug drawing. * Avoids a runtime pixi.js dependency in the ./api subpath. */ interface DebugGraphics { position: { x: number; y: number; }; rotation: number; visible: boolean; clear(): DebugGraphics; rect(x: number, y: number, width: number, height: number): DebugGraphics; roundRect(x: number, y: number, width: number, height: number, radius: number): DebugGraphics; circle(x: number, y: number, radius: number): DebugGraphics; moveTo(x: number, y: number): DebugGraphics; lineTo(x: number, y: number): DebugGraphics; stroke(style: { width: number; color: number; alpha?: number; }): DebugGraphics; fill(style: { color: number; alpha?: number; }): DebugGraphics; } /** Camera-space drawing API passed to contributors. */ interface SceneWorldDebugApi { acquireGraphics(): DebugGraphics | undefined; readonly cameraZoom: number; } interface WorldDebugApi extends SceneWorldDebugApi { isFlagEnabled(flag: string): boolean; /** Drawing for a visible scene, or undefined while hidden or off the stack. */ forScene(scene: Scene): SceneWorldDebugApi | undefined; } /** Screen-space HUD API passed to contributors. */ interface HudDebugApi { addLine(text: string): void; isFlagEnabled(flag: string): boolean; readonly screenWidth: number; readonly screenHeight: number; } /** Rolling-window statistics collector. */ interface StatsApi { push(key: string, value: number): void; average(key: string): number; latest(key: string): number; min(key: string): number; max(key: string): number; } /** A debug contributor that registers drawing/sampling callbacks. */ interface DebugContributor { readonly name: string; readonly flags: readonly string[]; drawWorld?(api: WorldDebugApi): void; drawHud?(api: HudDebugApi): void; sample?(stats: StatsApi, dt: number): void; dispose?(): void; } /** * Supplies the vector to draw this frame, in the entity's world space. Return * `null` or `undefined` to draw nothing this frame. */ type DebugVectorProvider = () => Vec2Like | null | undefined; /** Appearance and cutoff options for {@link DebugRegistry.drawVector}. */ interface DebugVectorOptions { /** Pixels of arrow per unit of the vector. Default 1. */ scale?: number; /** Arrow color. Default `0xffffff`. */ color?: number; /** Arrow opacity, 0-1. Default 0.9. */ alpha?: number; /** * World-space pixel offset added to the entity's position, so the arrow can * start at a muzzle or a hand instead of the entity's origin. Not rotated by * the entity. Default `{ x: 0, y: 0 }`. */ origin?: Vec2Like; /** * Draw nothing while the vector is shorter than this. Measured on the value * the provider returns, before `scale` is applied, so the cutoff is in the * vector's own units (px/s for a velocity). Default 0 — a zero-length vector * never draws either way, since it has no direction. */ minLength?: number; /** Shaft thickness in screen pixels, held constant across camera zoom. Default 2. */ width?: number; /** Arrowhead length in screen pixels, held constant across camera zoom. Default 8. */ headSize?: number; } /** Service interface for the debug registry. */ interface DebugRegistry { register(contributor: DebugContributor): void; isEnabled(): boolean; /** Switch all debug drawing on or off. */ toggle(): void; isFlagEnabled(contributorName: string, flag: string): boolean; /** Set whether a contributor's named view is drawn. */ setFlag(contributorName: string, flag: string, value: boolean): void; /** * Draw an arrow on `entity` for a vector that is read fresh every frame — * velocity, aim direction, knockback, steering output. * * ```ts * // tryResolve, not use(): use() throws without DebugPlugin installed. * const debug = this.context.tryResolve(DebugRegistryKey); * this.stopArrow = debug?.drawVector(this.entity, () => agent.velocity, { * scale: 0.35, * color: 0x4ade80, * minLength: 1, * }); * ``` * * The arrow starts at the entity's world position (plus `options.origin`) * and points along the vector. Nothing is retained but the provider itself: * it is called once per frame while the overlay is on and the `vectors` * contributor's `arrows` flag is enabled, and not at all otherwise — a * `drawVector` call in a hot path costs nothing while debug is off. * * Returns a disposer that stops the drawing. Calling it twice is harmless. * The registration is also dropped when the entity's life ends — destroyed, * or a pool member whose lease ended — so a provider closure never outlives * the entity it draws for, and a per-lease registration never accumulates. */ drawVector(entity: Entity, vector: DebugVectorProvider, options?: DebugVectorOptions): () => void; } /** Service key for resolving the DebugRegistry via DI. */ declare const DebugRegistryKey: ServiceKey; export { type DebugContributor, type DebugGraphics, type DebugRegistry, DebugRegistryKey, type DebugVectorOptions, type DebugVectorProvider, type HudDebugApi, type SceneWorldDebugApi, type StatsApi, type WorldDebugApi };