Doc: Add docs for index, intro, custom tasks, gdextension and featured classes
This commit is contained in:
parent
cbbc0b0135
commit
f9219fd509
|
@ -14,7 +14,7 @@ release = '1.0'
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#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']
|
templates_path = ['_templates']
|
||||||
exclude_patterns = ['_build']
|
exclude_patterns = ['_build']
|
||||||
|
|
|
@ -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
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -1,24 +1,53 @@
|
||||||
LimboAI's Class Reference
|
LimboAI Documentation
|
||||||
==========================
|
=====================
|
||||||
|
|
||||||
Highlights
|
About
|
||||||
----------
|
-----
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
BehaviorTree <classes/class_behaviortree>
|
**LimboAI** is an open-source C++ module for Godot Engine 4 providing a combination of
|
||||||
BTTask: Foundation for all behavior tree tasks <classes/class_bttask>
|
**Behavior Trees** and **State Machines** for crafting your game’s AI. It comes with a
|
||||||
BTPlayer: A node that executes BehaviorTree resources <classes/class_btplayer>
|
behavior tree editor, built-in documentation, visual debugger, and more! While
|
||||||
LimboState: A state node for hierarchical state machine <classes/class_limbostate>
|
it is implemented in C++, it fully supports GDScript for :ref:`creating your own tasks <custom_tasks>`
|
||||||
LimboHSM: Event-based hierarchical state machine <classes/class_limbohsm>
|
and states. The full list of features is available on the
|
||||||
BTState: A state node for LimboHSM that hosts a BehaviorTree <classes/class_btstate>
|
`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::
|
.. 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_*
|
||||||
|
|
Loading…
Reference in New Issue