[
{
"kind": "body",
"tag": "h1",
"path": "",
"html": "LimboAI Documentation",
"text": "LimboAI Documentation",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "LimboAI is an open-source C++ module for Godot Engine 4 providing a combination of Behavior Trees and State Machines for crafting your game’s 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 creating your own tasks and states. The full list of features is available on the LimboAI GitHub page.",
"text": "LimboAI is an open-source C++ module for Godot Engine 4 providing a combination of Behavior Trees and State Machines for crafting your game’s 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 creating your own tasks and states. The full list of features is available on the LimboAI GitHub page.",
"markers": {
"1": "creating your own tasks",
"2": "LimboAI GitHub"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Behavior Trees are powerful 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 Introduction to Behavior Trees.",
"text": "Behavior Trees are powerful 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 Introduction to Behavior Trees.",
"markers": {
"1": "Introduction to Behavior Trees"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Hierarchical State Machines are finite state machines that allow any state to host their own sub-state machine. This allows you to tackle your AI’s state and transition complexity by breaking down one big state machine into multiple smaller ones.",
"text": "Hierarchical State Machines are finite state machines that allow any state to host their own sub-state machine. This allows you to tackle your AI’s state and transition complexity by breaking down one big state machine into multiple smaller ones.",
"markers": {}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Getting LimboAI",
"text": "Getting LimboAI",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "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. The module version provides better editor experience and is slightly more performant, but it requires using custom engine builds including the export templates. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time.",
"text": "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. The module version provides better editor experience and is slightly more performant, but it requires using custom engine builds including the export templates. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Choose the version you’d like to use. If you’re unsure, start with the GDExtension version. You can change your decision at any time - both versions are fully compatible.",
"text": "Choose the version you’d like to use. If you’re unsure, start with the GDExtension version. You can change your decision at any time - both versions are fully compatible.",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Get GDExtension version",
"text": "Get GDExtension version",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Precompiled builds are available on the official LimboAI GitHub page, and in the Asset Library.",
"text": "Precompiled builds are available on the official LimboAI GitHub page, and in the Asset Library.",
"markers": {
"1": "LimboAI GitHub"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "GDExtension is the most convenient way of using the LimboAI plugin, but it comes with certain limitations:",
"text": "GDExtension is the most convenient way of using the LimboAI plugin, but it comes with certain limitations:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Documentation tooltips are not available.",
"text": "Documentation tooltips are not available.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Handy BBParam property editor is not available in the extension due to dependencies on the engine classes that are not available in the Godot API.",
"text": "Handy BBParam property editor is not available in the extension due to dependencies on the engine classes that are not available in the Godot API.",
"markers": {
"1": "BBParam"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "🛈 See also: What is GDExtension?",
"text": "🛈 See also: What is GDExtension?",
"markers": {
"1": "What is GDExtension?"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Installation instructions:",
"text": "Installation instructions:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Make sure you’re using the latest stable version of the Godot editor.",
"text": "Make sure you’re using the latest stable version of the Godot editor.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Create a new project for your experiments with LimboAI.",
"text": "Create a new project for your experiments with LimboAI.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In Godot, click AssetLib tab at the top of the screen and search for LimboAI. Download it. LimboAI plugin will be downloaded with the demo project files. Don’t mind the errors printed at this point, this is due to the extension library not being loaded just yet.",
"text": "In Godot, click AssetLib tab at the top of the screen and search for LimboAI. Download it. LimboAI plugin will be downloaded with the demo project files. Don’t mind the errors printed at this point, this is due to the extension library not being loaded just yet.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Reload your project with Project -> Reload project. There shouldn’t be any errors printed now.",
"text": "Reload your project with Project -> Reload project. There shouldn’t be any errors printed now.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In the project files, locate a scene file called showcase.tscn and run it. It’s the demo’s entry point.",
"text": "In the project files, locate a scene file called showcase.tscn and run it. It’s the demo’s entry point.",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Get module version",
"text": "Get module version",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Precompiled builds are available on the official LimboAI GitHub page.",
"text": "Precompiled builds are available on the official LimboAI GitHub page.",
"markers": {
"1": "LimboAI GitHub"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Installation instructions:",
"text": "Installation instructions:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In GitHub releases, download the latest pre-compiled release build for your platform.",
"text": "In GitHub releases, download the latest pre-compiled release build for your platform.",
"markers": {
"1": "GitHub releases"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Download the demo project archive from the same release.",
"text": "Download the demo project archive from the same release.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Extract the pre-compiled editor and the demo project files.",
"text": "Extract the pre-compiled editor and the demo project files.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Launch the pre-compiled editor binary, import and open the demo project.",
"text": "Launch the pre-compiled editor binary, import and open the demo project.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Run the project.",
"text": "Run the project.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Important: To export your game using the module version of LimboAI, make sure to use the pre-compiled export templates included in the same GitHub release build.",
"text": "Important: To export your game using the module version of LimboAI, make sure to use the pre-compiled export templates included in the same GitHub release build.",
"markers": {}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Using LimboAI with C#",
"text": "Using LimboAI with C#",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Here’s how you can use the module version with C# to write your tasks and states.",
"text": "Here’s how you can use the module version with C# to write your tasks and states.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Locate LimboAI NuGet package files.",
"text": "Locate LimboAI NuGet package files.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Each provided build comes with a GodotSharp folder, which has packages under “GodotSharp/Tools/nupkgs/”. Note down the directory path; you’ll need it in the next step.",
"text": "Each provided build comes with a GodotSharp folder, which has packages under “GodotSharp/Tools/nupkgs/”. Note down the directory path; you’ll need it in the next step.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Add a local source for NuGet packages using the following command:",
"text": "Add a local source for NuGet packages using the following command:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Your C# project should be able to see LimboAI classes and compile.",
"text": "Your C# project should be able to see LimboAI classes and compile.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Regarding GDExtension, I can only confirm success with the module version and C#. Unfortunately, I haven’t had any luck with the GDExtension version yet. If you’ve had success with GDExtension, please let me know via Discord or email.",
"text": "Regarding GDExtension, I can only confirm success with the module version and C#. Unfortunately, I haven’t had any luck with the GDExtension version yet. If you’ve had success with GDExtension, please let me know via Discord or email.",
"markers": {}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Contributing",
"text": "Contributing",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "We target the latest stable version of the Godot Engine for development until a third beta or a release candidate of an upcoming Godot release becomes available. If you want to contribute to the project, please ensure that you are using the corresponding Godot version.",
"text": "We target the latest stable version of the Godot Engine for development until a third beta or a release candidate of an upcoming Godot release becomes available. If you want to contribute to the project, please ensure that you are using the corresponding Godot version.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "We follow the Godot code style guidelines. Please use <2/> to maintain consistent styling. You can install <3/> hooks for Git using <4/> to automate this process.",
"text": "We follow the Godot code style guidelines. Please use to maintain consistent styling. You can install hooks for Git using to automate this process.",
"markers": {
"1": "Godot code style guidelines",
"2": "clang-format",
"3": "pre-commit",
"4": "pre-commit install"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Please keep the minor versions backward-compatible when submitting pull requests.",
"text": "Please keep the minor versions backward-compatible when submitting pull requests.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "We support building LimboAI as a module for the Godot Engine and as a GDExtension library. Make sure your contribution is compatible with both. Our CI workflow will verify that your changes can be compiled in both configurations.",
"text": "We support building LimboAI as a module for the Godot Engine and as a GDExtension library. Make sure your contribution is compatible with both. Our CI workflow will verify that your changes can be compiled in both configurations.",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Compiling as module of the Godot Engine",
"text": "Compiling as module of the Godot Engine",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Clone the Godot Engine repository.",
"text": "Clone the Godot Engine repository.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Switch to the latest stable tag.",
"text": "Switch to the latest stable tag.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Clone the LimboAI repository into the <1/> directory.",
"text": "Clone the LimboAI repository into the directory.",
"markers": {
"1": "modules/limboai"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Consult the Godot Engine documentation for detailed instructions on building the engine.",
"text": "Consult the Godot Engine documentation for detailed instructions on building the engine.",
"markers": {
"1": "Godot Engine documentation"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Unit tests can be compiled using the <1/> build option. To execute them, run the compiled Godot binary with the <2/> command-line options.",
"text": "Unit tests can be compiled using the build option. To execute them, run the compiled Godot binary with the command-line options.",
"markers": {
"1": "tests=yes",
"2": "--test --tc=\"*[LimboAI]*\""
}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Building C# Packages",
"text": "Building C# Packages",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "If you want C# Support for LimboAI when building from source, follow Godot’s instructions for building from source with C# Support: Compiling with .NET. LimboAI’s classes will be included in the output from that build process.",
"text": "If you want C# Support for LimboAI when building from source, follow Godot’s instructions for building from source with C# Support: Compiling with .NET. LimboAI’s classes will be included in the output from that build process.",
"markers": {
"1": "Compiling with .NET"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Compiling as GDExtension library",
"text": "Compiling as GDExtension library",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "You’ll need the SCons build tool and a C++ compiler. See also Compiling. Run <2/> to build the plugin library for your current platform.",
"text": "You’ll need the SCons build tool and a C++ compiler. See also Compiling. Run to build the plugin library for your current platform.",
"markers": {
"1": "Compiling",
"2": "scons target=editor"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "SCons will automatically clone the <1/> repository if it doesn’t already exist in the <2/> directory.",
"text": "SCons will automatically clone the repository if it doesn’t already exist in the directory.",
"markers": {
"1": "godot-cpp",
"2": "limboai/godot-cpp"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "By default, built targets are placed in the demo project: <1/>.",
"text": "By default, built targets are placed in the demo project: .",
"markers": {
"1": "demo/addons/limboai/bin/"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Check <1/> for other options and targets.",
"text": "Check for other options and targets.",
"markers": {
"1": "scons -h"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Contributing to the documentation",
"text": "Contributing to the documentation",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Online documentation is created using Sphinx. Source files are located in the <2/> directory in RST format and can be built locally with <3/>. See the Sphinx documentation for more details.",
"text": "Online documentation is created using Sphinx. Source files are located in the directory in RST format and can be built locally with . See the Sphinx documentation for more details.",
"markers": {
"1": "Sphinx",
"2": "doc/source",
"3": "sphinx-build",
"4": "Sphinx documentation"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Class documentation resides in XML files within the <1/> directory. If you create a new class or modify an existing one, you can run the compiled Godot binary with the <2/> option in the root of the Godot source code to generate the missing XML files or sections within those files in the class documentation. After editing the XML files, please run the compiled editor binary with the <3/> option again to update and tidy up the XML files.",
"text": "Class documentation resides in XML files within the directory. If you create a new class or modify an existing one, you can run the compiled Godot binary with the option in the root of the Godot source code to generate the missing XML files or sections within those files in the class documentation. After editing the XML files, please run the compiled editor binary with the option again to update and tidy up the XML files.",
"markers": {
"1": "doc_classes/",
"2": "--doctool",
"3": "--doctool"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Sphinx RST files for the class documentation are generated from XML files using the Godot script <1/> and stored in the <2/> directory. This process is performed using our own script <3/>. RST files in <4/> should not be edited manually.",
"text": "Sphinx RST files for the class documentation are generated from XML files using the Godot script and stored in the directory. This process is performed using our own script . RST files in should not be edited manually.",
"markers": {
"1": "make_rst.py",
"2": "doc/source/classes",
"3": "scripts/update_rst.sh",
"4": "doc/source/classes"
}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Introduction to Behavior Trees",
"text": "Introduction to Behavior Trees",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "🛈 Note: Demo project includes a tutorial that provides an introduction to behavior trees through illustrative examples.",
"text": "🛈 Note: Demo project includes a tutorial that provides an introduction to behavior trees through illustrative examples.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "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.",
"text": "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.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "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 Sequence, Selector, and Invert. Leaf tasks represent specific actions to perform, like moving or attacking, or conditions that need to be checked. The BTTask class provides the foundation for various building blocks of the Behavior Trees. Such tasks can share data using the Blackboard.",
"text": "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 Sequence, Selector, and Invert. Leaf tasks represent specific actions to perform, like moving or attacking, or conditions that need to be checked. The BTTask class provides the foundation for various building blocks of the Behavior Trees. Such tasks can share data using the Blackboard.",
"markers": {
"1": "Sequence",
"2": "Selector",
"3": "Invert",
"4": "BTTask",
"5": "share data using the Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "🛈 Note: To create your own actions, extend the BTAction class.",
"text": "🛈 Note: To create your own actions, extend the BTAction class.",
"markers": {
"1": "create your own actions",
"2": "BTAction"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "A Behavior Tree is usually processed each frame. It is traversed from top to bottom, with the control tasks determining the control flow. Each task has a _tick method, which performs the task’s work and returns a status indicating its progress: <2/>, <3/>, or <4/>. <5/> and <6/> indicate the outcome of finished work, while <7/> status is returned when a task requires more than one tick to complete its job. These statuses determine how the tree progresses, with the <8/> status usually meaning that the tree will continue execution during the next frame.",
"text": "A Behavior Tree is usually processed each frame. It is traversed from top to bottom, with the control tasks determining the control flow. Each task has a _tick method, which performs the task’s work and returns a status indicating its progress: , , or . and indicate the outcome of finished work, while status is returned when a task requires more than one tick to complete its job. These statuses determine how the tree progresses, with the status usually meaning that the tree will continue execution during the next frame.",
"markers": {
"1": "_tick",
"2": "SUCCESS",
"3": "FAILURE",
"4": "RUNNING",
"5": "SUCCESS",
"6": "FAILURE",
"7": "RUNNING",
"8": "RUNNING"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "There are four types of tasks:",
"text": "There are four types of tasks:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Actions are leaf tasks that perform the actual work.",
"text": "Actions are leaf tasks that perform the actual work.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Examples: PlayAnimation, Wait.",
"text": "Examples: PlayAnimation, Wait.",
"markers": {
"1": "PlayAnimation",
"2": "Wait"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Conditions are leaf tasks that conduct various checks.",
"text": "Conditions are leaf tasks that conduct various checks.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Examples: CheckVar, InRange.",
"text": "Examples: CheckVar, InRange.",
"markers": {
"1": "CheckVar",
"2": "InRange"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Composites can have one or more child tasks, and dictate the execution flow of their children.",
"text": "Composites can have one or more child tasks, and dictate the execution flow of their children.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Examples: Sequence, Selector, Parallel.",
"text": "Examples: Sequence, Selector, Parallel.",
"markers": {
"1": "Sequence",
"2": "Selector",
"3": "Parallel"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Decorators can only have a single child and they change how their child task operates.",
"text": "Decorators can only have a single child and they change how their child task operates.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Examples: AlwaysSucceed, Invert, TimeLimit.",
"text": "Examples: AlwaysSucceed, Invert, TimeLimit.",
"markers": {
"1": "AlwaysSucceed",
"2": "Invert",
"3": "TimeLimit"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Sequence is one of the core composite tasks. It executes its child tasks sequentially, from first to last, until one of them returns <2/>, or all of them result in <3/>. In other words, if any child task results in <4/>, the Sequence execution will be aborted, and the Sequence itself will return <7/>.",
"text": "Sequence is one of the core composite tasks. It executes its child tasks sequentially, from first to last, until one of them returns , or all of them result in . In other words, if any child task results in , the Sequence execution will be aborted, and the Sequence itself will return .",
"markers": {
"1": "Sequence",
"2": "FAILURE",
"3": "SUCCESS",
"4": "FAILURE",
"5": "Sequence",
"6": "Sequence",
"7": "FAILURE"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Selector is another essential composite task. It executes its child tasks sequentially, from first to last, until one of them returns <2/> or all of them result in <3/>. In other words, when a child task results in <4/>, it moves on to the next one until it finds the one that returns <5/>. Once a child task results in <6/>, the Selector stops and also returns <8/>. The purpose of the Selector is to find a child that succeeds.",
"text": "Selector is another essential composite task. It executes its child tasks sequentially, from first to last, until one of them returns or all of them result in . In other words, when a child task results in , it moves on to the next one until it finds the one that returns . Once a child task results in , the Selector stops and also returns . The purpose of the Selector is to find a child that succeeds.",
"markers": {
"1": "Selector",
"2": "SUCCESS",
"3": "FAILURE",
"4": "FAILURE",
"5": "SUCCESS",
"6": "SUCCESS",
"7": "Selector",
"8": "SUCCESS",
"9": "Selector"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Behavior Trees handle conditional logic using condition tasks. These tasks check for specific conditions and return either <1/> or <2/> based on the state of the agent or its environment (e.g., “IsLowOnHealth”, “IsTargetInSight”). Conditions can be used together with Sequence and Selector to craft your decision-making logic.",
"text": "Behavior Trees handle conditional logic using condition tasks. These tasks check for specific conditions and return either or based on the state of the agent or its environment (e.g., “IsLowOnHealth”, “IsTargetInSight”). Conditions can be used together with Sequence and Selector to craft your decision-making logic.",
"markers": {
"1": "SUCCESS",
"2": "FAILURE",
"3": "Sequence",
"4": "Selector"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "🛈 Note: To create your own conditions, extend the BTCondition class.",
"text": "🛈 Note: To create your own conditions, extend the BTCondition class.",
"markers": {
"1": "create your own conditions",
"2": "BTCondition"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Check out the BTTask class documentation, which provides the foundation for various building blocks of Behavior Trees.",
"text": "Check out the BTTask class documentation, which provides the foundation for various building blocks of Behavior Trees.",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Creating Behavior Trees",
"text": "Creating Behavior Trees",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "This chapter describes how to create and debug behavior trees.",
"text": "This chapter describes how to create and debug behavior trees.",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Add a Behavior Tree to an agent",
"text": "Add a Behavior Tree to an agent",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Follow these steps to add a behavior tree to a new or existing agent:",
"text": "Follow these steps to add a behavior tree to a new or existing agent:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Make a scene file for your agent, or open an existing scene.",
"text": "Make a scene file for your agent, or open an existing scene.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Add a BTPlayer node to your scene.",
"text": "Add a BTPlayer node to your scene.",
"markers": {
"1": "BTPlayer"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Select BTPlayer, and create a new behavior tree in the inspector.",
"text": "Select BTPlayer, and create a new behavior tree in the inspector.",
"markers": {
"1": "BTPlayer"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Optionally, you can save the behavior tree to a file using the property’s context menu.",
"text": "Optionally, you can save the behavior tree to a file using the property’s context menu.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Click the behavior tree property to open it in the LimboAI editor.",
"text": "Click the behavior tree property to open it in the LimboAI editor.",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Debugging Behavior Trees",
"text": "Debugging Behavior Trees",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In Godot Engine, follow to “Bottom Panel > Debugger > LimboAI” tab. With the LimboAI debugger, you can inspect any currently active behavior tree within the running project. The debugger can be detached from the main editor window, which can be particularly useful if you have a HiDPI or a secondary display.",
"text": "In Godot Engine, follow to “Bottom Panel > Debugger > LimboAI” tab. With the LimboAI debugger, you can inspect any currently active behavior tree within the running project. The debugger can be detached from the main editor window, which can be particularly useful if you have a HiDPI or a secondary display.",
"markers": {}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Inspecting task properties and blackboard",
"text": "Inspecting task properties and blackboard",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "When you click on a task in the LimboAI debugger, its properties are shown in the remote Inspector panel, including the Blackboard reference. Click the Blackboard to open it and view all variables across the full scope chain, grouped by scope. You can also edit variable values live, which can be useful for testing and debugging your game’s AI.",
"text": "When you click on a task in the LimboAI debugger, its properties are shown in the remote Inspector panel, including the Blackboard reference. Click the Blackboard to open it and view all variables across the full scope chain, grouped by scope. You can also edit variable values live, which can be useful for testing and debugging your game’s AI.",
"markers": {
"1": "Blackboard",
"2": "Blackboard"
}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Creating custom tasks",
"text": "Creating custom tasks",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "By default, user tasks should be placed in the <1/> directory. You can set an alternative location for user tasks in the <2/> (To see those options, <3/> should be enabled in the Project Settings).",
"text": "By default, user tasks should be placed in the directory. You can set an alternative location for user tasks in the (To see those options, should be enabled in the Project Settings).",
"markers": {
"1": "res://ai/tasks",
"2": "Project Settings → Limbo AI",
"3": "Advanced Settings"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "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.”",
"text": "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.”",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "When creating custom tasks, extend one of the following base classes: BTAction, BTCondition, BTDecorator, BTComposite. More on task types you can read in the Introduction to Behavior Trees.",
"text": "When creating custom tasks, extend one of the following base classes: BTAction, BTCondition, BTDecorator, BTComposite. More on task types you can read in the Introduction to Behavior Trees.",
"markers": {
"1": "BTAction",
"2": "BTCondition",
"3": "BTDecorator",
"4": "BTComposite",
"5": "Introduction to Behavior Trees"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "🛈 Note: To help you write new tasks, you can add a script template to your project using “Misc → Create script template” menu option.",
"text": "🛈 Note: To help you write new tasks, you can add a script template to your project using “Misc → Create script template” menu option.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Using the Blackboard is covered in Accessing the Blackboard in a Task.",
"text": "Using the Blackboard is covered in Accessing the Blackboard in a Task.",
"markers": {
"1": "Blackboard",
"2": "Accessing the Blackboard in a Task"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Task anatomy",
"text": "Task anatomy",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Example 1: A simple action",
"text": "Example 1: A simple action",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Example 2: InRange condition",
"text": "Example 2: InRange condition",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Creating tasks in C#",
"text": "Creating tasks in C#",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "You can use the following script template for custom tasks:",
"text": "You can use the following script template for custom tasks:",
"markers": {}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Sharing data using Blackboard",
"text": "Sharing data using Blackboard",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "To share data between different tasks and states, we employ a feature known as the Blackboard. The Blackboard serves as a central repository where tasks and states can store and retrieve named variables, allowing for seamless data interchange. Each instance of a behavior tree or a state machine gets its own dedicated Blackboard. It has the capability to store various data types, including objects and resources.",
"text": "To share data between different tasks and states, we employ a feature known as the Blackboard. The Blackboard serves as a central repository where tasks and states can store and retrieve named variables, allowing for seamless data interchange. Each instance of a behavior tree or a state machine gets its own dedicated Blackboard. It has the capability to store various data types, including objects and resources.",
"markers": {
"1": "Blackboard",
"2": "Blackboard",
"3": "Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Using the Blackboard, you can easily share data in your behavior trees, making the tasks in the behavior tree more flexible.",
"text": "Using the Blackboard, you can easily share data in your behavior trees, making the tasks in the behavior tree more flexible.",
"markers": {
"1": "Blackboard"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Accessing the Blackboard in a Task",
"text": "Accessing the Blackboard in a Task",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Every BTTask has access to the Blackboard, providing a straightforward mechanism for data exchange. Here’s an example of how you can interact with the Blackboard in GDScript:",
"text": "Every BTTask has access to the Blackboard, providing a straightforward mechanism for data exchange. Here’s an example of how you can interact with the Blackboard in GDScript:",
"markers": {
"1": "BTTask",
"2": "Blackboard",
"3": "Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "If you are accessing a variable that holds an object instance, and it is expected that the instance may be null or freed, you can do it like this:",
"text": "If you are accessing a variable that holds an object instance, and it is expected that the instance may be null or freed, you can do it like this:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "It is recommended to suffix variable name properties with <1/>, like in the example above, which enables the inspector to provide a more convenient property editor for the variable. This editor allows you to select or add the variable to the blackboard plan, and provides a warning icon if the variable does not exist in the blackboard plan.",
"text": "It is recommended to suffix variable name properties with , like in the example above, which enables the inspector to provide a more convenient property editor for the variable. This editor allows you to select or add the variable to the blackboard plan, and provides a warning icon if the variable does not exist in the blackboard plan.",
"markers": {
"1": "_var"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "🛈 Note: The variable doesn’t need to exist when you set it in code.",
"text": "🛈 Note: The variable doesn’t need to exist when you set it in code.",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Editing the Blackboard Plan",
"text": "Editing the Blackboard Plan",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "The Blackboard Plan, associated with each BehaviorTree resource, dictates how the Blackboard initializes for each new instance of the BehaviorTree. BlackboardPlan resource stores default values, type information, and data bindings necessary for BehaviorTree initialization.",
"text": "The Blackboard Plan, associated with each BehaviorTree resource, dictates how the Blackboard initializes for each new instance of the BehaviorTree. BlackboardPlan resource stores default values, type information, and data bindings necessary for BehaviorTree initialization.",
"markers": {
"1": "BehaviorTree",
"2": "Blackboard",
"3": "BehaviorTree",
"4": "BehaviorTree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "To add, modify, or remove variables from the Blackboard Plan, follow these steps:",
"text": "To add, modify, or remove variables from the Blackboard Plan, follow these steps:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Open the LimboAI editor and load the behavior tree you want to edit.",
"text": "Open the LimboAI editor and load the behavior tree you want to edit.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In the editor, click on the small button located inside the tab. This will open the BlackboardPlan in the Inspector.",
"text": "In the editor, click on the small button located inside the tab. This will open the BlackboardPlan in the Inspector.",
"markers": {
"1": "BlackboardPlan"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In the Inspector, click the “Manage…” button to show the blackboard plan editor.",
"text": "In the Inspector, click the “Manage…” button to show the blackboard plan editor.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In the blackboard plan editor, you can add, remove, or reorder variables, and modify their data type and hint.",
"text": "In the blackboard plan editor, you can add, remove, or reorder variables, and modify their data type and hint.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "The hint provides additional information about the variable to the Inspector, such as minimum and maximum values for an integer variable. Learn more about property hints in the official Godot documentation.",
"text": "The hint provides additional information about the variable to the Inspector, such as minimum and maximum values for an integer variable. Learn more about property hints in the official Godot documentation.",
"markers": {
"1": "property hints in the official Godot documentation"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "You can specify the default values of the variables directly in the Inspector.",
"text": "You can specify the default values of the variables directly in the Inspector.",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Overriding variables in BTPlayer",
"text": "Overriding variables in BTPlayer",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Each BTPlayer node also has a “Blackboard Plan” property, providing the ability to override values of the BehaviorTree’s blackboard variables. These overrides are specific to the BTPlayer’s scene and do not impact other scenes using the same BehaviorTree. To modify these values:",
"text": "Each BTPlayer node also has a “Blackboard Plan” property, providing the ability to override values of the BehaviorTree’s blackboard variables. These overrides are specific to the BTPlayer’s scene and do not impact other scenes using the same BehaviorTree. To modify these values:",
"markers": {
"1": "BTPlayer",
"2": "BehaviorTree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Select the BTPlayer node in the scene tree.",
"text": "Select the BTPlayer node in the scene tree.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In the Inspector, locate the “Blackboard Plan” property.",
"text": "In the Inspector, locate the “Blackboard Plan” property.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Override the desired values to tailor the blackboard variables for the specific scene.",
"text": "Override the desired values to tailor the blackboard variables for the specific scene.",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Task parameters",
"text": "Task parameters",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In some cases, it can be beneficial to allow behavior tree tasks to export parameters that can either be bound to a blackboard variable or specified directly by the user. For this purpose, LimboAI provides special parameter types that begin with “BB”, such as BBInt, BBBool, BBString, BBFloat, BBNode, and more. For a complete list, please refer to the BBParam class reference.",
"text": "In some cases, it can be beneficial to allow behavior tree tasks to export parameters that can either be bound to a blackboard variable or specified directly by the user. For this purpose, LimboAI provides special parameter types that begin with “BB”, such as BBInt, BBBool, BBString, BBFloat, BBNode, and more. For a complete list, please refer to the BBParam class reference.",
"markers": {
"1": "BBInt",
"2": "BBBool",
"3": "BBString",
"4": "BBFloat",
"5": "BBNode",
"6": "BBParam"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Usage example:",
"text": "Usage example:",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Connecting variables in BTs to HSMs: Variable mapping",
"text": "Connecting variables in BTs to HSMs: Variable mapping",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Each BTState creates a new blackboard scope for its BehaviorTree instance. Because BehaviorTrees are reusable resources that can run in different contexts or on different agents, they do not automatically see variables defined in the HSM. At runtime, HSM variables are usually accessible inside the BT via the parent scope blackboard, but the recommended way to access them is through mapping.",
"text": "Each BTState creates a new blackboard scope for its BehaviorTree instance. Because BehaviorTrees are reusable resources that can run in different contexts or on different agents, they do not automatically see variables defined in the HSM. At runtime, HSM variables are usually accessible inside the BT via the parent scope blackboard, but the recommended way to access them is through mapping.",
"markers": {
"1": "BTState"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Note",
"text": "Note",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "To learn more about scopes, see Blackboard.",
"text": "To learn more about scopes, see Blackboard.",
"markers": {
"1": "Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "When both the BehaviorTree and the HSM declare variables in their respective BlackboardPlan resources, the editor provides a Mapping section in the BlackboardPlan inspector. Mapping is the intended and recommended way to connect variables between related plans.",
"text": "When both the BehaviorTree and the HSM declare variables in their respective BlackboardPlan resources, the editor provides a Mapping section in the BlackboardPlan inspector. Mapping is the intended and recommended way to connect variables between related plans.",
"markers": {
"1": "BlackboardPlan"
}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Key points about mapping",
"text": "Key points about mapping",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Mapping connects two variables so they behave as a single logical variable at runtime.",
"text": "Mapping connects two variables so they behave as a single logical variable at runtime.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Linked variables are updated immediately in both scopes — they literally share the same state in memory (no polling or copying).",
"text": "Linked variables are updated immediately in both scopes — they literally share the same state in memory (no polling or copying).",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Mapping is explicit: you decide which variables the BT exposes as inputs and outputs.",
"text": "Mapping is explicit: you decide which variables the BT exposes as inputs and outputs.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Linkage is bidirectional — there is no distinction between input and output.",
"text": "Linkage is bidirectional — there is no distinction between input and output.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Mapping does not create new variables automatically — the variables must already exist in both blackboard plans before they can be linked.",
"text": "Mapping does not create new variables automatically — the variables must already exist in both blackboard plans before they can be linked.",
"markers": {}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Inspector workflow",
"text": "Inspector workflow",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Define the required variables in each BlackboardPlan (HSM plan and BT plan, for example).",
"text": "Define the required variables in each BlackboardPlan (HSM plan and BT plan, for example).",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Select the BTState node in the scene or a BTSubtree inside a behavior tree.",
"text": "Select the BTState node in the scene or a BTSubtree inside a behavior tree.",
"markers": {
"1": "BTState",
"2": "BTSubtree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In the Inspector, select the Blackboard Plan property.",
"text": "In the Inspector, select the Blackboard Plan property.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In the BlackboardPlan resource inspector, locate the Mapping section.",
"text": "In the BlackboardPlan resource inspector, locate the Mapping section.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Create mappings by pairing variables (<1/>).",
"text": "Create mappings by pairing variables ().",
"markers": {
"1": "BT variable ↔ parent variable"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "On startup the mappings are applied, and the variables are automatically linked for the running instance.",
"text": "On startup the mappings are applied, and the variables are automatically linked for the running instance.",
"markers": {}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Programmatic alternative: linking variables in code",
"text": "Programmatic alternative: linking variables in code",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "You can also link variables directly in code using Blackboard.link_var:",
"text": "You can also link variables directly in code using Blackboard.link_var:",
"markers": {
"1": "Blackboard.link_var"
}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Best practices",
"text": "Best practices",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Declare all BT dependencies in the BT’s BlackboardPlan instead of relying on parent scopes.",
"text": "Declare all BT dependencies in the BT’s BlackboardPlan instead of relying on parent scopes.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Use Mapping to explicitly declare which variables should be shared with the HSM.",
"text": "Use Mapping to explicitly declare which variables should be shared with the HSM.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Prefer the inspector-based Mapping workflow for clarity and editor support; use <1/> only when runtime or programmatic setup is required.",
"text": "Prefer the inspector-based Mapping workflow for clarity and editor support; use only when runtime or programmatic setup is required.",
"markers": {
"1": "link_var"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Avoid writing to <1/> from inside BT tasks unless you have a very specific reason and accept the coupling it introduces.",
"text": "Avoid writing to from inside BT tasks unless you have a very specific reason and accept the coupling it introduces.",
"markers": {
"1": "blackboard.get_parent()"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Advanced topic: Blackboard scopes",
"text": "Advanced topic: Blackboard scopes",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "The Blackboard in LimboAI can act as a parent scope for another Blackboard. This means that if a specific variable is not found in the active scope, the system will look in the parent Blackboard to find it. This creates a “blackboard scope chain,” where each 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 Blackboard doesn’t modify values in the parent scopes.",
"text": "The Blackboard in LimboAI can act as a parent scope for another Blackboard. This means that if a specific variable is not found in the active scope, the system will look in the parent Blackboard to find it. This creates a “blackboard scope chain,” where each 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 Blackboard doesn’t modify values in the parent scopes.",
"markers": {
"1": "Blackboard",
"2": "Blackboard",
"3": "Blackboard",
"4": "Blackboard",
"5": "Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Scopes are created automatically to prevent naming collisions between contextually separate environments:",
"text": "Scopes are created automatically to prevent naming collisions between contextually separate environments:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Within BTNewScope.",
"text": "Within BTNewScope.",
"markers": {
"1": "BTNewScope"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Under BTSubtree decorators.",
"text": "Under BTSubtree decorators.",
"markers": {
"1": "BTSubtree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "With LimboState that have a non-empty blackboard plan defined.",
"text": "With LimboState that have a non-empty blackboard plan defined.",
"markers": {
"1": "LimboState"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Under LimboHSM nodes: A new scope is created at the root level, and each BTState child also receives its own separate scope.",
"text": "Under LimboHSM nodes: A new scope is created at the root level, and each BTState child also receives its own separate scope.",
"markers": {
"1": "LimboHSM",
"2": "BTState"
}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Sharing data between several agents",
"text": "Sharing data between several agents",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "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:",
"text": "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:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In this example, blackboard.top() accesses the root scope of the Blackboard chain. We assign that scope to each agent in a group through code:",
"text": "In this example, blackboard.top() accesses the root scope of the Blackboard chain. We assign that scope to each agent in a group through code:",
"markers": {
"1": "blackboard.top()",
"2": "Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In conclusion, the 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.",
"text": "In conclusion, the 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.",
"markers": {
"1": "Blackboard"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Debugging blackboard variables",
"text": "Debugging blackboard variables",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "When debugging a running project, you can inspect Blackboard variables in the remote Inspector. Click on a task in the LimboAI debugger to view its properties, then click the Blackboard reference to see all variables across the full scope chain, grouped by scope. Variables can be edited live to aid in debugging. For state machines, select a LimboState node in the Remote Scene Tree to access its Blackboard in the same way.",
"text": "When debugging a running project, you can inspect Blackboard variables in the remote Inspector. Click on a task in the LimboAI debugger to view its properties, then click the Blackboard reference to see all variables across the full scope chain, grouped by scope. Variables can be edited live to aid in debugging. For state machines, select a LimboState node in the Remote Scene Tree to access its Blackboard in the same way.",
"markers": {
"1": "Blackboard",
"2": "Blackboard",
"3": "LimboState",
"4": "Blackboard"
}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Accessing nodes in the scene tree",
"text": "Accessing nodes in the scene tree",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "There are several ways to access nodes in the agent’s scene tree from a BTTask.",
"text": "There are several ways to access nodes in the agent’s scene tree from a BTTask.",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "🛈 Note: The root node of the agent’s scene tree can be accessed with the scene_root property.",
"text": "🛈 Note: The root node of the agent’s scene tree can be accessed with the scene_root property.",
"markers": {
"1": "scene_root"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "With <1/> property",
"text": "With property",
"markers": {
"1": "BBNode"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "With <1/> property",
"text": "With property",
"markers": {
"1": "NodePath"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Using blackboard plan",
"text": "Using blackboard plan",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "You can create a blackboard variable in the editor with the type <2/> and point it to the proper node in the BTPlayer blackboard plan. By default, any <4/> variable will be replaced with the node instance when the blackboard is instantiated at runtime (see BlackboardPlan.prefetch_nodepath_vars).",
"text": "You can create a blackboard variable in the editor with the type and point it to the proper node in the BTPlayer blackboard plan. By default, any variable will be replaced with the node instance when the blackboard is instantiated at runtime (see BlackboardPlan.prefetch_nodepath_vars).",
"markers": {
"1": "create a blackboard variable",
"2": "NodePath",
"3": "BTPlayer",
"4": "NodePath",
"5": "BlackboardPlan.prefetch_nodepath_vars"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "The property BTPlayer.prefetch_nodepath_vars should be set to <1/>.",
"text": "The property BTPlayer.prefetch_nodepath_vars should be set to .",
"markers": {
"1": "true"
}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Create State Machines",
"text": "Create State Machines",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "This guide will show how to set up and use a state machine using LimboHSM.",
"text": "This guide will show how to set up and use a state machine using LimboHSM.",
"markers": {
"1": "LimboHSM"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Initialization",
"text": "Initialization",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "To use the LimboHSM state machine, you first need to initialize it in your code. This is typically done in the <2/> function of your script. Here’s an example of how to do this:",
"text": "To use the LimboHSM state machine, you first need to initialize it in your code. This is typically done in the function of your script. Here’s an example of how to do this:",
"markers": {
"1": "LimboHSM",
"2": "_ready"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In this example, we first declare the state machine and the states we want to use. Then, in the <1/> function, we add transitions between the states. Finally, we initialize the state machine and set it to active.",
"text": "In this example, we first declare the state machine and the states we want to use. Then, in the function, we add transitions between the states. Finally, we initialize the state machine and set it to active.",
"markers": {
"1": "_init_state_machine"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "State example",
"text": "State example",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "You can define the behavior of a state in a script and attach it to the state node. Here’s an example of a state that plays an animation on an <1/> and waits for it to finish:",
"text": "You can define the behavior of a state in a script and attach it to the state node. Here’s an example of a state that plays an animation on an and waits for it to finish:",
"markers": {
"1": "AnimationPlayer"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In this example, the <1/> method is called when the state is entered, and it plays the specified animation. The <2/> method is called every frame, and it checks if the animation is finished. If it is, it dispatches the <3/> event, which can result in a transition to the next state.",
"text": "In this example, the method is called when the state is entered, and it plays the specified animation. The method is called every frame, and it checks if the animation is finished. If it is, it dispatches the event, which can result in a transition to the next state.",
"markers": {
"1": "_enter",
"2": "_update",
"3": "EVENT_FINISHED"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Events and transitions",
"text": "Events and transitions",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "The LimboHSM comes with an event system that helps to decouple transitions from the state implementations. A transition is associated with a specific event, a starting state, and a destination state, and it is performed automatically when such an event is dispatched.",
"text": "The LimboHSM comes with an event system that helps to decouple transitions from the state implementations. A transition is associated with a specific event, a starting state, and a destination state, and it is performed automatically when such an event is dispatched.",
"markers": {
"1": "LimboHSM"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "To register a transition and associate it with a specific event, you can use the LimboHSM.add_transition method:",
"text": "To register a transition and associate it with a specific event, you can use the LimboHSM.add_transition method:",
"markers": {
"1": "LimboHSM.add_transition"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In this example, we’re registering a transition from the <1/> to the <2/> when the <3/> event is dispatched.",
"text": "In this example, we’re registering a transition from the to the when the event is dispatched.",
"markers": {
"1": "idle_state",
"2": "move_state",
"3": "movement_started"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "A transition can be also associated with no particular starting state:",
"text": "A transition can be also associated with no particular starting state:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Events are dispatched with the LimboState.dispatch method. It’s important to note that this method can be called from anywhere in the state machine hierarchy and outside of it. Events are propagated from the leaf to the root state. This means that if an event is consumed by a state, it won’t be propagated to its parent states.",
"text": "Events are dispatched with the LimboState.dispatch method. It’s important to note that this method can be called from anywhere in the state machine hierarchy and outside of it. Events are propagated from the leaf to the root state. This means that if an event is consumed by a state, it won’t be propagated to its parent states.",
"markers": {
"1": "LimboState.dispatch"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "States can also define event handlers, which are methods that react to specific events. These event handlers typically don’t result in a state transition; they are simply a mechanism for states to react to particular events. You can use the LimboState.add_event_handler method to register event handlers in your states:",
"text": "States can also define event handlers, which are methods that react to specific events. These event handlers typically don’t result in a state transition; they are simply a mechanism for states to react to particular events. You can use the LimboState.add_event_handler method to register event handlers in your states:",
"markers": {
"1": "LimboState.add_event_handler"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "If the event handler returns <1/>, the event will be considered as consumed, and it won’t propagate further or result in a state transition.",
"text": "If the event handler returns , the event will be considered as consumed, and it won’t propagate further or result in a state transition.",
"markers": {
"1": "true"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "State anatomy",
"text": "State anatomy",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Using behavior trees with state machines",
"text": "Using behavior trees with state machines",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "The BTState is a specialized state node in LimboHSM that can host a behavior tree. When a BTState is active, it executes the hosted behavior tree each frame, effectively using the behavior tree as its implementation.",
"text": "The BTState is a specialized state node in LimboHSM that can host a behavior tree. When a BTState is active, it executes the hosted behavior tree each frame, effectively using the behavior tree as its implementation.",
"markers": {
"1": "BTState",
"2": "LimboHSM",
"3": "BTState"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "This allows you to combine the power of behavior trees with the structure and control of state machines. Behavior trees are excellent for defining complex, hierarchical behaviors, while state machines are great for managing the flow and transitions between different behaviors.",
"text": "This allows you to combine the power of behavior trees with the structure and control of state machines. Behavior trees are excellent for defining complex, hierarchical behaviors, while state machines are great for managing the flow and transitions between different behaviors.",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Once the LimboHSM has been created, a BTState can be created for a given LimboHSM:",
"text": "Once the LimboHSM has been created, a BTState can be created for a given LimboHSM:",
"markers": {
"1": "LimboHSM",
"2": "BTState",
"3": "LimboHSM"
}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "Single-file state machine setup",
"text": "Single-file state machine setup",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "In certain scenarios, such as prototyping or during game jams, it’s practical to keep the state machine code in a single file. For such cases, LimboHSM supports delegation and provides chained methods for easier setup. Let’s illustrate this with a practical code example:",
"text": "In certain scenarios, such as prototyping or during game jams, it’s practical to keep the state machine code in a single file. For such cases, LimboHSM supports delegation and provides chained methods for easier setup. Let’s illustrate this with a practical code example:",
"markers": {
"1": "LimboHSM"
}
},
{
"kind": "body",
"tag": "h2",
"path": "",
"html": "Important classes",
"text": "Important classes",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "There are a lot of classes introduced in LimboAI. Here is a list of the most important ones you should know about:",
"text": "There are a lot of classes introduced in LimboAI. Here is a list of the most important ones you should know about:",
"markers": {}
},
{
"kind": "body",
"tag": "h3",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Inherits: BT",
"text": "Inherits: BT",
"markers": {
"1": "BT"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Inherited By: BTAction, BTComment, BTComposite, BTCondition, BTDecorator",
"text": "Inherited By: BTAction, BTComment, BTComposite, BTCondition, BTDecorator",
"markers": {
"1": "BTAction",
"2": "BTComment",
"3": "BTComposite",
"4": "BTCondition",
"5": "BTDecorator"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Base class for all BehaviorTree tasks.",
"text": "Base class for all BehaviorTree tasks.",
"markers": {
"1": "BehaviorTree"
}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Description",
"text": "Description",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Base class for all BehaviorTree tasks. A task is a basic building block in a BehaviorTree that represents a specific behavior or control flow. Tasks are used to create complex behaviors by combining and nesting them in a hierarchy.",
"text": "Base class for all BehaviorTree tasks. A task is a basic building block in a BehaviorTree that represents a specific behavior or control flow. Tasks are used to create complex behaviors by combining and nesting them in a hierarchy.",
"markers": {
"1": "BehaviorTree",
"2": "BehaviorTree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "A task can be one of the following types: action, condition, composite, or decorator. Each type of task has its own corresponding subclass: BTAction, BTCondition, BTDecorator, BTComposite.",
"text": "A task can be one of the following types: action, condition, composite, or decorator. Each type of task has its own corresponding subclass: BTAction, BTCondition, BTDecorator, BTComposite.",
"markers": {
"1": "BTAction",
"2": "BTCondition",
"3": "BTDecorator",
"4": "BTComposite"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Tasks perform their work and return their status using the _tick method. Status values are defined in Status. Tasks can be initialized using the _setup method. See also _enter & _exit.",
"text": "Tasks perform their work and return their status using the _tick method. Status values are defined in Status. Tasks can be initialized using the _setup method. See also _enter & _exit.",
"markers": {
"1": "_tick",
"2": "Status",
"3": "_setup",
"4": "_enter",
"5": "_exit"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Note: Do not extend BTTask directly for your own tasks. Instead, extend one of the subtypes mentioned above.",
"text": "Note: Do not extend BTTask directly for your own tasks. Instead, extend one of the subtypes mentioned above.",
"markers": {}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Properties",
"text": "Properties",
"markers": {}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "agent",
"text": "agent",
"markers": {
"1": "agent"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "agent",
"text": "agent",
"markers": {
"1": "agent"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "Blackboard",
"text": "Blackboard",
"markers": {
"1": "Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Blackboard",
"text": "Blackboard",
"markers": {
"1": "Blackboard"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "blackboard",
"text": "blackboard",
"markers": {
"1": "blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "blackboard",
"text": "blackboard",
"markers": {
"1": "blackboard"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "custom_name",
"text": "custom_name",
"markers": {
"1": "custom_name"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "custom_name",
"text": "custom_name",
"markers": {
"1": "custom_name"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "elapsed_time",
"text": "elapsed_time",
"markers": {
"1": "elapsed_time"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "elapsed_time",
"text": "elapsed_time",
"markers": {
"1": "elapsed_time"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "scene_root",
"text": "scene_root",
"markers": {
"1": "scene_root"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "scene_root",
"text": "scene_root",
"markers": {
"1": "scene_root"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "Status",
"text": "Status",
"markers": {
"1": "Status"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Status",
"text": "Status",
"markers": {
"1": "Status"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "status",
"text": "status",
"markers": {
"1": "status"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "status",
"text": "status",
"markers": {
"1": "status"
}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Methods",
"text": "Methods",
"markers": {}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "_enter() <2/>",
"text": "_enter() ",
"markers": {
"1": "_enter",
"2": "virtual"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "_enter() <2/>",
"text": "_enter() ",
"markers": {
"1": "_enter",
"2": "virtual"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "_exit() <2/>",
"text": "_exit() ",
"markers": {
"1": "_exit",
"2": "virtual"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "_exit() <2/>",
"text": "_exit() ",
"markers": {
"1": "_exit",
"2": "virtual"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "_generate_name() <2/> <3/>",
"text": "_generate_name() ",
"markers": {
"1": "_generate_name",
"2": "virtual",
"3": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "_generate_name() <2/> <3/>",
"text": "_generate_name() ",
"markers": {
"1": "_generate_name",
"2": "virtual",
"3": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "_get_configuration_warnings() <2/> <3/>",
"text": "_get_configuration_warnings() ",
"markers": {
"1": "_get_configuration_warnings",
"2": "virtual",
"3": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "_get_configuration_warnings() <2/> <3/>",
"text": "_get_configuration_warnings() ",
"markers": {
"1": "_get_configuration_warnings",
"2": "virtual",
"3": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "_setup() <2/>",
"text": "_setup() ",
"markers": {
"1": "_setup",
"2": "virtual"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "_setup() <2/>",
"text": "_setup() ",
"markers": {
"1": "_setup",
"2": "virtual"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "Status",
"text": "Status",
"markers": {
"1": "Status"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Status",
"text": "Status",
"markers": {
"1": "Status"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "_tick(delta: <2/>) <3/>",
"text": "_tick(delta: ) ",
"markers": {
"1": "_tick",
"2": "float",
"3": "virtual"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "_tick(delta: <2/>) <3/>",
"text": "_tick(delta: ) ",
"markers": {
"1": "_tick",
"2": "float",
"3": "virtual"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "abort()",
"text": "abort()",
"markers": {
"1": "abort"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "abort()",
"text": "abort()",
"markers": {
"1": "abort"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "add_child(task: BTTask)",
"text": "add_child(task: BTTask)",
"markers": {
"1": "add_child",
"2": "BTTask"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "add_child(task: BTTask)",
"text": "add_child(task: BTTask)",
"markers": {
"1": "add_child",
"2": "BTTask"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "add_child_at_index(task: BTTask, idx: <3/>)",
"text": "add_child_at_index(task: BTTask, idx: )",
"markers": {
"1": "add_child_at_index",
"2": "BTTask",
"3": "int"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "add_child_at_index(task: BTTask, idx: <3/>)",
"text": "add_child_at_index(task: BTTask, idx: )",
"markers": {
"1": "add_child_at_index",
"2": "BTTask",
"3": "int"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "clone() <2/>",
"text": "clone() ",
"markers": {
"1": "clone",
"2": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "clone() <2/>",
"text": "clone() ",
"markers": {
"1": "clone",
"2": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "BehaviorTree",
"text": "BehaviorTree",
"markers": {
"1": "BehaviorTree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "BehaviorTree",
"text": "BehaviorTree",
"markers": {
"1": "BehaviorTree"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "editor_get_behavior_tree()",
"text": "editor_get_behavior_tree()",
"markers": {
"1": "editor_get_behavior_tree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "editor_get_behavior_tree()",
"text": "editor_get_behavior_tree()",
"markers": {
"1": "editor_get_behavior_tree"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "Status",
"text": "Status",
"markers": {
"1": "Status"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Status",
"text": "Status",
"markers": {
"1": "Status"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "execute(delta: <2/>)",
"text": "execute(delta: )",
"markers": {
"1": "execute",
"2": "float"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "execute(delta: <2/>)",
"text": "execute(delta: )",
"markers": {
"1": "execute",
"2": "float"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "get_child(idx: <2/>) <3/>",
"text": "get_child(idx: ) ",
"markers": {
"1": "get_child",
"2": "int",
"3": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "get_child(idx: <2/>) <3/>",
"text": "get_child(idx: ) ",
"markers": {
"1": "get_child",
"2": "int",
"3": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "get_child_count() <2/>",
"text": "get_child_count() ",
"markers": {
"1": "get_child_count",
"2": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "get_child_count() <2/>",
"text": "get_child_count() ",
"markers": {
"1": "get_child_count",
"2": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "get_child_count_excluding_comments() <2/>",
"text": "get_child_count_excluding_comments() ",
"markers": {
"1": "get_child_count_excluding_comments",
"2": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "get_child_count_excluding_comments() <2/>",
"text": "get_child_count_excluding_comments() ",
"markers": {
"1": "get_child_count_excluding_comments",
"2": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "get_index() <2/>",
"text": "get_index() ",
"markers": {
"1": "get_index",
"2": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "get_index() <2/>",
"text": "get_index() ",
"markers": {
"1": "get_index",
"2": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "get_parent() <2/>",
"text": "get_parent() ",
"markers": {
"1": "get_parent",
"2": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "get_parent() <2/>",
"text": "get_parent() ",
"markers": {
"1": "get_parent",
"2": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "get_root() <2/>",
"text": "get_root() ",
"markers": {
"1": "get_root",
"2": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "get_root() <2/>",
"text": "get_root() ",
"markers": {
"1": "get_root",
"2": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "get_task_name()",
"text": "get_task_name()",
"markers": {
"1": "get_task_name"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "get_task_name()",
"text": "get_task_name()",
"markers": {
"1": "get_task_name"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "has_child(task: BTTask) <3/>",
"text": "has_child(task: BTTask) ",
"markers": {
"1": "has_child",
"2": "BTTask",
"3": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "has_child(task: BTTask) <3/>",
"text": "has_child(task: BTTask) ",
"markers": {
"1": "has_child",
"2": "BTTask",
"3": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "initialize(agent: <2/>, blackboard: Blackboard, scene_root: <4/>)",
"text": "initialize(agent: , blackboard: Blackboard, scene_root: )",
"markers": {
"1": "initialize",
"2": "Node",
"3": "Blackboard",
"4": "Node"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "initialize(agent: <2/>, blackboard: Blackboard, scene_root: <4/>)",
"text": "initialize(agent: , blackboard: Blackboard, scene_root: )",
"markers": {
"1": "initialize",
"2": "Node",
"3": "Blackboard",
"4": "Node"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "is_descendant_of(task: BTTask) <3/>",
"text": "is_descendant_of(task: BTTask) ",
"markers": {
"1": "is_descendant_of",
"2": "BTTask",
"3": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "is_descendant_of(task: BTTask) <3/>",
"text": "is_descendant_of(task: BTTask) ",
"markers": {
"1": "is_descendant_of",
"2": "BTTask",
"3": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "is_root() <2/>",
"text": "is_root() ",
"markers": {
"1": "is_root",
"2": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "is_root() <2/>",
"text": "is_root() ",
"markers": {
"1": "is_root",
"2": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "BTTask",
"text": "BTTask",
"markers": {
"1": "BTTask"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "next_sibling() <2/>",
"text": "next_sibling() ",
"markers": {
"1": "next_sibling",
"2": "const"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "next_sibling() <2/>",
"text": "next_sibling() ",
"markers": {
"1": "next_sibling",
"2": "const"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "print_tree(initial_tabs: <2/> = 0)",
"text": "print_tree(initial_tabs: = 0)",
"markers": {
"1": "print_tree",
"2": "int"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "print_tree(initial_tabs: <2/> = 0)",
"text": "print_tree(initial_tabs: = 0)",
"markers": {
"1": "print_tree",
"2": "int"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "remove_child(task: BTTask)",
"text": "remove_child(task: BTTask)",
"markers": {
"1": "remove_child",
"2": "BTTask"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "remove_child(task: BTTask)",
"text": "remove_child(task: BTTask)",
"markers": {
"1": "remove_child",
"2": "BTTask"
}
},
{
"kind": "body",
"tag": "td",
"path": "",
"html": "remove_child_at_index(idx: <2/>)",
"text": "remove_child_at_index(idx: )",
"markers": {
"1": "remove_child_at_index",
"2": "int"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "remove_child_at_index(idx: <2/>)",
"text": "remove_child_at_index(idx: )",
"markers": {
"1": "remove_child_at_index",
"2": "int"
}
},
{
"kind": "body",
"tag": "h4",
"path": "",
"html": "Property Descriptions",
"text": "Property Descriptions",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> agent 🔗",
"text": " agent 🔗",
"markers": {
"1": "Node",
"2": "🔗"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> set_agent(value: <2/>)",
"text": " set_agent(value: )",
"markers": {
"1": "void",
"2": "Node"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> get_agent()",
"text": " get_agent()",
"markers": {
"1": "Node"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "The agent is the contextual object for the BehaviorTree instance. This is usually the parent of the BTPlayer node that utilizes the BehaviorTree resource.",
"text": "The agent is the contextual object for the BehaviorTree instance. This is usually the parent of the BTPlayer node that utilizes the BehaviorTree resource.",
"markers": {
"1": "BehaviorTree",
"2": "BTPlayer",
"3": "BehaviorTree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Blackboard blackboard 🔗",
"text": "Blackboard blackboard 🔗",
"markers": {
"1": "Blackboard",
"2": "🔗"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Blackboard get_blackboard()",
"text": "Blackboard get_blackboard()",
"markers": {
"1": "Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Provides access to the Blackboard. Blackboard is used to share data among tasks of the associated BehaviorTree.",
"text": "Provides access to the Blackboard. Blackboard is used to share data among tasks of the associated BehaviorTree.",
"markers": {
"1": "Blackboard",
"2": "BehaviorTree"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "See Blackboard for additional info.",
"text": "See Blackboard for additional info.",
"markers": {
"1": "Blackboard"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> custom_name = <2/> 🔗",
"text": " custom_name = 🔗",
"markers": {
"1": "String",
"2": "\"\"",
"3": "🔗"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> set_custom_name(value: <2/>)",
"text": " set_custom_name(value: )",
"markers": {
"1": "void",
"2": "String"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> get_custom_name()",
"text": " get_custom_name()",
"markers": {
"1": "String"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "User-provided name for the task. If not empty, it is used by the editor to represent the task. See get_task_name.",
"text": "User-provided name for the task. If not empty, it is used by the editor to represent the task. See get_task_name.",
"markers": {
"1": "get_task_name"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> elapsed_time 🔗",
"text": " elapsed_time 🔗",
"markers": {
"1": "float",
"2": "🔗"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> get_elapsed_time()",
"text": " get_elapsed_time()",
"markers": {
"1": "float"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Elapsed time since the task was “entered”. See _enter.",
"text": "Elapsed time since the task was “entered”. See _enter.",
"markers": {
"1": "_enter"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Returns <1/> when task is not <2/>.",
"text": "Returns when task is not .",
"markers": {
"1": "0",
"2": "RUNNING"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> scene_root 🔗",
"text": " scene_root 🔗",
"markers": {
"1": "Node",
"2": "🔗"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "<1/> get_scene_root()",
"text": " get_scene_root()",
"markers": {
"1": "Node"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Root node of the scene the behavior tree is used in (e.g., the owner of the BTPlayer node). Can be uses to retrieve <2/> references.",
"text": "Root node of the scene the behavior tree is used in (e.g., the owner of the BTPlayer node). Can be uses to retrieve references.",
"markers": {
"1": "BTPlayer",
"2": "NodePath"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Example:",
"text": "Example:",
"markers": {}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Status status 🔗",
"text": "Status status 🔗",
"markers": {
"1": "Status",
"2": "🔗"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Status get_status()",
"text": "Status get_status()",
"markers": {
"1": "Status"
}
},
{
"kind": "body",
"tag": "p",
"path": "",
"html": "Last execution Status returned by _tick.",
"text": "Last execution Status returned by _tick.",
"markers": {
"1": "