Performance Housekeeping

Hey Folks! Hope everyone had a good weekend. Fairly low-key, here. What spare time I had I squeezed in some Stellaris, where I finally managed to have a competent empire. My usual "nice guy" empires always failed/were defeated, so this one's pretty cutthroat :)

Back at the office, I figured out why that O2 amount was so wonky after playing with the canister pre-filled amounts. It turns out that I was using the wrong value for O2 molar mass. I was multiplying by 1000 where I should've been dividing. (Converting g to kg.) Also, I forgot to use the molar mass of O2 instead of just O, which didn't mess-up the UI at all, but would've probably been noticeable to any science-hawks out there.

Once that was done, (or more accurately, as I was testing that), I decided it was time for some performance housekeeping. Framerates were really low when this large test ship loaded in Crew Sim mode. And there was a ton of hitching/lagging each second, largely due to the game stats update heartbeat. I could probably ignore it for short stints, as I have been while testing UI. But if I'm going to long-play this a bit more to test travel across the System, 14-20 frames per second with frequent freeze-hitching was going to be painful.

So I broke out Unity's Profiler tool to see what was going on. And there were some doozies in there.

I moved a lot of item and crew update stuff out of the overall simulator into each item and crew itself. The simulation was trying to manage when they all updated, which was unnecessary, since each got an update call implicitly through Unity's entity-component model.

I was doing a lot of other per-frame stuff that should've been more optimized, too. Things like setting animation states, adding/removing "IsPowered" condition, getting references to components that are used all the time (e.g. fusion reactor). I also noticed a lot of items had things added to them unnecessarily, which were updating each frame. Like container properties on non-containers (e.g. the tile and wall objects and some invisible helper objects).

Plus, my conditions were all updating each-frame to check if they've expired. Even ones that never expire.

So as you can tell, a lot of wasted CPU cycles in the code. And trimming this down improved overall performance from ~15fps to 30-60fps, depending on what was on-screen. And I think this might be due to rendering sprites and lighting, so I may check into that tomorrow.

It's a bit of a diversion from the core game loop task, but I think an important one. I was starting to get really frustrated with the slow/laggy performance when testing my mechanics, and this will hopefully make that less noticeable!


matsy's picture

Always nice when performance issues are that easy to find, and resolve!

dcfedor's picture

Yeah, these were definitely some of the easier sort. I'm not looking forward to the next time I have to do this, after all the low-hanging fruit is gone :)

Dan Fedor - Founder, Blue Bottle Games