0
\$\begingroup\$

For context, I am coding a naive implementation of behavior trees myself, in C#. Let's say I have two scenarios that I want to create behaviors for. Both AI's will traverse/patrol four specific locations (markers), in order, and then repeat the path.

AI 1) Upon seeing the player, freeze. Once the player is out of sight, begin patrolling again, but from the very first marker (i.e. restart).

AI 2) Upon seeing the player, freeze. Once the player is out of sight, begin patrolling again, but from whatever marker it was previously on before being interrupted by the player (i.e. carry on).

I would expect both of these behaviors to be modeled by first checking for the player, and if that fails proceeding further down to a Sequence node that contains four children, each being a "traverse to maker" behavior.

In other words -> after a behavior is interrupted by a node higher up the tree, how do I retain the current place in a sequence and carry on when we finally make it back down the tree again?

\$\endgroup\$
0
\$\begingroup\$

Put all the information needed to restore the state you're interrupting into some structure representing the context of the current action. This is likely at least:

  • a reference to the tree about to be interrupted (if you have more than one tree capable of processing at a time)
  • a reference to the node about to be interrupted
  • state specific to that node (e.g., destination if a "move to target" node, et cetera)

You may want to stuff in some extra information like the time of interruption, so that you can do some logic to enable AI to disregard old actions if their interruption ended up lasting more than X seconds, or whatever.

Put all that kind of stuff in something called, say, InterruptedActionContext. When a node is about to be interrupted, build one of those contexts from the node that is currently executing and stuff it onto a stack of interrupted actions, and then proceed with the interrupting node.

Whenever a node naturally completes (or a branch of the tree naturally completes; whatever criteria is most important to you), check the interruption stack to see if you should pop something from it and return to a previously-interrupted behavior. Otherwise continue as you would normally.

\$\endgroup\$
  • \$\begingroup\$ Thanks, this definitely makes sense. I'm curious as to your thoughts on how I would specify the difference between the two AI's in my example with this setup, assuming I want a system that supports BOTH behaviors. Where should I put the logic of choosing that AI #1 retains its state, but AI #2 resets after the interrupt is dealt with? Should it be in the leaf node that is interrupted? Or have both AI's share the same "Move-To" node and have it above that in their respective trees? \$\endgroup\$ – Takaji Messer Feb 9 '18 at 16:47
  • \$\begingroup\$ The difference in them is just be data: they do exactly the same thing, except they move to different points in the world before resuming patrol. The actual task node for the patrol can have a field for "position to resume from" and a flag/enum on the node can indicate whether this field is filled out with current position or patrol start position on interrupt. Or if you have arbitrary scripts attached to these nodes, have the script directly set the resume position. It's hard to say without more detail about your code, but it should be fairly straightforward. \$\endgroup\$ – Josh Feb 9 '18 at 16:52

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.