#Help Needed, Optimizing Horde Battler

30 messages · Page 1 of 1 (latest)

round nest
#

Do you update the hordes movement every frame?

wise quail
#

If it's pathfinding, try updating each unit only, say 10 frames, and give each unit a random frame offset that they update on. So the updates will look like this:```
unit0:----x---------x---------x---------x---------x-----
unit1:x---------x---------x---------x---------x---------
unit2:---------x---------x---------x---------x---------x
unit3:-------x---------x---------x---------x---------x--
'-': no update
'x': update

#

The concept is very simple, you maintain a dictionary where the keys are the rounded position of the units, and the values are an array of units in that cell

wise quail
#

What is in move_towards_player?

#

Also, I forgot to mention this before but cache as much data as you can

#

Ahh, it probably is the physics system then

#

Those other functions seem like they have nothing to do with physics/collision, right?

thorn orbit
#

Techniques used:

  • non-solid enemies
  • simple Areas with circle collision shapes and circle detection
  • separate the enemies through a basic algorithm
  • reduced detection frequency by skipping physics frames
  • reducing potential overlap results by only checking immediate neighbors and a low cap on maximum overlap results returned

Drawbacks:

  • enemies can overlap
  • "Collisions" with obstacles/level geometry requires some creativity and tweaking
#

Yeah with CharacterBodies it's impossible to achieve this kind of performance I think. Unless they aren't colliding at all, with different collision layer and mask or disabled collision shapes, which ofc defeats the purpose of using solid objects in the first place

#

The move_..() just get exponentially more expensive when increasing object count due to the collision pairs is my understanding

#

I think a custom rigidbody solution may have a better performance but this would require a lot of tinkering too I guess

#

This is a constant number of enemies?

#

With CharacterBodies most people report frame drops starting at 300-400.
Probably depends if move_and_collide or move_and_slide is used, but there doesn't really seem to be a simple way to improve it.
You can try running the move calls only every n frames and stagger it so not all enemies call it during the same frame. Or try a custom solution where you put some to sleep that aren't able to move any more

#

But in the end I dont think it'll work with this approach

#

Oh right, and I think from the profiler output the lag is caused by the physics simulation, and not the move calls. So this performance hit may be due to the depenetration the engine is attempting. And probably a lot of recursion happening when they are stuck in between like this.
Just a guess, I'm no expert

#

That's what I was trying to achieve in my solution but no matter how I tweak it they would either overlap eventually or spread out way too far

#

Maybe you could run a test_move to see if the body would collide, if so run a vicinity area detection check to see if it's to crowded and make it sleep until the situation is resolved

#

But this ofc will come at a performance cost too. Maybe it'll just end up as expensive as before, just in a different way

#

I have to go to bed but will check back in tomorrow

#

Actually I've been discussing a raycast steering approach with someone else over the past few days and I'm pretty confident I could make a 500+ enemies solution work this way without overlaps. Just not sure how smooth the movement would look. Will try to make a demo this weekend

wise quail
#

Are you on 4.3? If so, try using physics interpolation

#

You can probably push the physics ticks even lower if you do

thorn orbit
#

Interesting! Are you reducing the physics frames per seconds in the project settings to 50 fps to make it update at 0.02 or are there timers involved?

CharacterBodies have a max_slides property, maybe when they are bunched up they all try to slide a lot. But as far as I can tell that should still only give you a maximum number of enemies times 4 move calls.

The engine will drop rendering frames when the physics processing time spikes and could be running multiple physics steps per frame and maybe the profiler adds them together

#

Guess I have to try a Characterbody version of my project now. Seems like I prematurely counted them out

thorn orbit
#

ok, so the physics process delta is pretty much fixed at 1/60 = 0.016, so if you use an update_interval of 0.2, it will skip every other frame which should in theory double the performance and make the enemies move at 30 fps. thats probably just enough to still look fluid

#

i think its as granual as it gets. there's also a visual profiler but it will only show some totals

thorn orbit