limbonaut / limboai Goto Github PK
View Code? Open in Web Editor NEWLimboAI - Behavior Trees and State Machines for Godot 4
Home Page: https://limboai.readthedocs.io/
License: MIT License
LimboAI - Behavior Trees and State Machines for Godot 4
Home Page: https://limboai.readthedocs.io/
License: MIT License
Easy to use in-game behavior tree inspector, that would allow choosing a running BT instance.
BTInspector.show()
.BTInspector.inspect(bt_player.get_tree_instance())
.Window
would allow moving the inspector view around, or popping it out in its own detached window.The issue is likely that icons are not imported with scale option enabled (we don't ship .import
files in GDExtension builds currently). Build action simply packages icons with the build.
I notice after installing the addon that there's a demo/agents/tutorial
folder that contains a lot of tutorial scenes.
How are these supposed to be used? Opening them up and running the scenes, nothing seems to happen.
Under certain scenarios the usage of EditorUndoRedoManager
in the LimboAI Editor plugin will pollute the scene history when it shouldn't -- for example when creating a new BehaviorTree
and adding tasks to it while on an empty scene.
This will make will make undo/redo operations error out from time to time and not work as expected sometimes.
Since EditorUndoRedoManager
is not able to automatically track parent/child relationships of Resource
objects (which include BTTask
), we need a way to force it to use a specific undo/redo history in order to properly manage undo/redo operations in the Editor.
Once the following patch is merged upstream, the LimboAI Editor undo/redo operations can be properly fixed.
Crashes Godot with segmentation fault, no stack trace.
Godot 4.2.1, Linux-based OS.
When running multiple instances of a game to test multiplayer, the debugger panel only shows up on the last session.
Here is a small recording of the problem:
https://github.com/limbonaut/limboai/assets/351420/06a2ce31-88ba-4068-9732-49b8b5b1a108
Allowing BTCallMethod
to pass the delta value within its _tick
method, perhaps optionally, could be quite useful.
My tree contains a BTSubTree that I want to load dynamically. In order to do this, I leave the subtree field unset, and a sibling custom node does this:
var target_subtree: BTSubtree = find_btask(
bt_player.get_tree_instance(),
my_subtree_task_name
) as BTSubtree
# assert target_subtree != null
target_subtree.subtree = null
var new_btree := ... # roughly load('res://...') as BehaviorTree
target_subtree.subtree = new_btree
In the editor, before this runs, I get the following error:
my_file.gd:95 @ <anonymous lambda>(): Subtree root task is not valid.
<C++ Error> Condition "!subtree->get_root_task().is_valid()" is true.
<C++ Source> limboai/bt/tasks/decorators/bt_subtree.cpp:33 @ initialize()
And when my code above runs, the task doesn't update properly.
As a workaround, I tried creating a dummy btree and assign it to the BTSubTree, so that the error isn't raised and the subtree can be replaced. It works until I try to set subtree
to the new BehaviorTree, which doesn't raise an issue and doesn't update it.
Is this supported?
Godot version: 4.2.1.stable non-mono
Describe the bug
Just FYI Installing LimboAI and Beehave together in the same project do not play nicely with one another. I was hoping to compare performance/useability but no such luck. Not sure what best solution would be. It's unfortunate Godot doesn't have namespaces. Seems both addons are creating their own Blackboard class. I also posted this in Beehave just so both addon devs would be aware.
To Reproduce
Steps to reproduce the behavior:
Create new project. Add LimboAI from asset store. Add latest Beehave release from GitHub.
Enable plugin
Attempt to run scene
Error
Expected behavior
Scene runs without error
Desktop (please complete the following information):
OS: Windows
Minimal Project with both Addons installed
testing_limbo_AI_with_beehave.zip
Hey, I'm using the latest test build of the LimboAI project and I believe I've found a bug.
According to the official LimboAI documentation, a LimboStates's dispatch method
"Recursively dispatches a state machine event named p_event with an optional argument p_cargo. Returns true if the event was consumed."
The example below showcases that the dispatch method is not being recursively applied to parent LimboStates:
I've also inspected the source code, and I'm pretty sure that the dispatch method eagerly returns false if the event is not a key in its handler HashMap.
If this is not a bug but rather expected behavior, sorry for the inconvenience.
Thanks in advance.
I'm attaching a minimal project to reproduce, but long story short the issue is that for a BBInt left to its default value shows as 0
in the editor panel:
but actually returns a null
value.
Now I tried incrementing & then decrementing the value, in order to actually set it to 0, and in that case it works as expected. All summed up here:
@tool
extends BTAction
@export var my_bbint_default: BBInt
@export var my_bbint_0: BBInt
@export var my_bbint_1: BBInt
func _enter() -> void:
assert(my_bbint_default.value_source == BBParam.ValueSource.SAVED_VALUE)
print(my_bbint_default.saved_value) # null, would expect 0
print(my_bbint_default.get_value(agent, blackboard)) # null, would expect 0
assert(my_bbint_0.value_source == BBParam.ValueSource.SAVED_VALUE)
print(my_bbint_0.saved_value) # 0 as expected
print(my_bbint_0.get_value(agent, blackboard)) # 0 as expected
assert(my_bbint_1.value_source == BBParam.ValueSource.SAVED_VALUE)
print(my_bbint_1.saved_value) # 1 as expected
print(my_bbint_1.get_value(agent, blackboard)) # 1 as expected
print('all good')
So this may not be an issue... once we know it π
I am using v1.0.2, installed via AssetLib on Godot 4.2.2
Hey I was trying to add a new task via the add task button. But when I created it and tried to add it to the behavior tree it says its not a BTTask.
The behavior dir and task dir is defined and the files are saved in each appropriate dir.
limboai\editor\limbo_ai_editor_plugin.cpp:133 - LimboAI: Failed to instantiate task. Script is not a BTTask: res://ai/tasks/new_task.gd
limboai\editor\limbo_ai_editor_plugin.cpp:83 - Condition "p_task.is_null()" is true.
GDExtension is adding support for declaring ClassDB
virtual methods in Godot 4.3.
Implemented and merged, with unresolved issues documented below.
ERROR: Condition "_instance_bindings != nullptr && _instance_bindings[0].binding != nullptr" is true.
GDExtension 4.3 adds class documentation support, and we should utilize it.
wait_for_resource
: If true, the task should wait for the resource to be released; otherwise, return FAILURE
when the resource is not available.max_concurrency
: maximum number of concurrent access allowed.
counter
or count
, units_available
, available
.Object
-derived instance on the blackboard.
Object::get_instance_id()
for resource identification.StringName
or String
&"default"
&"engage"
, &"heal"
, &"hack"
.StringName
?When transition is registered using such pattern:
hsm.add_transition(hsm.ANYSTATE, some_state, "event")
In such case, transition to self is permitted as of now, which leads to state execution being restarted.
Transitions to self should only be allowed if registered explicitly like add_transition(some_state, some_state, "event")
.
This is the structure of my states
The IdleState from StandingHSM runs, but when I call dispatch in the IdleState, the game just freezes.
Here is how I initialize the root HSM
extends CharacterBody2D
@export var speed := 200.0
@export var hsm: LimboHSM
@export var standing: LimboState
@export var crouching: LimboState
func _ready() -> void:
initialize_state()
func initialize_state():
hsm.add_transition(standing, crouching, "crouch_start")
hsm.add_transition(crouching, standing, "crouch_end")
hsm.initialize(self)
hsm.set_active(true)
Standing HSM
extends LimboHSM
@export var idle: LimboState
@export var walking: LimboState
@export var sprinting: LimboState
func _setup():
initialize_state()
func initialize_state():
add_transition(idle, walking, "walk_start")
add_transition(walking, idle, "walk_end")
add_transition(ANYSTATE, sprinting, "sprint_start")
add_transition(sprinting, idle, "sprint_end")
## Code from standing/idle_state.gd
func _update(delta: float) -> void:
var input_dir := Input.get_vector("move_left", "move_right", "move_up", "move_down")
if input_dir.length() > 0:
get_root().dispatch("walk_start") ## Causes freeze
return
agent.velocity = Vector2.ZERO
agent.move_and_slide()
Add menu actions with shortcuts to cut, copy and paste tasks inside a behavior tree and between different behavior trees.
RunLimit should allow specifying if only successful runs should be counted.
This can be done with a policy
property, which can take the following values (enum):
COUNT_SUCCESSFUL
(default?)COUNT_FAILED
COUNT_ALL
Currently, we can obtain the running instance of a behavior tree by invoking BTPlayer.get_tree_instance()
. However, there are times when a user may wish to temporarily exit the current behavior tree to execute a different one and return to it later. This is a common scenario when utilizing smart objects, as it allows for the transfer of actor control between different behavior trees."
Possible implement: When you are prepared to exit, encapsulate the BT context within an object and return it to the user. This object can then be passed to the resume method to continue the BT.
Implement property and method picker to be used in inspector plugins.
CallMethod
, CheckAgentProperty
, and others.Hey, I am using Godot 4.2 stable.
I just git cloned the LimboAI repo from github, launched Godot and imported a new project, from the "project.godot" file included in the "demo" directory in cloned LimboAI repo. I then installed the LimboAI plugin from the AssetLib into that project, in the default folder "addons", and launched the main scene with F5.
Weirdly, the program crashed, and in the terminal which I used to monitor its execution, it was saying that Godot's parser could not find the "BehaviorTreeData" of which the variable "bt_data" being declared in line 30 in the script attached to the main scene's root node "AgentShowcase" was therein being typed. It seemed to me, though I certainly know worse, that this must be a BehaviorTreeData-specific issue, since the variable declarations above in the script succeeded in being typed from other LimboAI's classes, such as BehaviorTreeView and BTPlayer.
Additionally, I started a new project in Godot, installed the LimboAI plugin from AssetLib, created a scene with a CharacterBody2D root node and attached a script to it. Therein, I declared in a line "class MyClass extends BehaviorTreeData: pass", to see the parser once again not see BehaviorTreeData in the current scope and throw a parser error message. I've had experiences with Godot native parser bugs in the past, so I'm not entirely confident this is a LimboAI issue, if an issue at all or just a misunderstanding of my part about the proper use of LimboAI.
For now, I'll try to compile the engine with the LimboAI module included, and see if this behavior persists. If this is not a bug but rather an expected functionality, I'd appreciate a warning.
Anyway, thanks in advance, for any support eventually directed towards the resolution of this problem, and for the awesome work on developing and releasing this library so far.
Godot 4.3 adds a new method AnimationPlayer.play_with_capture. Utilize it in PlayAnimation
as an option (or the other new method - AnimationMixer.capture
.
Some state transitions would benefit from being able to tell the from and to states. This could be useful for debugging, and creating behavior for transitions between specific states.
An example method could look like this:
signal state_changed(previous : LimboState, next : LimboState)
Hello, This is a really great addon and i would like to study how it works but i cant seem to grasp how to run this on gdscript? can someone make a guide(with pictures if possible) on how to use this? I got confused on the builds? running commands? clones? repositories?
Speaking from the perspective of someone new to github and godot.
Thanks in advance.
Currently the Editor is crashing when attempting to add arguments to BTCallMethod
, either when increasing the argument array size or clicking Add Element
.
Internally the crash happens due to derefencing a null Object
pointer.
Here's the backtrace:
#0 Object::get (this=0x0, p_name=..., r_valid=r_valid@entry=0x0) at core/object/object.cpp:317
#1 0x00005555582bd3b0 in EditorProperty::get_edited_property_value (this=0x55557673bea0) at ./editor/editor_inspector.h:162
#2 EditorPropertyBBParam::_get_edited_param (this=this@entry=0x55557673bea0) at modules/limboai/editor/editor_property_bb_param.cpp:44
#3 0x00005555582bd646 in EditorPropertyBBParam::_notification (this=this@entry=0x55557673bea0, p_what=p_what@entry=45) at modules/limboai/editor/editor_property_bb_param.cpp:313
#4 0x00005555582c00cb in EditorPropertyBBParam::_notificationv (this=0x55557673bea0, p_notification=45, p_reversed=false) at modules/limboai/editor/editor_property_bb_param.h:32
#5 0x000055555a90ad76 in Object::notification (this=0x55557673bea0, p_notification=p_notification@entry=45, p_reversed=p_reversed@entry=false) at core/object/object.cpp:837
#6 0x0000555559e46dca in ThemeOwner::_owner_context_changed (this=this@entry=0x555576b965c0) at scene/theme/theme_owner.cpp:101
#7 0x0000555559e471fe in ThemeOwner::set_owner_context (this=0x555576b965c0, p_context=<optimized out>, p_propagate=true) at scene/theme/theme_owner.cpp:87
#8 0x0000555559526417 in Control::set_theme_context (this=0x55557673bea0, p_context=0x55556eab2aa0, p_propagate=80) at scene/gui/control.cpp:2472
#9 0x000055555952a3a6 in Control::_notification (this=0x55557673bea0, p_notification=10) at scene/gui/control.cpp:3184
#10 0x0000555557cd3881 in Control::_notificationv (this=0x55557673bea0, p_notification=10, p_reversed=false) at ./scene/gui/control.h:48
#11 0x0000555558158fb0 in Container::_notificationv (this=0x55557673bea0, p_notification=10, p_reversed=false) at ./scene/gui/container.h:37
#12 0x00005555582bf1f8 in EditorProperty::_notificationv (this=0x55557673bea0, p_notification=10, p_reversed=p_reversed@entry=false) at ./editor/editor_inspector.h:58
#13 0x00005555582c00dc in EditorPropertyBBParam::_notificationv (this=0x55557673bea0, p_notification=10, p_reversed=false) at modules/limboai/editor/editor_property_bb_param.h:32
#14 0x000055555a90ad76 in Object::notification (this=this@entry=0x55557673bea0, p_notification=p_notification@entry=10, p_reversed=p_reversed@entry=false) at core/object/object.cpp:837
#15 0x00005555594107c2 in Node::_propagate_enter_tree (this=this@entry=0x55557673bea0) at scene/main/node.cpp:262
#16 0x0000555559410afe in Node::_set_tree (this=0x55557673bea0, p_tree=0x55555f6334d0) at scene/main/node.cpp:3011
#17 0x0000555559411c0a in Node::_add_child_nocheck (this=this@entry=0x555576bdadf0, p_child=<optimized out>, p_child@entry=0x55557673bea0, p_name=..., p_internal_mode=p_internal_mode@entry=Node::INTERNAL_MODE_DISABLED) at scene/main/node.cpp:1404
#18 0x0000555559415b59 in Node::add_child (this=0x555576bdadf0, p_child=0x55557673bea0, p_force_readable_name=<optimized out>, p_internal=Node::INTERNAL_MODE_DISABLED) at scene/main/node.cpp:1436
#19 0x000055555941f31b in Node::add_sibling (this=0x555576dd8d50, p_sibling=0x55557673bea0, p_force_readable_name=80, p_force_readable_name@entry=false) at scene/main/node.cpp:1446
#20 0x0000555558a24b4f in EditorPropertyArray::update_property (this=0x55557696b430) at editor/editor_properties_array_dict.cpp:410
#21 0x0000555558a216ec in EditorPropertyArray::_length_changed (this=0x55557696b430, p_page=1) at editor/editor_properties_array_dict.cpp:609
#22 0x0000555558a2e1d9 in call_with_variant_args_helper<EditorPropertyArray, double, 0ul> (p_instance=<optimized out>, p_method=<optimized out>, p_args=<optimized out>, r_error=...) at ./core/variant/binder_common.h:304
#23 0x0000555558a2e21a in call_with_variant_args<EditorPropertyArray, double> (p_instance=<optimized out>, p_method=<optimized out>, p_args=p_args@entry=0x7fffffffae20, p_argcount=p_argcount@entry=1, r_error=...) at ./core/variant/binder_common.h:418
#24 0x0000555558a2e2b9 in CallableCustomMethodPointer<EditorPropertyArray, double>::call (this=0x555576c313c0, p_arguments=0x7fffffffae20, p_argcount=1, r_return_value=..., r_call_error=...) at ./core/object/callable_method_pointer.h:98
#25 0x000055555a721472 in Callable::callp (this=this@entry=0x555577058130, p_arguments=p_arguments@entry=0x7fffffffae20, p_argcount=p_argcount@entry=1, r_return_value=..., r_call_error=...) at core/variant/callable.cpp:56
#26 0x000055555a911431 in Object::emit_signalp (this=0x555576ef7df0, p_name=..., p_args=0x7fffffffae20, p_argcount=1) at core/object/object.cpp:1134
#27 0x000055555942389c in Node::emit_signalp (this=0x555576ef7df0, p_name=..., p_args=0x7fffffffae20, p_argcount=1) at scene/main/node.cpp:3762
#28 0x0000555558235c6e in Object::emit_signal<double> (this=0x555576ef7df0, p_name=...) at ./core/object/object.h:923
#29 0x000055555961ae0d in Range::_value_changed_notify (this=0x555576ef7df0) at scene/gui/range.cpp:48
#30 0x000055555961aea9 in Range::Shared::emit_value_changed (this=<optimized out>) at scene/gui/range.cpp:58
#31 0x000055555961af34 in Range::set_value (this=this@entry=0x555576ef7df0, p_val=<optimized out>) at scene/gui/range.cpp:92
#32 0x0000555558bfc6a9 in EditorSpinSlider::gui_input (this=0x555576ef7df0, p_event=...) at editor/gui/editor_spin_slider.cpp:65
#33 0x000055555952a118 in Control::_call_gui_input (this=this@entry=0x555576ef7df0, p_event=...) at scene/gui/control.cpp:1797
#34 0x00005555594662d4 in Viewport::_gui_call_input (this=this@entry=0x55555f6339e0, p_control=<optimized out>, p_input=...) at scene/main/viewport.cpp:1603
#35 0x0000555559473b59 in Viewport::_gui_input_event (this=0x55555f6339e0, p_event=...) at scene/main/viewport.cpp:1835
#36 0x0000555559477c99 in Viewport::push_input (this=0x55555f6339e0, p_event=..., p_local_coords=80, p_local_coords@entry=false) at scene/main/viewport.cpp:3371
#37 0x0000555559499ea7 in Window::_window_input (this=0x55555f6339e0, p_ev=...) at scene/main/window.cpp:1620
#38 0x00005555594ba032 in call_with_variant_args_helper<Window, Ref<InputEvent> const&, 0ul> (p_instance=<optimized out>, p_method=<optimized out>, p_args=<optimized out>, r_error=...) at ./core/variant/binder_common.h:304
#39 0x00005555594ba092 in call_with_variant_args<Window, Ref<InputEvent> const&> (p_instance=<optimized out>, p_method=<optimized out>, p_args=p_args@entry=0x7fffffffd3d0, p_argcount=p_argcount@entry=1, r_error=...) at ./core/variant/binder_common.h:418
#40 0x00005555594ba131 in CallableCustomMethodPointer<Window, Ref<InputEvent> const&>::call (this=0x55556eac20b0, p_arguments=0x7fffffffd3d0, p_argcount=1, r_return_value=..., r_call_error=...) at ./core/object/callable_method_pointer.h:98
#41 0x000055555a721472 in Callable::callp (this=this@entry=0x7fffffffd460, p_arguments=p_arguments@entry=0x7fffffffd3d0, p_argcount=p_argcount@entry=1, r_return_value=..., r_call_error=...) at core/variant/callable.cpp:56
#42 0x00005555578868ae in Callable::call<Ref<InputEvent> > (this=this@entry=0x7fffffffd460) at ./core/variant/variant.h:863
#43 0x000055555787d9e1 in DisplayServerX11::_dispatch_input_event (this=<optimized out>, p_event=...) at platform/linuxbsd/x11/display_server_x11.cpp:4037
#44 0x000055555787da93 in DisplayServerX11::_dispatch_input_events (p_event=...) at platform/linuxbsd/x11/display_server_x11.cpp:4013
#45 0x000055555a6e32ea in Input::_parse_input_event_impl (this=this@entry=0x55555d769320, p_event=..., p_is_emulated=p_is_emulated@entry=false) at core/input/input.cpp:770
#46 0x000055555a6e3fe5 in Input::flush_buffered_events (this=0x55555d769320) at core/input/input.cpp:1041
#47 0x0000555557880ab9 in DisplayServerX11::process_events (this=0x55555dfba4a0) at platform/linuxbsd/x11/display_server_x11.cpp:5138
#48 0x000055555785e8b3 in OS_LinuxBSD::run (this=this@entry=0x7fffffffd820) at platform/linuxbsd/os_linuxbsd.cpp:941
#49 0x000055555785d142 in main (argc=<optimized out>, argv=0x7fffffffde28) at platform/linuxbsd/godot_linuxbsd.cpp:86
I was implementing a character controller and wanted to store the value of a function I was calling through BTCallMethod
when I realized I can't store its value in the blackboard.
Object::callp
returns a Variant
that is currently unused:
Would be great to be able to save this Variant
when its value is useful. Perhaps this could be done by storing the value only when a key is provided in the editor.
Godot 4.3 brings back playing animations with capture: godotengine/godot#86715
Add support for that functionality in the 4.3 port. It can be a property of BTPlayAnimation
or a new task.
An Expression-based task which could be used against agents to evaluate complex expressions that can't be handled by current tasks would be nice to have upstream. For my purposes it would be really nice to be able to call Expression::execute
and store the result in the blackboard to later inspect it with CheckVar
or CheckTrigger
. For a ton of simple use cases, this eliminates the need to subclass and step into GDScript or <InsertLangHere>
land -- allowing for faster prototyping straight through LimboAI.
The implementation would be virtually the same as BTCallMethod
.
I'm using Godot 4.2.1 with the LimboAI latest master branch commit (0ff93fa) GDExtension, and the editor shortcuts don't work. For example I can't use delete
to delete a task, and I can't use Ctrl + D
to duplicate a task.
Currently, the BT update mode primarily invokes the _tick()
method to poll the current state at each frame. This approach is generally inefficient when executing time-consuming asynchronous functions, such as playing animations, navigating, and timing. It may cause a useless function call just to poll whether it is finished.
For actions based on signals, implementation would be straightforward: set the update mode to manual upon node setup, and switch it back to auto upon exit. For user convenience, adding an option to automate this function for task nodes would be beneficial.
Currently BTPlayer
hardcodes BTTask.agent
to be the scene owner where BTPlayer
lives upon a BTPlayer
+ BehaviorTree
initialization. I don't see a reason not to have BTTask.agent
be the parent node of BTPlayer
by default.
This will be specially useful for new users since they will be able to have multiple BTPlayer
nodes within the same scene and be able to assign their desired agent by selecting a node instead of walking the BehaviorTree
to set the agent they want.
This should include all blackboard variables and the current running indexes of any composite nodes, as well as the current running state of any HSMs. This would allow developers to dump the state of the entire behavior tree to a save file, which is useful for allowing players to save and load at any time (including mid-behavior tree execution, so an AI agent can remember what it was doing).
Currently, only separate scripts are supported (scripts that are saved in separate files).
This is a minor issue but thought I'd report it.
The following warnings and errors will ensue when pre-commit-make-rst
executes:
Running hook: pre-commit-make-rst
Checking for errors in the XML class reference...
Generating the RST class reference...
WARNING: Blackboard.xml: Found a code string "p_key" that matches one of the parameters in method "has_var" description.
WARNING: BTAction.xml: Found a code string "BTAction" that matches one of the known classes in class "BTAction" description.
ERROR: BTCheckTrigger.xml: Unresolved member reference "blackboard" in property "variable" description.
WARNING: BTCondition.xml: Found a code string "BTCondition" that matches one of the known classes in class "BTCondition" description.
WARNING: BTPlayer.xml: Found a code string "p_status" that matches one of the parameters in signal "behavior_tree_finished" description.
WARNING: BTPlayer.xml: Found a code string "p_status" that matches one of the parameters in signal "updated" description.
WARNING: BTRandomWait.xml: Found a code string "min_duration" that matches the BTRandomWait.min_duration member in class "BTRandomWait" description.
WARNING: BTRandomWait.xml: Found a code string "max_duration" that matches the BTRandomWait.max_duration member in class "BTRandomWait" description.
WARNING: BTTask.xml: Found a code string "BTTask" that matches one of the known classes in class "BTTask" description.
WARNING: BTTask.xml: Found a code string "custom_name" that matches the BTTask.custom_name member in property "custom_name" description.
WARNING: BTTask.xml: Found a code string "p_child" that matches one of the parameters in method "add_child" description.
WARNING: BTTask.xml: Found a code string "p_child" that matches one of the parameters in method "add_child_at_index" description.
WARNING: BTTask.xml: Found a code string "p_idx" that matches one of the parameters in method "add_child_at_index" description.
WARNING: BTTask.xml: Found a code string "p_child" that matches one of the parameters in method "has_child" description.
WARNING: BTTask.xml: Found a code string "p_task" that matches one of the parameters in method "is_descendant_of" description.
WARNING: BTTask.xml: Found a code string "p_task" that matches one of the parameters in method "is_descendant_of" description.
WARNING: BTTask.xml: Found a code string "p_child" that matches one of the parameters in method "remove_child" description.
WARNING: LimboHSM.xml: Found a code string "p_event" that matches one of the parameters in method "add_transition" description.
WARNING: LimboHSM.xml: Found a code string "p_from_state" that matches one of the parameters in method "add_transition" description.
WARNING: LimboHSM.xml: Found a code string "p_to_state" that matches one of the parameters in method "add_transition" description.
WARNING: LimboState.xml: Found a code string "p_event" that matches one of the parameters in method "add_event_handler" description.
WARNING: LimboState.xml: Found a code string "p_callable" that matches one of the parameters in method "call_on_enter" description.
WARNING: LimboState.xml: Found a code string "p_callable" that matches one of the parameters in method "call_on_exit" description.
WARNING: LimboState.xml: Found a code string "p_callable" that matches one of the parameters in method "call_on_update" description.
WARNING: LimboState.xml: Found a code string "p_event" that matches one of the parameters in method "dispatch" description.
WARNING: LimboState.xml: Found a code string "p_cargo" that matches one of the parameters in method "dispatch" description.
Steps to reproduce:
.git/hooks
within the Godot repository.git commit --verify
Currently, changing the type of a task requires dragging all of its' children to the new task one by one. This can be very time consuming if there are a large amount of tasks that need to be moved, as each task has to be moved individually to their new parent (where at such point it would be faster to edit the behavior tree resource manually through an external code editor).
A "Change Type..." similar to how Node's type change, or another similar functionality that can help with managing multiple tasks such as multiple selection dragging or a cut + paste function would be very helpful in managing large behavior trees.
When using the GDextension (downloaded from the Godot Asset Library), creating a new custom task based on the template throws a bunch of "overrides a method from native class" errors for each method:
Line 18:The method "_setup()" overrides a method from native class "BTTask". This won't be called by the engine and may not work as expected. (Warning treated as error.)
Line 23:The method "_enter()" overrides a method from native class "BTTask". This won't be called by the engine and may not work as expected. (Warning treated as error.)
Line 28:The method "_exit()" overrides a method from native class "BTTask". This won't be called by the engine and may not work as expected. (Warning treated as error.)
Line 33:The method "_tick()" overrides a method from native class "BTTask". This won't be called by the engine and may not work as expected. (Warning treated as error.)
Line 38:The method "_get_configuration_warnings()" overrides a method from native class "BTTask". This won't be called by the engine and may not work as expected. (Warning treated as error.)```
Historically, String
is used for such things as blackboard variable names and event names in LimboAI. StringName
was introduced in GDScript 2.0, and it needs to be evaluated as a replacement for strings.
Hello! I'm using the latest LimboAI 1.0.2 and Godot 4.2.2
When I build the demo project out to Linux everything runs flawlessly, but when I try adding a LimboHMS node with child BTState nodes the exported project will crash on launch with the following errors in the godot.log:
USER SCRIPT ERROR: Parse Error: Could not find type "LimboHSM" in the current scope.
USER SCRIPT ERROR: Parse Error: Could not find type "BTState" in the current scope.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.