Actor Pooling?

Hey Epic Friends!

UE doesn’t seem to me to have any built in actor pooling system- you just fully spawn and destroy actors as necessary. (This is suggested to me most by the fact that Iris’s net actor factory is hardcoded to call Spawn instead of potentially pulling something from a pool.) Why is this? Do you optimize your actors to have very few components such that they’re so efficient to spawn you can allocate and initialize tons of monsters without noticing a performance hit? Or do you end up hacking up the engine to plug in custom pooling systems that are made specifically for the game? What does fortnite do? And do you expect it to keep doing that in the future? We’re a bit torn between paths because pooling always ends up being hard to maintain (as you have to efficiently make sure you’re resetting all your properties and nobody is holding onto references to your actor or objects) but spawning ends up calling a zillion virtual functions and allocating so much gunk that it’s painfully slow.

Thoughts?

Thanks!

Josh

Hi!

You are correct that the engine’s workflow primarily relies on spawning and destroying actors instead of pooling them.

Spawning expensive and/or many actors in a frame is a common source of hitches in Unreal projects, so much so that it made it as the third most common source of hitches in The Great Hitch Hunt presentation. That link takes you to the Actor Spawning Hitch section, which has some advice on mitigating the problem.

We’re investigating actor pooling here at Epic Games, but it’s quite an engineering effort to get it working for all current and future use cases and industries. It’s much simpler for you to just do it per actor type in a way that fits your project’s needs. You know which properties need to be reset, which can be reused, which dynamically spawned components can stay/be removed, etc. The more generic the solution, the slower it will be, because we will have to go through every single property recursively and compare it to the CDO to reset, instead of just resetting the variables you know can change for that actor type. And it would only work on reflected properties (UPROPERTY), or we’d need to have a native reset function for every single UObject class. Because of the difficulty in generalizing an actor pool functionality while staying performant, there is currently no promise or ETA on a native pooling solution.

Our recommendation: custom pool per actor or object where it makes sense for you (e.g., bullets), otherwise make sure that actors you do spawn per frame aren’t too expensive (by simplifying them or delaying initialization of things where you can), and finally, make sure that you limit the number of actors you spawn each frame.

thank you for the detailed info- makes lots of sense!

Josh