Performance improvement by batching agent behavior tree update

Noxalus

New member
Hello everyone,

We are working on a tycoon game with ~200 active agents at the same time, and we would like to reduce the cost of AI logic by splitting their execution over multiple frames.

Here is the code I would like to write:

C#:
public class AIManager : MonoBehaviour
{
    // List of all agents present in the game currently
    private List<Agent> _agents = new List<Agent>();
    private Queue<Agent> _agentsToExecute = new Queue<Agent>();

    private void Update()
    {
        if (!_agentsToExecute.Any())
        {
            _agents.ForEach(agent => _agentsToExecute.Enqueue(agent));
        }

        for (int i = 0; i < 20; i++)
        {
            var agent = _agentsToExecute.Dequeue();

            if (agent != null)
            {
                agent.BehaviorTree.Execute();
            }
        }
    }
}

There is no "Execute" method for the "BehaviorTree" class, but it's what I need to take the lead over the "BehaviorManager".

So my question: there is a way to do what I want without updating the Behavior Designer code?

Is that a good idea to reduce the performance cost of AI or it's a little bit dangerous? (maybe behavior trees expect to be executed each frame?)

Thanks in advance for your help!
 
So my question: there is a way to do what I want without updating the Behavior Designer code?
Yes, you can change the Behavior Manager update type to manual and call tick. See this page:


Is that a good idea to reduce the performance cost of AI or it's a little bit dangerous?
That method is no problem and makes sense if you don't need to tick every frame.
 
Thank you very much for your answer, and sorry for not reading the documentation properly.

So from what I see, the code above should looks like that:

C#:
public class AIManager : MonoBehaviour
{
    // List of all agents present in the game currently
    private List<Agent> _agents = new List<Agent>();
    private Queue<Agent> _agentsToExecute = new Queue<Agent>();

    private void Update()
    {
        if (!_agentsToExecute.Any())
        {
            _agents.ForEach(agent => _agentsToExecute.Enqueue(agent));
        }

        for (int i = 0; i < 20; i++)
        {
            var agent = _agentsToExecute.Dequeue();

            if (agent != null)
            {
                BehaviorManager.instance.Tick(agent.BehaviorTree);
            }
        }
    }
}

I will try that, thank you again!
 
Top