Jido.BehaviorTree.Tree (Jido Behavior Tree v1.0.0)

View Source

Manages the execution and traversal of behavior trees.

The Tree module provides a clean API for executing behavior trees. It handles the tick propagation through the tree structure and maintains the current execution state.

Structure

A behavior tree is represented as a simple tree structure where each node can have child nodes. The tree maintains the root node and provides traversal and execution capabilities.

Execution Model

Trees follow the standard behavior tree execution model:

  1. Start at the root node
  2. Traverse down to child nodes based on node type logic
  3. Execute leaf nodes (actions, conditions)
  4. Propagate results back up the tree
  5. Return final status

State Management

The tree maintains execution state through individual node states. This allows for stateful execution where nodes can remember their progress between ticks.

Summary

Types

t()

A behavior tree with execution state

Functions

Gets the depth of the tree (maximum number of levels).

Halts the execution of the entire tree.

Creates a new behavior tree with the given root node.

Counts the total number of nodes in the tree.

Replaces the root node of the tree.

Gets the root node of the tree.

Returns the Zoi schema for this module

Executes a single tick of the behavior tree.

Executes a single tick with context, returning the updated tick.

Traverses the tree and applies a function to each node.

Checks if the tree is valid (has a root node that implements Node behavior).

Types

t()

@type t() :: %Jido.BehaviorTree.Tree{root: any()}

A behavior tree with execution state

Functions

depth(tree)

@spec depth(t()) :: non_neg_integer()

Gets the depth of the tree (maximum number of levels).

Examples

iex> tree = Jido.BehaviorTree.Tree.new(leaf_node)
iex> Jido.BehaviorTree.Tree.depth(tree)
1

halt(tree)

@spec halt(t()) :: t()

Halts the execution of the entire tree.

This recursively calls halt on all nodes in the tree to ensure proper cleanup of resources and state.

Examples

iex> tree = Jido.BehaviorTree.Tree.new(root_node)
iex> halted_tree = Jido.BehaviorTree.Tree.halt(tree)
%Jido.BehaviorTree.Tree{}

new(root_node)

@spec new(Jido.BehaviorTree.Node.t()) :: t()

Creates a new behavior tree with the given root node.

Examples

iex> root = %MyNode{data: "test"}
iex> tree = Jido.BehaviorTree.Tree.new(root)
%Jido.BehaviorTree.Tree{}

node_count(tree)

@spec node_count(t()) :: non_neg_integer()

Counts the total number of nodes in the tree.

Examples

iex> tree = Jido.BehaviorTree.Tree.new(root_node)
iex> Jido.BehaviorTree.Tree.node_count(tree)
5

replace_root(tree, new_root)

@spec replace_root(t(), Jido.BehaviorTree.Node.t()) :: t()

Replaces the root node of the tree.

Examples

iex> tree = Jido.BehaviorTree.Tree.new(old_root)
iex> new_tree = Jido.BehaviorTree.Tree.replace_root(tree, new_root)
%Jido.BehaviorTree.Tree{}

root(tree)

@spec root(t()) :: Jido.BehaviorTree.Node.t()

Gets the root node of the tree.

Examples

iex> tree = Jido.BehaviorTree.Tree.new(root_node)
iex> root = Jido.BehaviorTree.Tree.root(tree)
%MyNode{}

schema()

Returns the Zoi schema for this module

tick(tree, tick)

Executes a single tick of the behavior tree.

This function traverses the tree and executes nodes according to their logic, returning the final status and updated tree state.

Examples

iex> tree = Jido.BehaviorTree.Tree.new(root_node)
iex> tick = Jido.BehaviorTree.Tick.new()
iex> {status, updated_tree} = Jido.BehaviorTree.Tree.tick(tree, tick)
{:success, %Jido.BehaviorTree.Tree{}}

tick_with_context(tree, tick)

Executes a single tick with context, returning the updated tick.

This variant is used by Jido.Agent.Strategy.BehaviorTree to thread agent state and directives through the tree during traversal.

Unlike tick/2, this function returns the updated tick which may contain modified agent state and accumulated directives from Action nodes.

Examples

iex> tree = Jido.BehaviorTree.Tree.new(root_node)
iex> tick = Jido.BehaviorTree.Tick.new_with_context(blackboard, agent, [], ctx)
iex> {status, updated_tree, updated_tick} = Jido.BehaviorTree.Tree.tick_with_context(tree, tick)

traverse(tree, fun)

@spec traverse(t(), (Jido.BehaviorTree.Node.t() -> Jido.BehaviorTree.Node.t())) :: t()

Traverses the tree and applies a function to each node.

The function receives the node and should return an updated node.

Examples

iex> tree = Jido.BehaviorTree.Tree.new(root_node)
iex> updated_tree = Jido.BehaviorTree.Tree.traverse(tree, &reset_node/1)
%Jido.BehaviorTree.Tree{}

valid?(tree)

@spec valid?(t()) :: boolean()

Checks if the tree is valid (has a root node that implements Node behavior).

Examples

iex> tree = Jido.BehaviorTree.Tree.new(valid_node)
iex> Jido.BehaviorTree.Tree.valid?(tree)
true