#Help Needed, Optimizing Horde Battler
30 messages · Page 1 of 1 (latest)
If you profile it, what takes the longest? https://docs.godotengine.org/en/latest/tutorials/scripting/debug/the_profiler.html
You run your game from Godot and play around. It's fun, it's becoming feature complete, and you feel it's getting close to release. But then, you open the skill tree, and it grinds to a halt as som...
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
If each unit needs to see the closest other units, consider using spatial hashing: https://gamedev.net/tutorials/programming/general-and-gameplay-programming/spatial-hashing-r2697/
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
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?
I just released a demo project
https://discord.com/channels/212250894228652034/1291420767791353927
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
Are you on 4.3? If so, try using physics interpolation
You can probably push the physics ticks even lower if you do
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
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
but now the enemies should be moving at half speed..?