BehaviorManager Update Interval Manual best practise / advice?

Arakade

New member
I've often wondered whether it might be advantageous to switch from BehaviorManager from "Every frame" to "Manual".

I imagine there's probably some pivot where more than a certain number of AIs and/or number of nodes that get evaluated each frame makes it beneficial to switch.
Obviously there's also the question of how to schedule manual ticks. I'm picturing an "event driven" approach and recognise it might entail reworking the trees and perhaps more.

I have a bunch of "senses" classes that deal with inputs which currently fire BT events but could just as easily fire some custom event (via my own event system) that triggers a Tick to evaluate the results. My movement is done using A*Pathfinding project (and I've recently integrated the "Easy Character Movement" for that). I could modify my movement BD nodes to dispatch an event/custom event on arrival. Other things that are currently BD nodes checking every frame could do the same. I suspect all this might save quite a lot of cycles I'm currently burning on each AI.

Is this a mad concept? As I said, I've pondered it quite often and suspect I read something similar in the old forum but I can't access to refresh my memory.

All thoughts/examples/etc welcome :)
 

Justin

Administrator
Staff member
Personally I wouldn't switch to manual unless you have a reason to. Your best bet is to profile and then see if the behavior manager has a large overhead which would benefit from not running as often.
 

Arakade

New member
I appreciate the likely sage advice. I guess that's due to the "premature optimisation" rule?

My game already has a high CPU load already so I'm looking to recover it where I can. I'm only running a couple of AI agents atm. You're right that I maybe should wait until they're consistently topping the Profiler charts but some optimisations need considering at an architectural level rather than a lower one and restructuring my BTs later will be much more of a pain. Looking at the amount of work that my (relatively simple) trees are going through already makes me concerned I'll end up doing this eventually so I feel it's worth considering/investigating now.

My (relatively simple so far) tree architecture seems to end up involving 2 top-level branches under a Parallel:
  1. One top level branch (that's maybe more like a state machine) where 1 of several branches is generally doing the same thing (e.g. idling, moving to X) and some more "active" ones like "attacking by doing a few things repeatedly.
  2. The other top level branch is a whole slew of conditional branches with Aborts meaning they're all being evaluated every frame (e.g. a few trigger tests and a whole load of "HasReceivedEvent"). With the exception of the "active" bits, each one of these AIs end up pointlessly redoing all that work every frame. Pointlessly because I know that those conditions haven't changed.
Please do tell me I'm doing it wrong. I've always worried I'm missing something with BD. I feel these are 'relatively simple' because I know I'll be adding a lot more to them for more interesting behaviours.

I've done a provisional implementation in an experimental project since I originally wrote. Making virtual a few Behavior methods (SendMessage() variants and a few lifecycle ones) and overriding in a "BehaviourTreeManualTicked" class so they tick `this` works to get things started. I also register against a few A*'s Seeker events to tick again when it reaches destinations, repaths, etc. Obviously it's a simple case but a reasonable base.

I'll see how it progresses as I take it further. It may all become too complex but it's at least interesting to see that maybe it could work.

Like I said, I still worry that maybe I'm not 'getting' BTs somehow. Sorry.
 
Top