Doc: Add docs for index, intro, custom tasks, gdextension and featured classes

This commit is contained in:
Serhii Snitsaruk 2024-01-14 15:28:06 +01:00
parent cbbc0b0135
commit f9219fd509
6 changed files with 306 additions and 17 deletions

View File

@ -14,7 +14,7 @@ release = '1.0'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = ['sphinx_markdown_builder', 'sphinx_rtd_dark_mode']
extensions = ['myst_parser', 'sphinx_markdown_builder', 'sphinx_rtd_dark_mode']
templates_path = ['_templates']
exclude_patterns = ['_build']

View File

@ -0,0 +1,139 @@
.. _custom_tasks:
Creating custom tasks in GDScript
=================================
By default, user tasks should be placed in the ``res://ai/tasks``
directory. You can set an alternative location for user tasks in the
``Project Settings → Limbo AI`` (To see those options,
``Advanced Settings`` should be enabled in the Project Settings).
Each subdirectory within the user tasks directory is treated as a category.
Therefore, if you create a subdirectory named “motion_and_physics,” your
custom tasks in that directory will automatically be categorized under
“Motion And Physics.”
**🛈 Note:** To help you write new tasks, you can add a script template to
your project using “Misc → Create script template” menu option.
Task anatomy
------------
.. code:: gdscript
@tool
extends BTAction
# Task parameters.
@export var parameter1: float
@export var parameter2: Vector2
## Note: Each method declaration is optional.
## At minimum, you only need to define the "_tick" method.
# Called to generate a display name for the task (requires @tool).
func _generate_name() -> String:
return "MyTask"
# Called to initialize the task.
func _setup() -> void:
pass
# Called when the task is entered.
func _enter() -> void:
pass
# Called when the task is exited.
func _exit() -> void:
pass
# Called each time this task is ticked (aka executed).
func _tick(delta: float) -> Status:
return SUCCESS
# Strings returned from this method are displayed as warnings in the editor.
func _get_configuration_warnings() -> PackedStringArray:
var warnings := PackedStringArray()
return warnings
Example 1: A simple action
--------------------------
.. code:: gdscript
@tool
extends BTAction
## Shows or hides a node and returns SUCCESS.
## Returns FAILURE if the node is not found.
# Task parameters.
@export var node_path: NodePath
@export var visible := true
# Called to generate a display name for the task (requires @tool).
func _generate_name() -> String:
return "SetVisible %s node_path: \"%s\"" % [visible, node_path]
# Called each time this task is ticked (aka executed).
func _tick(p_delta: float) -> Status:
var n: CanvasItem = agent.get_node_or_null(node_path)
if is_instance_valid(n):
n.visible = visible
return SUCCESS
return FAILURE
Example 2: InRange condition
----------------------------
.. code:: gdscript
@tool
extends BTCondition
## InRange condition checks if the agent is within a range of target,
## defined by distance_min and distance_max.
## Returns SUCCESS if the agent is within the defined range;
## otherwise, returns FAILURE.
@export var distance_min: float
@export var distance_max: float
@export var target_var := "target"
var _min_distance_squared: float
var _max_distance_squared: float
# Called to generate a display name for the task.
func _generate_name() -> String:
return "InRange (%d, %d) of %s" % [distance_min, distance_max,
LimboUtility.decorate_var(target_var)]
# Called to initialize the task.
func _setup() -> void:
_min_distance_squared = distance_min * distance_min
_max_distance_squared = distance_max * distance_max
# Called when the task is executed.
func _tick(_delta: float) -> Status:
var target: Node2D = blackboard.get_var(target_var, null)
if not is_instance_valid(target):
return FAILURE
var dist_sq: float = agent.global_position.distance_squared_to(target.global_position)
if dist_sq >= _min_distance_squared and dist_sq <= _max_distance_squared:
return SUCCESS
else:
return FAILURE

View File

@ -0,0 +1,17 @@
Important classes
=================
There are a lot of classes introduced in LimboAI. Here is a list of the most important ones you should know about:
.. toctree::
:maxdepth: 1
BTTask: Foundation for all behavior tree tasks <../classes/class_bttask>
BTPlayer: A node that executes BehaviorTree resources <../classes/class_btplayer>
Blackboard: Sharing data between tasks <../classes/class_blackboard>
BBParam: Parametrization helper for your tasks <../classes/class_bbparam>
LimboState: A state node for hierarchical state machine <../classes/class_limbostate>
LimboHSM: Event-based hierarchical state machine <../classes/class_limbohsm>
BTState: A state node for LimboHSM that hosts a BehaviorTree <../classes/class_btstate>
Full class reference is available in the side bar.

View File

@ -0,0 +1,59 @@
.. _gdextension:
Using GDExtension
=================
**🛈 See also:** `What is GDExtension? <https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/what_is_gdextension.html#what-is-gdextension>`_
LimboAI can be used as either a C++ module or as a GDExtension shared library.
The module version is the most feature-full and slightly more performant, but
it requires using custom engine builds including the export templates.
**🛈 Note:** Precompiled builds are available on the official
`LimboAI GitHub <https://github.com/limbonaut/limboai#getting-limboai>`_ page.
GDExtension version is more convenient to use, as you don't need a custom engine
build. You can simply download the extension and put it inside your project.
However, it has certain limitations, described in detail in the next section.
Whichever you choose to use, remember, your project will stay compatible with
both and you can transition from one to the other any time.
Limitations of the GDExtension version
--------------------------------------
GDExtension is the most convenient way of using the LimboAI plugin, but it comes
with certain limitations.
The biggest one is that marking methods as virtual for scripting is not
currently possible in godot-cpp. We use these methods to allow creating custom
behavior tree tasks in GDScript.
Due to a workaround we employ, the editor will complain about native
methods being overridden. And by default, such warnings are treated as errors.
You have two options...
In your Project Settings, you can edit ``Debug -> GDScript -> Warnings -> Native Methods Override``
and set it to either ``Warn`` or ``Ignore``.
Those settings are hidden, unless ``Advanced Settings`` toggle is switched on!
Alternatively, in your custom tasks, you can add specific instructions for
the parser to ignore the warning. For example:
.. code:: gdscript
# The following line instructs parser to ignore the warning:
@warning_ignore("native_method_override")
func _tick(p_delta: float) -> Status:
return SUCCESS
You would have to do that for each overridden method in your custom tasks.
It's up to you which option you prefer. Personally, I'd set it to ``Warn`` and
add ignores only if it gets overwhelming. Hopefully, this will be fixed in the
future releases of Godot!
**Other GDExtension limitations**
* In-editor documentation is not available. The plugin will open online documentation instead when requested.
* Documentation tooltips are not available.
* Handy :ref:`class_BBParam` property editor is not available in the extension due to dependencies on the engine classes that are not available in the Godot API.

View File

@ -0,0 +1,45 @@
.. _introduction:
Introduction to Behavior Trees
==============================
**Behavior Trees (BT)** are hierarchical structures used to model and
control the behavior of agents in a game (e.g., characters, enemies,
entities). They are designed to make it easier to create complex and
highly modular behaviors for your games.
Behavior Trees are composed of tasks that represent specific actions or
decision-making rules. Tasks can be broadly categorized into two main
types: control tasks and leaf tasks. Control tasks determine the
execution flow within the tree. They include :ref:`Sequence<class_BTSequence>`,
:ref:`Selector<class_BTSelector>`, and
:ref:`Invert<class_BTInvert>`. Leaf tasks represent specific actions
to perform, like moving or attacking, or conditions that need to be
checked. The :ref:`BTTask<class_BTTask>` class provides the foundation for various
building blocks of the Behavior Trees. BT tasks can share data with the
help of the :ref:`Blackboard<class_Blackboard>`.
**🛈 Note:** To create your own actions, extend the :ref:`BTAction<class_BTAction>`
class.
The Behavior Tree is executed from the root task and follows the rules
specified by the control tasks, all the way down to the leaf tasks,
which represent the actual actions that the agent should perform or
conditions that should be checked. Each task returns a status when it is
executed. It can be ``SUCCESS``, ``RUNNING``, or ``FAILURE``. These
statuses determine how the tree progresses. They are defined in
:ref:`BT.Status <enum_BT_Status>`.
Behavior Trees handle conditional logic using condition tasks. These
tasks check for specific conditions and return either ``SUCCESS`` or
``FAILURE`` based on the state of the agent or its environment (e.g.,
“IsLowOnHealth”, “IsTargetInSight”). Conditions can be used together
with :ref:`Sequence<class_BTSequence>` and :ref:`Selector<class_BTSelector>`
to craft your decision-making logic.
**🛈 Note:** To create your own conditions, extend the :ref:`BTCondition<class_BTCondition>`
class.
Check out the :ref:`BTTask<class_BTTask>` class documentation, which
provides the foundation for various building blocks of Behavior Trees.

View File

@ -1,24 +1,53 @@
LimboAI's Class Reference
==========================
LimboAI Documentation
=====================
Highlights
----------
.. toctree::
:maxdepth: 1
About
-----
BehaviorTree <classes/class_behaviortree>
BTTask: Foundation for all behavior tree tasks <classes/class_bttask>
BTPlayer: A node that executes BehaviorTree resources <classes/class_btplayer>
LimboState: A state node for hierarchical state machine <classes/class_limbostate>
LimboHSM: Event-based hierarchical state machine <classes/class_limbohsm>
BTState: A state node for LimboHSM that hosts a BehaviorTree <classes/class_btstate>
**LimboAI** is an open-source C++ module for Godot Engine 4 providing a combination of
**Behavior Trees** and **State Machines** for crafting your games AI. It comes with a
behavior tree editor, built-in documentation, visual debugger, and more! While
it is implemented in C++, it fully supports GDScript for :ref:`creating your own tasks <custom_tasks>`
and states. The full list of features is available on the
`LimboAI GitHub <https://github.com/limbonaut/limboai#features>`_ page.
.. * :ref:`search`
.. SCREENSHOT
Class Reference
**Behavior Trees** are hierarchical structures used to model and control the behavior
of agents in a game (e.g., characters, enemies, entities). They are designed to
make it easier to create complex and highly modular behaviors for your games.
To learn more about behavior trees, check out :ref:`introduction`.
Getting LimboAI
---------------
Precompiled builds are available on the official
`LimboAI GitHub <https://github.com/limbonaut/limboai#getting-limboai>`_ page,
and in the Asset Library (coming soon!).
LimboAI can be used as either a C++ module or as a GDExtension shared library.
There are some differences between the two. In short, GDExtension version is more
convenient to use but somewhat limited in features. Whichever you choose to use,
your project will stay compatible with both and you can switch from one to
the other any time. For more information on this topic, see :ref:`gdextension`.
**🛈 Note:** Class reference is available in the side bar.
.. toctree::
:maxdepth: 2
:hidden:
:maxdepth: 1
:caption: Getting started
classes/index
getting-started/introduction
getting-started/custom-tasks
getting-started/gdextension
getting-started/featured-classes
.. toctree::
:hidden:
:maxdepth: 1
:caption: Class reference
:glob:
classes/class_*