I have been working with NodeCanvas for quite a while now and I thought I had a good understanding of the basic nodes. Alas, I was wrong. I found that dynamic selectors and sequencers (maybe more?) do not reset connections when they are re-evaluated. In my attached example, the “PlayAudio” task will only ever be triggered once. This was actually quite surprising to me, because the word ‘re-evaluated’ (which is appears as ‘revaluated’ in the description of the nodes) suggests to me that it would evaluate the same thing again from the start. Instead, it ‘continues’ executing connections that already finished (with Failure or Success). I’m not even sure what to expect in all cases. Is this by design?
Dynamic Selector and Sequencers indeed do not Reset their child nodes per-frame. If they were to Reset the child nodes per-frame, then a Dynamic Sequencer or Selector would both simoultanously execute child action nodes and act as a parallel. Even worse and in case of Running (actions for example) the action would simply start and reset (restart) per-frame as well. This is also why the Action Node specifically, only execute assigned Action Task only after the node has been reset, which in your example image, it would have been when the tree is restarted, but due to the “Run Forever” action you are using, the tree is “locked” forever running that node.
If you were to return Success instead of Failure on your action node on the left, then the tree would work correctly (as far as I understand what the expected behaviour is), since the Selector (regardless of Dynamic or not) looks to higher priority child nodes that return Success (not Failure).
If they were to Reset the child nodes per-frame, then a Dynamic Sequencer or Selector would both simoultanously execute child action nodes and act as a parallel.
I’m not sure I follow your explanation. A dynamic selector may already execute multiple child connections right? As long as child connections finish within the same update (without returning Running), the selector will continue iterating over the available alternatives. As soon as a higher priority node returns Running, it resets the other connection that was Running before.
Even worse and in case of Running (actions for example) the action would simply start and reset (restart) per-frame as well.
I would not expect it to reset a connection that is running, because in that case the result is still pending. However, after a Selector connection finishes and returns Failure or even Optional (or maybe anything but Running?), I think it would be more logical to reset the connection before next time it is re-evaluated. In my example resetting the left connection actually makes it feel less like a Parallel node to me. Right now it is keeping track of the state of multiple connections.
My example is a minimal example which I specifically constructed to show the (for me) unexpected behavior of a dynamic selector. Imagine both the left connection and the right connection are larger trees with much more logic in them. There are several ways in which the left part can fail, but I want to keep trying the left side each update. As long as that keeps failing, I want to continue executing the right hand side, but as soon as the left hand side can be executed, the right had side should be interrupted. (which dynamic selector already does)
Oh, and in this example, the dynamic selector is the start node, which it often isn’t. In this case you could say “just return success instead and it will work”, but that will complete the selector, which I don’t want in my larger tree.