Communicating between behavior trees - how?

I’m trying to figure out the best option for communicating between two different behavior trees. It seems that events are global to a particular tree only. Other trees (including subtrees) don’t see events generated by a tree.

Similarly, the notepad really only seems to be global to a particular behavior tree. Because of the way Javascript handles arguments, I can’t send a variable down into a subtree from a parent and have the subtree directly update the parent (as near as I can tell).

I found the blackboard, which seems to be truly global across all the behavior trees from the root on down. This is currently what I’m using, but it’s not really documented, and doesn’t appear in sample code, which makes me wonder if it’s going away at some point.

Here’s my main use case for this kind of thing:

I set off the “idle.bt” from the sample code in parallel with some of my skill, so Jibo looks around at random while doing stuff, and isn’t static. I control the parameters of the looking (how wide the gaze is), by placing the functions the idle bt uses to randomly pick the look point on the blackboard, and changing those functions in other behavior trees. (That’s the first use.)

The other use is when I want to play an animation from another behavior tree. If I just play it, the idle behavior tree takes over and starts looking around partway through the animation. So I set a flag variable on the blackboard that the idle can use, and skip its normal motions if another behavior tree set the flag.

Are there other ways of doing this? I don’t really want to stick everything in one big behavior tree - it would get unwieldy. Are there ways of sending events between behavior trees? Will the blackboard always be around?

2 Likes

Hi Chris - I was just looking at the sample code docs regarding a child bt called from a subtree defined in a parent bt.

The getNotepad argument allows a parent tree to pre-populate a Subtree’s notepad, allowing a behavior trees to pass arguments to a subtree. The behaviors/10-subtrees/choose-animation.bt plays an animation according to a property on its notepad, which is set by its parent tree.

See item 10 Subtrees

I like your blackboard idea also

2 Likes

Yes, I’ve done that. That lets you essentially send arguments to a Subtree. I want to send info from one Subtree to another Subtree running in parallel from the same root, with both trees still executing (i.e not by sending result information back through the root.)

Hi Chris,

You can absolutely continue to use blackboard in that fashion and there are no plans to change how blackboard works at the moment. That being said, there is another, somewhat more targeted way to pass variables between sub-trees.

Similar to how you can set a variable to be global within a sub-tree/.bt using notepad.example you can set a variable to be returned to a parent behavior (such as main.bt) by using result.example .

Once you have done that you can reference that variable in the onResult behavior argument for a Subtree behavior within your parent behavior that plays the subtree. A good example of this can be seen in our sample code’s 10-subtrees.bt behavior.

That behavior includes 3 subtrees. The third subtree (return-animation.bt) sets result.animation. If you look at the onResult arguments for that subtree back in 10-subtrees.bt you will see that result.animation is referenced back in the parent behavior usingtreeResult.animation. In the case of the example it is referenced in a console.log as seen here:

(treeResult) => {
    console.log('This subtree played ' + treeResult.animation + '.keys');
}

So, in summary, you can absolutely use blackboard to set a global variable but, as you noted, that can get unwieldy. Using result. and treeResult. allow for you to pass info from subtrees in a more specified fashion.

I hope that is helpful but definitely let me know if I an clarify anything about that example!

2 Likes