Code Cleanup and Performance

Hey Folks! I decided to do a bit of code cleanup and performance optimizations today.

I started out fixing a few bugs, and managed to fix a pathfinding issue I introduced fixing another path bug. So far so good, but as I transitioned into testing the plot system again, I realized I was dreading loading the full game. It takes close to 13 seconds to go from the main menu to a fresh game world, and several seconds to just load a flyable ship. Furthermore, whenever AI is moving around the ship, there is a ton of hitching and stuttering.

It was really starting to impact my ability to iterate, so I dug into why.

One of the first things I found involved loading of images. Every visible object in the game is composed of one or more tiles, and as it turns out, each of these tiles had some bloat in the initialization code. Each tile was loading a PNG from disk when created, and that could happen thousands of times when a scene is loaded. Furthermore, that PNG was already assigned elsewhere!

Yanking that out shaved a few seconds off of load times.

Loading PNGs still seemed to be bogging me down, though, so I looked into why. In a similar situation, every time the game needed an image, it was loaded from disk. The ideal way to handle this is to only load images once and pool them in memory for reuse later. (Ideally as atlases, but that's for another day.)

A quick few lines of code got rudimentary image pooling setup, and now I could reuse already loaded images. This cut my new game load times in half!

I dug a bit further, but I started to hit harder earth, so to speak. It was getting down into the code that loaded individual ship items, and I think the obvious fix here is to just load less stuff until absolutely needed. This means a pretty substantial change to how the game loads off-screen things. And quite a few of today's discoveries come back to this. So I'll be looking into this more soon.

I poked around a few other areas of performance lag, and found another one when the user selects an object in game. First, I found that the bracket itself was storing a reference to a transform, but every time I used it I would be using GetComponent to get the CondOwner class from it. So I just cut out the middleman and stored a ref to the CondOwner, and removed a bunch of redundant GetComponents. A minor gain, and small code simplification.

A more significant improvement involved the way UI populated with NPC data when they were selected. The code was setup to clear the existing UI of all text whenever a new condition was added to it, which basically performed a series of useless add/remove loops to show some text. I simply changed the function to accept a "suppress updates" flag in cases where I'm adding a bunch in a loop, and now I can just update at the end. That reduced the apparent lag when selecting things.

After the above, it was time to focus on some of the hitches when AI steps through doors and does other interactions. I'm still working on this, but it appears there are some ~0.4 second hitches when de-queue-ing interactions from an AI/object, sometimes multiple such hitches stacked-up. I haven't narrowed down why yet, but I'm thinking it might be redundant pathfinding checks, or maybe a redundant GetReply check.

Hopefully, if I can get some of these sorted out, I can focus more on what's happening in-game instead of wondering why everything stops and starts so much!

Tags: Ostranauts