Since last post I fixed the rendering having blown out diffuse/specular textures, optimized some of the rendering and compute shaders, and added:

  • Enemy spawning
  • Basic AI system
  • Round Timer
  • Player and enemy projectiles
  • Window icon
  • Animation interrupts

I added a new model for enemies, and a system for spawning enemies in over time. In order to stress test the system, I spawned in 1000 enemies, 1000 point lights, and 1000 spot lights. The system slowed to a crawl and I was only getting 15 FPS on quite a decent dev machine. Looking into the timings, I found 3 main issues: compute shaders, and building buffers.

The compute calls started numbering in the thousands, so I redesigned the shaders so that we only issue one compute call per model that handles all the meshes and instances. Then I redid the buffers so that we can reload static and animated model buffers separately, so that reloading the map or spawning enemies did not interfere with each other.

I made a few more optimizations for rendering as well, though it’s still dropping frames when enemies spawn if there are a lot of them because we regenerate a few large animation buffers every time. I may look into pre-allocating large buffers and tracking which parts are in use to see if we can avoid constantly regenerating and repopulating them.

Once the lag was under control, I added an AI system that keeps enemies within a certain radius of the player. Anything too far runs towards the player, and anything too close runs away. When they are in attacking distance, they will attack every couple seconds. This leads into the bullets, which I added for both the player and enemies.

I allocated ring buffers of bullets for players and enemies separately, each holding up to 1000 bullets. Bullets have a lifespan and despawn after they run out, or if they get tossed out of the ring buffer due to capacity. I set it up so they mark their scene entity for removal, and updated other despawning systems like the map unloading to do the same. This means we can clear out all the dead models in one sweep at a predictable time, to save on computation.

My next steps are adding in a collision system for the bullets (and potentially enemies) so that we know if they have hit a player or enemy, start removing health and despawning bullets on collision, and tweak the spawn and attack speeds to actually be reasonable.

As always, the game is open source, and the code can be found here: https://github.com/Maceris/BulletHell