Doc: Explain blackboard scopes
This commit is contained in:
parent
bb6fab7555
commit
c96e2019af
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
project = 'LimboAI'
|
project = 'LimboAI'
|
||||||
copyright = '2021-present Serhii Snitsaruk and the LimboAI contributors'
|
copyright = '2021-present Serhii Snitsaruk and the LimboAI contributors'
|
||||||
author = 'Serhii Snitsaruk'
|
author = 'Serhii Snitsaruk and the LimboAI contributors'
|
||||||
release = '1.0'
|
release = '1.0'
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
|
@ -16,6 +16,7 @@ release = '1.0'
|
||||||
|
|
||||||
extensions = ['sphinx_rtd_dark_mode', 'sphinx_copybutton']
|
extensions = ['sphinx_rtd_dark_mode', 'sphinx_copybutton']
|
||||||
|
|
||||||
|
master_doc = 'index'
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
exclude_patterns = ['_build']
|
exclude_patterns = ['_build']
|
||||||
|
|
||||||
|
@ -38,5 +39,6 @@ html_logo = "logo.png"
|
||||||
html_theme_options = {
|
html_theme_options = {
|
||||||
'logo_only': True,
|
'logo_only': True,
|
||||||
'display_version': True,
|
'display_version': True,
|
||||||
|
"collapse_navigation": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,68 @@ Usage example:
|
||||||
Advanced topic: Blackboard scopes
|
Advanced topic: Blackboard scopes
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
**🛈 Note:** This section is not finished.
|
The :ref:`Blackboard<class_Blackboard>` in LimboAI can act as a parent scope
|
||||||
|
for another :ref:`Blackboard<class_Blackboard>`.
|
||||||
|
This means that if a specific variable is not found in the active scope,
|
||||||
|
the system will look in the parent :ref:`Blackboard<class_Blackboard>` to find it.
|
||||||
|
This creates a "blackboard scope chain," where each :ref:`Blackboard<class_Blackboard>` can have its own parent scope,
|
||||||
|
and there is no limit to how many blackboards can be in this chain.
|
||||||
|
It's important to note that the :ref:`Blackboard<class_Blackboard>` doesn't modify values in the parent scopes.
|
||||||
|
|
||||||
**🛈 Note:** Blackboard scopes isolate variable namespaces and enable advanced techniques like sharing data between agents in a group.
|
Some scopes are created automatically. For instance, when using the :ref:`BTNewScope<class_BTNewScope>`
|
||||||
|
and :ref:`BTSubtree<class_BTSubtree>` decorators, or when a :ref:`LimboState<class_LimboState>`
|
||||||
|
has non-empty blackboard plan defined, or when a root-level :ref:`LimboHSM<class_LimboHSM>`
|
||||||
|
node is used. Such scopes prevent naming collisions between contextually separate environments.
|
||||||
|
|
||||||
|
Sharing data between several agents
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The blackboard scope mechanism can also be used for sharing data between several agents.
|
||||||
|
In the following example, we have a group of agents, and we want to share a common target between them:
|
||||||
|
|
||||||
|
.. code:: gdscript
|
||||||
|
|
||||||
|
extends BTAction
|
||||||
|
|
||||||
|
@export var group_target_var: String = "group_target"
|
||||||
|
|
||||||
|
func _tick(delta: float) -> Status:
|
||||||
|
if not blackboard.has_var(group_target_var):
|
||||||
|
var new_target: Node = acquire_target()
|
||||||
|
# Set common target shared between agents in a group:
|
||||||
|
blackboard.top().set_var(group_target_var, new_target)
|
||||||
|
|
||||||
|
# Access common target shared between agents in a group:
|
||||||
|
var target: Node = blackboard.get_var(group_target_var)
|
||||||
|
|
||||||
|
|
||||||
|
In this example, :ref:`blackboard.top()<class_Blackboard_method_top>` accesses the root scope of the
|
||||||
|
:ref:`Blackboard<class_Blackboard>` chain.
|
||||||
|
We assign that scope to each agent in a group through code:
|
||||||
|
|
||||||
|
.. code:: gdscript
|
||||||
|
|
||||||
|
class_name AgentGroup
|
||||||
|
extends Node2D
|
||||||
|
## AgentGroup node: Manages the shared Blackboard for agents in a group.
|
||||||
|
## Children of this node are assumed to be agents that belong to a common group.
|
||||||
|
## This implementation assumes that each agent has a "BTPlayer" node for AI.
|
||||||
|
|
||||||
|
@export var blackboard_plan: BlackboardPlan
|
||||||
|
|
||||||
|
var shared_scope: Blackboard
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
if blackboard_plan == null:
|
||||||
|
shared_scope = Blackboard.new()
|
||||||
|
else:
|
||||||
|
shared_scope = blackboard_plan.create_blackboard()
|
||||||
|
|
||||||
|
for child in get_children():
|
||||||
|
var bt_player: BTPlayer = child.find_child("BTPlayer")
|
||||||
|
if is_instance_valid(bt_player):
|
||||||
|
bt_player.blackboard.set_parent(shared_scope)
|
||||||
|
|
||||||
|
In conclusion, the :ref:`Blackboard<class_Blackboard>` scope chain not only
|
||||||
|
prevents naming conflicts that can occur between state machines, behavior trees, and sub-trees,
|
||||||
|
but it can also be used to share data between several agents.
|
||||||
|
|
Loading…
Reference in New Issue