Behavior Tree v0.3.1 BehaviorTree.Node.Protocol protocol View Source

A protocol so you can define your own custom behavior tree nodes.

If you would like to make your own nodes with custom traversal behavior, you need to implement this protocol. A node is just a wrapper around a collection of children, that defines a context on how to traverse the tree when one of its children fails or succeeds.

Note that any node that has not explicitly implemented this protocol will be considered a leaf.

BehaviorTree is backed by ExZipper.Zipper, so you will need to understand how that library works.

Each function will provide your node as the first argument as per the protocol standard, but many will also include the current zipper as the second argument.

For examples, look at the source of the standard BehaviorTree.Nodes.

Note that your nodes can be stateful if necessary, see the implementation for BehaviorTree.Node.repeat_n/2 for an example.

Link to this section Summary

Functions

Focus your node’s first child

Get the node’s children

What to do when one of your node’s children fail

What to do when one of your node’s children succeeds

Sets the node’s children

Link to this section Types

Link to this section Functions

Link to this function first_child(data, zipper) View Source
first_child(any(), ExZipper.Zipper.t()) :: ExZipper.Zipper.t()

Focus your node’s first child.

In most cases, this will be the first (left-most) child, but in some cases, like for a “random” node, it could be a different child.

The supplied zipper will be focused on your node, and you need to advance it to the starting child. Usually ExZipper.Zipper.down/1 would be desired.

Link to this function get_children(data) View Source
get_children(any()) :: [any()]

Get the node’s children.

Link to this function on_fail(data, zipper) View Source
on_fail(any(), ExZipper.Zipper.t()) :: ExZipper.Zipper.t() | :succeed | :fail

What to do when one of your node’s children fail.

This is the meat of your custom node logic. You can move the zipper’s focus to a different child (usually with ExZipper.Zipper.right/1), or signal that your entire node failed or succeeded by returning the special atom :fail or :succeed.

Note that you will need to handle any of the ExZipper.Zipper.error/0 types (like :right_from_rightmost) appropriately.

Link to this function on_succeed(data, zipper) View Source
on_succeed(any(), ExZipper.Zipper.t()) :: ExZipper.Zipper.t() | :succeed | :fail

What to do when one of your node’s children succeeds.

This is the meat of your custom node logic. You can move the zipper’s focus to a different child (usually with ExZipper.Zipper.right/1), or signal that your entire node failed or succeeded by returning the special atom :fail or :succeed.

Note that you will need to handle any of the ExZipper.Zipper.error/0 types (like :right_from_rightmost) appropriately.

Link to this function set_children(data, children) View Source
set_children(any(), [any()]) :: any()

Sets the node’s children.