NodeCanvas Forums › Support › Dynamic node execution order
Tagged: Execution order
Hi.
I have a dynamic node checking for a bool (playerDetection) and an action happening (wander).
The problem I have is that when it becomes true, it’s OnExecute gets called before the previous action’s OnStop (which I use to reset some things).
My questions are: is that the expected execution order? If so, how would I go about reseting things then?
Thanks in advance.
Hello,
Can you please post a screenshot of the graph so that I can see better the setup? What dynamic node are you using specifically? Conditional Decorator, Sequencer, Selector, Parallel?
Thank you.
Join us on Discord: https://discord.gg/97q2Rjh
It’s the transition between the running node (which has the OnStop I use to reset things) and the dynamic conditional decorator. The action underneath it executes it’s OnExecute before the OnStop of the current node.
If that’s the expected behaviour, can you elaborate on why that is? (so that I can build my trees according to the intended design)
Hello again,
Thanks for the extra details.
It is actually neither intended, nor a bug, but rather a limitation on execution order when using dynamic nodes. Please allow me to explain what is going on:
When using a Dynamic Node (in this case the Dynamic Selector), the selector will keep reevaluating/executing all the leftmost child nodes of the currently Running child node. As soon as another child node on the left return Success (in case of Selector), the currently Running node will be interrupted (stopped) and the flow will continue down the new flow branch.
What this means, is that for a Success Status to be returned from a leftmost child node in the first place, that child node needs to be executed first (to determine Status) and only then the currently Running child node be interrupted.
As a result, what naturally happens is that OnExecute is called first (which is responsible for returning a Status.Success in the first place back to the Dynamic Selector), and only then the OnStop is called in the currently Running child node due to the interruption taking place from that Dynamic Selector.
I really hope this explanation made sense as to clarify why and what is going on.
OnExecute callbacks will of course always execute in the correct order, but OnStop callbacks and depending on the situation (specifically moving from a right-most node to a left-most node due to a parent Dynamic node), are not called in order as explained above. As such, when using Dynamic nodes (and even in general), it is best to not depend on the order of execution for the OnStop callbacks to “prepare” the next tasks, from a previous task. Ideally, each task should be as independent as possible and this is why the OnStop callback should best be used only to “reset” things relevant to the task iteself.
Using OnExecute though, once again, is completely safe execution-order wise.
Please let me know if that helps at all.
If you let me know what you are after in a bit more detail, I am sure we could find another solution to what you want to achieve, without relying on the OnStop callback.
Thank you!
Join us on Discord: https://discord.gg/97q2Rjh
Hi, sorry for the huge delay.
That clarified a lot, thanks!
What I want to do is to reset my walking script’s variables (such as target and path) and set in the animator that I’m no longer walking.
I think the an appropriate place to put something like that would be on the stop of the right dynamic selector, as everything below it is movement stuff and nothing on the left is about movement.
But I can’t have an OnStop on a composite or decorator right?
Anyway, that has already helped cement a bit how I should handle some things. Thanks a lot!
Hello and sorry for the late reply (I was ill).
I am very glad that clarifies things and not complicate them as I would fear my explanation would 🙂
Since ‘OnStop’ callbacks are related to ActionTasks, no you can’t have an OnStop callback on a Composite or Decorator, since none of the Composites or Decorators (at least the stock ones) can’t have an Action Task attached to them (but rather only ConditionTasks).
Having said that, I have gone and experiment with a new Decorator node called “Monitor”. The Monitor Decorator, is monitoring the decorated child for a return status and executes an action if the return status is the one that is being monitored. This can be used for example, to execute an action when something (a branch) completes in the desired status and I think can help in your situation.
I have attached the node for you here to try it out.
Let me know what you think.
Thanks! 🙂
Join us on Discord: https://discord.gg/97q2Rjh
Hi.
After testing a bit, that decorator did exactly what I needed!
Thanks for all the help!
Great! You are very welcome 🙂
I think I will add the Monitor Decorator in the next NodeCanvas version as well. 🙂
Thanks!
Join us on Discord: https://discord.gg/97q2Rjh