Understanding aborts with inverted children

I am a bit confused, should this not trigger my lower priority abort?

"Is storage full" returns fail, which means inverter returns success. But it never enters "Find gatherable tree", it just stays in idle. Why is this?

1631454458511.png
 

Nightkin

New member
Your conditional abort should be set to "self" instead of "lower priority" I think. In this tree, you're telling your second sub-tree (the "go to workplace" one) to be interrupted whenever any node of your first sub-tree (the "is storage full" one) changes status. What it does right now, since "idle" does nothing at all, and nothing else happens, is constantly re-evaluate "is storage full" without noticing any change, so nothing gets aborted anyway and your NPC keeps twiddling its virtual thumbs.
 
Your conditional abort should be set to "self" instead of "lower priority" I think. In this tree, you're telling your second sub-tree (the "go to workplace" one) to be interrupted whenever any node of your first sub-tree (the "is storage full" one) changes status. What it does right now, since "idle" does nothing at all, and nothing else happens, is constantly re-evaluate "is storage full" without noticing any change, so nothing gets aborted anyway and your NPC keeps twiddling its virtual thumbs.
While this didnt work it did tell me what was wrong, the first node never changes status, its the second node that does. Which apparently does not trigger the conditional abort, which makes sense. I can fix this now, thanks!
 

Nightkin

New member
Welcome!

Indeed conditional aborts check only conditional nodes, I think (needs to be confirmed but that's how I understand it), so your "is storage full" conditional needs to change status in order to trigger a "self" conditional abort located in the sequence containing it.
 
Welcome!

Indeed conditional aborts check only conditional nodes, I think (needs to be confirmed but that's how I understand it), so your "is storage full" conditional needs to change status in order to trigger a "self" conditional abort located in the sequence containing it.
Makes sense, I opted for a more performant solution in the end. Its messier but will only run the check every X seconds instead of every tick 1631536068983.png
 
Welcome!

Indeed conditional aborts check only conditional nodes, I think (needs to be confirmed but that's how I understand it), so your "is storage full" conditional needs to change status in order to trigger a "self" conditional abort located in the sequence containing it.

Sorry to write again so soon but I’ve spent 5 hours trying to figure this out now, I guess I dont fully get it yet.

When this tree starts branch 1 is run as expected and I can go through it all just fine. However if node 2 fails, I would expect it to exit the branch (as it does) and then (since there is a conditional abort on branch 1) I would expect it to restart again the next tick since both conditionals return Success. However it never get past node 3 even though its returning success.

What am I not seeing here? Im sure I am misunderstanding something.

eW1TLSkB9SigiqoBQR1I4CoJS
 

Justin

Administrator
Staff member
Conditional aborts work by triggering when the status changes, not only when the task returns success. Looking at your screenshot it looks like your left branch returned failure and Is Storage Full / Can Find Storage Source continue to return their same status so the abort never triggers.

In cases where you need more direct control over aborts you should use the interrupt and perform interruption tasks. This gives you direct control over when to do the abort. The Mini Gauntlet (or RTS sample project) has an example of these interruptions.
 
Conditional aborts work by triggering when the status changes, not only when the task returns success. Looking at your screenshot it looks like your left branch returned failure and Is Storage Full / Can Find Storage Source continue to return their same status so the abort never triggers.

In cases where you need more direct control over aborts you should use the interrupt and perform interruption tasks. This gives you direct control over when to do the abort. The Mini Gauntlet (or RTS sample project) has an example of these interruptions.

Makes sense, thanks.

Is there some way to make a conditional abort evaluate all children before triggering? Meaning if I have 3 conditional children in the sequence, the conditional abort only triggers if all 3 return success (if the last return was a failure).
 

Justin

Administrator
Staff member
Is there some way to make a conditional abort evaluate all children before triggering? Meaning if I have 3 conditional children in the sequence, the conditional abort only triggers if all 3 return success (if the last return was a failure).
Yes, you can use the Stacked Conditional task.
 
Yes, you can use the Stacked Conditional task.

Perfect in theory but the conditional task cannot reference my dynamic variables.

In the screenshot you can see I use the same conditional before the stacked conditional.

In the stacked conditional, "workplace" is null, but in the conditional to the left of it "workplace" has the correct value.

1631868919420.png
 
Last edited:

Justin

Administrator
Staff member
I just tested the stacked conditional with dynamic variables and it worked. Are you using the fast enter to playmode? If so it could be related to this and I'll send you a fix.
 
I just tested the stacked conditional with dynamic variables and it worked. Are you using the fast enter to playmode? If so it could be related to this and I'll send you a fix.

I re-use that same dynamic variable in several places in the tree, so I dont think that is the issue, "workplace" is used in 6 of those successful nodes but fails when it gets to the stacked conditional:
1631957832349.png



I am getting some really strange results. If I take the variable that fails "workplace" and assign it to another variable using a set-node, it works fine. But the workplace variable is not the issue because I use that in another 7 nodes in that same tree. Very confusing. I guess I can use this hack for now.

Thanks for always trying to help.

1631956830669.png
 
Last edited:
I just tested the stacked conditional with dynamic variables and it worked. Are you using the fast enter to playmode? If so it could be related to this and I'll send you a fix.

Even weirder, as long as I use a "Set Shared Game Object" node first, even the "workplace" variable (target value) works.
 

Justin

Administrator
Staff member
Can you send me a small repro scene so I can take a look at it? The only other thing that I can think of is that the dynamic variable type is different between the tasks so then it won't be shared.
 
Can you send me a small repro scene so I can take a look at it? The only other thing that I can think of is that the dynamic variable type is different between the tasks so then it won't be shared.

I kind of solved this, I guess? It seems using the name "workplace" for the dynamic variable was the issue. I use it in other external trees as well, but I thought that wouldnt have any effect since the trees are never run at the same time (can only have 1 workplace). Changing the name to "clownfaceshitshitshit" solved it. Might have to refactor eventually tho
 

Justin

Administrator
Staff member
Ahh, that makes sense. When the tree loads it replaces all of the shared variable instances with that name so it looks like the multiple external trees was the issue. For situations like this I recommend using regular variables instead of dynamic variables to make it easier to track.
 
Top