<180> Events and transitions <181> 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. <182> To register a transition and associate it with a specific event, you can use the LimboHSM.add_transition method: <183> In this example, we’re registering a transition from the <1/> to the <2/> when the <3/> event is dispatched. <184> A transition can be also associated with no particular starting state: <185> 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. <186> 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: <187> 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. <188> State anatomy <189> Using behavior trees with state machines <190> 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. <191> 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. <192> Once the LimboHSM has been created, a BTState can be created for a given LimboHSM: <193> Single-file state machine setup <194> 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: <195> Important classes <196> There are a lot of classes introduced in LimboAI. Here is a list of the most important ones you should know about: <197> BTTask <198> Inherits: BT <199> Inherited By: BTAction, BTComment, BTComposite, BTCondition, BTDecorator <200> Base class for all BehaviorTree tasks. <201> Description <202> 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. <203> 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. <204> 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. <205> Note: Do not extend BTTask directly for your own tasks. Instead, extend one of the subtypes mentioned above. <206> Properties <207> agent <208> Blackboard <209> blackboard <210> custom_name <211> elapsed_time <212> scene_root <213> Status <214> status <215> Methods <216> _enter() <2/> <217> _exit() <2/> <218> _generate_name() <2/> <3/> <219> _get_configuration_warnings() <2/> <3/> <220> _setup() <2/> <221> _tick(delta: <2/>) <3/> <222> abort() <223> add_child(task: BTTask) <224> add_child_at_index(task: BTTask, idx: <3/>) <225> BTTask <226> clone() <2/> <227> BehaviorTree <228> editor_get_behavior_tree() <229> execute(delta: <2/>) <230> get_child(idx: <2/>) <3/> <231> get_child_count() <2/> <232> get_child_count_excluding_comments() <2/> <233> get_index() <2/> <234> get_parent() <2/> <235> get_root() <2/> <236> get_task_name() <237> has_child(task: BTTask) <3/> <238> initialize(agent: <2/>, blackboard: Blackboard, scene_root: <4/>) <239> is_descendant_of(task: BTTask) <3/> <240> is_root() <2/> <241> next_sibling() <2/> <242> print_tree(initial_tabs: <2/> = 0) <243> remove_child(task: BTTask) <244> remove_child_at_index(idx: <2/>) <245> Property Descriptions <246> <1/> agent 🔗 <247> <1/> set_agent(value: <2/>) <248> <1/> get_agent() <249> The agent is the contextual object for the BehaviorTree instance. This is usually the parent of the BTPlayer node that utilizes the BehaviorTree resource. <250> Blackboard blackboard 🔗 <251> Blackboard get_blackboard() <252> Provides access to the Blackboard. Blackboard is used to share data among tasks of the associated BehaviorTree. <253> See Blackboard for additional info. <254> <1/> custom_name = <2/> 🔗 <255> <1/> set_custom_name(value: <2/>) <256> <1/> get_custom_name() <257> User-provided name for the task. If not empty, it is used by the editor to represent the task. See get_task_name. <258> <1/> elapsed_time 🔗 <259> <1/> get_elapsed_time() <260> Elapsed time since the task was “entered”. See _enter. <261> Returns <1/> when task is not <2/>. <262> <1/> scene_root 🔗 <263> <1/> get_scene_root() <264> 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. <265> Example: <266> Status status 🔗 <267> Status get_status() <268> Last execution Status returned by _tick. <269> Method Descriptions <270> <1/> _enter() <2/> 🔗 <271> Called when task is “entered”, i.e. when task is executed while not having a <1/> status. <272> It is called before _tick in the execution order. This method is used when preparation is needed before main work begins, usually when it takes more than one tick to finish the task. See also execute. <273> <1/> _exit() <2/> 🔗 <274> Called when task is “exited”, i.e. after _tick returns <2/> or <3/> status. See also execute. <275> <1/> _generate_name() <2/> <3/> 🔗 <276> Called to generate a display name for the task unless custom_name is set. See get_task_name. <277> <1/> _get_configuration_warnings() <2/> <3/> 🔗 <278> The string returned by this method is shown as a warning message in the behavior tree editor. Any task script that overrides this method must include <1/> annotation at the top of the file. <279> <1/> _setup() <2/> 🔗 <280> Called to initialize a task during initialization step. It is called only once before the task’s first execution tick. This method allows you to set up any necessary state or configurations for the task before it begins executing. <281> Status _tick(delta: <2/>) <3/> 🔗 <282> Called when task is “ticked”, i.e. executed by BTPlayer or BTState during an update. <283> Returns execution status as defined in Status. <284> Note: Tasks perform their main function by implementing this method. <285> <1/> abort() 🔗 <286> Resets the task and its children recursively. If a task is in the <1/> state, it is exited and its status is reset to <2/>. <287> <1/> add_child(task: BTTask) 🔗 <288> Adds a child task. The <1/> is placed at the end of the children list. <289> <1/> add_child_at_index(task: BTTask, idx: <3/>) 🔗 <290> Adds a child task. The <1/> is placed at <2/> position in the children list. <291> BTTask clone() <2/> 🔗 <292> Duplicates the task and its children, copying the exported members. Sub-resources are shared for efficiency, except for BBParam subtypes, which are always copied. Used by the editor to instantiate BehaviorTree and copy-paste tasks. <293> BehaviorTree editor_get_behavior_tree() 🔗 <294> Returns the behavior tree that owns this task. This is only available in the editor. <295> Status execute(delta: <2/>) 🔗 <296> Performs task’s execution. The execution follows a specific sequence: <297> If task’s current status is not <2/>, the _enter method is called first. <298> Next, the _tick method is called next to perform the task’s work. <299> If the _tick method returns <2/> or <3/> status, the _exit method will be called next as part of the execution cleanup. <300> BTTask get_child(idx: <2/>) <3/> 🔗 <301> Returns a child task by specifying its index. <302> <1/> get_child_count() <2/> 🔗 <303> Returns the number of child tasks. <304> <1/> get_child_count_excluding_comments() <2/> 🔗 <305> Returns the number of child tasks not counting BTComment tasks. <306> <1/> get_index() <2/> 🔗 <307> Returns the task’s position in the behavior tree branch. Returns <1/> if the task doesn’t belong to a task tree, i.e. doesn’t have a parent. <308> BTTask get_parent() <2/> 🔗 <309> Returns the task’s parent. <310> BTTask get_root() <2/> 🔗 <311> Returns the root task of the behavior tree. <312> <1/> get_task_name() 🔗 <313> The string returned by this method is used to represent the task in the editor. <314> Method _generate_name is called to generate a display name for the task unless custom_name is set. <315> <1/> has_child(task: BTTask) <3/> 🔗 <316> Returns <1/> if <2/> is a child of this task. <317> <1/> initialize(agent: <2/>, blackboard: Blackboard, scene_root: <4/>) 🔗 <318> Initilizes the task. Assigns agent and blackboard, and calls _setup for the task and its children. <319> The method is called recursively for each child task. <1/> should be the root node of the scene the behavior tree is used in (e.g., the owner of the node that contains the behavior tree). <320> <1/> is_descendant_of(task: BTTask) <3/> 🔗 <321> Returns <1/> if this task is a descendant of <2/>. In other words, this task must be a child of <3/> or one of its children or grandchildren.