Sign in to follow this  

Question about composite nodes in behavior trees

Recommended Posts

Hey devs,

 

I've been learning a lot about behavior trees, but one thing is a bit confusing to me.

 

On one hand, the behavior tree starts from the root every tick, and re-checks all the conditions, so it can adjust to changes.

On the other hand, a sequence can be used to group perform several actions one after the other.

 

Now, if the sequence finished performing the first action, it will start the second action, but in the next tick, won't it try to evaluate the first action once again?

 

For example, assume a root node sequence, that has 3 children: Walk to door, open door, walk to bed.

So at first it will perform walk to door, and continue performing it (because the walk to door node will return "running" state) until the ai reaches the door.

Then the walk to door node will return success, because the character is already at the door, and the open door node will execute until the door is open.

Next, both the walk to door and open door nodes return success, it will move on to the walk to bed node. After a tick of walking to bed, the ai is no longer near the door, so next time the "walk to door" node is ticked, instead of returning success, it will walk the AI back towards the door and return "running", until it is back at the door.

 

So the way I understand, it will be stuck walking one step from the door to the bed and back, over and over.

 

What am I not getting here?

Share this post


Link to post
Share on other sites
[DISCLAIMER: I haven't used BTs, and honestly I don't get what their appeal is; to me they look like an extremely limited scripting language.]

You can modify your operations slightly to avoid your problem, even if you start from the root of the tree every time: Walk to door if you are outside the room, open door if door is closed, walk to bed.

Just make sure "Walk to door if you are outside the room" returns success if you are at the door or inside the room. Edited by Álvaro

Share this post


Link to post
Share on other sites

It seems that you are missing something. I don't use those BTs (<- disclaimer here), but I can imagine that not every tree should check every parent up to the first node to continue a sequence of actions. In fact, I can even imagine a node making jumps all over the tree (which is strange, but it would even give more creative freedom). BTs are all about juggling with hierarchies and enter/exit leaf nodes. Maybe somebody can give you a more specific answer, are you using an existing tool? Is there anything like a "standard BT"? It's just a tree. 

Edited by RenzoCoppola

Share this post


Link to post
Share on other sites

The AI shouldn't be starting at the root of the behavior tree until it's finished with its current node.

 

This is a pretty good article on the topic ->http://www.gamasutra.com/blogs/ChrisSimpson/20140717/221339/Behavior_trees_for_AI_How_they_work.php

 

Happy coding!

 

Thanks, but then it wouldn't support reaction to state changes. For example, if an agent is walking somewhere, and suddenly an enemy comes near, I expect him to stop the walking and defend himself. (I read the article btw, he doesn't really explain this although he mentions it)

 

 

[DISCLAIMER: I haven't used BTs, and honestly I don't get what their appeal is; to me they look like an extremely limited scripting language.]

You can modify your operations slightly to avoid your problem, even if you start from the root of the tree every time: Walk to door if you are outside the room, open door if door is closed, walk to bed.

Just make sure "Walk to door if you are outside the room" returns success if you are at the door or inside the room.

 

I'm not trying to find a solution for a problem, I'm trying to understand how the "common" design for behavior tree works, and wasn't able to figure this part out from anything that I've read.


It seems that you are missing something. I don't use those BTs (<- disclaimer here), but I can imagine that not every tree should check every parent up to the first node to continue a sequence of actions. In fact, I can even imagine a node making jumps all over the tree (which is strange, but it would even give more creative freedom). BTs are all about juggling with hierarchies and enter/exit leaf nodes. Maybe somebody can give you a more specific answer, are you using an existing tool? Is there anything like a "standard BT"? It's just a tree. 

 

As I said, I'm trying to figure out how "common" BTs should work. I'm sure I'll make my own tweaks and adjustments as necessary, but my question includes two cases which I consider to be fundamental, and from what I've read behavior trees should be able to handle such a problem easily, I'm just not clear on the details of how.

 

Not using any tool in particular, still investigating the subject in order to decide which tool is best for me (or writing my own of course)

Edited by Tomer Barkan

Share this post


Link to post
Share on other sites

When nodes are entered they are handled considering whether or not they are already running. A sequence node, for example, would not restart if it is running. I think that would do the trick.

 

However, the found issues are not new: When I once read about BTs they first sound to be a wonderful tool. Later on during studying existing implementations I saw 2 major drawbacks (where the 2nd one is not inherent to BTs by themselves):

 

a) BTs need crutches to get them work (halfway?) as expected, especially w.r.t. reaction. For example I saw "interruptable" nodes.

 

b) The same BT is used to do everything from decision making down to directly controlling the animation and placement of models. That's mixing of responsibilities, like once done with the nowadays overpowered scene graphs.

 

The conclusion I drew from this is once again: There is no tool to rule them all; instead, use the tool that is appropriate for solving the given single task. In detail:

 

a)  The strict left-to-right execution is not a good thing for decision making. In other words, decision making should be done by using another tool (currently I favor utility based AI for this thing).

 

b) BTs are good for executing (more or less) canned behaviors.

 

 

These are just my 2 Cents.

Share this post


Link to post
Share on other sites

a)  The strict left-to-right execution is not a good thing for decision making. In other words, decision making should be done by using another tool (currently I favor utility based AI for this thing).

That raises another question: Designer tools (BTs, Planning, Utility, FSMs, etc.) VS Computer Simulations (Montecarlo, minimax, gametree searches) VS Blackboxes (the sky's the limit).

Share this post


Link to post
Share on other sites
Posted (edited)

 

That raises another question: Designer tools (BTs, Planning, Utility, FSMs, etc.) VS Computer Simulations (Montecarlo, minimax, gametree searches) VS Blackboxes (the sky's the limit).

 

and your question is? .... 

 

It seems like a strange idiomatical issue. I think the "what to use in which circumstance"/"what to use" could be assumed because of context. 
 

Edited by RenzoCoppola

Share this post


Link to post
Share on other sites

b) The same BT is used to do everything from decision making down to directly controlling the animation and placement of models. That's mixing of responsibilities, like once done with the nowadays overpowered scene graphs.

AI and Animation should be segregated to their own places. The animations belong to the animators. AI belong to AI programmers until we take over animation too (but we would separate into components... I HOPE). 

Share this post


Link to post
Share on other sites

When nodes are entered they are handled considering whether or not they are already running. A sequence node, for example, would not restart if it is running. I think that would do the trick.

 

But then none of the sequences on the way to the current node will be evaluated, because they are all 'running', and the BT won't be able to react to changes...? And same with Selectors.

Share this post


Link to post
Share on other sites

It seems like a strange idiomatical issue. I think the "what to use in which circumstance"/"what to use" could be assumed because of context. 

What I wanted to say: Problems like the one mentioned in the OP may occur because the one tool at hand is not suitable for the job. Splitting the problem into sub-problems and using the correct (whatever that means in the given situation) tool for each one should be preferred.

 

 

When nodes are entered they are handled considering whether or not they are already running. A sequence node, for example, would not restart if it is running. I think that would do the trick.

 

But then none of the sequences on the way to the current node will be evaluated, because they are all 'running', and the BT won't be able to react to changes...? And same with Selectors.

 

Nodes work accordingly to their type. A selector node is allowed to work another way than a sequence node.

Share this post


Link to post
Share on other sites

There's no standard for behaviour trees, as far as I know; I've seen some people implement them starting from the root every time, some people only go from the root when an explicit re-evaluation is needed, and I've seen compromise approaches where the last decision was cached.

 

If it helps, consider the behaviour tree to be deciding the behaviour - and if the behaviour you decide upon this tick is the same behaviour you had decided upon in the previous tick, then the behaviour does not have to be changed, which means its state persists.

Share this post


Link to post
Share on other sites

An update, one way I've seen this solved, is marking which nodes are "interrupting". This means that these nodes will be evaluated every tick (if they are in the path to the current running node), while other nodes will not.

 

Funny thing is, in all the articles I've read that describe how behavior trees work, and even those implementing them, no one mentions this issue... It seems like a kind of problem that everyone would encounter.

Share this post


Link to post
Share on other sites

After a tick of walking to bed, the ai is no longer near the door, so next time the "walk to door" node is ticked, instead of returning success, it will walk the AI back towards the door and return "running", until it is back at the door.

 

These actions would be placed under a sequence node. Therefore, all the actions would be ticked until completion one after the other. There is no going back to a completed action. So when the AI start the "go to bed action", the previous actions have succeeded and are completed, the sequence node won't tick then again. So the AI would go to bed as expected, and won't get back to the door (unless the sequence node is re-initialized and restarted again).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this