BULLET ENGINE OPTIMIZATIONS:
- October 27, 2017
- 2 Comments
Ok, technical post ahead. Sorry about that.
My bullets code was terrible: I wrote it a long time ago without any optimizations and forethought. It worked and it was enough for me.
Then I had second thoughts, some nightmares and bad nights, and I finally decided to write a real bullet manager and optimize the guy.
Keep in mind that I’m not a real coder by trade (I’m a tech artist / coder) so please don’t laugh at my naive way of doing things :)
I knew that creating and destructing a lot of objects every frame was bad, so I created a pool of bullet objects at the SHMUP Creator runtime. It worked. What was bad was the way to manage the active and free bullets in an efficient way. I was iterating on all the bullets to find a free one before spawning it and to update the alive bullets and so on. Not too bad with the CPU power of 2017, but not very efficient with 6000 bullets.
So I wrote a bullet manager which keep tabs on all this. I still create a pool of bullet objects but also 2 lists of bullets IDs: one of active bullets and one of free bullets. Those IDs are references of the pool’s bullets.
If I want to spawn a new bullet, I can use the last free bullets ID and set the bullet from the pool sharing this ID to “active”. I then remove this ID from the free bullets list and add it to the active bullets ID list.
This active bullets list allow me to only update the active bullets and also to maintain an ordered bullets list, which I need for rendering (more details in the next section).
When a bullet is dead, I set its state to “DEAD” and I erase his ID from the alive bullets vector (I know it’s not the most efficient thing in the world, but…) and add it to the free bullets vector.
DRAWING the BULLETS and DRAW CALLS
The most terrible thing I was doing was to draw individually each bullet. It was working on my laptop, so what the heck?
But I really felt bad about it, and with a lot of bullets, I began to see some performance drop. On top of this, ordering the rendering of thousands of objects was not easy with Ogre and was slowing down the game a lot.
So, I wrote my own bullet renderer. For each bullet type I create a polygons list using all the current bullets positions and orientations and draw it with its own material. Thanks to the active bullets list I’m able to draw each bullets in the right order.
At the end, I have only one draw call for each bullet type, instead of 3000 draw calls for 3000 bullets. Much better!
ROOM FOR IMPROVEMENT
At the end, the bullet manager is not perfect and could be more optimized but I’m pretty happy with it. Maybe one day I’ll go back to it and make it better.
But for now, yes, it’s much faster :)