I’ve edited a bit of the BTrees visual editor plugin, and it should no longer lag when you select any object in your game (not just behavior trees). The issue was that no matter what you selected, behavior-tree or not, the plugin always called a ChangeHistoryService::SetEnabled method. This method is called to stop folder changes to be undone on ctrl z, so be aware that this modified version of the plugin breaks undo behavior! https://www.roblox.com/library/6988737146/BehaviorTreesPlugin-V4-Optimized-version
On a sidenote, @Defaultio - whenever I return RUNNING, it still re-evaluates the whole tree the next time I call the :Run() method. Is this expected behavior? If so, is there any way to only call the currently running task if the state is RUNNING, instead of re-evaluating the whole tree?
But decided that removing the ChangeHistoryService line caused more usability problems than it was worth. By removing this, you risk irrecoverably losing work. I’d advise building trees in a separate blank place, where the spike won’t happen, and copying the trees over to the master place.
On the running issue, I took a quick look and it seems like the intended behavior is only run the current task, and the rest of the nodes will not be evaluated. Are you sure it is reexecuting the whole tree? Are you sure you are calling the same tree? That is, that the obj parameter passed to run is consistent. I don’t have time to debug this at the moment, let me know if you find a fix.
Ah! found the culprit. I watched sleitnick’s video where his code looked like so:
It seems like he was only returning RUNNING in some very specific scenarios, which caused his code to work fine but not mine.
The issue is that whenever my tree would return RUNNING, I would never re-evaluate it again - I was basically waiting for my TreeRunning variable to change, even though it never would’ve since I’d never run the tree in the first place. Sorry for the trouble
EDIT:
In regards to the issue you mentioned, I was actually aware of that post - in fact, that’s why I was able to figure out why that line was there in the first place, so I could put up a warning to those that would install it
Is there a way to duplicate an entire tree folder?
I want to retain a bunch of behavior for a seperate npc but I also want to use a bunch of the same logic.
The editor doesn’t work on a new clone of a folder if I just try to copy it.
Now with Roblox’s new Task Library it would be a good idea to change the “task” table to treeTask or something different to prevent compatibility issues in new work.
Would be amazing if we could specify the quality of the bezier curve (i.e how many frames it uses) as on my larger behaviour trees it gets really painful to use. I also can’t split them out into more as then we loose features such as linked tasks.
UPDATE: You can modify the variable ‘segments’ in DrawCurve.lua as low as 6 (down from 24). There are lots of other improvements which could be made. Right now there’s way too much instancing and destroying going on but I haven’t found the time to dig my teeth into it.
UPDATE UPDATE: It is now 2:30am, Got sucked in haha. Found a fair few inefficiencies, for instance rather than pooling existing frames for the bezier curves we were creating new ones each time and destroying the old. Changelog:
Use existing pool, only create new instances when required
Switch from RenderStepped to Heartbeat
Only call update every 4 frames for avg cost and 6th for expensive
Reduce framecount per bezier curve from 24 to 6
BehaviorTreesPlugin_V4.rbxmx (1.1 MB)
All my changes were made on the fly with no consideration for futureproofing or conflicts passed the immediate term. Only use if you need it (i.e you have large trees).
I can’t find a single tutorial anywhere and I have no clue how to use it, I really need this for an AI system I’m making as it will be a pain to code a custom behavior tree. I would really appreciate if someone linked me with a comprehensible tutorial.
Ok Guys, I’ll give my best explanation as to how I think this should work. So the most basic of basics is that you need an update function
-- Services
local RunService = game:GetService("RunService")
local Tree = BehaviorTreeCreator:Create("Place Tree location here")
local function Update()
Tree:Run()
end
RunService.Stepped:Connect(Update)
In order to run your tree repeatedly. As of right now I’m trying to figure out the logic as to how to make it not run when it is currently running/ doing something repeatedly. My best bet is to go into each script and return the script when it IS running so that i can
A) Identify the script that is running and just do checks to see if it is running
B) Stop the entire tree from running
Hopefully i’ll figure out something and share more with you guys!
I’m having a similar issue, if anyone has a solution to this would be much appreciated. As soon as one NPC dies another one fires up, but two can’t run simultaneously. tree:run() is being fired but it doesn’t do anything in the “waiting” npcs. I’m guessing that the repeat node I have has it running and disallows other NPCs from running(don’t know why). Been trying to resolve this issue for almost a week now. Would really appreciate any advice or help.Thanks for the assistance and can provide code if needed!
Hey everyone! I know one of the big problems I had while using this plugin was the lack of easy Rojo support as well as the lack of sharing tasks between behavior trees.
Well, given I had some time I decided to quickly try playing around with the module and plugin and have come up with a decent solution to this:
External Tasks
External tasks work independently from Tasks in that rather than having the task module sit inside the the BehaviorTree’s folder, it can now be referenced from another source entirely! This is a nice way to have all your tasks made easily accessible to something like Rojo, or other behavior trees.
Some things to note:
This is not battle tested and may still have bugs. Feel free to DM me if you find any.
You’ll need both the ET edition plugin and module for things to work.
I am not responsible for creating or maintaining BehaviorTrees, and all credit still mostly applies to the others involved, I’m just trying to make things more accessible for this amazing tool!
I did ask before posting this and it seems like I’m in the clear. If I made a mistake with how I posted something I’ll update ASAP.
Im trying to create and AI that has 2 trees:
Idle and Chase
the idle tree requires the chase tree and vise versa
this causes some kind of error where they generate recursivley causing a error and about 5k output lines
update: nvm i always find the solution when i post it, still might be helpful if someone has the same error, the go to the other tree node dosen’t mean it will be stuck at the node it will always revaluate from the root node (idk did i explain it properly)
I find this library really awesome , i want to point to some important topic about RUNNING state: https://devforum.roblox.com/t/btreesv5-rojo-support-fixes/1781449 as this is the latest version and you should use this for newer work , with this version when tree sees a RUNNING state while traversing , it pauses the tree and starts traversing from where it returned running instead of traversing all tree again. I don’t know if this was like that on prior versions , but i saw couple messages about this above. So i felt the need to clarify this for other devs thinking using this module.
I might be wrong on this, but I think I’ve found an issue with the way the tree traversal handles subtrees. The loop through nodes relies on “didResume” to determine whether or not to call the task.start() method of tasks. didResume is the result of data.paused and this works fine for trees.
However, if a sub tree ever returns the status RUNNING, data.paused is set to true. When the tree eventually returns a SUCCESS / FAIL result, this doesn’t swap data.paused or didResume.
This causes an annoying issue: whenever a tree returns the RUNNING result, subsequent nodes will no longer have their .start() methods called (even after the tree returns success), as the traversal also uses data.paused to evaluate whether the node at the current index has already had its start method called.
Currently:
My suggested amendment:
I’m hoping this amendment is correct and I haven’t made a glaringly obvious mistake! Anyhow, this plugin is an amazing resource and I’m extremely grateful to all of you who helped make it!
Sorry for the necro but are you planning on updating this module to work with Parallel Luau?
these module and plugin are amazing but the performance boost you can have with Parallel make it almost a waste