[Feature Request] Async Loading / Initialization and user-defined De-initialization (or Cache clear)

Kichang Kim

New member
Hi, I used Behavior Designer heavily on my previous project, and I have some feature requests for the next project.

1. Async Loading / Initialization
With mobile devices, the loading/initialization process of Behavior Designer is extremely slow. In my test case, it consume 10sec ~ 1min for 1 behavior tree instance. I solved this issue by modifying the source code of Behavior Designer to support parallel async loading. But due to this modification, version up is very difficult. So if Behavior Designer support async/multi threaded initialization logic, it makes users very happy.

2. User-defined de-initialization
I found that Behavior Designer uses internal static cache (object pool) for its internal classes include behavior tree nodes. But if user custom node have references to any of resources, it is not released because of it is still located in internal pool. So I want to some of user-defined clean up method or cleaning internal object pool.

Thanks.
 
1. That's awesome that you added it. If you can send me a PM with your changes that'll help speed up my implementation for it and I can also run it through the unit tests that I have.

2. I'll add a clear method to the object pool with the next version.
 
Thanks for reply.

Unforunately, my modification for async initialization is heavily depend on my project and its internal libraries so I can't send it to you. But I can tell you main ideas:

1. Separate CheckForSerialization() and AddToTaskList() in BehaviorManager.cs into other thread (I used Observable.Start() of UniRx, reactive extention for unity). These two methods occupied most of initialization time. Then make both methods to be thread safe.

2. Make ObjectPool to be thread safe too. I simply used lock statement (more advanced lock-free implementation can be used for further improvement, I think.)
 
Hello, both of these features would be a great help.
1. Async loading would help a lot, because there are situation that a pooling just does not cut. (too many trees to keep pooled all the time in memory, open world with fluid world transitions - no loading screens)
2. We implemented the clear function in custom tasks (our custom task have all the same base - one for each task type (action, composites, etc.) and are calling it on all nodes when the entity is recycled.
 
Hello, I did try to re-do Kichang Kim wrote, first in a test project with the UniRx, then in the main project using a different threading system. It seems to work (big thanks to Kichang Kim for the inspiration).

If you want, I could send you the test project and relevant snippets of the final implementation (which is without the UniRx). (should I attach it here?)(It would include modyfied BD runtime source)
 
Behavior Designer 1.6.3 will contain async loading. If anybody would like to test this out before it is released feel free to send an email to support@opsive.com with your Behavior Designer invoice number and Unity version.
 
Would pooling external trees still be necessary if using this new async loading?

I've started optimizing a big(lots of Ai with big Btrees) game I'm working on and if I enable my BT's at runtime I'm getting huge lag spikes-

I was just about to implement External Behavior Tree pooling but should I skip pooling and upgrade to 1.6.3(currently on 1.6.1) and try async loading instead?

Just did some simple tests with nested external trees with a clean project and 1.6.3 and the differences with Async loading seem to be amazing- can this be right?

Just enabled a group of agents at runtime without aync loading ticked and got 8.2mb of GC and 214ms with async ticked it generates only 1.3kb of GC and 11ms 0_0
 
Last edited:
I was just about to implement External Behavior Tree pooling but should I skip pooling and upgrade to 1.6.3(currently on 1.6.1) and try async loading instead?
If async loading works well I would stop there :) The two features are independent so they can be used in combination with each other but if async loading improves the load time so you don't even notice it then I would just stick with that until you decide that you need to optimize more.

Just enabled a group of agents at runtime without aync loading ticked and got 8.2mb of GC and 214ms with async ticked it generates only 1.3kb of GC and 11ms 0_0
The amount of data loaded doesn't change with async load, but it spreads it out across multiple frames so the effects on a single frame are reduced.
 
It works great as is and was an easy fix for the Movement Pack tasks- 1.6.3 is an amazing upgrade for performance! I feel like you should add an exclamation point on the release notes for it :)
 
@Justin Hi, I tried the asynchronous load feature of latest Behavior Designer (1.7.1) and found some issues:


Also, I found that you used Thread class directly for async loading, but C#'s recommendation is Task (because it uses thread pool internally). Is there any special reason for that?
 
Top