Download

Delay to avoid cluttering

Hi.

I have an optimization question.
I have a game featuring a soldier squad up to 5, and about 25 enemies in a level.
Regularly (about once per second), they each soldier line trace each enemy and vice versa to see if they can see each other, make rotation calculations, distance calculations based on several parameters and so forth.

These are made with for loops where one soldier/enemy performs all own calculations in one loop. These individual loops are spread out with random float delays such that every character/enemy has their own frame to make these calculations in.

But i imagine that when one soldier makes his own calculations, it still stresses the system a fair amount.
Since loops doesn’t support delays within the loop itself, is there a way to spread out the calculations over a period, or am i worrying too much because the computer can to handle those calculation and many, many more in one instance?

Thank you in advance :slight_smile:

I recommend using seperate timers and only have them run as often as they need to for each calculation. If you need all of the calculations every second, maybe you can limit how far each loop gets in its calculations by using Branch/If statements. For example, if the trace fails (cannot see an enemy), then you might not need to calculate the rotation. You can use the profiler to determine how much CPU time the calculations are taking. If you just have a ton of calculations, you should think about using C++ for them since blueprint is slower.

I have already eliminated unnecessary calculations (like the one you mentioned), and set them in a logical order, but it can ofc always be trimmed down further. All calculations are also in seperate timers, so it doesn’t seem there is much i can save out on, in blueprint. I will look further into c++, if it becomes a problem.
Ty for your reply :slight_smile:

Are the timers, for loops, and calculations done by a separate class or the level blueprint, or are they within the characters? Because the only other thing that comes to mind is to create an event on your character that is called using the same timer setup and also place all of your calculations within the characters. Each character would then run its own calculations based on its own timer. Doing this should keep you from needing as many loops. With less loops you could use more delays. If you are removing any characters (DestroyActor) make sure to unbind from the aforementioned event or the binding will still exist in memory.

Optimization will always be a balance between fidelity and performance. Based on the parameters youve given, i doubt youll run into problems unless youre developing for mobile or you spawn a few hundred of these units at once.

As lomg as you arent looping more than a few thousand times per frame the loops themselves wont be stressing the CPU too much. Unless the computaioms are ridiculpusly complex, but based on what info youve given, most modern PCs should be able to chug along no problem.

That said, you can stagger the computations across several frames many different ways. The one off the top of my head is to populate a randomly ordered array of units that need to update their sensing and use that array to pull which ones to update for a given frame. You can recompile this list every so often to “rerandomize” the update sequence.

You probably want to compensate for unit counts (more units active, more loops per frame) to keep AI sensing within reasonable tolerances (updates every 0.2-0.5 seconds). That sort of thing.

Good luck!

Every character does his own computation in his own blueprint, and every computation is set with these individual random float delays, so they are spread out as much as possible. But i wasn’t aware of the unbind function, instead i have a branch checking if the character is dead when updating, that then makes it the last update.
At the moment they update between 0.3 and 0.9 secs (+/- the random float), depending on what type of update it is.

Compared to other games, i can only imagine that these computations are rather simple. So if i can throw some hundred in the level, i should be more than safe :slight_smile:

My apologies - in the context of Timers you would not use Unbind, but rather Clear Timer by Handle. Obviously you can only unbind from events that are binded to.