Qriva/MonoBehaviourTree

Performance from example

SmikeSix opened this issue · 2 comments

Hey i like the approch of you behaviour tree.

Im looking at example 2 and when the red enemy is next to the green one, the service.onexit gets called 250 times and allocates quite a lot of memory.
Which is a bug i believe. Otherwise using unity events... is bad on mobile, since it will cause memory alloc and has bad performance.

Qriva commented

Nice catch! There are several things we must touch here.

The example is actually not well designed, the fact it loops 250 times comes from poor construction of the tree. The loop does not take into account that distance check might fail, and when it does then tree is stuck traversing the same several nodes untill execution limit is reached (1000 by default).

About the allocation, yes it comes from service enter and exit methods, to be more precise from Calculate distance service (looped 250 times), but the allocation is not bug itself. As there was need for mechanism to listen tree updates the onTick event has been introducted - service use that event to run tasks when needed. However this is not unity event, but simple C# delegate. behaviourTree.onTick += OnBehaviourTreeTick;

The problem comes from the fact that the service node should not be called/entered so often. The idea is that service enter/exit should be called sometimes, maximum once per tick. By design interval is expected to be like ~100ms to several seconds and the tree should "stuck" in some leaf nodes to do stuff.

I understand that ideally there should be 0 allocation, but I had no better implementation idea that meets all requirements.
In any case, I guess there should be no problem (even on mobile) if tree is made in smart way, plus you are not forced to use services, or you can code custom services executed by something else with zero alloc.

Qriva commented

I didn't want to create separate tick lists, but what I could do is to create something like ITickListener interface and separate list of objects to be ticked, then make services to register themselfs to that list. This way there would be just a bit of initial list allocation and this change would not break any other mechanisms.

Also another thing is it might be good to consider some kind of "BreakOnFail" setting in repeater node.