/**
 * Behavior Tree Plugin for ECSpresso
 *
 * Provides composable, priority-driven AI via behavior trees. Shared immutable
 * tree definitions drive per-entity runtime state. Uses hybrid traversal
 * (Approach C): re-evaluate from root each tick to preserve priority, resume
 * running leaves, and abort diverged running nodes via `onAbort`.
 *
 * Each entity gets a `behaviorTree` component referencing a shared definition
 * plus a typed blackboard for per-entity AI memory. One system processes all
 * behavior-tree entities each tick.
 *
 * Node types:
 *   Composites — sequence, selector, parallel
 *   Decorators — inverter, repeat, cooldown, guard
 *   Leaves     — action (tick → NodeStatus, optional onAbort), condition (predicate)
 */
import { type BasePluginOptions, type BaseWorld, type ComponentsConfig, type EventsConfig } from 'ecspresso';
/**
 * Return value from behavior tree node ticks.
 *
 * - `Success` (0) — node completed successfully
 * - `Failure` (1) — node failed
 * - `Running` (2) — node still executing, will resume next tick
 */
export declare const NodeStatus: {
    readonly Success: 0;
    readonly Failure: 1;
    readonly Running: 2;
};
export type NodeStatus = (typeof NodeStatus)[keyof typeof NodeStatus];
/** BaseWorld narrowed to behavior-tree components for typed access in helpers. */
type BehaviorTreeWorld = BaseWorld<BehaviorTreeComponentTypes>;
/**
 * Context passed to all leaf node callbacks (action tick, condition check,
 * onAbort, guard predicates).
 *
 * @template BB - Blackboard type for per-entity AI memory
 * @template W  - World interface type (default: BehaviorTreeWorld)
 */
export interface BehaviorTreeContext<BB extends object = Record<string, unknown>, W extends BaseWorld<BehaviorTreeComponentTypes> = BehaviorTreeWorld> {
    readonly ecs: W;
    readonly entityId: number;
    readonly dt: number;
    readonly blackboard: BB;
}
/**
 * Action leaf — executes behavior each tick.
 * Returns `Running` for multi-frame actions. Optional `onAbort` fires
 * when a higher-priority branch preempts this running action.
 */
export interface ActionNode<BB extends object = Record<string, unknown>> {
    readonly type: 'action';
    readonly name: string;
    readonly tick: (ctx: BehaviorTreeContext<BB>) => NodeStatus;
    readonly onAbort?: (ctx: BehaviorTreeContext<BB>) => void;
    nodeIndex: number;
}
/**
 * Condition leaf — checks a predicate. Returns Success or Failure, never Running.
 */
export interface ConditionNode<BB extends object = Record<string, unknown>> {
    readonly type: 'condition';
    readonly name: string;
    readonly check: (ctx: BehaviorTreeContext<BB>) => boolean;
    nodeIndex: number;
}
/**
 * Sequence composite — runs children left-to-right.
 * Fails on first failure, succeeds when all succeed.
 * Resumes from stored child index when a running node exists.
 */
export interface SequenceNode<BB extends object = Record<string, unknown>> {
    readonly type: 'sequence';
    readonly children: readonly BehaviorTreeNode<BB>[];
    nodeIndex: number;
}
/**
 * Selector composite — runs children left-to-right.
 * Succeeds on first success, fails when all fail.
 * Always re-evaluates from child 0 to preserve priority ordering.
 */
export interface SelectorNode<BB extends object = Record<string, unknown>> {
    readonly type: 'selector';
    readonly children: readonly BehaviorTreeNode<BB>[];
    nodeIndex: number;
}
/**
 * Parallel composite — ticks all children each frame.
 * Configurable success/failure thresholds.
 *
 * Limitation (v1): only one running leaf is tracked for abort.
 * Other running children in a parallel stop being ticked if the
 * tree path diverges but do not receive an `onAbort` call.
 */
export interface ParallelNode<BB extends object = Record<string, unknown>> {
    readonly type: 'parallel';
    readonly children: readonly BehaviorTreeNode<BB>[];
    readonly successThreshold: number;
    readonly failureThreshold: number;
    nodeIndex: number;
}
/** Decorator — inverts child result (Success↔Failure), passes Running through. */
export interface InverterNode<BB extends object = Record<string, unknown>> {
    readonly type: 'inverter';
    readonly child: BehaviorTreeNode<BB>;
    nodeIndex: number;
}
/** Decorator — repeats child `count` times (or forever when count is -1). */
export interface RepeatNode<BB extends object = Record<string, unknown>> {
    readonly type: 'repeat';
    readonly child: BehaviorTreeNode<BB>;
    readonly count: number;
    nodeIndex: number;
}
/** Decorator — prevents child re-entry for `duration` seconds after completion. */
export interface CooldownNode<BB extends object = Record<string, unknown>> {
    readonly type: 'cooldown';
    readonly child: BehaviorTreeNode<BB>;
    readonly duration: number;
    nodeIndex: number;
}
/** Decorator — conditional gate. Ticks child only when condition passes. */
export interface GuardNode<BB extends object = Record<string, unknown>> {
    readonly type: 'guard';
    readonly child: BehaviorTreeNode<BB>;
    readonly condition: (ctx: BehaviorTreeContext<BB>) => boolean;
    nodeIndex: number;
}
/** Union of all behavior tree node types. */
export type BehaviorTreeNode<BB extends object = Record<string, unknown>> = ActionNode<BB> | ConditionNode<BB> | SequenceNode<BB> | SelectorNode<BB> | ParallelNode<BB> | InverterNode<BB> | RepeatNode<BB> | CooldownNode<BB> | GuardNode<BB>;
/**
 * Create an action leaf node.
 *
 * @param name   - Human-readable name (used in abort events)
 * @param tick   - Called each frame while this node is active; return NodeStatus
 * @param options - Optional `onAbort` callback fired when preempted by a higher-priority branch
 */
export declare function action<BB extends object>(name: string, tick: (ctx: BehaviorTreeContext<BB>) => NodeStatus, options?: {
    onAbort?: (ctx: BehaviorTreeContext<BB>) => void;
}): ActionNode<BB>;
/**
 * Create a condition leaf node.
 *
 * @param name  - Human-readable name
 * @param check - Predicate returning true (Success) or false (Failure). Never Running.
 */
export declare function condition<BB extends object>(name: string, check: (ctx: BehaviorTreeContext<BB>) => boolean): ConditionNode<BB>;
/**
 * Create a sequence composite. Runs children L→R, fails on first failure.
 */
export declare function sequence<BB extends object>(children: BehaviorTreeNode<BB>[]): SequenceNode<BB>;
/**
 * Create a selector composite. Runs children L→R, succeeds on first success.
 * Always starts from child 0 to re-evaluate priority.
 */
export declare function selector<BB extends object>(children: BehaviorTreeNode<BB>[]): SelectorNode<BB>;
/**
 * Create a parallel composite. Ticks all children each frame.
 *
 * @param children         - Child nodes to tick in parallel
 * @param options.successThreshold - Successes needed for parallel to succeed (default: all)
 * @param options.failureThreshold - Failures needed for parallel to fail (default: all)
 */
export declare function parallel<BB extends object>(children: BehaviorTreeNode<BB>[], options?: {
    successThreshold?: number;
    failureThreshold?: number;
}): ParallelNode<BB>;
/** Create an inverter decorator. Flips Success↔Failure, passes Running. */
export declare function inverter<BB extends object>(child: BehaviorTreeNode<BB>): InverterNode<BB>;
/**
 * Create a repeat decorator.
 *
 * @param child - Node to repeat
 * @param count - Number of repetitions, or -1 for infinite (default: -1)
 */
export declare function repeat<BB extends object>(child: BehaviorTreeNode<BB>, count?: number): RepeatNode<BB>;
/**
 * Create a cooldown decorator. Prevents re-entry for `duration` seconds
 * after child completes (Success or Failure).
 */
export declare function cooldown<BB extends object>(child: BehaviorTreeNode<BB>, duration: number): CooldownNode<BB>;
/**
 * Create a guard decorator. Ticks child only when condition returns true.
 * Returns Failure when condition is false.
 */
export declare function guard<BB extends object>(cond: (ctx: BehaviorTreeContext<BB>) => boolean, child: BehaviorTreeNode<BB>): GuardNode<BB>;
/**
 * Immutable behavior tree definition. Shared across entities.
 *
 * @template BB - Blackboard type for per-entity AI memory
 */
export interface BehaviorTreeDefinition<BB extends object = Record<string, unknown>> {
    readonly id: string;
    readonly root: BehaviorTreeNode<BB>;
    readonly nodeCount: number;
}
/**
 * Define a behavior tree with a typed blackboard.
 *
 * The `blackboard` value serves as both the type source and the default
 * initial state cloned for each entity via `createBehaviorTree`.
 *
 * @param id     - Unique identifier for this tree definition
 * @param config - `{ blackboard, root }` — default blackboard + root node
 * @returns Frozen BehaviorTreeDefinition
 *
 * @example
 * ```typescript
 * const tree = defineBehaviorTree('patrol', {
 *   blackboard: { targetId: null as number | null, timer: 0 },
 *   root: selector([
 *     guard(ctx => ctx.blackboard.targetId !== null, action('chase', ...)),
 *     action('wander', ...),
 *   ]),
 * });
 * ```
 */
export declare function defineBehaviorTree<BB extends object>(id: string, config: {
    blackboard: BB;
    root: BehaviorTreeNode<BB>;
}): BehaviorTreeDefinition<BB>;
/**
 * Runtime behavior tree state stored on each entity.
 *
 * The `blackboard` is typed as `object` at the component level.
 * Inside tree callbacks, the `BehaviorTreeContext<BB>` provides
 * typed access to the blackboard via the tree definition's generic.
 * Outside the tree, cast the blackboard to the specific BB type.
 */
export interface BehaviorTreeComponent {
    readonly definition: BehaviorTreeDefinition<Record<string, unknown>>;
    blackboard: object;
    /** Index of the currently running leaf, or -1 if none. */
    runningNodeIndex: number;
    /**
     * Dense per-node state array (sized to `definition.nodeCount`).
     * Semantics vary by node type:
     * - sequence/selector: child progress index
     * - repeat: completed iteration count
     * - cooldown: expiry timestamp (elapsedTime when cooldown ends)
     */
    nodeState: Float64Array;
    /** Accumulated time (seconds) for cooldown tracking. */
    elapsedTime: number;
}
/**
 * Component types provided by the behavior tree plugin.
 */
export interface BehaviorTreeComponentTypes {
    behaviorTree: BehaviorTreeComponent;
}
/**
 * Event published when a running action is preempted (aborted) by a
 * higher-priority branch taking over.
 */
export interface BehaviorTreeAbortEvent {
    entityId: number;
    /** nodeIndex of the aborted action */
    nodeIndex: number;
    /** Human-readable name of the aborted action */
    nodeName: string;
    /** Definition id of the behavior tree */
    definitionId: string;
}
/**
 * Event types provided by the behavior tree plugin.
 */
export interface BehaviorTreeEventTypes {
    behaviorTreeAbort: BehaviorTreeAbortEvent;
}
/**
 * WorldConfig representing the behavior tree plugin's provided types.
 */
export type BehaviorTreeWorldConfig = ComponentsConfig<BehaviorTreeComponentTypes> & EventsConfig<BehaviorTreeEventTypes>;
/**
 * Create a `behaviorTree` component from a definition.
 *
 * @param definition - Shared tree definition
 * @param blackboard - Optional partial overrides for the default blackboard
 * @returns Component object suitable for spreading into spawn()
 *
 * @example
 * ```typescript
 * ecs.spawn({
 *   ...createBehaviorTree(villagerTree, { hunger: 80 }),
 *   ...createLocalTransform(100, 200),
 * });
 * ```
 */
export declare function createBehaviorTree<BB extends object>(definition: BehaviorTreeDefinition<BB>, blackboard?: Partial<BB>): Pick<BehaviorTreeComponentTypes, 'behaviorTree'>;
/**
 * Check whether an entity's behavior tree has a running action.
 */
export declare function isBehaviorTreeRunning(ecs: {
    getComponent(entityId: number, name: 'behaviorTree'): BehaviorTreeComponent | undefined;
}, entityId: number): boolean;
/**
 * Reset an entity's behavior tree: abort any running action, clear all
 * composite progress, and optionally reset the blackboard.
 */
export declare function resetBehaviorTree(ecs: BehaviorTreeWorld, entityId: number, blackboard?: Partial<Record<string, unknown>>): void;
/**
 * Typed helpers for the behavior tree plugin.
 * Creates helpers that validate callback parameters against the world type W.
 * Call after `.build()` using `typeof ecs`.
 */
export interface BehaviorTreeHelpers<W extends BaseWorld<BehaviorTreeComponentTypes>> {
    defineBehaviorTree: <BB extends object>(id: string, config: {
        blackboard: BB;
        root: BehaviorTreeNode<BB>;
    }) => BehaviorTreeDefinition<BB>;
    action: <BB extends object>(name: string, tick: (ctx: BehaviorTreeContext<BB, W>) => NodeStatus, options?: {
        onAbort?: (ctx: BehaviorTreeContext<BB, W>) => void;
    }) => ActionNode<BB>;
    condition: <BB extends object>(name: string, check: (ctx: BehaviorTreeContext<BB, W>) => boolean) => ConditionNode<BB>;
    guard: <BB extends object>(cond: (ctx: BehaviorTreeContext<BB, W>) => boolean, child: BehaviorTreeNode<BB>) => GuardNode<BB>;
}
/**
 * Create typed behavior tree helpers bound to a specific world type.
 *
 * @example
 * ```typescript
 * const ecs = ECSpresso.create()
 *   .withPlugin(createBehaviorTreePlugin())
 *   .build();
 *
 * const { defineBehaviorTree, action, condition, guard } = ecs.getHelpers(createBehaviorTreeHelpers);
 * ```
 */
export declare function createBehaviorTreeHelpers<W extends BaseWorld<BehaviorTreeComponentTypes> = BehaviorTreeWorld>(_world?: W): BehaviorTreeHelpers<W>;
/**
 * Configuration options for the behavior tree plugin.
 */
export interface BehaviorTreePluginOptions<G extends string = 'ai'> extends BasePluginOptions<G> {
}
/**
 * Create a behavior tree plugin for ECSpresso.
 *
 * Provides composable, priority-driven AI via behavior trees with:
 * - Hybrid traversal: re-evaluate from root each tick, resume running leaves
 * - Automatic abort with `onAbort` callback when preempted
 * - Typed blackboard for per-entity AI memory
 * - `behaviorTreeAbort` events on preemption
 *
 * @example
 * ```typescript
 * const ecs = ECSpresso.create()
 *   .withPlugin(createBehaviorTreePlugin())
 *   .build();
 *
 * const { defineBehaviorTree, action, condition, guard } = ecs.getHelpers(createBehaviorTreeHelpers);
 *
 * const tree = defineBehaviorTree('villager', {
 *   blackboard: { hunger: 100, targetId: null as number | null },
 *   root: selector([
 *     guard(ctx => ctx.blackboard.hunger < 30, action('eat', ...)),
 *     action('wander', ...),
 *   ]),
 * });
 *
 * ecs.spawn({
 *   ...createBehaviorTree(tree),
 *   ...createLocalTransform(100, 200),
 * });
 * ```
 */
export declare function createBehaviorTreePlugin<G extends string = 'ai'>(options?: BehaviorTreePluginOptions<G>): import("ecspresso").Plugin<import("ecspresso").WithEvents<import("ecspresso").WithComponents<import("ecspresso").EmptyConfig, BehaviorTreeComponentTypes>, BehaviorTreeEventTypes>, import("ecspresso").EmptyConfig, "behavior-tree-update", G, never, never>;
export {};
