bitbrain / beehave

🐝 behavior tree AI for Godot Engine
https://bitbra.in/beehave
MIT License
1.85k stars 116 forks source link

Choose measurement strategy on time nodes #319

Open Remi123 opened 6 months ago

Remi123 commented 6 months ago

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

bitbrain commented 6 months ago

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

rxlecky commented 3 months ago

@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.