beehave
beehave copied to clipboard
Choose measurement strategy on time nodes
Godot version: 4.2
Describe the bug
Both delayer and cooldown update their internal timer using get_physics_process_delta_time()
on each tick. However, if you update your tree every 20 frame just like I do, this mean that it take 20 time the desired amount.
There is a few ways to make it tick-independent. I would store the time at before_run, then each tick compare if the difference betwen now and then is higher than the desired amount. But you could also create_timer
.
To Reproduce Add a Cooldown or delay node, set a wait_time to 1. set the behavior tree tick rate to 20. Wait 20 second to see the desired behavior.
Expected behavior waiting 1 second
The only feasible way I see here is to add a new enum to time dependent nodes that define how the is measured, e.g. "tick based" or "clock based"
Each has their use-cases. I will implement this for V3
@bitbrain I have been thinking about this issue for a couple of days now because I came across an issue in my project where my cooldown node was in a deeply nested branch which wasn't ticked frequently. This made the cooldown much longer because the cooldown node was ticked so infrequently. In the end, I had to roll out my own solution, which was pretty much what @Remi123 suggested, taking a timestamp when the cooldown was started and comparing it to the current time on tick to determine SUCCESS
/FAILURE
. It made me wonder in which use cases the tick-based solution would be preferable but I couldn't come up with any.
One edge case that would have to be worked around with the clock-based solution was game pausing, but that wouldn't be too difficult.
There's also a bug with the current implementation, where it's hardcoded to use physics_process_delta_time
but that will result in incorrect cooldown in trees that use idle ProcessThread
, instead of the default physics thread. However, this is somewhat unrelated to this issue so let me know if I should open a separate ticket.