My attempt to bring Behavior Trees to js with support for a visual editor. This project was reverse engineered around the open source tool Groot. This Groot tool was designed to output trees for BehaviorTree.CPP. Note that this library is meant as a js port of BehaviorTree without being a direct port. Many features supported by BehaviorTree.CPP are not supported by this library. (I didn't look at the source code of BehaviorTree.CPP at all when developing this library).
This is a screenshot of Groot with a logfile that was written to disk during one of the unit tests.
Create an xml tree file with Groot. Bind to a "Blackboard" object during instantiation of the class in js. Execute the tree.
The blackboard stores both variables and functions. If the functions are async they are executed as such. Access blackboard variables with ${}
notation, similar to the notation in template literals https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals.
By default, functions expect a single argument which is a object with keys. The Groot tool allows the setting and retreiving of these keys.
Functions can be called with normal arguments. To do this name the inputs like _in_0
and _in_1
in the Groot Action notes.
This app suports a subset of node that Groot supports. As of today I'm not sure how to make "reactive" node types work. For this reason I've skipped them.
Node Type | Support Status |
---|---|
Sequence | + Supported |
Fallback | + Supported |
Inverter | + Supported |
ForceSuccess | + Supported |
Action | + Supported |
Condition | + Supported |
AlwaysFailure | + Supported |
AlwaysSuccess | + Supported |
ForceFailure | + Supported |
Repeat | + Supported |
SetBlackboard | + Supported |
RetryUntilSuccesful | + Supported |
KeepRunningUntilFailure | ! Plan To Support |
Switch2 | ! Plan To Support |
Switch3 | ! Plan To Support |
Switch4 | ! Plan To Support |
Switch5 | ! Plan To Support |
Switch6 | ! Plan To Support |
BlackboardCheckDouble | ! Plan To Support |
BlackboardCheckInt | ! Plan To Support |
BlackboardCheckString | ! Plan To Support |
Timeout | ! Plan To Support |
SubTree | ! Plan To Support |
Delay | ! Plan To Support |
SubTreePlus | - Will Not Support |
ReactiveFallback | - Will Not Support |
ReactiveSequence | - Will Not Support |
IfThenElse | - Will Not Support |
ManualSelector | - Will Not Support |
SequenceStar | - Will Not Support |
Parallel | - Will Not Support |
WhileDoElse | - Will Not Support |
exe
is a member which has the tree. Each tree node can have a member called seq
which is an array of children. Each tree node has a member called path
which is a dot notation of numbers. path
skips the root node, however in most (all?) trees the first node is a nesting type (sqeuence, fallback, invert) etc. Thus the first element of the path will always be 0
.
If a fallback has 2 failures and a success under it. The nodes will stay marked as such. Once the final fallback has completed. The log will "go back" and mark the nodes from "failure" to "idle". The success will be marked from "success" to "idle". This "dims" the entire subtree. Then the Fallback will be marked success. I don't copy this behavior very well atm.
Because the log file-format is so complex, I opted to wrap part of actual BehaviorTree.CPP in WASM, and then call the internals to get log files. This is optional as running WASM can be complicated. If you don't need logs you can skip reading this. See setFileLogger()