Skip to content

Commit

Permalink
Implement a customizable tick rate to improve perf (closes #255). (#258)
Browse files Browse the repository at this point in the history
* Implement a customizable tick rate to improve perf (closes #255).

* Add unit test.

* Add test reports to gitignore.

---------

Co-authored-by: miguel <[email protected]>
  • Loading branch information
lucasrafael98 and bitbrain authored Dec 4, 2023
1 parent d607a20 commit 8228d42
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ export_presets.cfg
.mono/
data_*/
.godot/

reports/
29 changes: 22 additions & 7 deletions addons/beehave/nodes/beehave_tree.gd
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ signal tree_enabled
signal tree_disabled


## Wether this behavior tree should be enabled or not.
## Whether this behavior tree should be enabled or not.
@export var enabled: bool = true:
set(value):
enabled = value
Expand All @@ -35,6 +35,11 @@ signal tree_disabled
return enabled


## How often the tree should tick, in frames. The default value of 1 means
## tick() runs every frame.
@export var tick_rate: int = 1


## An optional node path this behavior tree should apply to.
@export_node_path var actor_node_path : NodePath:
set(anp):
Expand Down Expand Up @@ -95,6 +100,7 @@ signal tree_disabled

var actor : Node
var status : int = -1
var last_tick : int = 0

var _internal_blackboard: Blackboard
var _process_time_metric_name : String
Expand Down Expand Up @@ -132,19 +138,28 @@ func _ready() -> void:
BeehaveGlobalDebugger.register_tree(self)
BeehaveDebuggerMessages.register_tree(_get_debugger_data(self))

# Randomize at what frames tick() will happen to avoid stutters
last_tick = randi_range(0, tick_rate - 1)


func _physics_process(delta: float) -> void:
_process_internally(delta)
func _physics_process(_delta: float) -> void:
_process_internally()


func _process(delta: float) -> void:
_process_internally(delta)
func _process(_delta: float) -> void:
_process_internally()


func _process_internally(delta: float) -> void:
func _process_internally() -> void:
if Engine.is_editor_hint():
return

if last_tick < tick_rate - 1:
last_tick += 1
return

last_tick = 0

# Start timing for metric
var start_time = Time.get_ticks_usec()

Expand Down Expand Up @@ -250,7 +265,7 @@ func _exit_tree() -> void:

# Called by the engine to profile this tree
func _get_process_time_metric_value() -> int:
return _process_time_metric_value
return int(_process_time_metric_value)


func _get_debugger_data(node: Node) -> Dictionary:
Expand Down
Empty file modified runtest.sh
100644 → 100755
Empty file.
20 changes: 20 additions & 0 deletions test/beehave_tree_test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ func test_normal_tick() -> void:
scene.beehave_tree._physics_process(1.0)
assert_that(scene.beehave_tree.status).is_equal(BeehaveNode.SUCCESS)

func test_low_tick_rate() -> void:
var scene = create_scene()
scene_runner(scene)
scene.beehave_tree.tick_rate = 3
scene.beehave_tree._physics_process(1.0)
assert_that(scene.beehave_tree.status).is_equal(-1)
scene.beehave_tree._physics_process(1.0)
assert_that(scene.beehave_tree.status).is_equal(-1)
scene.beehave_tree._physics_process(1.0)
assert_that(scene.beehave_tree.status).is_equal(BeehaveNode.SUCCESS)

func test_low_tick_rate_last_tick() -> void:
var scene = create_scene()
scene_runner(scene)
scene.beehave_tree.tick_rate = 3
scene.beehave_tree.last_tick = 1
scene.beehave_tree._physics_process(1.0)
assert_that(scene.beehave_tree.status).is_equal(-1)
scene.beehave_tree._physics_process(1.0)
assert_that(scene.beehave_tree.status).is_equal(BeehaveNode.SUCCESS)

func test_nothing_running_before_first_tick() -> void:
var scene = create_scene()
Expand Down

0 comments on commit 8228d42

Please sign in to comment.