Skip to content

Commit 13d3964

Browse files
authored
Merge pull request #42 from kagenash1/v2
Update to 2.0
2 parents 964bd24 + 61f1922 commit 13d3964

File tree

99 files changed

+2938
-1208
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+2938
-1208
lines changed

.gitignore

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
.import/
1+
# Godot 4+ specific ignores
2+
.godot/
3+
/android/
4+
build/
25
*.import
36
*.png.import
47
export.cfg
58
export_presets.cfg
6-
project.godot
9+
.vscode/
10+
*.uid
11+
.tmp

LICENSE

Lines changed: 0 additions & 21 deletions
This file was deleted.

README.md

Lines changed: 165 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,165 @@
1-
# godot-behavior-tree
2-
3-
A GDScript implementation of a behavior tree for game AI, based on native Godot nodes and using the built in scene tree editor.
4-
5-
C# VERSION -> https://github.com/MadFlyFish/godot-behavior-tree-csharp
6-
7-
INSTALLATION
8-
- Copy the 'addons' folder into the main directory of your project.
9-
- Enable the plugin from project settings, THEN RESTART Godot, otherwise it will not recognize the new classes (that's a bug of the engine).
10-
- Optionally, you can also drag the bt_example folder into the main directory of your project.
11-
- To see the example working, run the agent.tscn scene. The ex_behavior_tree.tscn scene is an example of how the tree is built.
12-
13-
![alt text](https://raw.githubusercontent.com/GabrieleTorini/godot-behavior-tree/main/bt_images/Screenshot%202021-03-13%20085615.png)![alt text](https://raw.githubusercontent.com/GabrieleTorini/godot-behavior-tree/main/bt_images/Screenshot%202021-03-13%20085633.png)
14-
15-
INSTRUCTIONS:
16-
- Click the node creation icon. You should see new nodes available (if you don't, restart Godot). You must use a BehaviourTree as the root node, which should have only a single child. This child can be any of the nodes under the BTNode category, which all inherit from the BTNode class.
17-
- After creating a behavior tree, you must specify who is the owner of the AI (the Agent) and what Blackboard is being used. Blackboards can be put anywhere (given it is outside the tree), and even shared among different trees. The system is flexible enough to allow you to decide how and when to update your blackboard data. For example, you can make a plain Node with a script that handles updating the blackboard, eg. with signal callbacks or even in process(). Or you can do it from anywhere else, even from inside the tree, just make sure to design things in a way you can maintain and keep track of.
18-
- A Behavior Tree flows executing each of its children, which return some kind of success or failure state. Only those branches following a successful node will be executed. A BTNode must return either success or failure, and can suspend execution only with a yield() call, after which it will remain in a running state until execution is completed. When a BTNode is in running state, the tree will progressively suspend execution (with the only exeption being BTParallel ) until all of the children complete execution. This is for optimisation purposes.
19-
- The flow of the tree is defined by the so called composite nodes: BTSequence, BTSelector, BTRandomSelector, BTRandomSequence, BTParallel which all inherit from BTComposite. A sequence is successfull if all the children are successful, while it fails if one of the children fails. The selector is the logical opposite, it succeeds if one children succeeds, and fails if all the children fail. A parallel will run all the children and always succeed regardless, WITHOUT waiting for children to complete execution. The base composite node runs all the children and always succeeds, but it also waits for execution completion.
20-
- The actions of your AI behavior are carried out in BTLeaf nodes. Add a BTLeaf, then do 'extend script'. Now you can define your own behavior in this script by overriding the _ _tick()_ method. Your actions will go here. Make sure to read the comments in the base script to know the best practices. Also remember BTLeaf shouldn't have children.
21-
- BTDecorator is used to customise the execution of a child node. They can only have ONE child.
22-
- BTConditional is the most common type of decorator. Add a BTConditional and extend the script, then override the _ _pre_tick()_ method to define the conditions under which the child will be executed. Make sure you read the comment cause there is a useful example there.
23-
- BTGuards are decorators which can be used to temporarily lock branches. Optionally, you can assign an unlocker, which will override the lock time specified. There is also the option to assign a locker. BTGuards can make your behavior very rich and reactive, as well as optimised, as they avoid unnecessary branching and repetition.
24-
- Other decorators allow you to loop execution, reverse the result of tick, and so on. There is a lot you can do by customising execution through decorators.
25-
- Good practice is to use the provided nodes and follow the design pattern of the behavior tree. But since this is a purely code based implementation without any visual editor, you have a lot of control over the design and thus a margin of error. These are just useful scripts that follow some "good practices" but are not bound to them, if not for a couple of basic rules. It is up to you to decide how you design your behavior tree, but keep in mind that if you misuse it you will not benefit from the power of the behavior tree pattern. (for example, you could even use the base BTNode for everything and just extend it everytime, although it would be a mess)
26-
- You could have a huge behaviour tree, but the best practice is to follow the component philosophy of Godot and make several smaller behaviour trees for each component of your scene. For example, a tree for your movement controller, a tree for your weapon controller, a tree for your pathfinder component, etc.. A behaviour tree can only have one blackboard, but the same blackboard can be used by many trees, so this is particularly handy if you wanna have several trees without also making multiple blackboards. Personally, the reason why I have the blackboard as a decoupled component, is because I wanted to make squads of enemies sharing the same data but behaving independently, so this is a use case for this. Moreover, I usually have several components in my actors, and I wanna use the same database for different tree.
1+
# GodotBT: Behavior Tree Framework for Godot 4.x
2+
3+
A flexible, extensible behavior tree framework for Godot 4.x that makes it easy to create complex AI behaviors for your games.
4+
5+
## Overview
6+
7+
GodotBT provides a complete behavior tree implementation for the Godot Engine, allowing you to create sophisticated AI behaviors with a clear, modular structure. The framework follows behavior tree design principles with a focus on reusability and separation of concerns.
8+
9+
## Key Features
10+
11+
- **Complete Behavior Tree Implementation**: Core composite nodes, decorators, services, tasks, and conditions
12+
- **Reusable Behavior Trees**: Define a behavior tree once and use it across multiple agents with their own contexts
13+
- **Blackboard System**: Flexible data sharing between nodes with typed accessors and change detection
14+
- **Reactive Conditions**: Trigger behavior changes based on world events with configurable abort scopes
15+
- **Service System**: Run periodic background tasks with customizable frequency
16+
- **Context Separation**: Each agent maintains its own execution context with the shared tree
17+
- **Utility Components**: Helpers like BTTargetKey for simplified movement and targeting operations
18+
- **Example Implementation**: Includes a complete demo with enemies that can patrol, chase the player, and react to events
19+
20+
## Core Components
21+
22+
### Composite Nodes
23+
24+
- **BTSelector**: Runs child nodes until one succeeds or all fail
25+
- **BTSequence**: Runs child nodes until one fails or all succeed
26+
- **BTParallel**: Runs all child nodes simultaneously
27+
- **BTRandomSelector/BTRandomSequence**: Random execution order versions of selector and sequence
28+
29+
### Decorators
30+
31+
- **BTInverter**: Inverts the result of a node
32+
- **BTRepeater**: Repeats a node a specified number of times
33+
- **BTRepeatUntil**: Repeats a node until it returns a specific result
34+
- **BTAlwaysReturn**: Forces a node to return a specific result
35+
36+
### Conditions
37+
38+
- **BTBlackboardBasedCondition**: Condition based on blackboard values
39+
- **BTReactiveCondition**: Condition that can trigger aborts
40+
- **BTCheckNonZeroBBEntry**: Checks if a blackboard value is non-zero/non-empty
41+
- **BTCompareBBEntries**: Compares two blackboard entries
42+
43+
### Services
44+
45+
- **BTService**: Base class for services that run periodically
46+
- Custom services in examples like **BTPlayerDetector**, **BTPatrolPathFollower**
47+
48+
### Tasks
49+
50+
- **BTTask**: Base class for leaf nodes that perform actions
51+
- **BTWait**: Wait for a specified amount of time
52+
- Example implementations for movement, path finding, and more
53+
54+
## Installation
55+
56+
1. Clone or download this repository
57+
2. Copy the `addons/godot_bt` folder into your project's `addons` folder
58+
3. Enable the plugin in Project Settings > Plugins
59+
60+
## Basic Usage
61+
62+
### Creating a Behavior Tree
63+
64+
1. Create a new scene with a root node of type `BehaviorTree`
65+
2. Add a `BTSelector` or `BTSequence` as the first child
66+
3. Build your behavior tree by adding more composite nodes and tasks
67+
4. Save the scene
68+
69+
### Using the Behavior Tree with Multiple Agents
70+
71+
```gdscript
72+
# Level.gd - Sets up the behavior tree and passes it to agents
73+
extends Node2D
74+
75+
func _ready():
76+
# Find all agents and set their behavior trees
77+
for enemy in get_tree().get_nodes_in_group("enemies"):
78+
enemy.run_behavior_tree()
79+
```
80+
81+
```gdscript
82+
# Enemy.gd - Each agent handles its own context
83+
extends CharacterBody2D
84+
85+
@export var bt: BehaviorTree
86+
@export var patrol_path: Node2D
87+
88+
var ctx: BTContext
89+
90+
# Called by the level or manager
91+
func run_behavior_tree() -> void:
92+
if not is_instance_valid(bt):
93+
return
94+
95+
ctx = bt.create_context(self, Blackboard.new())
96+
97+
# Set up blackboard values for this agent
98+
if patrol_path:
99+
var patrol_points: Array = []
100+
for patrol_pt in patrol_path.get_children():
101+
patrol_points.append(patrol_pt.global_position)
102+
ctx.blackboard.set_value("patrol_points", patrol_points)
103+
104+
func _physics_process(delta: float) -> void:
105+
if is_instance_valid(bt) and ctx:
106+
bt.tick(ctx, delta)
107+
```
108+
109+
## Example Implementation
110+
111+
The included example demonstrates:
112+
113+
1. **Enemy Patrol System**: Enemies follow patrol paths or look in random directions
114+
2. **Player Detection**: A service that detects the player within a specified range
115+
3. **Chase Behavior**: Enemies chase the player when detected
116+
4. **Navigation**: Path finding to navigate around obstacles
117+
118+
To see the example in action, open the `example/TestLevel.tscn` scene.
119+
120+
## Extending the Framework
121+
122+
The GodotBT framework is designed to be highly extensible. You can:
123+
124+
### Create Custom Tasks
125+
126+
```gdscript
127+
class_name MyCustomTask extends BTTask
128+
129+
@export var _some_parameter: float = 1.0
130+
131+
func _tick(ctx: BTContext) -> BTResult:
132+
# Your implementation here
133+
if some_condition:
134+
return BTResult.SUCCESS
135+
else:
136+
return BTResult.RUNNING
137+
```
138+
139+
### Create Custom Conditions
140+
141+
```gdscript
142+
class_name MyCustomCondition extends BTCondition
143+
144+
func _tick(ctx: BTContext) -> bool:
145+
# Your implementation here
146+
return some_condition_check
147+
```
148+
149+
### Create Custom Services
150+
151+
```gdscript
152+
class_name MyCustomService extends BTService
153+
154+
func _tick(ctx: BTContext) -> void:
155+
# Your implementation here
156+
ctx.blackboard.set_value("some_key", calculate_some_value())
157+
```
158+
159+
## License
160+
161+
This project is available under the MIT License.
162+
163+
## Contributing
164+
165+
Contributions are welcome! Feel free to submit pull requests or open issues for bugs and feature requests.

addons/behavior_tree/bt_plugin.gd

Lines changed: 0 additions & 3 deletions
This file was deleted.

addons/behavior_tree/icons/btguard.svg

Lines changed: 0 additions & 107 deletions
This file was deleted.

addons/behavior_tree/plugin.cfg

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)