Compare commits

...

143 Commits

Author SHA1 Message Date
Serhii Snitsaruk 1a192b6129
Port BBParam editor to GDExtension (#287) 2025-02-18 12:39:47 +01:00
Serhii Snitsaruk 8e3f37d46a
GHA: Update Godot version used in GDExtension workflow 2025-02-16 14:27:29 +01:00
Serhii Snitsaruk 98778c1645
GHA: Test with `strict_checks=yes` 2025-02-16 13:06:13 +01:00
Serhii Snitsaruk 7ca4c63191
Update demo due to 4.4 changes 2025-02-16 13:01:39 +01:00
Serhii Snitsaruk 8788d8bf12
Bump version to 1.4.0-dev 2025-02-16 12:59:26 +01:00
Serhii Snitsaruk f31d722320
Merge pull request #223 from Rubonnek/support-godot-4.4
Support Godot 4.4
2025-02-16 12:52:15 +01:00
Wilson E. Alvarez bbb4512437
Add guards around PROPERTY_HINT_NO_NODEPATH which is not available in GDExtension 2025-02-15 11:29:36 -05:00
Wilson E. Alvarez 43ec612949
Fix broken conversion: Ref<Script> to const String 2025-02-15 09:48:16 -05:00
Wilson E. Alvarez 998bf212b7
Fix unhandled PROPERTY_HINT_NO_NODEPATH warning
Due to upstream change:

	6f7525c396
2025-02-15 09:48:16 -05:00
Wilson E. Alvarez ec8eb4bf91
Override renamed EditorPlugin::get_name() method
Due to upstream change:

	0ab3dc273e
2025-02-15 09:48:16 -05:00
Wilson E. Alvarez 05cd3e67b0
Refactor EditorHelpBit usage
Due to upstream change:

	4e19ab8afe
2025-02-15 09:48:16 -05:00
Wilson E. Alvarez ed9762e62f
Fix unhandled PROPERTY_HINT_ONESHOT warning
Due to upstream change:

	761a20f7a7
2025-02-15 09:48:16 -05:00
Wilson E. Alvarez ac0b68aa13
Fix forbidden comparisons between Ref and nullptr.
Necessary when compiling with strict_checks=yes.

Due to upstream change:

	df29cc696f
2025-02-15 09:48:16 -05:00
Wilson E. Alvarez c3da26caba
Fix internal Button set_icon calls to set_button_icon
Due to upstream change:

    562c666e3d
2025-02-15 09:48:16 -05:00
Wilson E. Alvarez e9f6a6fea5
Fix unhandled PROPERTY_HINT_TOOL_BUTTON warning
Due to upstream change:

	85dfd89653
2025-02-15 09:48:16 -05:00
Wilson E. Alvarez c3144875df
Fix unhandled PROPERTY_HINT_DICTIONARY_TYPE warning
Due to upstream change:

	9853a69144
2025-02-15 09:48:16 -05:00
Wilson E. Alvarez e37ff39641
Update EditorMainScreen calls after its extraction
Due to upstream change:

	5e1c9d68aa
2025-02-15 09:48:16 -05:00
Serhii Snitsaruk 6292ee4404
chore: Move `update_rst` to `scripts/` dir 2025-02-15 13:40:54 +01:00
Serhii Snitsaruk 77dc9b3b85
GHA: Build editor targets for iOS & web GDExtension libs (#285)
Compile iOS & Web GDExtension libs with editor support.
2025-02-13 11:58:03 +01:00
Serhii Snitsaruk 88701e9f20
GDExtension: Build Android libs with editor features (#284)
Also, fix the macOS Vulkan SDK installation step in CI.

Resolves GH-282.
2025-02-12 12:05:50 +01:00
Serhii Snitsaruk 576df4092a
Bump version to 1.3.1 2025-02-02 21:22:51 +01:00
Serhii Snitsaruk b8f266588a
Fix duplicate UI banners (#279)
During the editor launch, duplicate UI banners may appear in the LimboAI tab. Maybe in some other instances too. This PR fixes this issue.
2025-02-02 21:19:58 +01:00
Serhii Snitsaruk eac7e56f42
Doc: Mention pre-built templates (#280) 2025-02-02 19:45:54 +01:00
namelessvoid 7aebed5897
Update Readme to accomodate new documentation structure
(cherry picked from commit fe87a87759)
2025-01-22 01:18:37 +01:00
Steven Schoen a6613c32f9
Navigate to subtree resource when clicked in editor (#276)
Co-authored-by: Steven Schoen <digisteve5@gmail.com>
2025-01-22 01:05:51 +01:00
Serhii Snitsaruk 76e02a75e5
Fix BTInstance not registered with debugger on BTPlayer.set_bt_instance() (#275) 2025-01-21 23:43:52 +01:00
Serhii Snitsaruk 1b9cf17339
Fix BTPlayer.set_behavior_tree() not populating Blackboard (#274) 2025-01-21 23:35:28 +01:00
Serhii Snitsaruk 0584b0401f
Bump version to 1.4.0-dev 2025-01-21 12:00:35 +01:00
Serhii Snitsaruk 98917a2055
Bump version to 1.3.0 2025-01-21 03:18:11 +01:00
Serhii Snitsaruk 10defe21a5
Update copyright notices across the project files & in LICENSE.md (#272)
* Include LimboAI contributors in the notice
* Clarify first year of publication as copyright year
2025-01-21 02:18:59 +01:00
Laurent Senta 3dcbee829c
doc: clarify scoping for BTState (#271) 2025-01-10 16:42:09 +01:00
Serhii Snitsaruk e3be34670e
Doc: Clarify how to access objects on the blackboard that may be freed 2025-01-05 20:53:53 +01:00
Dave Palais e3262108d7
Amend logic error in `BlackboardPlan` variable listing (#269) 2025-01-03 02:33:29 +01:00
Dave Palais b144ebc7bc
Do not show warning for NIL type BlackboardPlan variables on BBParam. (#267)
Enable variable mapping for NIL type public BlackboardPlan variables.
2025-01-01 18:14:39 +01:00
Serhii Snitsaruk 672f92c87b
Update doc 2024-12-30 01:24:52 +01:00
Serhii Snitsaruk e2e42b90a8 Fix documentation links in the editor 2024-12-29 16:03:21 -08:00
Serhii Snitsaruk a952009293
Add `Blackboard.print_state()` (#264)
Method that prints values of all variables in each scope.
2024-12-29 23:45:59 +01:00
Pheubel 0982804a86
Remove arbitrary limit on user task directories (#263)
Resolves GH-256
2024-12-28 19:03:51 +01:00
Serhii Snitsaruk dd427c25e2
Revert "Update Readme to accomodate new documentation structure"
This reverts commit fe87a87759.
2024-12-18 21:18:08 +01:00
Serhii Snitsaruk dddc713a3a
Merge pull request #261 from limbonaut/fix-crash-with-vscode-and-gdextension
Fix crash with VSCode and GDExtension
2024-12-17 23:54:21 +01:00
Serhii Snitsaruk 6fecc1e4b5
Merge pull request #262 from namelessvoid/re-arrange-documentation
Suggestion on re-arranging the docs
2024-12-17 23:35:56 +01:00
namelessvoid fe87a87759 Update Readme to accomodate new documentation structure 2024-12-17 20:14:51 +01:00
Simon Kerler 0e0a4685f9
De-duplicated info about pros/cons of GDExtension vs Module
Co-authored-by: Serhii Snitsaruk <limbonaut@pm.me>
2024-12-17 19:47:45 +01:00
Simon Kerler 955da07652
Remove outdated info about built-in documentation
Co-authored-by: Serhii Snitsaruk <limbonaut@pm.me>
2024-12-17 19:42:27 +01:00
namelessvoid 90c0a9a4f6 Merge remote-tracking branch 'origin/master' into re-arrange-documentation 2024-12-17 00:51:05 +01:00
namelessvoid 1359f1e606 Merge BT debugging docs into 'Creating BT' chapter 2024-12-17 00:33:47 +01:00
namelessvoid 0d65c1117a Remove now redundant page from documentation 2024-12-17 00:23:32 +01:00
Serhii Snitsaruk a5118ebc1b
Fix crash while using callable_mp in GDExtension 2024-12-17 00:11:16 +01:00
Serhii Snitsaruk 17872e7048
Fix broken syntax in docs 2024-12-16 22:19:54 +01:00
Serhii Snitsaruk f7a63ca673
Merge pull request #260 from limbonaut/doc-contributing
Doc: Add Contributing page
2024-12-16 22:04:00 +01:00
Serhii Snitsaruk 691208016c
Doc: Add Contributing page 2024-12-16 22:03:59 +01:00
namelessvoid 35a2cbac56 Re-arrange documentation 2024-12-16 21:47:20 +01:00
Serhii Snitsaruk db827a8d30
Merge pull request #258 from namelessvoid/fix-typo-in-example
Add missing 'not' in HSM state example
2024-12-16 12:36:22 +01:00
namelessvoid 360e24c330 Add missing 'not' in HSM state example 2024-12-16 00:43:46 +01:00
Serhii Snitsaruk e9884589a8
Doc: Add offline formats 2024-12-11 20:28:42 +01:00
Serhii Snitsaruk 9cfdabca3f
Merge pull request #255 from limbonaut/fix-setting-bt-crash
Fix: Keep `BTInstance` alive until update is finished (fixes #254)
2024-12-04 18:15:55 +01:00
Serhii Snitsaruk 23a6e5fdfe
Fix: Keep `BTInstance` alive until update is finished
Fixes #254
2024-12-04 17:57:11 +01:00
Serhii Snitsaruk 6644f191ca
Merge pull request #252 from limbonaut/gha-mingw-windows
GHA: Improve Windows builds: MinGW/GCC with LTO, D3D12, ANGLE
2024-12-01 22:35:44 +01:00
Serhii Snitsaruk 8b0b15fce4
GHA: Fix scons cache in test builds 2024-12-01 18:44:31 +01:00
Serhii Snitsaruk 11548c51f0
GHA: Fix build name missing in Windows builds 2024-12-01 18:35:21 +01:00
Serhii Snitsaruk 62a142f188
GHA: Compile with D3D12 support and Mesa libs 2024-12-01 16:46:27 +01:00
Serhii Snitsaruk 7a3d5bc6a2
GHA: Compile Windows builds with statically linked ANGLE 2024-12-01 16:46:21 +01:00
Serhii Snitsaruk 6d79b7474e
GHA: Don't use SCons cache in release builds 2024-12-01 16:28:10 +01:00
Serhii Snitsaruk 44040dda06
GHA: Build Windows binaries using MinGW/GCC in a docker container 2024-12-01 16:28:03 +01:00
Serhii Snitsaruk ba90deaa6a
Merge pull request #245 from limbonaut/editor-prop-binding
Feature: Bind `BlackboardPlan` variables to node properties in the Inspector
2024-11-15 11:35:13 -08:00
Serhii Snitsaruk 08d8fcdf92
Don't show binding/mapping for hidden variables 2024-11-15 18:50:42 +01:00
Serhii Snitsaruk 51878e4b6e
Limit a variable to either binding or mapping, but not both at once 2024-11-15 18:15:40 +01:00
Serhii Snitsaruk 008702b1e4
Fix template compilation 2024-11-11 11:43:26 +01:00
Serhii Snitsaruk 6e8c22d598
Clean up & strengthen code 2024-11-11 10:24:14 +01:00
Serhii Snitsaruk 0b3b11a383
Enable binding in BehaviorTree-owned blackboard plan 2024-11-11 10:13:41 +01:00
Serhii Snitsaruk 4cac6276aa
Fix GDExtension issues 2024-11-11 10:01:20 +01:00
Serhii Snitsaruk ea671dd54b
Improve binding presentation within inspector, fix compilation issues 2024-11-11 09:49:01 +01:00
Serhii Snitsaruk bc7f677810
Specialized inspector property editor for NodePath 2024-11-11 08:24:54 +01:00
Serhii Snitsaruk 057d4e669c
Bind variables to scene node properties upon runtime Blackboard creation 2024-11-10 19:58:35 +01:00
Serhii Snitsaruk f600d633a3
Store property bindings in BlackboardPlan 2024-11-10 19:08:56 +01:00
Serhii Snitsaruk ae61d551c0
Doc: Clarify when `LimboState::_exit` is called 2024-11-05 19:41:16 +01:00
Serhii Snitsaruk a14cc4cc68
GHA: Use 4.3-stable in "All builds" 2024-11-05 19:16:41 +01:00
Serhii Snitsaruk d304f957ef
Merge pull request #244 from limbonaut/save-builtin-bt-on-ctrls
Improve workflow with built-in BT resources
2024-11-05 01:40:51 -08:00
Serhii Snitsaruk bf85350260
Open the owner scene when switching to a built-in BT 2024-11-04 19:45:54 +01:00
Serhii Snitsaruk 03476721d9
Change shortcut for "Jump to Owner"
Ctrl+J is no longer available by default
2024-11-04 15:52:42 +01:00
Serhii Snitsaruk bebd6a15eb
Save edited built-in BT resource on `Ctrl+S` 2024-11-04 14:52:35 +01:00
Serhii Snitsaruk 4c9028fc66
Merge pull request #243 from limbonaut/fix-builtin-resource-save
Improve saving for built-in BTs attached to scenes
2024-11-03 01:59:52 -08:00
Serhii Snitsaruk e21156df35
Save external BTs on plugin callback
Also fixes dirty state handling, however it's currently unused.
2024-11-02 15:41:34 +01:00
Serhii Snitsaruk 591a1fe672
Improve saving for built-in BTs attached to scenes 2024-11-01 22:22:23 +01:00
Serhii Snitsaruk f90c48eb81
Merge pull request #242 from limbonaut/fix-hsm-reparenting-saga-episode-three
Fix re-parenting an agent interrupts its state machine
2024-11-01 11:11:45 -07:00
Serhii Snitsaruk 162de0f868
Fix re-parenting agent interrupts its state machine 2024-11-01 18:47:36 +01:00
Serhii Snitsaruk 423c4ce7a4
Merge pull request #241 from limbonaut/hsm-transition-guards
`LimboHSM`: Ability to specify per-transition guard function
2024-11-01 07:49:20 -07:00
Serhii Snitsaruk a5d59a0a51
Update docs 2024-11-01 15:24:32 +01:00
Serhii Snitsaruk 85eda3c804
Tests for per-transition guards 2024-11-01 14:59:10 +01:00
Serhii Snitsaruk 6de8b9e4c4
Merge pull request #227 from limbonaut/fix-bttask-setup-overriding
Call both native and script `_setup/_enter/_exit` in BTTask
2024-11-01 06:19:13 -07:00
Serhii Snitsaruk bbe71bb378
Add transition guards 2024-11-01 14:00:30 +01:00
Serhii Snitsaruk 7feff38d6b
Call both native and script _enter/_exit in BTTask 2024-11-01 13:50:08 +01:00
Serhii Snitsaruk 632e26c922
Call both native and script's `_setup()` in BTTask
Current behavior is overriding, which is not correct as it's an initializer function.
2024-11-01 13:42:49 +01:00
Serhii Snitsaruk 106608aca9
Merge pull request #239 from limbonaut/fix-clone-bttask-and-arrays
Duplicate `BBParam` instances in typed arrays in `BTTask::clone()`
2024-10-28 09:17:39 -07:00
Serhii Snitsaruk d5bc62830a
Duplicate BBParam instances inside arrays in `BTTask::clone()`
Fixes issue with `CallMethod` arguments being shared between tasks after duplication.
2024-10-28 15:06:29 +01:00
Serhii Snitsaruk 3b15abf2c9
GHA: Fix vulkan sdk in ios packaging 2024-10-19 22:09:03 +02:00
Serhii Snitsaruk 6d049a3701
Merge pull request #237 from limbonaut/gha-ios-vulkan
GHA: Fix Vulkan SDK on iOS
2024-10-19 11:35:28 -07:00
Serhii Snitsaruk 65454c36a8
GHA: Fix Vulkan SDK on iOS 2024-10-19 20:04:48 +02:00
Serhii Snitsaruk e0e15b0ec4
Merge pull request #163 from limbonaut/gha-gdext-ios
GHA: Build iOS GDExtension libraries
2024-10-17 06:23:06 -07:00
Serhii Snitsaruk ee8c773e71
GHA: Build with ios_simulator=yes flag 2024-10-16 14:32:39 +02:00
Serhii Snitsaruk 7f38fe2b8b
GHA: Change iOS arch to arm64 & build simulator libs 2024-10-16 14:32:39 +02:00
Serhii Snitsaruk 500775eb14
Add iOS builds to the GDExtension manifest 2024-10-16 14:32:39 +02:00
Serhii Snitsaruk 1cdde4d5a9
GHA: Add iOS builds to GDExtension workflow 2024-10-16 14:31:56 +02:00
Serhii Snitsaruk eaa43020f5
Merge pull request #235 from limbonaut/doc-get-var-fix
Doc: Clarify `Blackboard.get_var()` and `set_var()`
2024-10-13 12:27:12 -07:00
Serhii Snitsaruk b5b1ac7289
Doc: Clarify `Blackboard.get_var()` and `set_var()` 2024-10-13 21:04:59 +02:00
Serhii Snitsaruk ece17d68d9
Merge pull request #234 from limbonaut/doc-fixes
GHA: Code style checks for PRs and commits
2024-10-13 12:03:17 -07:00
Serhii Snitsaruk 85787616e7
GHA: Add code style check for PRs and direct commits 2024-10-13 20:43:59 +02:00
Serhii Snitsaruk 11abf36c99
Clang format 2024-10-13 20:25:03 +02:00
Serhii Snitsaruk 19d771fef2
Merge pull request #229 from monxa/tasktree-search
Implement Tree Search Functionality with Highlighting and Filtering
2024-10-13 11:18:37 -07:00
Serhii Snitsaruk 2b89d1d23e
Merge pull request #233 from limbonaut/gha-fix-macos-vulkan
GHA: Fix Vulkan SDK installation step
2024-10-13 10:48:31 -07:00
Serhii Snitsaruk 6f318b83b8
GHA: Fix Vulkan SDK installation step 2024-10-13 18:25:54 +02:00
Serhii Snitsaruk 7a1b56f9c8
GHA: Switch workflows to Godot 4.3 branch 2024-10-13 17:06:25 +02:00
Alexander Montag 2b86928737
Add tooltip to explain case sensitivity behavior 2024-10-13 07:02:59 +00:00
Alexander Montag 8c557f87f7
Address 2. review for TreeSearch
Remove redundant comment

Prune tab_search_context

Fix restore tab on `_tab_closed`

Add break statement

Pass callable by reference in _draw_highlight_item

Refactor _initialize_controls into constructor

Remove redundant if (!line_edit_search)-check
2024-10-13 07:31:35 +02:00
Alexander Montag 6776319472
Implement Tree Search Functionality with Highlighting and Filtering
This commit introduces a comprehensive Tree Search feature, including:
- Tree highlighting: Highlights items that match the search query.
- Tree filtering: Filters items so only matches and descendants are
  shown.
- Counting descendants: Shows the number of matching items within collapsed branches.
- Jump to next match: on enter.
- (Limbo-)Shortcut: Default CTRL-F.
- Menu entry: Misc->Search Tree.
- Remember separate SearchInfo for each tab.

Key implementation details:
- Optimized performance for large trees
- Implemented recursive filtering for efficiency
- Added UI elements including next/previous match buttons

Development History:
- Initial implementation of highlighting and filtering
- Multiple rounds of performance optimization
- Bug fixes and refactoring for correctness
- UI enhancements and polish
- Code cleanup and style improvements
2024-10-06 06:57:11 +02:00
Serhii Snitsaruk 760af804c0
Merge pull request #230 from limbonaut/fix-docs
Fix and update docs
2024-09-30 12:36:57 +02:00
Serhii Snitsaruk c49e5142a5
Fix and update docs 2024-09-30 11:17:01 +02:00
Serhii Snitsaruk 60a767032e
Merge pull request #226 from limbonaut/fix-hsm-exit-crash
Fix invalid access errors on exit in LimboHSM
2024-09-26 16:54:31 +02:00
Serhii Snitsaruk 60142b191d
Fix invalid access crash on exit in LimboHSM
Since #131, `LimboState::_exit()` became a source of potential crashes
if object references are used without a validity check. It's too easy
to miss this, which can lead to game crashing during runtime.

This fix reverts #131 change and proposes alternative approach of
re-activating root HSM upon tree entering if it was previously active.
Note that it's not an ideal solution, as some state will be lost upon
re-parenting: HSM exits and then re-activates and enters its initial state.
2024-09-22 13:57:15 +02:00
Serhii Snitsaruk 134bb3214a
Merge pull request #225 from ydeltastar/remember-last-session
Remember loaded `BehaviorTree`s of last session
2024-09-22 13:32:56 +02:00
yds db7c990f51 Remember loaded BehaviorTrees of last session 2024-09-21 16:23:13 -03:00
Serhii Snitsaruk 08884e6180
Merge pull request #219 from monxa/fix-miscmenu-layout-duplicates
Fix duplicate entries in Misc->Layout
2024-09-17 14:42:01 +02:00
Alexander Montag c2130a7b2f Fix duplicate entries in Misc->layout
Fixes #218
2024-09-17 02:16:47 +02:00
Serhii Snitsaruk 5ddc43fe94
Merge pull request #215 from limbonaut/prefetch-with-base-plan
Prefetch nodes set directly in the BehaviorTree's BlackboardPlan
2024-09-15 17:06:55 +02:00
Serhii Snitsaruk 601aed3684
Merge pull request #216 from limbonaut/gha-debug-builds
GHA: Add an option to create GDExtension debug builds
2024-09-15 16:23:08 +02:00
Serhii Snitsaruk 0e4c06f3b8
Update class docs 2024-09-15 15:47:22 +02:00
Serhii Snitsaruk ac2d734122
Use different prefetch root for the base plan in BTPlayer and BTState 2024-09-15 15:47:11 +02:00
Serhii Snitsaruk 1ca1154cd0
Merge pull request #214 from limbonaut/fix-warnings
Fix loop variables used as copy
2024-09-15 14:36:36 +02:00
Serhii Snitsaruk a8a0f24492
BlackboardPlan: Allow passing different prefetch root for the base plan 2024-09-15 14:16:54 +02:00
Serhii Snitsaruk 50e9e570dd
Fix loop variables used as copy 2024-09-15 13:32:58 +02:00
Serhii Snitsaruk d72c2e0648
Merge pull request #213 from limbonaut/fix-setagentprop-name
Fix `BTSetAgentProperty` name generation
2024-09-14 20:23:58 +02:00
Serhii Snitsaruk da2bc5e3bb
Fix `BTSetAgentProperty` name generation 2024-09-14 19:56:31 +02:00
Serhii Snitsaruk c4481d8bed
Merge pull request #212 from limbonaut/fix-bbnode-getvalue-crash
Fix `BBNode::get_value()` crash with a freed object using GDExtension
2024-09-14 19:49:29 +02:00
Serhii Snitsaruk 689c8fab6f
Fix `BBNode::get_value()` crash with a freed object in GDExtension
It may be a bug in GDExtension. I optimized the code, and, as a workaround, removed casting to Object* from Variant. This fixed the issue. The same code worked well using module.
2024-09-14 19:30:28 +02:00
Serhii Snitsaruk fd0eb34b4e
Merge pull request #211 from limbonaut/fix-bt-for-each
Fix `BTForEach` crash if elements are removed from the array during iteration
2024-09-14 17:00:10 +02:00
Serhii Snitsaruk bfcc2f8e1b
Merge pull request #210 from ydeltastar/multi-select
Implement task multiple selection and drag and drop
2024-09-14 16:54:07 +02:00
Serhii Snitsaruk b8c9db0d44
Fix BTForEach crash if elements are removed from the array during iteration 2024-09-14 16:42:30 +02:00
yds 4df6647a75 Improve multiple drag and drop 2024-09-14 11:22:52 -03:00
Serhii Snitsaruk d78adabf7c
Bump version to 1.3-dev 2024-09-13 14:13:00 +02:00
yds 1742018696 Preserve selection after drop 2024-09-13 09:04:18 -03:00
yds a460c7898b Add drag preview 2024-09-13 09:04:18 -03:00
yds 8ee3688da2 Implement task multiple selection and drag and drop 2024-09-13 09:04:18 -03:00
Serhii Snitsaruk 9032ca0c7b
GHA: Add an option to create GDExtension debug builds 2024-09-09 13:53:42 +02:00
421 changed files with 3581 additions and 1505 deletions

View File

@ -8,6 +8,9 @@ inputs:
- linuxbsd
- windows
- macos
bin:
required: true
type: string
runs:
using: "composite"
@ -22,7 +25,7 @@ runs:
- name: Generate C# glue
shell: bash
run: |
./bin/${BIN} --headless --generate-mono-glue ./modules/mono/glue || true
./bin/${{inputs.bin}} --headless --generate-mono-glue ./modules/mono/glue || true
- name: Build .NET assemblies
shell: bash

View File

@ -5,7 +5,7 @@ on:
godot-ref:
description: A tag, branch or commit hash in the Godot repository.
type: string
default: 4.3-stable
default: master
limboai-ref:
description: A tag, branch or commit hash in the LimboAI repository.
type: string
@ -13,7 +13,7 @@ on:
godot-cpp-ref:
description: A tag, branch or commit hash in the godot-cpp repository.
type: string
default: godot-4.3-stable
default: master
jobs:
cache-sha:

View File

@ -165,15 +165,16 @@ jobs:
python --version
scons --version
- name: Set up scons cache
uses: actions/cache@v4
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
restore-keys: |
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
${{env.BIN}}-${{inputs.godot-ref}}
# ! Note: we stopped using the scons cache in release builds.
# - name: Set up scons cache
# uses: actions/cache@v4
# with:
# path: ${{github.workspace}}/.scons_cache/
# key: ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
# restore-keys: |
# ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
# ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
# ${{env.BIN}}-${{inputs.godot-ref}}
- name: Compilation
env:

View File

@ -11,7 +11,11 @@ on:
type: string
default: master
test-build:
description: Should we perform only a limited number of test builds?
description: Limit to pre-defined test builds
type: boolean
default: false
debug-symbols:
description: Build with debug symbols
type: boolean
default: false
@ -26,17 +30,22 @@ on:
type: string
default: master
test-build:
description: Should we perform only a limited number of test builds?
description: Limit to pre-defined test builds
type: boolean
default: false
debug-symbols:
description: Build with debug symbols
type: boolean
default: false
# Global Settings
env:
SCONS_CACHE_LIMIT: 4096
SCONSFLAGS: dev_build=no debug_symbols=no
SCONSFLAGS: use_mingw=yes dev_build=no
EM_VERSION: 3.1.45
EM_CACHE_FOLDER: "emsdk-cache"
GODOT_VERSION: 4.3-stable
GODOT_VERSION: 4.4-beta3
GODOT_REPO: godotengine/godot-builds
jobs:
gdextension:
@ -100,7 +109,7 @@ jobs:
- name: 🌐 Web (wasm32, debug)
runner: ubuntu-20.04
platform: web
target: template_debug
target: editor
arch: wasm32
should-build: ${{ !inputs.test-build }}
@ -114,7 +123,7 @@ jobs:
- name: 🤖 Android (arm64, debug)
runner: ubuntu-20.04
platform: android
target: template_debug
target: editor
arch: arm64
should-build: ${{ !inputs.test-build }}
@ -128,7 +137,7 @@ jobs:
- name: 🤖 Android (arm32, debug)
runner: ubuntu-20.04
platform: android
target: template_debug
target: editor
arch: arm32
should-build: ${{ !inputs.test-build }}
@ -142,7 +151,7 @@ jobs:
- name: 🤖 Android (x86_64, debug)
runner: ubuntu-20.04
platform: android
target: template_debug
target: editor
arch: x86_64
should-build: ${{ !inputs.test-build }}
@ -156,10 +165,40 @@ jobs:
- name: 🤖 Android (x86_32, debug)
runner: ubuntu-20.04
platform: android
target: template_debug
target: editor
arch: x86_32
should-build: ${{ !inputs.test-build }}
- name: 🍏 iOS (arm64, release)
runner: macos-latest
platform: ios
target: template_release
arch: arm64
should-build: ${{ !inputs.test-build }}
- name: 🍏 iOS (arm64, debug)
runner: macos-latest
platform: ios
target: editor
arch: arm64
should-build: ${{ !inputs.test-build }}
- name: 🍏 iOS (simulator, release)
runner: macos-latest
platform: ios
target: template_release
arch: universal
scons-flags: ios_simulator=yes
should-build: ${{ !inputs.test-build }}
- name: 🍏 iOS (simulator, debug)
runner: macos-latest
platform: ios
target: editor
arch: universal
scons-flags: ios_simulator=yes
should-build: ${{ !inputs.test-build }}
exclude:
- { opts: { should-build: false } }
@ -247,26 +286,29 @@ jobs:
uses: ammaraskar/msvc-problem-matcher@master
- name: Set up scons cache
if: inputs.test-build # ! Only cache test/PR builds
uses: actions/cache@v4
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
key: ${{env.BIN}}-${{inputs.debug-symbols}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
restore-keys: |
${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}
${{env.BIN}}-${{inputs.godot-cpp-ref}}
${{env.BIN}}-${{inputs.debug-symbols}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
${{env.BIN}}-${{inputs.debug-symbols}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}
${{env.BIN}}-${{inputs.debug-symbols}}-${{inputs.godot-cpp-ref}}
- name: Compilation
shell: bash
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
DEBUG_FLAGS: ${{ inputs.debug-symbols && 'debug_symbols=yes symbols_visibility=visible' || 'debug_symbols=no' }}
run: |
PATH=${GITHUB_WORKSPACE}/buildroot/bin:$PATH
scons platform=${{matrix.opts.platform}} target=${{matrix.opts.target}} arch=${{matrix.opts.arch}} ${{env.SCONSFLAGS}}
scons platform=${{matrix.opts.platform}} target=${{matrix.opts.target}} arch=${{matrix.opts.arch}} ${{env.DEBUG_FLAGS}} ${{matrix.opts.scons-flags}} ${{env.SCONSFLAGS}}
- name: Prepare artifact
shell: bash
run: |
ls -R demo/addons/limboai/
mkdir out
mv demo/addons/ out/
cp {README,LICENSE,LOGO_LICENSE}.md out/addons/limboai/
@ -310,7 +352,7 @@ jobs:
echo "Downloading Godot ${GODOT_VERSION}"
mkdir bin
cd bin
wget "https://github.com/godotengine/godot/releases/download/${GODOT_VERSION}/Godot_v${GODOT_VERSION}_linux.x86_64.zip" -O godot.zip
wget "https://github.com/${GODOT_REPO}/releases/download/${GODOT_VERSION}/Godot_v${GODOT_VERSION}_linux.x86_64.zip" -O godot.zip
unzip godot.zip
rm godot.zip
mv Godot_* godot

View File

@ -136,17 +136,25 @@ jobs:
- name: Set up Vulkan SDK
run: |
sh misc/scripts/install_vulkan_sdk_macos.sh
# ! Note: Vulkan SDK changed packaging, so we need to inline these steps for the time being.
#sh misc/scripts/install_vulkan_sdk_macos.sh
- name: Set up scons cache
uses: actions/cache@v4
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
restore-keys: |
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
${{env.BIN}}-${{inputs.godot-ref}}
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.zip" -o /tmp/vulkan-sdk.zip
unzip /tmp/vulkan-sdk.zip -d /tmp
/tmp/InstallVulkan.app/Contents/MacOS/InstallVulkan --accept-licenses --default-answer --confirm-command install
rm -Rf /tmp/InstallVulkan.app
rm -f /tmp/vulkan-sdk.zip
# ! Note: we stopped using the scons cache in release builds.
# - name: Set up scons cache
# uses: actions/cache@v4
# with:
# path: ${{github.workspace}}/.scons_cache/
# key: ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
# restore-keys: |
# ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
# ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
# ${{env.BIN}}-${{inputs.godot-ref}}
- name: Compilation
env:
@ -192,7 +200,14 @@ jobs:
- name: Set up Vulkan SDK
run: |
sh misc/scripts/install_vulkan_sdk_macos.sh
# ! Note: Vulkan SDK changed packaging, so we need to inline these steps for the time being.
#sh misc/scripts/install_vulkan_sdk_macos.sh
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.zip" -o /tmp/vulkan-sdk.zip
unzip /tmp/vulkan-sdk.zip -d /tmp
/tmp/InstallVulkan.app/Contents/MacOS/InstallVulkan --accept-licenses --default-answer --confirm-command install
rm -Rf /tmp/InstallVulkan.app
rm -f /tmp/vulkan-sdk.zip
- name: Download templates artifact
uses: actions/download-artifact@v4

View File

@ -11,7 +11,7 @@ on:
type: string
default: master
test-build:
description: Should we perform only a limited number of test builds?
description: Limit to pre-defined test builds
type: boolean
default: false
@ -26,7 +26,7 @@ on:
type: string
default: master
test-build:
description: Should we perform only a limited number of test builds?
description: Limit to pre-defined test builds
type: boolean
default: false
@ -227,6 +227,7 @@ jobs:
sudo apt-get install libwayland-dev
- name: Set up scons cache
if: inputs.test-build # ! Only cache test/PR builds
uses: actions/cache@v4
with:
path: ${{github.workspace}}/.scons_cache/
@ -248,6 +249,7 @@ jobs:
uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
with:
platform: linuxbsd
bin: ${{env.BIN}}
- name: Prepare artifact
env:

View File

@ -11,7 +11,7 @@ on:
type: string
default: master
test-build:
description: Should we perform only a limited number of test builds?
description: Limit to pre-defined test builds
type: boolean
default: false
@ -26,7 +26,7 @@ on:
type: string
default: master
test-build:
description: Should we perform only a limited number of test builds?
description: Limit to pre-defined test builds
type: boolean
default: false
@ -165,9 +165,19 @@ jobs:
- name: Set up Vulkan SDK
run: |
sh misc/scripts/install_vulkan_sdk_macos.sh
# ! Note: Vulkan SDK changed packaging, so we need to inline these steps for the time being.
#sh misc/scripts/install_vulkan_sdk_macos.sh
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/config.json" -o /tmp/vulkan-sdk.json
sdk_version=`jq -r '.version' /tmp/vulkan-sdk.json`
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.zip" -o /tmp/vulkan-sdk.zip
unzip /tmp/vulkan-sdk.zip -d /tmp
/tmp/InstallVulkan-${sdk_version}.app/Contents/MacOS/InstallVulkan-${sdk_version} --accept-licenses --default-answer --confirm-command install
rm -Rf /tmp/InstallVulkan-${sdk_version}.app
rm -f /tmp/vulkan-sdk.zip
- name: Set up scons cache
if: inputs.test-build # ! Only cache test/PR builds
uses: actions/cache@v4
with:
path: ${{github.workspace}}/.scons_cache/
@ -188,6 +198,7 @@ jobs:
uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
with:
platform: macos
bin: ${{env.BIN}}
- name: Prepare artifact
run: |

View File

@ -26,8 +26,8 @@ concurrency:
# Global Settings.
env:
GODOT_REF: "4.3-stable"
GODOT_CPP_REF: "godot-4.3-stable"
GODOT_REF: "master"
GODOT_CPP_REF: "master"
jobs:
unit-tests:
@ -36,7 +36,7 @@ jobs:
# Settings
env:
SCONSFLAGS: platform=linuxbsd target=editor arch=x86_64 production=false dev_build=true tests=true verbose=yes warnings=extra werror=yes
SCONSFLAGS: platform=linuxbsd target=editor arch=x86_64 production=false dev_build=true tests=true verbose=yes warnings=extra werror=yes strict_checks=yes
SCONS_CACHE_LIMIT: 7168
BIN: godot.linuxbsd.editor.dev.x86_64
@ -101,6 +101,18 @@ jobs:
run: |
bin/${{ env.BIN }} --test --headless
static-checks:
name: ⚙️ Static checks
runs-on: ubuntu-20.04
steps:
- name: Clone LimboAI module
uses: actions/checkout@v4
- name: Code style checks
uses: pre-commit/action@v3.0.1
with:
extra_args: --all-files
cache-env:
runs-on: ubuntu-latest
outputs:

View File

@ -120,15 +120,16 @@ jobs:
python --version
scons --version
- name: Set up scons cache
uses: actions/cache@v4
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
restore-keys: |
${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
${{env.CACHE_NAME}}-${{inputs.godot-ref}}
# ! Note: we stopped using the scons cache in release builds.
# - name: Set up scons cache
# uses: actions/cache@v4
# with:
# path: ${{github.workspace}}/.scons_cache/
# key: ${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
# restore-keys: |
# ${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
# ${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
# ${{env.CACHE_NAME}}-${{inputs.godot-ref}}
- name: Compilation
env:

View File

@ -11,7 +11,7 @@ on:
type: string
default: master
test-build:
description: Should we perform only a limited number of test builds?
description: Limit to pre-defined test builds
type: boolean
default: false
@ -26,22 +26,23 @@ on:
type: string
default: master
test-build:
description: Should we perform only a limited number of test builds?
description: Limit to pre-defined test builds
type: boolean
default: false
# Global Settings
env:
SCONS_CACHE_MSVC_CONFIG: true
BUILD_IMAGE_VERSION: 4.3-f40
MESA_VERSION: 23.1.9-1
SCONS_CACHE_LIMIT: 4096
SCONSFLAGS: production=yes tests=no verbose=yes warnings=extra werror=yes
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
SCONSFLAGS: production=yes use_mingw=yes verbose=yes warnings=no progress=no d3d12=yes
jobs:
windows-builds:
runs-on: "windows-latest"
runs-on: "ubuntu-24.04"
name: ${{ matrix.opts.name }}
outputs:
built-dotnet-editor: ${{ steps.mark-dotnet-editor.outputs.built-dotnet-editor }}
strategy:
fail-fast: false
matrix:
@ -51,18 +52,21 @@ jobs:
- name: Editor (x86_64, release)
target: editor
arch: x86_64
llvm: false
dotnet: false
should-build: true
- name: Template (x86_64, release)
target: template_release
arch: x86_64
llvm: false
dotnet: false
should-build: ${{ !inputs.test-build }}
- name: Template (x86_64, debug)
target: template_debug
arch: x86_64
llvm: false
dotnet: false
should-build: ${{ !inputs.test-build }}
@ -71,18 +75,21 @@ jobs:
# - name: Editor (x86_32, release)
# target: editor
# arch: x86_32
# llvm: false
# dotnet: false
# should-build: ${{ !inputs.test-build }}
- name: Template (x86_32, release)
target: template_release
arch: x86_32
llvm: false
dotnet: false
should-build: ${{ !inputs.test-build }}
- name: Template (x86_32, debug)
target: template_debug
arch: x86_32
llvm: false
dotnet: false
should-build: ${{ !inputs.test-build }}
@ -91,19 +98,24 @@ jobs:
# - name: Editor (arm64, release)
# target: editor
# arch: arm64
# llvm: true
# dotnet: false
# should-build: ${{ !inputs.test-build }}
- name: Template (arm64, release)
target: template_release
arch: arm64
llvm: true
dotnet: false
scons-flags: mingw_prefix=/root/llvm-mingw
should-build: ${{ !inputs.test-build }}
- name: Template (arm64, debug)
target: template_debug
arch: arm64
llvm: true
dotnet: false
scons-flags: mingw_prefix=/root/llvm-mingw
should-build: ${{ !inputs.test-build }}
# * .NET x86_64
@ -111,18 +123,21 @@ jobs:
- name: Editor .NET (x86_64, release)
target: editor
arch: x86_64
llvm: false
dotnet: true
should-build: ${{ !inputs.test-build }}
- name: Template .NET (x86_64, release)
target: template_release
arch: x86_64
llvm: false
dotnet: true
should-build: ${{ !inputs.test-build }}
- name: Template .NET (x86_64, debug)
target: template_debug
arch: x86_64
llvm: false
dotnet: true
should-build: ${{ !inputs.test-build }}
@ -131,46 +146,54 @@ jobs:
# - name: Editor .NET (x86_32, release)
# target: editor
# arch: x86_32
# llvm: false
# dotnet: true
# should-build: ${{ !inputs.test-build }}
- name: Template .NET (x86_32, release)
target: template_release
arch: x86_32
llvm: false
dotnet: true
should-build: ${{ !inputs.test-build }}
- name: Template .NET (x86_32, debug)
target: template_debug
arch: x86_32
llvm: false
dotnet: true
should-build: ${{ !inputs.test-build }}
# * .NET arm64
# - name: Editor (arm64, release)
# - name: Editor .NET (arm64, release)
# target: editor
# arch: arm64
# llvm: true
# dotnet: true
# should-build: ${{ !inputs.test-build }}
- name: Template (arm64, release)
- name: Template .NET (arm64, release)
target: template_release
arch: arm64
llvm: true
dotnet: true
scons-flags: mingw_prefix=/root/llvm-mingw
should-build: ${{ !inputs.test-build }}
- name: Template (arm64, debug)
- name: Template .NET (arm64, debug)
target: template_debug
arch: arm64
llvm: true
dotnet: true
scons-flags: mingw_prefix=/root/llvm-mingw
should-build: ${{ !inputs.test-build }}
exclude:
- { opts: { should-build: false } }
env:
BIN: godot.windows.${{matrix.opts.target}}.${{matrix.opts.arch}}${{ matrix.opts.dotnet == true && '.mono' || '' }}
BIN: godot.windows.${{matrix.opts.target}}.${{matrix.opts.arch}}${{matrix.opts.llvm && '.llvm' || ''}}${{matrix.opts.dotnet == true && '.mono' || ''}}
steps:
- name: Clone Godot
@ -185,26 +208,11 @@ jobs:
path: modules/limboai
ref: ${{ inputs.limboai-ref }}
# Inits GODOT_VERSION, LIMBOAI_VERSION and NAME_PREFIX environment variables.
# Inits GODOT_VERSION, LIMBOAI_VERSION, NAME_PREFIX, GODOT_VERSION_STATUS, BUILD_NAME environment variables.
- uses: ./modules/limboai/.github/actions/init-version
- name: Set up Python 3.x
uses: actions/setup-python@v5
with:
python-version: "3.x"
architecture: "x64"
- name: Set up scons
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons==4.4.0
python --version
scons --version
- name: Set up MSVC problem matcher
uses: ammaraskar/msvc-problem-matcher@master
- name: Set up scons cache
if: inputs.test-build # ! Only cache test/PR builds
uses: actions/cache@v4
with:
path: ${{github.workspace}}/.scons_cache/
@ -214,17 +222,54 @@ jobs:
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
${{env.BIN}}-${{inputs.godot-ref}}
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
- name: Static ANGLE libs
run: |
scons -j2 platform=windows target=${{matrix.opts.target}} arch=${{matrix.opts.arch}} module_mono_enabled=${{matrix.opts.dotnet}} ${{env.SCONSFLAGS}}
mkdir -p deps/angle
cd deps/angle
url=https://github.com/godotengine/godot-angle-static/releases/download/chromium%2F6601.2/godot-angle-static
curl -L -o windows_${{matrix.opts.arch}}.zip $url-${{matrix.opts.arch}}-${{matrix.opts.llvm && 'llvm' || 'gcc'}}-release.zip
unzip windows_${{matrix.opts.arch}}.zip
rm windows_${{matrix.opts.arch}}.zip
- name: Build .NET assemblies
if: matrix.opts.dotnet && matrix.opts.target == 'editor'
uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
with:
platform: windows
- name: Mesa libs
run: |
mkdir -p deps/mesa
cd deps/mesa
curl -L -o mesa_${{matrix.opts.arch}}.zip https://github.com/godotengine/godot-nir-static/releases/download/${{env.MESA_VERSION}}/godot-nir-static-${{matrix.opts.arch}}-${{matrix.opts.llvm && 'llvm' || 'gcc'}}-release.zip
unzip -o mesa_${{matrix.opts.arch}}.zip
rm -f mesa_${{matrix.opts.arch}}.zip
- name: Pull build container
run: |
podman pull ghcr.io/limbonaut/godot-windows:${{env.BUILD_IMAGE_VERSION}}
- name: Build using container
shell: bash
run: |
scons_command="scons \
platform=windows \
target=${{matrix.opts.target}} \
arch=${{matrix.opts.arch}} \
use_llvm=${{matrix.opts.llvm}} \
module_mono_enabled=${{matrix.opts.dotnet}} \
${{env.SCONSFLAGS}} \
${{matrix.opts.scons-flags}} \
angle_libs=/build/deps/angle \
mesa_libs=/build/deps/mesa \
"
podman_run="podman run -it --rm \
--env GODOT_VERSION_STATUS=${GODOT_VERSION_STATUS} \
--env BUILD_NAME=${BUILD_NAME} \
--env NUM_CORES=$(nproc --all) \
--env DOTNET_NOLOGO=true \
--env DOTNET_CLI_TELEMETRY_OPTOUT=true \
--env SCONS_CACHE=/build/.scons_cache/ \
--env SCONS_CACHE_LIMIT=${SCONS_CACHE_LIMIT} \
-v ${GITHUB_WORKSPACE}/:/build/ \
-w /build godot-windows:${{env.BUILD_IMAGE_VERSION}} bash -c \
"
echo "Running ${podman_run} \"${scons_command}\""
${podman_run} "${scons_command}"
- name: Prepare artifact
shell: bash
@ -252,3 +297,62 @@ jobs:
with:
name: ${{env.NAME_PREFIX}}${{matrix.opts.dotnet == true && '.dotnet' || ''}}.${{matrix.opts.target}}.windows.${{matrix.opts.arch}}
path: out/*
- name: Mark .NET editor as built
if: matrix.opts.dotnet && matrix.opts.target == 'editor'
id: mark-dotnet-editor
run: echo "built-dotnet-editor=true" >> $GITHUB_OUTPUT
dotnet-assemblies:
name: .NET assembly for ${{matrix.opts.arch}}
needs: windows-builds
if: always() && needs.windows-builds.outputs.built-dotnet-editor == 'true'
runs-on: "windows-latest"
strategy:
fail-fast: false
matrix:
opts:
- arch: x86_64
llvm: false
env:
BIN: godot.windows.editor.${{matrix.opts.arch}}${{matrix.opts.llvm && '.llvm' || ''}}.mono
steps:
- name: Clone Godot
uses: actions/checkout@v4
with:
repository: godotengine/godot
ref: ${{ inputs.godot-ref }}
- name: Clone LimboAI module
uses: actions/checkout@v4
with:
path: modules/limboai
ref: ${{ inputs.limboai-ref }}
# Inits GODOT_VERSION, LIMBOAI_VERSION and NAME_PREFIX environment variables.
- uses: ./modules/limboai/.github/actions/init-version
- name: Reconstruct artifact name
shell: bash
run: |
echo "ARTIFACT=${{env.NAME_PREFIX}}.dotnet.editor.windows.${{matrix.opts.arch}}" >> $GITHUB_ENV
- name: Download editor artifact
uses: actions/download-artifact@v4
with:
name: ${{env.ARTIFACT}}
path: bin/
- name: Build .NET assemblies
uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
with:
platform: windows
bin: ${{env.BIN}}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{env.ARTIFACT}}
overwrite: true
path: bin/*

View File

@ -1,4 +1,4 @@
Copyright 2021-2024 Serhii Snitsaruk
Copyright (c) 2023-2025 Serhii Snitsaruk and the LimboAI contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -16,7 +16,7 @@
**LimboAI** is an open-source C++ plugin for **Godot Engine 4** providing a combination of
**Behavior Trees** and **State Machines**, which can be used together to create complex AI behaviors.
It comes with a behavior tree editor, built-in documentation, visual debugger, extensive demo project with a tutorial, and more!
While it is implemented in C++, it fully supports GDScript for [creating your own tasks](https://limboai.readthedocs.io/en/stable/getting-started/custom-tasks.html) and [states](https://limboai.readthedocs.io/en/stable/getting-started/hsm.html).
While it is implemented in C++, it fully supports GDScript for [creating your own tasks](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html) and [states](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html).
If you enjoy using LimboAI, please **consider supporting** my efforts with a donation on Ko-fi 😊 Your contribution will help me continue developing and improving it.
@ -24,7 +24,7 @@ If you enjoy using LimboAI, please **consider supporting** my efforts with a don
![Textured screenshot](doc/images/behavior-tree-editor-debugger.png)
Behavior Trees are powerful hierarchical structures used to model and control the behavior of agents in a game (e.g., characters, enemies). They are designed to make it easier to create rich and highly modular behaviors for your games. To learn more about behavior trees, check out [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/getting-started/introduction.html) and our demo project, which includes a tutorial.
Behavior Trees are powerful hierarchical structures used to model and control the behavior of agents in a game (e.g., characters, enemies). They are designed to make it easier to create rich and highly modular behaviors for your games. To learn more about behavior trees, check out [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/behavior-trees/introduction.html) and our demo project, which includes a tutorial.
## Demonstration
@ -50,13 +50,13 @@ Behavior Trees are powerful hierarchical structures used to model and control th
- Execute `BehaviorTree` resources using the `BTPlayer` node.
- Create complex behaviors by combining and nesting tasks in a hierarchy.
- Control execution flow using composite, decorator, and condition tasks.
- [Create custom tasks](https://limboai.readthedocs.io/en/stable/getting-started/custom-tasks.html) by extending core classes: `BTAction`, `BTCondition`, `BTDecorator`, and `BTComposite`.
- [Create custom tasks](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html) by extending core classes: `BTAction`, `BTCondition`, `BTDecorator`, and `BTComposite`.
- Built-in class documentation.
- Blackboard system: Share data seamlessly between tasks using the `Blackboard`.
- Blackboard plans: Define variables in the BehaviorTree resource and override their values in the BTPlayer node.
- Plan editor: Manage variables, their data types and property hints.
- Blackboard scopes: Prevent name conflicts and enable advanced techniques like [sharing data between several agents](https://limboai.readthedocs.io/en/stable/getting-started/using-blackboard.html#sharing-data-between-several-agents).
- Blackboard parameters: [Export a BB parameter](https://limboai.readthedocs.io/en/stable/getting-started/using-blackboard.html#task-parameters), for which user can provide a value or bind it to a blackboard variable (can be used in custom tasks).
- Blackboard scopes: Prevent name conflicts and enable advanced techniques like [sharing data between several agents](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html#sharing-data-between-several-agents).
- Blackboard parameters: [Export a BB parameter](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html#task-parameters), for which user can provide a value or bind it to a blackboard variable (can be used in custom tasks).
- Inspector support for specifying blackboard variables (custom editor for exported `StringName` properties ending with "_var").
- Use the `BTSubtree` task to execute a tree from a different resource file, promoting organization and reusability.
- Visual Debugger: Inspect the execution of any BT in a running scene to identify and troubleshoot issues.
@ -67,24 +67,24 @@ Behavior Trees are powerful hierarchical structures used to model and control th
- Extend the `LimboState` class to implement state logic.
- `LimboHSM` node serves as a state machine that manages `LimboState` instances and transitions.
- `LimboHSM` is a state itself and can be nested within other `LimboHSM` instances.
- [Event-based](https://limboai.readthedocs.io/en/stable/getting-started/hsm.html#events-and-transitions): Transitions are associated with events and are triggered by the state machine when the relevant event is dispatched, allowing for better decoupling of transitions from state logic.
- [Event-based](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html#events-and-transitions): Transitions are associated with events and are triggered by the state machine when the relevant event is dispatched, allowing for better decoupling of transitions from state logic.
- Combine state machines with behavior trees using `BTState` for advanced reactive AI.
- Delegation Option: Using the vanilla `LimboState`, [delegate the implementation](https://limboai.readthedocs.io/en/stable/getting-started/hsm.html#single-file-state-machine-setup) to your callback functions, making it perfect for rapid prototyping and game jams.
- Delegation Option: Using the vanilla `LimboState`, [delegate the implementation](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html#single-file-state-machine-setup) to your callback functions, making it perfect for rapid prototyping and game jams.
- 🛈 Note: State machine setup and initialization require code; there is no GUI editor.
- **Tested:** Behavior tree tasks and HSM are covered by unit tests.
- **GDExtension:** LimboAI can be [used as extension](https://limboai.readthedocs.io/en/stable/getting-started/gdextension.html). Custom engine builds are not necessary.
- **GDExtension:** LimboAI can be [used as extension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version). Custom engine builds are not necessary.
- **Demo + Tutorial:** Check out our extensive demo project, which includes an introduction to behavior trees using examples.
## First steps
Follow the [First steps](https://limboai.readthedocs.io/en/stable/index.html#first-steps) guide to learn how to get started with LimboAI and the demo project.
Follow the [Getting started](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html) guide to learn how to get started with LimboAI and the demo project.
## Getting LimboAI
LimboAI can be used as either a C++ module or as a GDExtension shared library. GDExtension version is more convenient to use but somewhat limited in features. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time. See [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/gdextension.html).
LimboAI can be used as either a C++ module or as a GDExtension shared library. GDExtension version is more convenient to use but somewhat limited in features. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time. See [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version).
### Precompiled builds
@ -109,19 +109,20 @@ LimboAI can be used as either a C++ module or as a GDExtension shared library. G
## Using the plugin
- Online Documentation: [stable](https://limboai.readthedocs.io/en/stable/index.html), [latest](https://limboai.readthedocs.io/en/latest/index.html)
- [First steps](https://limboai.readthedocs.io/en/stable/index.html#first-steps)
- [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/getting-started/introduction.html)
- [Creating custom tasks in GDScript](https://limboai.readthedocs.io/en/stable/getting-started/custom-tasks.html)
- [Sharing data using Blackboard](https://limboai.readthedocs.io/en/stable/getting-started/using-blackboard.html)
- [Accessing nodes in the scene tree](https://limboai.readthedocs.io/en/stable/getting-started/accessing-nodes.html)
- [State machines](https://limboai.readthedocs.io/en/stable/getting-started/hsm.html)
- [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/gdextension.html)
- [Getting started](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html)
- [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/behavior-trees/introduction.html)
- [Creating custom tasks in GDScript](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html)
- [Sharing data using Blackboard](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html)
- [Accessing nodes in the scene tree](https://limboai.readthedocs.io/en/stable/behavior-trees/accessing-nodes.html)
- [State machines](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html)
- [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version)
- [Using LimboAI with C#](https://limboai.readthedocs.io/en/stable/getting-started/c-sharp.html)
- [Class reference](https://limboai.readthedocs.io/en/stable/getting-started/featured-classes.html)
- [Class reference](https://limboai.readthedocs.io/en/stable/classes/featured-classes.html)
## Contributing
Contributions are welcome! Please open issues for bug reports, feature requests, or code changes. Keep the minor versions backward-compatible when submitting pull requests.
Contributions are welcome! Please open issues for bug reports, feature requests, or code changes.
For detailed guidelines on contributing to code or documentation, check out our [Contributing](https://limboai.readthedocs.io/en/latest/getting-started/contributing.html) page.
If you have an idea for a behavior tree task or a feature that could be useful in a variety of projects, open an issue to discuss it.

View File

@ -1,7 +1,7 @@
/**
* bb_aabb.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_basis.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_bool.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_byte_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_color.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_color_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_dictionary.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_float.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_float32_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_float64_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_int.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_int32_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_int64_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_node.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -11,18 +11,9 @@
#include "bb_node.h"
#ifdef LIMBOAI_MODULE
#include "core/error/error_macros.h"
#include "scene/main/node.h"
#endif // LIMBOAI_MODULE
#ifdef LIMBOAI_GDEXTENSION
#include <godot_cpp/classes/node.hpp>
#endif // LIMBOAI_GDEXTENSION
Variant BBNode::get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default) {
ERR_FAIL_NULL_V_MSG(p_scene_root, Variant(), "BBNode: get_value() failed - scene_root is null.");
ERR_FAIL_NULL_V_MSG(p_blackboard, Variant(), "BBNode: get_value() failed - blackboard is null.");
ERR_FAIL_COND_V_MSG(p_blackboard.is_null(), Variant(), "BBNode: get_value() failed - blackboard is null.");
Variant val;
if (get_value_source() == SAVED_VALUE) {
@ -33,13 +24,10 @@ Variant BBNode::get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboar
if (val.get_type() == Variant::NODE_PATH) {
return p_scene_root->get_node_or_null(val);
} else if (val.get_type() == Variant::OBJECT || val.get_type() == Variant::NIL) {
return val;
} else {
Object *obj = val;
if (unlikely(obj == nullptr && val.get_type() != Variant::NIL)) {
WARN_PRINT("BBNode: Unexpected variant type of a blackboard variable.");
return p_default;
} else {
return obj;
}
WARN_PRINT("BBNode: Unexpected variant type: " + Variant::get_type_name(val.get_type()) + ". Returning default value.");
return p_default;
}
}

View File

@ -1,7 +1,7 @@
/**
* bb_node.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_param.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_param.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_plane.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_projection.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_quaternion.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_rect2.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_rect2i.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_string.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_string_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_string_name.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_transform2d.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_transform3d.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_variant.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_variant.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_vector2.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_vector2_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_vector2i.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_vector3.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_vector3_array.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_vector3i.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_vector4.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_vector4i.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_variable.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bb_variable.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* blackboard.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -10,6 +10,7 @@
*/
#include "blackboard.h"
#include "../util/limbo_compat.h"
#ifdef LIMBOAI_MODULE
#include "core/variant/variant.h"
@ -75,6 +76,26 @@ TypedArray<StringName> Blackboard::list_vars() const {
return var_names;
}
void Blackboard::print_state() const {
Ref<Blackboard> bb{ this };
int scope_idx = 0;
while (bb.is_valid()) {
int i = 0;
String line = "Scope " + itos(scope_idx) + ": { ";
for (const KeyValue<StringName, BBVariable> &kv : bb->data) {
if (i > 0) {
line += ", ";
}
line += String(kv.key) + ": " + String(kv.value.get_value());
i++;
}
line += " }";
PRINT_LINE(line);
bb = bb->get_parent();
scope_idx++;
}
}
Dictionary Blackboard::get_vars_as_dict() const {
Dictionary dict;
for (const KeyValue<StringName, BBVariable> &kv : data) {
@ -136,6 +157,7 @@ void Blackboard::_bind_methods() {
ClassDB::bind_method(D_METHOD("erase_var", "var_name"), &Blackboard::erase_var);
ClassDB::bind_method(D_METHOD("clear"), &Blackboard::clear);
ClassDB::bind_method(D_METHOD("list_vars"), &Blackboard::list_vars);
ClassDB::bind_method(D_METHOD("print_state"), &Blackboard::print_state);
ClassDB::bind_method(D_METHOD("get_vars_as_dict"), &Blackboard::get_vars_as_dict);
ClassDB::bind_method(D_METHOD("populate_from_dict", "dictionary"), &Blackboard::populate_from_dict);
ClassDB::bind_method(D_METHOD("top"), &Blackboard::top);

View File

@ -1,7 +1,7 @@
/**
* blackboard.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -57,6 +57,7 @@ public:
void erase_var(const StringName &p_name);
void clear() { data.clear(); }
TypedArray<StringName> list_vars() const;
void print_state() const;
Dictionary get_vars_as_dict() const;
void populate_from_dict(const Dictionary &p_dictionary);

View File

@ -1,7 +1,7 @@
/**
* blackboard_plan.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -13,9 +13,20 @@
#include "../util/limbo_utility.h"
#ifdef LIMBOAI_MODULE
#include "editor/editor_inspector.h"
#include "editor/editor_interface.h"
#elif LIMBOAI_GDEXTENSION
#include <godot_cpp/classes/editor_inspector.hpp>
#include <godot_cpp/classes/editor_interface.hpp>
#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/scene_tree.hpp>
#endif
bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
String name_str = p_name;
#ifdef TOOLS_ENABLED
// * Editor
if (var_map.has(p_name)) {
BBVariable &var = var_map[p_name];
@ -26,29 +37,51 @@ bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
}
return true;
}
#endif // TOOLS_ENABLED
// * Mapping
if (name_str.begins_with("mapping/")) {
StringName mapped_var_name = name_str.get_slicec('/', 1);
StringName value = p_value;
bool properties_changed = false;
bool prop_list_changed = false;
if (value == StringName()) {
if (parent_scope_mapping.has(mapped_var_name)) {
properties_changed = true;
prop_list_changed = true;
parent_scope_mapping.erase(mapped_var_name);
}
} else {
if (!parent_scope_mapping.has(mapped_var_name)) {
properties_changed = true;
prop_list_changed = true;
}
parent_scope_mapping[mapped_var_name] = value;
}
if (properties_changed) {
if (prop_list_changed) {
notify_property_list_changed();
}
return true;
}
// * Binding
if (name_str.begins_with("binding/")) {
StringName bound_var = name_str.get_slicec('/', 1);
NodePath value = p_value;
bool prop_list_changed = false;
if (value.is_empty()) {
if (property_bindings.has(bound_var)) {
prop_list_changed = true;
property_bindings.erase(bound_var);
}
} else {
if (!property_bindings.has(bound_var)) {
prop_list_changed = true;
}
property_bindings[bound_var] = value;
}
if (prop_list_changed) {
notify_property_list_changed();
}
}
// * Storage
if (name_str.begins_with("var/")) {
StringName var_name = name_str.get_slicec('/', 1);
@ -66,6 +99,8 @@ bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
var_map[var_name].set_hint((PropertyHint)(int)p_value);
} else if (what == "hint_string") {
var_map[var_name].set_hint_string(p_value);
} else if (what == "property_binding") {
property_bindings[var_name] = NodePath(p_value);
} else {
return false;
}
@ -78,28 +113,64 @@ bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
bool BlackboardPlan::_get(const StringName &p_name, Variant &r_ret) const {
String name_str = p_name;
#ifdef TOOLS_ENABLED
// * Editor
if (var_map.has(p_name)) {
if (has_mapping(p_name)) {
r_ret = "Mapped to " + LimboUtility::get_singleton()->decorate_var(parent_scope_mapping[p_name]);
} else if (has_property_binding(p_name)) {
const NodePath &binding = property_bindings[p_name];
Node *edited_node = Object::cast_to<Node>(EditorInterface::get_singleton()->get_inspector()->get_edited_object());
if (!edited_node) {
edited_node = SCENE_TREE()->get_edited_scene_root();
}
Node *bound_node = edited_node ? edited_node->get_node_or_null(binding) : nullptr;
String shortened_path;
if (bound_node) {
shortened_path = (String)bound_node->get_name() +
":" + (String)binding.get_concatenated_subnames();
} else {
shortened_path = (String)binding.get_name(binding.get_name_count() - 1) +
":" + (String)binding.get_concatenated_subnames();
}
r_ret = String::utf8("🔗 ") + shortened_path;
} else {
r_ret = var_map[p_name].get_value();
}
return true;
}
#endif // TOOLS_ENABLED
// * Mapping
if (name_str.begins_with("mapping/")) {
StringName mapped_var_name = name_str.get_slicec('/', 1);
ERR_FAIL_COND_V(mapped_var_name == StringName(), false);
if (parent_scope_mapping.has(mapped_var_name)) {
if (has_mapping(mapped_var_name)) {
r_ret = parent_scope_mapping[mapped_var_name];
} else if (has_property_binding(mapped_var_name)) {
r_ret = RTR("Already bound to property.");
} else {
r_ret = StringName();
}
return true;
}
// * Binding
if (name_str.begins_with("binding/")) {
StringName bound_var = name_str.get_slicec('/', 1);
ERR_FAIL_COND_V(bound_var == StringName(), false);
if (has_property_binding(bound_var)) {
r_ret = property_bindings[bound_var];
} else if (has_mapping(bound_var)) {
r_ret = RTR("Already mapped to variable.");
} else {
r_ret = NodePath();
}
return true;
}
// * Storage
if (!name_str.begins_with("var/")) {
return false;
@ -127,14 +198,16 @@ void BlackboardPlan::_get_property_list(List<PropertyInfo> *p_list) const {
String var_name = p.first;
BBVariable var = p.second;
#ifdef TOOLS_ENABLED
// * Editor
if (var.get_type() != Variant::NIL && (!is_derived() || !var_name.begins_with("_"))) {
if (has_mapping(var_name)) {
if (!_is_var_nil(var) && !_is_var_private(var_name, var)) {
if (has_mapping(var_name) || has_property_binding(var_name)) {
p_list->push_back(PropertyInfo(Variant::STRING, var_name, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY));
} else {
p_list->push_back(PropertyInfo(var.get_type(), var_name, var.get_hint(), var.get_hint_string(), PROPERTY_USAGE_EDITOR));
}
}
#endif // TOOLS_ENABLED
// * Storage
if (is_derived() && (!var.is_value_changed() || var.get_value() == base->var_map[var_name].get_value())) {
@ -153,9 +226,32 @@ void BlackboardPlan::_get_property_list(List<PropertyInfo> *p_list) const {
if (is_mapping_enabled()) {
p_list->push_back(PropertyInfo(Variant::NIL, "Mapping", PROPERTY_HINT_NONE, "mapping/", PROPERTY_USAGE_GROUP));
for (const Pair<StringName, BBVariable> &p : var_list) {
// Serialize only non-empty mappings.
PropertyUsageFlags usage = has_mapping(p.first) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR;
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "mapping/" + p.first, PROPERTY_HINT_NONE, "", usage));
if (_is_var_private(p.first, p.second)) {
continue;
}
if (unlikely(has_property_binding(p.first))) {
p_list->push_back(PropertyInfo(Variant::STRING, "mapping/" + p.first, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY));
} else {
// Serialize only non-empty mappings.
PropertyUsageFlags usage = has_mapping(p.first) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR;
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "mapping/" + p.first, PROPERTY_HINT_NONE, "", usage));
}
}
}
// * Binding
p_list->push_back(PropertyInfo(Variant::NIL, "Binding", PROPERTY_HINT_NONE, "binding/", PROPERTY_USAGE_GROUP));
for (const Pair<StringName, BBVariable> &p : var_list) {
if (_is_var_nil(p.second) || _is_var_private(p.first, p.second)) {
continue;
}
if (unlikely(has_mapping(p.first))) {
p_list->push_back(PropertyInfo(Variant::STRING, "binding/" + p.first, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY));
} else {
PropertyUsageFlags usage = has_property_binding(p.first) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR;
// PROPERTY_HINT_LINK is used to signal that NodePath should point to a property.
// Our inspector plugin will know how to handle it.
p_list->push_back(PropertyInfo(Variant::NODE_PATH, "binding/" + p.first, PROPERTY_HINT_LINK, itos(p.second.get_type()), usage));
}
}
}
@ -199,6 +295,11 @@ bool BlackboardPlan::has_mapping(const StringName &p_name) const {
return is_mapping_enabled() && parent_scope_mapping.has(p_name) && parent_scope_mapping[p_name] != StringName();
}
void BlackboardPlan::set_property_binding(const StringName &p_name, const NodePath &p_path) {
property_bindings[p_name] = p_path;
emit_changed();
}
void BlackboardPlan::set_prefetch_nodepath_vars(bool p_enable) {
prefetch_nodepath_vars = p_enable;
emit_changed();
@ -387,33 +488,16 @@ void BlackboardPlan::sync_with_base_plan() {
}
}
// Add a variable duplicate to the blackboard, optionally with NodePath prefetch.
inline void bb_add_var_dup_with_prefetch(const Ref<Blackboard> &p_blackboard, const StringName &p_name, const BBVariable &p_var, bool p_prefetch, Node *p_node) {
if (unlikely(p_prefetch && p_var.get_type() == Variant::NODE_PATH)) {
Node *n = p_node->get_node_or_null(p_var.get_value());
BBVariable var = p_var.duplicate(true);
if (n != nullptr) {
var.set_value(n);
} else {
ERR_PRINT(vformat("BlackboardPlan: Prefetch failed for variable $%s with value: %s", p_name, p_var.get_value()));
var.set_value(Variant());
}
p_blackboard->assign_var(p_name, var);
} else {
p_blackboard->assign_var(p_name, p_var.duplicate(true));
}
}
Ref<Blackboard> BlackboardPlan::create_blackboard(Node *p_node, const Ref<Blackboard> &p_parent_scope) {
ERR_FAIL_COND_V(p_node == nullptr && prefetch_nodepath_vars, memnew(Blackboard));
Ref<Blackboard> BlackboardPlan::create_blackboard(Node *p_prefetch_root, const Ref<Blackboard> &p_parent_scope, Node *p_prefetch_root_for_base_plan) {
ERR_FAIL_COND_V(p_prefetch_root == nullptr && prefetch_nodepath_vars, memnew(Blackboard));
Ref<Blackboard> bb = memnew(Blackboard);
bb->set_parent(p_parent_scope);
populate_blackboard(bb, true, p_node);
populate_blackboard(bb, true, p_prefetch_root, p_prefetch_root_for_base_plan);
return bb;
}
void BlackboardPlan::populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_node) {
ERR_FAIL_COND(p_node == nullptr && prefetch_nodepath_vars);
void BlackboardPlan::populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_prefetch_root, Node *p_prefetch_root_for_base_plan) {
ERR_FAIL_COND(p_prefetch_root == nullptr && prefetch_nodepath_vars);
ERR_FAIL_COND(p_blackboard.is_null());
for (const Pair<StringName, BBVariable> &p : var_list) {
if (p_blackboard->has_local_var(p.first) && !overwrite) {
@ -427,15 +511,48 @@ void BlackboardPlan::populate_blackboard(const Ref<Blackboard> &p_blackboard, bo
#endif
continue;
}
bool is_bound = has_property_binding(p.first) || (is_derived() && get_base_plan()->has_property_binding(p.first));
bool has_mapping = parent_scope_mapping.has(p.first);
bool do_prefetch = !has_mapping && prefetch_nodepath_vars;
bb_add_var_dup_with_prefetch(p_blackboard, p.first, p.second, do_prefetch, p_node);
bool do_prefetch = !is_bound && !has_mapping && prefetch_nodepath_vars;
// Add a variable duplicate to the blackboard, optionally with NodePath prefetch.
BBVariable var = p.second.duplicate(true);
if (unlikely(do_prefetch && p.second.get_type() == Variant::NODE_PATH)) {
Node *prefetch_root = !p_prefetch_root_for_base_plan || !is_derived() || is_derived_var_changed(p.first) ? p_prefetch_root : p_prefetch_root_for_base_plan;
Node *n = prefetch_root->get_node_or_null(p.second.get_value());
if (n != nullptr) {
var.set_value(n);
} else {
ERR_PRINT(vformat("BlackboardPlan: Prefetch failed for variable $%s with value: %s", p.first, p.second.get_value()));
var.set_value(Variant());
}
}
p_blackboard->assign_var(p.first, var);
if (has_mapping) {
StringName target_var = parent_scope_mapping[p.first];
if (target_var != StringName()) {
ERR_CONTINUE_MSG(p_blackboard->get_parent() == nullptr, vformat("BlackboardPlan: Cannot link variable %s to parent scope because the parent scope is not set.", LimboUtility::get_singleton()->decorate_var(p.first)));
ERR_CONTINUE_MSG(p_blackboard->get_parent().is_null(), vformat("BlackboardPlan: Cannot link variable %s to parent scope because the parent scope is not set.", LimboUtility::get_singleton()->decorate_var(p.first)));
p_blackboard->link_var(p.first, p_blackboard->get_parent(), target_var);
}
} else if (is_bound) {
// Bind variable to a property of a scene node.
NodePath binding_path;
Node *binding_root;
if (has_property_binding(p.first)) {
binding_path = property_bindings[p.first];
binding_root = p_prefetch_root;
} else {
binding_path = get_base_plan()->property_bindings[p.first];
binding_root = p_prefetch_root_for_base_plan;
}
ERR_CONTINUE_MSG(binding_path.get_subname_count() != 1, vformat("BlackboardPlan: Can't bind variable %s using property path that contains multiple sub-names: %s", LimboUtility::get_singleton()->decorate_var(p.first), binding_path));
NodePath node_path{ binding_path.get_concatenated_names() };
StringName prop_name = binding_path.get_subname(0);
// TODO: Implement binding for base plan as well.
Node *n = binding_root->get_node_or_null(node_path);
ERR_CONTINUE_MSG(n == nullptr, vformat("BlackboardPlan: Binding failed for variable %s using property path: %s", LimboUtility::get_singleton()->decorate_var(p.first), binding_path));
var.bind(n, prop_name);
}
}
}
@ -450,8 +567,8 @@ void BlackboardPlan::_bind_methods() {
ClassDB::bind_method(D_METHOD("sync_with_base_plan"), &BlackboardPlan::sync_with_base_plan);
ClassDB::bind_method(D_METHOD("set_parent_scope_plan_provider", "callable"), &BlackboardPlan::set_parent_scope_plan_provider);
ClassDB::bind_method(D_METHOD("get_parent_scope_plan_provider"), &BlackboardPlan::get_parent_scope_plan_provider);
ClassDB::bind_method(D_METHOD("create_blackboard", "node", "parent_scope"), &BlackboardPlan::create_blackboard, DEFVAL(Ref<Blackboard>()));
ClassDB::bind_method(D_METHOD("populate_blackboard", "blackboard", "overwrite", "node"), &BlackboardPlan::populate_blackboard);
ClassDB::bind_method(D_METHOD("create_blackboard", "prefetch_root", "parent_scope", "prefetch_root_for_base_plan"), &BlackboardPlan::create_blackboard, DEFVAL(Ref<Blackboard>()), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("populate_blackboard", "blackboard", "overwrite", "prefetch_root", "prefetch_root_for_base_plan"), &BlackboardPlan::populate_blackboard, DEFVAL(Variant()));
// To avoid cluttering the member namespace, we do not export unnecessary properties in this class.
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "prefetch_nodepath_vars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_prefetch_nodepath_vars", "is_prefetching_nodepath_vars");

View File

@ -1,7 +1,7 @@
/**
* blackboard_plan.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -34,18 +34,26 @@ private:
// When base is not null, the plan is considered to be derived from the base plan.
// A derived plan can only have variables that exist in the base plan,
// and only the values can be different in those variables.
// The derived plan is synced with the base plan to maintain consistency.
Ref<BlackboardPlan> base;
// Mapping between variables in this plan and their parent scope names.
// Used for linking variables to their parent scope counterparts upon Blackboard creation/population.
HashMap<StringName, StringName> parent_scope_mapping;
// Fetcher function for the parent scope plan. Funtion should return a Ref<BlackboardPlan>.
// Used in the inspector. When set, mapping feature becomes available.
// Fetcher function for the parent scope plan. Function should return a Ref<BlackboardPlan>.
// Used in the inspector: enables mapping feature when set.
Callable parent_scope_plan_provider;
// Bindings to properties in the scene to which this plan belongs.
HashMap<StringName, NodePath> property_bindings;
bool property_binding_enabled = false;
// If true, NodePath variables will be prefetched, so that the vars will contain node pointers instead (upon BB creation/population).
bool prefetch_nodepath_vars = true;
_FORCE_INLINE_ bool _is_var_nil(const BBVariable &p_var) const { return p_var.get_type() == Variant::NIL; }
_FORCE_INLINE_ bool _is_var_private(const String &p_name, const BBVariable &p_var) const { return is_derived() && p_name.begins_with("_"); }
protected:
static void _bind_methods();
@ -69,6 +77,10 @@ public:
bool is_mapping_enabled() const { return parent_scope_plan_provider.is_valid() && (parent_scope_plan_provider.call() != Ref<BlackboardPlan>()); }
bool has_mapping(const StringName &p_name) const;
bool has_property_binding(const StringName &p_name) const { return property_bindings.has(p_name); }
void set_property_binding(const StringName &p_name, const NodePath &p_path);
NodePath get_property_binding(const StringName &p_name) const { return property_bindings.has(p_name) ? property_bindings[p_name] : NodePath(); }
void set_prefetch_nodepath_vars(bool p_enable);
bool is_prefetching_nodepath_vars() const;
@ -88,9 +100,10 @@ public:
void sync_with_base_plan();
_FORCE_INLINE_ bool is_derived() const { return base.is_valid(); }
_FORCE_INLINE_ bool is_derived_var_changed(const StringName &p_name) const { return base.is_valid() && var_map.has(p_name) && var_map[p_name].is_value_changed(); }
Ref<Blackboard> create_blackboard(Node *p_agent, const Ref<Blackboard> &p_parent_scope = Ref<Blackboard>());
void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_node);
Ref<Blackboard> create_blackboard(Node *p_prefetch_root, const Ref<Blackboard> &p_parent_scope = Ref<Blackboard>(), Node *p_prefetch_root_for_base_plan = nullptr);
void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_prefetch_root, Node *p_prefetch_root_for_base_plan = nullptr);
BlackboardPlan();
};

View File

@ -1,7 +1,7 @@
/**
* behavior_tree.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -78,10 +78,10 @@ void BehaviorTree::copy_other(const Ref<BehaviorTree> &p_other) {
}
Ref<BTInstance> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_instance_owner, Node *p_custom_scene_root) const {
ERR_FAIL_COND_V_MSG(root_task == nullptr, nullptr, "BehaviorTree: Instantiation failed - BT has no valid root task.");
ERR_FAIL_COND_V_MSG(root_task.is_null(), nullptr, "BehaviorTree: Instantiation failed - BT has no valid root task.");
ERR_FAIL_NULL_V_MSG(p_agent, nullptr, "BehaviorTree: Instantiation failed - agent can't be null.");
ERR_FAIL_NULL_V_MSG(p_instance_owner, nullptr, "BehaviorTree: Instantiation failed -- instance owner can't be null.");
ERR_FAIL_NULL_V_MSG(p_blackboard, nullptr, "BehaviorTree: Instantiation failed - blackboard can't be null.");
ERR_FAIL_COND_V_MSG(p_blackboard.is_null(), nullptr, "BehaviorTree: Instantiation failed - blackboard can't be null.");
Node *scene_root = p_custom_scene_root ? p_custom_scene_root : p_instance_owner->get_owner();
ERR_FAIL_NULL_V_MSG(scene_root, nullptr, "BehaviorTree: Instantiation failed - unable to establish scene root. This is likely due to the instance owner not being owned by a scene node and custom_scene_root being null.");
Ref<BTTask> root_copy = root_task->clone();

View File

@ -1,7 +1,7 @@
/**
* behavior_tree.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_instance.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -25,7 +25,7 @@
#endif
Ref<BTInstance> BTInstance::create(Ref<BTTask> p_root_task, String p_source_bt_path, Node *p_owner_node) {
ERR_FAIL_NULL_V(p_root_task, nullptr);
ERR_FAIL_COND_V(p_root_task.is_null(), nullptr);
ERR_FAIL_NULL_V(p_owner_node, nullptr);
Ref<BTInstance> inst;
inst.instantiate();
@ -42,6 +42,7 @@ BT::Status BTInstance::update(double p_delta) {
double start = Time::get_singleton()->get_ticks_usec();
#endif
const Ref<BTInstance> keep_alive{ this }; // keep instance alive until update is finished
last_status = root_task->execute(p_delta);
emit_signal(LW_NAME(updated), last_status);
@ -82,7 +83,7 @@ void BTInstance::register_with_debugger() {
void BTInstance::unregister_with_debugger() {
#ifdef DEBUG_ENABLED
if (LimboDebugger::get_singleton()->is_active()) {
if (LimboDebugger::get_singleton() && LimboDebugger::get_singleton()->is_active()) {
LimboDebugger::get_singleton()->unregister_bt_instance(get_instance_id());
}
#endif
@ -102,7 +103,7 @@ double BTInstance::_get_mean_update_time_msec_and_reset() {
void BTInstance::_add_custom_monitor() {
ERR_FAIL_NULL(get_owner_node());
ERR_FAIL_NULL(root_task);
ERR_FAIL_COND(root_task.is_null());
ERR_FAIL_NULL(root_task->get_agent());
if (monitor_id == StringName()) {
@ -150,5 +151,6 @@ BTInstance::~BTInstance() {
emit_signal(LW_NAME(freed));
#ifdef DEBUG_ENABLED
_remove_custom_monitor();
unregister_with_debugger();
#endif
}

View File

@ -1,7 +1,7 @@
/**
* bt_instance.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_player.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -42,13 +42,13 @@
VARIANT_ENUM_CAST(BTPlayer::UpdateMode);
void BTPlayer::_load_tree() {
void BTPlayer::_instantiate_bt() {
bt_instance.unref();
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Initialization failed - needs a valid behavior tree.");
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Initialization failed - behavior tree has no valid root task.");
Node *agent = GET_NODE(this, agent_node);
ERR_FAIL_NULL_MSG(agent, vformat("BTPlayer: Initialization failed - can't get agent with path '%s'.", agent_node));
Node *scene_root = scene_root_hint ? scene_root_hint : get_owner();
Node *scene_root = _get_scene_root();
ERR_FAIL_COND_MSG(scene_root == nullptr,
"BTPlayer: Initialization failed - unable to establish scene root. This is likely due to BTPlayer not being owned by a scene node. Check BTPlayer.set_scene_root_hint().");
bt_instance = behavior_tree->instantiate(agent, blackboard, this, scene_root);
@ -70,6 +70,19 @@ void BTPlayer::_update_blackboard_plan() {
blackboard_plan->set_base_plan(behavior_tree.is_valid() ? behavior_tree->get_blackboard_plan() : nullptr);
}
void BTPlayer::_initialize() {
if (blackboard.is_null()) {
blackboard = Ref<Blackboard>(memnew(Blackboard));
}
if (blackboard_plan.is_valid()) {
// Don't overwrite existing blackboard values as they may be initialized from code.
blackboard_plan->populate_blackboard(blackboard, false, this, _get_scene_root());
}
if (behavior_tree.is_valid()) {
_instantiate_bt();
}
}
void BTPlayer::set_bt_instance(const Ref<BTInstance> &p_bt_instance) {
ERR_FAIL_COND_MSG(p_bt_instance.is_null(), "BTPlayer: Failed to set behavior tree instance - instance is null.");
ERR_FAIL_COND_MSG(!p_bt_instance->is_instance_valid(), "BTPlayer: Failed to set behavior tree instance - instance is not valid.");
@ -78,6 +91,11 @@ void BTPlayer::set_bt_instance(const Ref<BTInstance> &p_bt_instance) {
blackboard = p_bt_instance->get_blackboard();
agent_node = p_bt_instance->get_agent()->get_path();
#ifdef DEBUG_ENABLED
bt_instance->set_monitor_performance(monitor_performance);
bt_instance->register_with_debugger();
#endif // DEBUG_ENABLED
blackboard_plan.unref();
behavior_tree.unref();
}
@ -104,7 +122,8 @@ void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
} else {
behavior_tree = p_tree;
if (get_owner() && is_inside_tree()) {
_load_tree();
_update_blackboard_plan();
_initialize();
}
}
}
@ -179,16 +198,7 @@ void BTPlayer::_notification(int p_notification) {
} break;
case NOTIFICATION_READY: {
if (!Engine::get_singleton()->is_editor_hint()) {
if (blackboard.is_null()) {
blackboard = Ref<Blackboard>(memnew(Blackboard));
}
if (blackboard_plan.is_valid()) {
// Don't overwrite existing blackboard values as they may be initialized from code.
blackboard_plan->populate_blackboard(blackboard, false, this);
}
if (behavior_tree.is_valid()) {
_load_tree();
}
_initialize();
} else {
_update_blackboard_plan();
}

View File

@ -1,7 +1,7 @@
/**
* bt_player.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -48,8 +48,10 @@ private:
Ref<BTInstance> bt_instance;
void _load_tree();
void _instantiate_bt();
void _update_blackboard_plan();
void _initialize();
_FORCE_INLINE_ Node *_get_scene_root() const { return scene_root_hint ? scene_root_hint : get_owner(); }
protected:
static void _bind_methods();

View File

@ -1,7 +1,7 @@
/**
* bt_state.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -65,10 +65,14 @@ void BTState::_update_blackboard_plan() {
}
}
Node *BTState::_get_prefetch_root_for_base_plan() {
return _get_scene_root();
}
void BTState::_setup() {
LimboState::_setup();
ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned.");
Node *scene_root = scene_root_hint ? scene_root_hint : get_owner();
Node *scene_root = _get_scene_root();
ERR_FAIL_NULL_MSG(scene_root, "BTState: Initialization failed - unable to establish scene root. This is likely due to BTState not being owned by a scene node. Check BTState.set_scene_root_hint().");
bt_instance = behavior_tree->instantiate(get_agent(), get_blackboard(), this, scene_root);
ERR_FAIL_COND_MSG(bt_instance.is_null(), "BTState: Initialization failed - failed to instantiate behavior tree.");
@ -94,7 +98,7 @@ void BTState::_update(double p_delta) {
// Bail out if a transition happened in the meantime.
return;
}
ERR_FAIL_NULL(bt_instance);
ERR_FAIL_COND(bt_instance.is_null());
BT::Status status = bt_instance->update(p_delta);
if (status == BTTask::SUCCESS) {
get_root()->dispatch(success_event, Variant());

View File

@ -1,7 +1,7 @@
/**
* bt_state.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -28,6 +28,8 @@ private:
Node *scene_root_hint = nullptr;
bool monitor_performance = false;
_FORCE_INLINE_ Node *_get_scene_root() const { return scene_root_hint ? scene_root_hint : get_owner(); }
protected:
static void _bind_methods();
@ -35,6 +37,7 @@ protected:
virtual bool _should_use_new_scope() const override { return true; }
virtual void _update_blackboard_plan() override;
virtual Node *_get_prefetch_root_for_base_plan() override;
virtual void _setup() override;
virtual void _exit() override;

View File

@ -1,7 +1,7 @@
/**
* bt_check_trigger.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_check_trigger.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_check_var.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_check_var.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_set_var.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_set_var.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_action.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_action.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_comment.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -30,7 +30,7 @@ PackedStringArray BTComment::get_configuration_warnings() {
if (get_child_count_excluding_comments() > 0) {
warnings.append("Can only have other comment tasks as children.");
}
if (get_parent() == nullptr) {
if (get_parent().is_null()) {
warnings.append("Can't be the root task.");
}
return warnings;

View File

@ -1,7 +1,7 @@
/**
* bt_comment.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_composite.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_composite.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_condition.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_condition.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_decorator.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_decorator.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_task.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
@ -163,7 +163,7 @@ void BTTask::set_custom_name(const String &p_name) {
void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) {
ERR_FAIL_NULL(p_agent);
ERR_FAIL_NULL(p_blackboard);
ERR_FAIL_COND(p_blackboard.is_null());
ERR_FAIL_NULL(p_scene_root);
data.agent = p_agent;
data.blackboard = p_blackboard;
@ -172,9 +172,8 @@ void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node
get_child(i)->initialize(p_agent, p_blackboard, p_scene_root);
}
if (!GDVIRTUAL_CALL(_setup)) {
_setup();
}
_setup();
GDVIRTUAL_CALL(_setup);
}
Ref<BTTask> BTTask::clone() const {
@ -182,60 +181,47 @@ Ref<BTTask> BTTask::clone() const {
// * Children are duplicated via children property. See _set_children().
// * Make BBParam properties unique.
HashMap<Ref<Resource>, Ref<Resource>> duplicates;
#ifdef LIMBOAI_MODULE
// Make BBParam properties unique.
List<PropertyInfo> props;
inst->get_property_list(&props);
HashMap<Ref<Resource>, Ref<Resource>> duplicates;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
}
Variant v = inst->get(E->get().name);
if (v.is_ref_counted()) {
Ref<RefCounted> ref = v;
if (ref.is_valid()) {
Ref<Resource> res = ref;
if (res.is_valid() && res->is_class("BBParam")) {
if (!duplicates.has(res)) {
duplicates[res] = res->duplicate();
}
res = duplicates[res];
inst->set(E->get().name, res);
}
}
}
}
PropertyInfo prop = E->get();
#elif LIMBOAI_GDEXTENSION
// Make BBParam properties unique.
TypedArray<Dictionary> props = inst->get_property_list();
HashMap<Ref<Resource>, Ref<Resource>> duplicates;
for (int i = 0; i < props.size(); i++) {
Dictionary prop = props[i];
if (!(int(prop["usage"]) & PROPERTY_USAGE_STORAGE)) {
PropertyInfo prop = PropertyInfo::from_dict(props[i]);
#endif
if (!(prop.usage & PROPERTY_USAGE_STORAGE)) {
continue;
}
StringName prop_name = prop["name"];
Variant v = inst->get(prop_name);
if (v.get_type() == Variant::OBJECT && int(prop["hint"]) == PROPERTY_HINT_RESOURCE_TYPE) {
Ref<RefCounted> ref = v;
if (ref.is_valid()) {
Ref<Resource> res = ref;
if (res.is_valid() && res->is_class("BBParam")) {
if (!duplicates.has(res)) {
duplicates[res] = res->duplicate();
Variant prop_value = inst->get(prop.name);
Ref<Resource> res = prop_value;
if (res.is_valid() && res->is_class("BBParam")) {
// Duplicate BBParam
if (!duplicates.has(res)) {
duplicates[res] = res->duplicate();
}
res = duplicates[res];
inst->set(prop.name, res);
} else if (prop_value.get_type() == Variant::ARRAY) {
// Duplicate BBParams instances inside an array.
// - This code doesn't handle arrays of arrays.
// - A partial workaround for: https://github.com/godotengine/godot/issues/74918
// - We actually don't want to duplicate resources in clone() except for BBParam subtypes.
Array arr = prop_value;
if (arr.is_typed() && ClassDB::is_parent_class(arr.get_typed_class_name(), LW_NAME(BBParam))) {
for (int j = 0; j < arr.size(); j++) {
Ref<Resource> bb_param = arr[j];
if (bb_param.is_valid()) {
arr[j] = bb_param->duplicate();
}
res = duplicates[res];
inst->set(prop_name, res);
}
}
}
}
#endif // LIMBOAI_MODULE & LIMBOAI_GDEXTENSION
return inst;
}
@ -248,9 +234,9 @@ BT::Status BTTask::execute(double p_delta) {
data.children.get(i)->abort();
}
}
if (!GDVIRTUAL_CALL(_enter)) {
_enter();
}
// First native, then script.
_enter();
GDVIRTUAL_CALL(_enter);
} else {
data.elapsed += p_delta;
}
@ -260,9 +246,9 @@ BT::Status BTTask::execute(double p_delta) {
}
if (data.status != RUNNING) {
if (!GDVIRTUAL_CALL(_exit)) {
_exit();
}
// First script, then native.
GDVIRTUAL_CALL(_exit);
_exit();
data.elapsed = 0.0;
}
return data.status;
@ -273,9 +259,9 @@ void BTTask::abort() {
get_child(i)->abort();
}
if (data.status == RUNNING) {
if (!GDVIRTUAL_CALL(_exit)) {
_exit();
}
// First script, then native.
GDVIRTUAL_CALL(_exit);
_exit();
}
data.status = FRESH;
data.elapsed = 0.0;

View File

@ -1,7 +1,7 @@
/**
* bt_task.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_dynamic_selector.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_dynamic_selector.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_dynamic_sequence.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_dynamic_sequence.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_parallel.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_parallel.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_probability_selector.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_probability_selector.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_random_selector.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_random_selector.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_random_sequence.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_random_sequence.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_selector.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_selector.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_sequence.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_sequence.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_always_fail.cpp
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

View File

@ -1,7 +1,7 @@
/**
* bt_always_fail.h
* =============================================================================
* Copyright 2021-2024 Serhii Snitsaruk
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
*
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at

Some files were not shown because too many files have changed in this diff Show More