diff --git a/doc/source/conf.py b/doc/source/conf.py index 8153904..c6b27a9 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -8,7 +8,7 @@ project = 'LimboAI' copyright = '2021-present Serhii Snitsaruk and the LimboAI contributors' -author = 'Serhii Snitsaruk' +author = 'Serhii Snitsaruk and the LimboAI contributors' release = '1.0' # -- General configuration --------------------------------------------------- @@ -16,6 +16,7 @@ release = '1.0' extensions = ['sphinx_rtd_dark_mode', 'sphinx_copybutton'] +master_doc = 'index' templates_path = ['_templates'] exclude_patterns = ['_build'] @@ -38,5 +39,6 @@ html_logo = "logo.png" html_theme_options = { 'logo_only': True, 'display_version': True, + "collapse_navigation": True, } diff --git a/doc/source/getting-started/using-blackboard.rst b/doc/source/getting-started/using-blackboard.rst index ea2bd8a..cb3665b 100644 --- a/doc/source/getting-started/using-blackboard.rst +++ b/doc/source/getting-started/using-blackboard.rst @@ -91,6 +91,68 @@ Usage example: Advanced topic: Blackboard scopes --------------------------------- - **🛈 Note:** This section is not finished. +The :ref:`Blackboard` in LimboAI can act as a parent scope +for another :ref:`Blackboard`. +This means that if a specific variable is not found in the active scope, +the system will look in the parent :ref:`Blackboard` to find it. +This creates a "blackboard scope chain," where each :ref:`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` 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` +and :ref:`BTSubtree` decorators, or when a :ref:`LimboState` +has non-empty blackboard plan defined, or when a root-level :ref:`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()` accesses the root scope of the +:ref:`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` 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.