Re-evaluation of action node differs if it is in a subtree or not

NodeCanvas Forums Support Re-evaluation of action node differs if it is in a subtree or not

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #15576
    jridd
    Participant

    I think I have an issue that is related to (or same as in https://nodecanvas.paradoxnotion.com/forums/topic/not-expected-subtree-reset/)

    My issue is that I get different kind of behavior in my tree if my node is encapsulated in a subtree or not.

    My action-node evaluation depends on two objects and both has a simple script (ReadyObject) that has a bool field isReady. One of the objects (TheAgent) is connected as agent and one (TheObject) as a BBParameter<ReadyObject>. (It doesn’t really matter if it is an agent or two BBParameters)
    The logic for my action task in quasi code

    To show the issue I found, I have added a Binary Selector so I can switch between using a node and subtree – where the subtree only has a copy of the same node in it with agent and object bound to it.

    My issue starts to occur then I have managed to get my node to evaluate to success so I get to the next step that is a “forever”-running task (in my example, just a wait-until-decorator that keeps evalutate to false)

    When I get to the state that the “forever”-node is running, and I use my task in a simple action-node, re-evaluation of the task won’t happen when change TheAgent.isReady or TheObject.isReady to false. But when I use the action-node from within a subtree it will be re-evaluted each tick thus the state will change between succeed, failed and running, depending on the values of TheAgent.isReady and TheObject.isReady.

    I am not sure what is is the designed or desired behavior, the single-node behavior or the wrapped-in-subtree node behavior, but having different behaviors seems to be wrong.
    In my current use case I would like it to be that the ActionNode will keep re-evaluating as it is doing when wrapped in a subtree, but I guess that might cause other problems in other use-cases or might have some preformance impact.

    What do you say is the correct behavior?

    The attached screenshots shows the different behaviors after we have been in the “forever”-running state with TheAgent.isReady = true and TheObject.isReady = trueshouldsucceed

    and setting the TheAgent.isReady = false shouldfail and setting TheObject.isReady = false shouldfail where left hand part is when evaluating as a plain node and righthand side evaluating the node in a subtree.

    Attachments:
    You must be logged in to view attached files.
    #15581
    jridd
    Participant

    I attach the sandbox
    with my script and tree if you want to try out.
    When in running-mode just change the isReady-field on the ReadyObject-component script attached TheAgent and TheObject in the inspector to fiddle around with the behavior. To change between the node-mode and subtree mode you will need to change a variable in the graph blackboard

    Attachments:
    You must be logged in to view attached files.
    #15589
    Gavalakis
    Keymaster

    Hello there and thanks for the info.

    Please let me clarify. The confusion comes specifically because of the “Dynamic” option and how that works differently for Action Task children versus Condition Task children. The behaviour of the Action Node you have here is the correct one. Action nodes do not re-evaluate per-frame even if their parent is set to be Dynamic. That is because Action nodes can also return Running and if they were to be re-evaluated, then they would not let the other nodes run at all. To demonstrate this please open up ActionNode.cs and comment out lines #38 and #40 as shown bellow.

    Then create a simple behaviour tree like this:
    DynamicRevaluate

    When you enter play mode you will see that as soon as the left wait action is finished and execution moves to the second one, the first wait action is instantly “re-enabled” and interrupts the second one. Without the code change stated above (thus the original code), both wait action tasks execute normally one after the other, which is of course the correct behaviour. This is because Actions are handled differently than other nodes so that they can work correctly in the context of Dynamic parents (as shown in the original code)

    SubTrees on the other hand do not make that distinction since they can contain any type of node and as such this special handling is not happening in the SubTree code. I hope all this was not very confusing 🙂

    To summarize:
    1) Your “RunningTask” I believe should be implemented as a Condition rather than an Action task. Doing this will allow it to work as you’d expect in the context of the Dynamic parent (and similar to how the SubTree behaviour works in your example BT).
    2) I could add an option in the SubTree node to change the behaviour between Action-like or Condition-like.

    Please let me know if the above clarify things up (or confuse things more) 🙂
    Thanks!

    Join us on Discord: https://discord.gg/97q2Rjh

    Attachments:
    You must be logged in to view attached files.
    #15596
    jridd
    Participant

    Thanks. You have clarified so I understand why things are working as it is… Now I have to figure out how to handle to get it to run as I want :), because I showed you a really stripped down simplified version of what we need.

Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.