Skip to content

Commit

Permalink
Merge branch 'godot-4.x' into fix_debug_view_runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
bitbrain authored Dec 3, 2023
2 parents f5a871d + 474a541 commit 2fc09c7
Show file tree
Hide file tree
Showing 172 changed files with 2,893 additions and 2,025 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/beehave-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
fail-fast: false
max-parallel: 10
matrix:
godot-version: ['4.0.3', '4.1.1']
godot-version: ['4.0.4', '4.1.3', '4.2']

name: "🤖 CI on Godot ${{ matrix.godot-version }}"
uses: ./.github/workflows/unit-tests.yml
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ In order to avoid bugs creeping into the codebase, every feature is covered by u

1. [Download Latest Release](https://github.com/bitbrain/beehave/releases/latest)
- (optional) access latest build for [Godot 3.x](https://github.com/bitbrain/beehave/archive/refs/heads/godot-3.x.zip), [Godot 4.x](https://github.com/bitbrain/beehave/archive/refs/heads/godot-4.x.zip)
2. Unpack the `beehave` folder into your `/addons` folder within the Godot project
2. Unpack the `addons/beehave` folder into your `/addons` folder within the Godot project
3. Enable this addon within the Godot settings: `Project > Project Settings > Plugins`
4. Move `script_templates` into your project folder.

To better understand what branch to choose from for which Godot version, please refer to this table:
|Godot Version|Beehave Branch|Beehave Version|
Expand Down
5 changes: 3 additions & 2 deletions addons/beehave/blackboard.gd
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
## The blackboard is an object that can be used to store and access data between
## multiple nodes of the behavior tree.
@icon("icons/blackboard.svg")
class_name Blackboard extends Node

## The blackboard is an object that can be used to store and access data between
## multiple nodes of the behavior tree.

var blackboard: Dictionary = {}

func keys() -> Array[String]:
Expand Down
2 changes: 2 additions & 0 deletions addons/beehave/debug/debugger_tab.gd
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func _ready() -> void:

var button := Button.new()
button.flat = true
button.name = "MakeFloatingButton"
button.icon = get_theme_icon(&"ExternalLink", &"EditorIcons")
button.pressed.connect(func(): make_floating.emit())
button.tooltip_text = "Make floating"
Expand All @@ -45,6 +46,7 @@ func _ready() -> void:

var toggle_button := Button.new()
toggle_button.flat = true
toggle_button.name = "TogglePanelButton"
toggle_button.icon = get_theme_icon(&"Back", &"EditorIcons")
toggle_button.pressed.connect(_on_toggle_button_pressed.bind(toggle_button))
toggle_button.tooltip_text = "Toggle Panel"
Expand Down
8 changes: 2 additions & 6 deletions addons/beehave/debug/graph_edit.gd
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ func _ready() -> void:
layout_button.flat = true
layout_button.focus_mode = Control.FOCUS_NONE
layout_button.pressed.connect(func(): horizontal_layout = not horizontal_layout)
# Godot 4.2+
if has_method("get_menu_hbox"):
call("get_menu_hbox").add_child(layout_button)
else:
call("get_zoom_hbox").add_child(layout_button)
get_menu_container().add_child(layout_button)
_update_layout_button()


Expand Down Expand Up @@ -152,7 +148,7 @@ func get_menu_container() -> Control:
return call("get_zoom_hbox")

# Godot 4.2+
return call("get_menu_hbox").get_parent()
return call("get_menu_hbox")


func get_status(status: int) -> String:
Expand Down
5 changes: 3 additions & 2 deletions addons/beehave/nodes/beehave_node.gd
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
## A node in the behavior tree. Every node must return `SUCCESS`, `FAILURE` or
## `RUNNING` when ticked.
@tool
class_name BeehaveNode extends Node

## A node in the behavior tree. Every node must return `SUCCESS`, `FAILURE` or
## `RUNNING` when ticked.

enum {
SUCCESS,
FAILURE,
Expand Down
85 changes: 63 additions & 22 deletions addons/beehave/nodes/beehave_tree.gd
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
## Controls the flow of execution of the entire behavior tree.
@tool
@icon("../icons/tree.svg")
class_name BeehaveTree extends Node

## Controls the flow of execution of the entire behavior tree.

enum {
SUCCESS,
FAILURE,
RUNNING
}

enum ProcessThread {
IDLE,
PHYSICS
}

signal tree_enabled
signal tree_disabled


## Wether this behavior tree should be enabled or not.
@export var enabled: bool = true:
set(value):
enabled = value
set_physics_process(enabled)

set_physics_process(enabled and process_thread == ProcessThread.PHYSICS)
set_process(enabled and process_thread == ProcessThread.IDLE)
if value:
tree_enabled.emit()
else:
Expand All @@ -27,8 +34,27 @@ signal tree_disabled
get:
return enabled


## An optional node path this behavior tree should apply to.
@export_node_path var actor_node_path : NodePath
@export_node_path var actor_node_path : NodePath:
set(anp):
actor_node_path = anp
if actor_node_path != null and str(actor_node_path) != "..":
actor = get_node(actor_node_path)
else:
actor = get_parent()
if Engine.is_editor_hint():
update_configuration_warnings()


## Whether to run this tree in a physics or idle thread.
@export var process_thread:ProcessThread = ProcessThread.PHYSICS:
set(value):
process_thread = value
set_physics_process(enabled and process_thread == ProcessThread.PHYSICS)
set_process(enabled and process_thread == ProcessThread.IDLE)



## Custom blackboard node. An internal blackboard will be used
## if no blackboard is provided explicitly.
Expand Down Expand Up @@ -61,6 +87,7 @@ signal tree_disabled

BeehaveDebuggerMessages.unregister_tree(get_instance_id())


var actor : Node
var status : int = -1

Expand All @@ -69,40 +96,49 @@ var _process_time_metric_name : String
var _process_time_metric_value : float = 0.0
var _can_send_message: bool = false

func _ready() -> void:
if Engine.is_editor_hint():
return

if self.get_child_count() > 0 and not self.get_child(0) is BeehaveNode:
push_warning("Beehave error: Root %s should have only one child of type BeehaveNode (NodePath: %s)" % [self.name, self.get_path()])
disable()
return
func _ready() -> void:
if not process_thread:
process_thread = ProcessThread.PHYSICS

if actor_node_path:
actor = get_node(actor_node_path)
else:
actor = get_parent()

if not blackboard:
_internal_blackboard = Blackboard.new()
add_child(_internal_blackboard, false, Node.INTERNAL_MODE_BACK)

actor = get_parent()
if actor_node_path:
actor = get_node(actor_node_path)


# Get the name of the parent node name for metric
var parent_name = actor.name
_process_time_metric_name = "beehave [microseconds]/process_time_%s-%s" % [parent_name, get_instance_id()]
_process_time_metric_name = "beehave [microseconds]/process_time_%s-%s" % [actor.name, get_instance_id()]

set_physics_process(enabled and process_thread == ProcessThread.PHYSICS)
set_process(enabled and process_thread == ProcessThread.IDLE)

# Register custom metric to the engine
if custom_monitor:
if custom_monitor and not Engine.is_editor_hint():
Performance.add_custom_monitor(_process_time_metric_name, _get_process_time_metric_value)
BeehaveGlobalMetrics.register_tree(self)

set_physics_process(enabled)
BeehaveGlobalDebugger.register_tree(self)
BeehaveDebuggerMessages.register_tree(_get_debugger_data(self))
if Engine.is_editor_hint():
update_configuration_warnings.call_deferred()
else:
BeehaveGlobalDebugger.register_tree(self)
BeehaveDebuggerMessages.register_tree(_get_debugger_data(self))

child_entered_tree.connect(_on_child_entered_tree)


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


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


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

Expand All @@ -125,6 +161,8 @@ func _physics_process(delta: float) -> void:


func tick() -> int:
if actor == null or get_child_count() == 0:
return FAILURE
var child := self.get_child(0)
if status != RUNNING:
child.before_run(actor, blackboard)
Expand All @@ -144,6 +182,9 @@ func tick() -> int:

func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []

if actor == null:
warnings.append("Configure target node on tree")

if get_children().any(func(x): return not (x is BeehaveNode)):
warnings.append("All children of this node should inherit from BeehaveNode class.")
Expand Down
10 changes: 1 addition & 9 deletions addons/beehave/nodes/composites/composite.gd
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
## A Composite node controls the flow of execution of its children in a specific manner.
@tool
@icon("../../icons/category_composite.svg")
class_name Composite extends BeehaveNode

## A Composite node controls the flow of execution of its children in a specific manner.

var running_child: BeehaveNode = null


func _ready():
if Engine.is_editor_hint():
return

if self.get_child_count() < 1:
push_warning("BehaviorTree Error: Composite %s should have at least one child (NodePath: %s)" % [self.name, self.get_path()])


func _get_configuration_warnings() -> PackedStringArray:
var warnings: PackedStringArray = super._get_configuration_warnings()

Expand Down
8 changes: 4 additions & 4 deletions addons/beehave/nodes/composites/selector.gd
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## Selector nodes will attempt to execute each of its children until one of
## them return `SUCCESS`. If all children return `FAILURE`, this node will also
## return `FAILURE`.
## If a child returns `RUNNING` it will tick again.
@tool
@icon("../../icons/selector.svg")
class_name SelectorComposite extends Composite

## Selector nodes will attempt to execute each of its children until one of
## them return `SUCCESS`. If all children return `FAILURE`, this node will also
## return `FAILURE`.
## If a child returns `RUNNING` it will tick again.

var last_execution_index: int = 0

Expand Down
7 changes: 4 additions & 3 deletions addons/beehave/nodes/composites/selector_random.gd
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
## This node will attempt to execute all of its children just like a
## [code]SelectorStar[/code] would, with the exception that the children
## will be executed in a random order.
@tool
@icon("../../icons/selector_random.svg")
class_name SelectorRandomComposite extends RandomizedComposite

## This node will attempt to execute all of its children just like a
## [code]SelectorStar[/code] would, with the exception that the children
## will be executed in a random order.

## A shuffled list of the children that will be executed in reverse order.
var _children_bag: Array[Node] = []
var c: Node
Expand Down
7 changes: 4 additions & 3 deletions addons/beehave/nodes/composites/selector_reactive.gd
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
@tool
@icon("../../icons/selector_reactive.svg")
class_name SelectorReactiveComposite extends Composite

## Selector Reactive nodes will attempt to execute each of its children until one of
## them return `SUCCESS`. If all children return `FAILURE`, this node will also
## return `FAILURE`.
## If a child returns `RUNNING` it will restart.
@tool
@icon("../../icons/selector_reactive.svg")
class_name SelectorReactiveComposite extends Composite

func tick(actor: Node, blackboard: Blackboard) -> int:
for c in get_children():
Expand Down
10 changes: 5 additions & 5 deletions addons/beehave/nodes/composites/sequence.gd
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
## Sequence nodes will attempt to execute all of its children and report
## `SUCCESS` in case all of the children report a `SUCCESS` status code.
## If at least one child reports a `FAILURE` status code, this node will also
## return `FAILURE` and restart.
## In case a child returns `RUNNING` this node will tick again.
@tool
@icon("../../icons/sequence.svg")
class_name SequenceComposite extends Composite

## Sequence nodes will attempt to execute all of its children and report
## `SUCCESS` in case all of the children report a `SUCCESS` status code.
## If at least one child reports a `FAILURE` status code, this node will also
## return `FAILURE` and restart.
## In case a child returns `RUNNING` this node will tick again.

var successful_index: int = 0

Expand Down
10 changes: 7 additions & 3 deletions addons/beehave/nodes/composites/sequence_random.gd
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
## This node will attempt to execute all of its children just like a
## [code]SequenceStar[/code] would, with the exception that the children
## will be executed in a random order.
@tool
@icon("../../icons/sequence_random.svg")
class_name SequenceRandomComposite extends RandomizedComposite

## This node will attempt to execute all of its children just like a
## [code]SequenceStar[/code] would, with the exception that the children
## will be executed in a random order.

# Emitted whenever the children are shuffled.
signal reset(new_order: Array[Node])

Expand Down Expand Up @@ -49,6 +50,9 @@ func tick(actor: Node, blackboard: Blackboard) -> int:
c.after_run(actor, blackboard)
FAILURE:
_children_bag.erase(c)
# Interrupt any child that was RUNNING before
# but do not reset!
super.interrupt(actor, blackboard)
c.after_run(actor, blackboard)
return FAILURE
RUNNING:
Expand Down
8 changes: 4 additions & 4 deletions addons/beehave/nodes/composites/sequence_reactive.gd
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
@tool
@icon("../../icons/sequence_reactive.svg")
class_name SequenceReactiveComposite extends Composite

## Reactive Sequence nodes will attempt to execute all of its children and report
## `SUCCESS` in case all of the children report a `SUCCESS` status code.
## If at least one child reports a `FAILURE` status code, this node will also
## return `FAILURE` and restart.
## In case a child returns `RUNNING` this node will restart.
@tool
@icon("../../icons/sequence_reactive.svg")
class_name SequenceReactiveComposite extends Composite


var successful_index: int = 0

Expand Down
13 changes: 8 additions & 5 deletions addons/beehave/nodes/composites/sequence_star.gd
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
## Sequence Star nodes will attempt to execute all of its children and report
## `SUCCESS` in case all of the children report a `SUCCESS` status code.
## If at least one child reports a `FAILURE` status code, this node will also
## return `FAILURE` and tick again.
## In case a child returns `RUNNING` this node will restart.
@tool
@icon("../../icons/sequence_reactive.svg")
class_name SequenceStarComposite extends Composite

## Sequence Star nodes will attempt to execute all of its children and report
## `SUCCESS` in case all of the children report a `SUCCESS` status code.
## If at least one child reports a `FAILURE` status code, this node will also
## return `FAILURE` and tick again.
## In case a child returns `RUNNING` this node will tick again.

var successful_index: int = 0

Expand All @@ -32,6 +32,9 @@ func tick(actor: Node, blackboard: Blackboard) -> int:
successful_index += 1
c.after_run(actor, blackboard)
FAILURE:
# Interrupt any child that was RUNNING before
# but do not reset!
super.interrupt(actor, blackboard)
c.after_run(actor, blackboard)
return FAILURE
RUNNING:
Expand Down
Loading

0 comments on commit 2fc09c7

Please sign in to comment.