[SOLVED] Unexpected Push/Pop order on Utility Selector

LinceWorks

New member
Hi,
We are experiencing an unexpected behavior with Push/Pop execution order after calling the following function of "UtilitySelector" Task.
Interrupt(Behavior behavior, Task task, Task interruptionTask, TaskStatus interruptTaskStatus = TaskStatus.Failure);
The following simplified example shows the issue:

1605114929779.png
(Capture 1: "Return Score A" OnStart is executed as expected.)

1605114971706.png
(Capture 2: "Return Score B" has more score than "A" but execution order is not triggered as expected)

As we can see at Capture 1, initially, "Return Score A" has more score than "Return Score B". When "B" reaches more score than "A" (Capture 2) becomes the current executed task, but, "Return Score A.OnEnd()" is called after "Return Score B.OnStart()". We expected the execution to be "Return Score A.OnEnd()" and then "Return Score B.OnStart()".

We can confirm that this issue starts to happen after upgrading from 1.6.4 to 1.6.6.

Is this a bug or we could be doing something wrong?

Thanks!
- Xavi
 

Justin

Administrator
Staff member
Internally the Utility Selector is similar to a parallel task where it can run multiple children at the same time. The parallel task execution order was reworked in 1.6.6 so it now reevaluates in the correct order. As a result of this the utility selector order isn't the same as what it was before. The reason for this is that the tasks are reevaluated from left to right, so the execution order looks like:

Frame 0:
ReturnScoreB has a higher utility than ReturnScoreA, interrupts ReturnScoreA

Frame 1:
ReturnScoreB Starts (leftmost child of the Utility Selector)
ReturnScoreA Ends (rightmost child of the Utility Selector)

Prior to version 1.6.6 ReturnScoreB would have been started after ReturnScoreA ends, but if the scenario was flipped so ReturnScoreA interrupted ReturnScoreB then you would have gotten similar results as what you are seeing now. In short you should not depend on a certain execution order under the Utility Selector since it is technically a task that can run multiple children at any time.
 
Top