-
Notifications
You must be signed in to change notification settings - Fork 18
Building A Behavior Tree
Any given behavior tree is specified as a JSON asset in the module's assets/behaviors
folder, with the .behavior
extension:
To create a new tree, just create a <name>.behavior
file in your module's assets/behaviors
folder and open it in your favorite editor.
The actual tree definition files have a very simple structure: essentially, the .behavior
file only represents the definition of the root (top-most) TreeNode, with all of its children/arguments, recursively. As an example, this is how the file still.behavior
(originally from the WildAnimalsMadness
module) is structured:
{
sequence:[
{
animation : {
play: "engine:Stand.animationPool",
loop: "engine:Stand.animationPool"
}
},
{
sleep : {
time : 3
}
}
]
}
Every TreeNode is required to have a name
. That name is pre-defined for the logic / flow control nodes and some special nodes - a reference of which is here - and every Action and Decorator node has its name specified by the name
field in its BehaviorAction
annotation - more on that here.
This name
represents any and every Node in the JSON defining the tree.
A simple node with no arguments - which includes most Actions - is represented only by writing down its name:
<node-name>
A node which needs some arguments to be specified needs to be written down as an object:
{
<node-name>: {
argument-1: value-1,
<..>
argument-n: value-n
}
}
In the case of Decorators (nodes with strictly 1 child), the child is provided as any other argument, in the form
child: <node-definition>
where <node-definition>
can be any arbitrary node, including composite nodes or other Decorators.
A Composite (multiple-children) node is represented using an array:
{
<composite-node-name> : [
<child-node-1>,
<child-node-2>,
<..>
<child-node-3>
]
}
success
While the JSON standard disallows keys not wrapped in double quotations, our GSON / deserialization implementation for the most part doesn't care about it - at least in terms of behavior tree files. This means that this:
{
sequence: [
{
timer: {time: 5}
},
{
log: {message: Hello!}
}
]
}
is virtually identical to this:
{
"sequence": [
{
"timer": {"time": 5}
},
{
"log": {"message": "Hello!"}
}
]
}
The variant without quotes is a bit more readable and less 'boilerplate-y', but both variants are possible.
However, the canonical - quote-infested - version is the only one 100% officially supported, so if you run into issues with the tree file loading, it is a good idea to try if the issue persists with a canonical JSON version of the same tree.
One very handy tool for converting the terse version into canonical JSON is YAML Parser - simply paste your tree definition into the left pane, and it spits out canonical JSON on the right. It also catches many formatting / syntax errors (but not all, as YAML is a superset of JSON).
You can find examples of behavior trees in action here.