CooldownDecorator and DelayDecorator never call after_run method of their child
Godot version: 4.2.1
To Reproduce Steps to reproduce the behavior:
- Create an empty scene with BeehaveTree as root node
- Add
DelayDecoratororCooldownDecoratoras its child - Add ActionLeaf as decorator's child
- Extend the ActionLeaf script with the following code:
extends ActionLeaf
func tick(actor: Node, blackboard: Blackboard) -> int:
return SUCCESS
func after_run(actor: Node, blackboard: Blackboard) -> void:
print('I finished running')
Expected behavior 'I finished running' message printing out in the output every tick.
Actual behaviour No message is being printed out.
I've also encountered this. I found it because I have a CooldownDecorator with a SelectorComposite inside of it. Since after_run never gets called on the SelectorComposite after a SUCCESS, it thinks the successful child node is still running, and skips all the children before it.
You can see in this screen capture how part of the subtree keeps lighting up without ever going back to the first child of the decorator's inner sequence: https://github.com/user-attachments/assets/49d3a5f9-6de1-4f33-b802-f30cd7cea3bc
I was able to work around this by subclassing CooldownDecorator and adding a call to after_run when the superclass's tick returns something other than RUNNING. This got things working as expected again.
It also seems that other decorators are not consistently calling before_run and after_run:
-
CooldownDecoratordoes not callafter_run -
DelayDecoratordoes not callafter_run -
LimiterDecoratordoes not callbefore_run -
UntilFailDecoratordoes not callafter_run -
ReapeaterDecoratorcallsbefore_runone time, but callsafter_runafter each repetition that returnsSUCCESSorFAILURE(I'm unsure which of these is correct, but I would expect them to match.)