2
\$\begingroup\$

When designing a behaviour tree that controls an agent, is it possible to construct the tree so that the agent first attempts task A, then depending on whether task A succeeds it attempts either task B or task C? That is, if A succeeds, the agent attempts task B, otherwise it attempts task C? Kind of like the ternary conditional operator?

The following may at first glance seem to work:

* Selector
|
+---* Sequence
|   |
|   +---* A
|   |
|   +---* B
|
+---* C

or equivalently, Selector(Sequence(A, B), C). However, if A succeeds and B fails, the sequence will still fail and C will be attempted (which it shouldn't since A succeeded).

This tree does run B if A succeeds and C if A fails and never runs both B and C:

* Selector
|
+---* Sequence
|   |
|   +---* A
|   |
|   +---* B
|
+---* Sequence
    |
    +---* Inverter
    |   |
    |   +---* A
    |
    +---* C

or equivalently, Selector(Sequence(A, B), Sequence(Inverter(A), C)). This is assuming that A yields the same result both times (oterwise either none of B and C will be attempted, or both will be attempted). However, this has the issue that will be attempted A twice if either either A or B fails.

What I want to achieve could be pseudo-coded like A ? B : C or like B if A else C. Can this be achieved with a behaviour tree?

\$\endgroup\$
2
\$\begingroup\$

When you don't care about whether the whole subtree returns success of failure, then you could use the first version and wrap B in a Succeeder (a decorator which replaces the return value of its child with success):

* Selector
|
+---* Sequence
|   |
|   +---* A
|   |
|   +---* Succeder 
|       | 
|       +---* B
|
+---* C

That way C won't be executed no matter if B succeeds of fails. The problem with this is that the tree one layer above this branch won't be informed correctly about whether B succeeded or failed.

You could also solve this issue by adding the ability to set and check variables to your behavior tree system:

* Selector
|
+---* Sequence
|   |
|   +---* A
|   |
|   +---* Set ( "aSuccess", true )
|   |
|   +---* Fail
|
+---* Sequence
|   |
|   |---* Check ( "aSuccess", true )
|   |
|   |---* B
|
+---* C

Introducing variables can make behavior trees much more powerful. But be careful to not overuse them, or you will start to lose many of the advantages of behavior trees like re-usability and readability.

And last but not least, there is of course always the option to invent your own nodes. When you really want that IfThenElse composite node, just create it. It's far from the weirdest thing I have seen in behavior tree systems.

\$\endgroup\$
  • \$\begingroup\$ Thanks. Introducing an IfThenElse node probably makes the most sense in my case, but if I need to be able to remember things for longer I will definitelly look into using variables. \$\endgroup\$ – HelloGoodbye Feb 18 '18 at 8:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.