import type { Blackboard, DecisionAbort, DecisionAction, DecisionGraphRuntime } from "../ai/decisionGraph.js"; import { type InterestGateState } from "../ai/interestScheduler.js"; import { type PursuitState } from "../ai/pursuit.js"; import { type ThreatTable, type ThreatTableState } from "../ai/threat.js"; import { type PathFollowState, type PathProgress, type Waypoint } from "../nav/pathFollow.js"; import type { GameContext } from "../runtime/gameContext.js"; import type { GameDefinition } from "../game/defineGame.js"; /** Whether a behavior instance advances and writes pose (`active`), is temporarily suspended retaining * state (`paused`), or is held off until re-enabled (`disabled`). */ export type BehaviorStatus = "active" | "paused" | "disabled"; /** Context supplied to a registered decision graph action. */ export interface BehaviorActionContext { ctx: GameContext; entityId: string; dt: number; } /** Callback used by a registered decision graph behavior action. */ export type BehaviorAction = DecisionAction; /** Optional hooks for a registered behavior action set. */ export interface BehaviorActionOptions { /** Called when an action running last think is pre-empted by another branch, to stop movement or release claims. */ onAbort?: DecisionAbort; } /** Register the named actions used by decision graph behavior descriptors. * @capability behavior-actions register named callbacks for decision graph behavior descriptors */ export declare function registerBehaviorActions(id: string, actions: Record, options?: BehaviorActionOptions): () => void; /** * Catch-up policy applied when a paused instance resumes. `freeze` (default, deterministic) discards * the time spent paused; `advance` silently fast-forwards the instance by the paused duration without * emitting intermediate pose writes. Only patrol honors `advance`; wander/pursue treat it as `freeze`. */ export type BehaviorResumePolicy = "freeze" | "advance"; /** Serializable snapshot of one behavior instance — round-trips exactly through * {@link BehaviorControl.serialize}/{@link BehaviorControl.restore}. */ export type BehaviorSnapshot = { readonly kind: "patrol"; readonly state: PathFollowState; } | { readonly kind: "wander"; readonly origin: Waypoint; readonly target: Waypoint | null; } | PursueBehaviorSnapshot | { readonly kind: "decisionGraph"; readonly graph: ReturnType; readonly gate: InterestGateState; readonly blackboard?: Blackboard; /** Seconds accrued since the last think. */ readonly pending?: number; }; /** Plain pursuit progress, including its original spawn home and scheduled elapsed time. */ export interface PursueBehaviorSnapshot { readonly kind: "pursue"; readonly home: Waypoint; readonly targetId: string | null; readonly explicitTargetId: string | null; readonly returning: boolean; readonly pursuit: PursuitState; readonly gate: InterestGateState; readonly pending: number; readonly threat?: ThreatTableState; } /** Inspection readout for editor/debug tooling, from {@link BehaviorControl.inspect}/{@link BehaviorControl.list}. */ export interface BehaviorInspection { id: string; kind: "patrol" | "wander" | "decisionGraph" | "pursue"; status: BehaviorStatus; reason: string | null; } /** * Per-entity control surface for the behavior runtime — pause/resume/disable/enable an instance, * seek it to semantic progress, serialize/restore its state, and inspect it, all keyed by stable * entity id without a full-world scan. Obtain it with {@link behaviorControl}. */ export interface BehaviorControl { /** Current status of the instance, or `null` if the entity has no live behavior. */ status(id: string): BehaviorStatus | null; /** Human-readable reason attached to the last pause/disable, or `null`. */ reason(id: string): string | null; /** Suspend advancement and pose writes, retaining state. No-op (`false`) if not active. */ pause(id: string, reason?: string): boolean; /** Resume a paused instance, applying the catch-up `policy` (default `freeze`). */ resume(id: string, policy?: BehaviorResumePolicy): boolean; /** Hold the instance off (no advance, no pose) until {@link enable}. Retains state. */ disable(id: string, reason?: string): boolean; /** Re-activate a disabled instance from its retained state (no catch-up). */ enable(id: string): boolean; /** Jump a patrol instance to semantic {@link PathProgress}. Returns `false` for non-patrol instances. */ seek(id: string, progress: PathProgress): boolean; /** Capture the instance's exact serializable state, or `null` if absent. */ serialize(id: string): BehaviorSnapshot | null; /** Restore an instance from a {@link BehaviorSnapshot} of the matching kind. */ restore(id: string, snapshot: BehaviorSnapshot): boolean; /** Inspect one instance, or `null` if absent. */ inspect(id: string): BehaviorInspection | null; /** Inspect every live instance (bounded by spawned behavior entities). */ list(): BehaviorInspection[]; /** The live, persistent blackboard of a decision graph instance for perception and game systems to write facts into, or `null`. */ blackboard(id: string): Blackboard | null; /** Optional pursuit threat table; explicit `setTarget` wins over taunt/threat and proximity. */ threat(id: string): ThreatTable | null; /** Clear pursuit target/cooldown/threat and reset its cadence, retaining the original home. */ reset(id: string): boolean; } /** * Advance every spawned entity carrying a patrol, wander, pursuit or decision graph behavior one tick — the * engine reads the descriptor, keeps the per-entity nav state itself, and poses the entity, so ambient * traffic and idle NPC routes are register-once (attach the behavior at spawn) instead of a per-game * per-frame `advancePathFollow` + `setPose` loop. Instances that are paused or disabled through * {@link behaviorControl} retain their state and are skipped. The shell/host call this each frame; a game never does. * * @capability behavior-tick auto-advance spawned patrol, wander, pursuit and decision graph behaviors with lifecycle control */ export declare function advanceBehaviors(ctx: GameContext, dt: number): void; /** * Obtain the per-context {@link BehaviorControl} surface for suspending, resuming, seeking, serializing, * and inspecting behavior instances by entity id — the lifecycle contract games use to hand pose * ownership to possession/streaming/staggering code instead of bypassing the behavior runtime. * * @capability behavior-control pause/disable/resume/seek/inspect behavior instances per entity */ export declare function behaviorControl(ctx: GameContext): BehaviorControl; /** @internal Register persistence before boot-time restore without constructing an AI runtime. */ export declare function installPursuitPersistence(ctx: GameContext, aoiRadius?: number, eligible?: NonNullable["eligible"]): void;