My AI bots are setup to only have 1 task loaded at a time. When the AI wants to do a different task, it loads in the new task and unloads the old. This works fine.
I’m wondering when there are many Bots running at the same time, will this constantly loading and unloading task cause problems?
I not using a behavior tree nor a blackboard. Just using an AI Controller. All the tasks are components.
The characters all have a soft reference array of tasks. The AI Controller decides what task to do. Then the task component is load on the character and then executed. The AI Controller then waits for the task to end and then it picks another task. The new task component is loaded and the old task is destroyed.
By doing this, I can make a breathe fire task. I can give it to a dragon a fish and it works great.
The idea is to have very elaborate AI bots that can do many task without carrying all the code
it all depends on if you are creating new segments in memory or not. If you have a pool of tasks that are activated / deactivated or the internals filled depending on the needs then you can do this efficiently as it would all just be in memory manipulation.
If you constantly create and delete tasks => that is where you can run into performance problems.
I’m loading asynchronous a task component then destroying the component when I’m done with it.
Maybe, when the level loads I can have the game instance gather all the task that are present in the level and load them. Then the characters can get what they need from the game instance. Or just run the code directly from the game instance
So if the task component already exist in memory, like on a level manger actor, then adding said task to a character is no big deal as the task was already load on the level manger. Is this correct?
I would also just add to this that actor components are pretty finicky when it comes to keeping them any where out of the actors themselves. Moving them from actor to actor also costs performance.
This thread also tackles the problem of if you are driving logic in actor components with tick enabled inside of them you will pay the penalty of a single actor constantly evaluating multiple ticks.
I would make a uobject (object) derived class that would get it’s tick update from a central ai manager. Guess it all depends on how complex you want the logic inside of the ai building blocks.
Personally I’d probably start off with state trees as their logic seems a bit more straightforward than behavior trees and already look like an ok system. They are internally optimized.
i have no idea without looking at your code, and using insight as proposed.
as a personal general rule, if anything has high churn then it’s probably something that can be optimized. as some suggested with a pool.
you can incur in unnecessary disk load, you risk hitching, you risk fragmenting the memory, mac/ios does no like memory request/free too often or too big (can kill your app), you also risk having issues if at the same time some blocking load happens as it might flush the load (meaning the whole app will stop until everything is loaded), also you make the gc work harder.
i’d go with a pool. or load everytihng if it’s really not necessary to dynamically load/unload.
K.I.S.S.
Scene components have the added cost of transform calculations. If you can pick your poison then actor components are better in that regard as the don’t physically exist on the actor but just just data containers with functions.
Though if it is separate logic then at that point why not go the route of the state tree. The behaviors are basically like actor components, just not stuck on the actor but condensed in the state tree.