# Behavior Trees

Behavior trees are a hierarchical model used to control the decision-making process of AI agents. They are composed of nodes that return a state of **Success**, **Failure**, or **Running**.

### Core Concepts

#### Nodes

Every node in a behavior tree is a subclass of `Node`. The tree is traversed from the root node down to leaf nodes.

* **Leaf Nodes**: Perform actions or checks (e.g., `ActionNode`, `ConditionNode`).
* **Composite Nodes**: Control the flow of execution by managing child nodes (e.g., `SequenceNode`, `SelectorNode`).
* **Decorator Nodes**: Modify the behavior of a single child node (e.g., `InverterNode`, `RepeatNode`).

#### Ticks

The tree is updated via a `tick(dt)` method, where `dt` is the delta time since the last update. This propagates down the tree, updating active nodes.

#### Node States

* `SUCCESS`: The node completed its task successfully.
* `FAILURE`: The node failed to complete its task.
* `RUNNING`: The node is currently executing and needs to be ticked again in the next frame.

### Built-in Nodes

Hology Engine provides a set of standard nodes to build your trees.

#### Composite Nodes

* **`SequenceNode`**: Runs children in order. Succeeds if all children succeed. Fails immediately if any child fails.
* **`SelectorNode`**: Runs children in order. Succeeds immediately if any child succeeds. Fails if all children fail.
* **`ParallelSequenceNode`**: Runs all children simultaneously. Succeeds if *all* children succeed. Fails if *any* child fails.
* **`ParallelSelectorNode`**: Runs all children simultaneously. Succeeds if *any* child succeeds. Fails if *all* children fail.
* **`WeightedRandomSelectorNode`**: Selects one child to run based on assigned weights.

#### Decorator Nodes

* **`InverterNode`**: Flips the result of its child (Success becomes Failure, Failure becomes Success).
* **`RepeatNode`**: Repeats the child node indefinitely.
* **`RepeatTimesNode`**: Repeats the child a specific number of times.
* **`RepeatUntilNode`**: Repeats the child until a condition function returns true.
* **`RepeatUntilFailNode`**: Repeats the child until it returns Failure.
* **`GuardNode`**: Only runs the child if a condition is met; otherwise returns Failure.
* **`CooldownNode`**: Prevents the child from running again until a cooldown period has passed.
* **`TimerNode`**: Runs the child for a specific duration, then returns Failure.
* **`DelayNode`**: Waits for a specified time before running the child.
* **`ThrottleNode`**: Limits how often the child node is ticked.

#### Leaf Nodes

* **`ActionNode`**: Executes a function that returns a `NodeState`.
* **`ConditionNode`**: Checks a condition function. Returns Success if true, Failure if false.
* **`WaitNode`**: Returns Running for a specified duration, then Success.
* **`SuccessNode`**: Always returns Success.
* **`FailNode`**: Always returns Failure.

### Creating a Behavior Tree

Behavior trees are typically constructed in your Actor's `onBeginPlay` method.

```typescript
import { 
  SelectorNode, SequenceNode, ActionNode, WaitNode, RepeatNode, 
  NodeState 
} from '@hology/core/gameplay';

// ... inside your Actor class

onBeginPlay() {
  // 1. Define leaf behaviors
  const attack = new ActionNode(() => {
    console.log("Attacking!");
    return NodeState.SUCCESS;
  });

  const patrol = new SequenceNode();
  patrol.addChild(new ActionNode(() => {
     console.log("Moving to waypoint");
     return NodeState.SUCCESS; 
  }));
  patrol.addChild(new WaitNode(1000)); // Wait 1 second

  // 2. Compose the tree
  const rootSelector = new SelectorNode();
  
  // Try to attack first, if that fails (e.g. condition not met), patrol.
  rootSelector.addChild(attack); 
  rootSelector.addChild(patrol);

  // 3. Wrap in a repeater to keep the AI active
  this.behaviorTree = new RepeatNode(rootSelector);
}

onUpdate(dt: number) {
  // 4. Update the tree every frame
  this.behaviorTree?.tick(dt);
}
```

### Custom Nodes

You can create custom nodes by extending `LeafNode` or `DecoratorNode` for more complex game-specific logic.

```typescript
import { LeafNode, NodeState } from '@hology/core/gameplay';

class CheckHealthNode extends LeafNode {
  constructor(private character: Character, private threshold: number) {
    super();
  }

  tick(dt: number): NodeState {
    if (this.character.health < this.threshold) {
      return NodeState.SUCCESS;
    }
    return NodeState.FAILURE;
  }
}
```

### Further Reading

For a complete step-by-step guide on implementing a chasing AI, check out the tutorial [Character AI behavior](/tutorials/character-ai-behavior.md) .


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hology.app/gameplay/behavior-trees.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
