Optimizing Atrio

Hi everyone, Stephen here with another progress update. We are closing in on 1.0 and will be picking a launch date within the next month. As such, our priority has shifted to increasing performance on both pc and Xbox. With our target being Xbox One S (a pretty old console), we have our work cut out for us... but that's great for PC users! If you have a decent graphics card (RTX 2080's anyone?) we're expecting Atrio to run buttery smooth for you. Kyle and François have been optimizing it for approximately 3 weeks, and I'd like to dive a bit deeper into how we are making bigger gains. Here's where we've seen the best gains so far: [h1]The overview[/h1] [h3]Increasing In game FPS[/h3] - Dynamically turning on and off Animators depending on if they are on screen - Culling the Tilemap (our floor environment) - Sleeping automation pieces that aren't being used or active - Lowering the rate at which we do physics calculations - A more optimized search for food algorithm for creatures - Creating a more optimized health-component for all buildings and creatures that have health - Cleaning up slow LINQ queries (tbh, I don't know what this is. I'm just relaying what Kyle told me) [h3]Speeding up load times[/h3] - All harvestable objects were getting loaded on start. We've updated the system to only load harvestables in use, or in sight of of the player. - Better texture/memory packing - Downgrading texture resolutions on textures that were too big (and you couldn't notice a difference when downgraded). All of these have contributed to huge performance gains while playing Atrio. [h1]A deep dive into our 'Food Searching' algorithm[/h1] We usually keep these blogs pretty high level, but I know there's at least one technical nerd like us who would appreciate a deep dive, so we're going to cover what we think is the most interesting optimization of the last couple of weeks. Here's how we gained some frames when searching for food. [h3]Introduction[/h3] The entire world in split into 1m x 1m tiles. [img]{STEAM_CLAN_IMAGE}/35579864/4b3e47020993203fa1b76daf88d75d76a1af4068.png[/img] Only one item or factory can occupy a single tile at a time. Even our visuals (the floor environment) are split up into 1x1m tiles. Everything runs off of this tile system, from deciding what footsteps sounds to play, to what item is on that tile. There's an "invisible" layer that we keep track of behind the scenes, that we call the automation layer (again, still using the 1x1m tiles). It runs without any visuals, but manages how the items move in the game. When you're off on another part of the world, we hide all the visuals and just let this automation layer run. This saves a lot of frames and is essential to running the game at a decent fps. [h3]Searching for food[/h3] All of the creatures in the wild roam around searching for food. If there's something delicious to snack on, they'll walk over and munch on it. The problem is, there's a lot of tiles. [img]{STEAM_CLAN_IMAGE}/35579864/8f4051de71b350e068a11ef424dbcb143ccb0ac2.png[/img] [img]{STEAM_CLAN_IMAGE}/35579864/66d3d39ad9ec284b44392dee088054de2959d222.png[/img] Approximately 212,000 tiles, to be specific. Imagine we had a big list that contained every tile (we refer to this as an [url=https://www.youtube.com/watch?v=OnPP5xDmFv0]array[/url]), [img]{STEAM_CLAN_IMAGE}/35579864/ed66ddbe0b8571fb863662a68ebbe909626dadd9.png[/img] and we wanted to know which ones have food on them. We'd have to check each and every tile, every frame! This would destroy even the fastest computer. So, we use a [url=https://computersciencewiki.org/index.php/Dictionaries]dictionary[/url] to track the set of "useful" automation tiles that contain food! We only add tiles to this dictionary whenever they're useful. When food gets eaten, we remove it from the dictionary. [i]*Note: You could use an array instead of the dictionary, but we're using the dictionary for other purposes not described in this post. [/i] [img]{STEAM_CLAN_IMAGE}/35579864/d02d7a5251c8cb15340d5fe1f4e98a3391252e08.png[/img] So now instead of 200,000 tiles, we maybe have 500. Problem solved? well, not quite. [h2]The problem with dictionaries[/h2] The problem is "accessing" the info of a single tile is quite slow. In fact, if we knew the exact position in the large array (example, if we wanted info on tile 197,201), its much, much faster. So how do you know what tile you want? In some cases you don't. That's when we use the dictionary. We can go "Hey check all the tiles and tell me which tiles have food, and I'll pick the closest one". But sometimes we know that a position x,y there's food (without going into too much detail about how our underlying system works). Using a little bit of sneaky math, if we know the x,y coordinates of the tile, we can easily calculate what position in the list we want to access. Unfortunately, maintaining a list of ~212,000 tiles does take a a lot of memory (32 MB in RAM to be specific) but we now get nearly instant access time. Game dev is about trade-offs. [h2]OK, so how much faster is this? [/h2] The results speak for themselves. In a single frame (if your game runs at 60fps, a frame will happen 60 times in one second), [b]Total before: 12.98ms[/b] to look for food in one frame for a deer [b]Total after: 5.78ms[/b] to look for food in one frame for a deer Now imagine doing that 60 times, that's a MASSIVE improvement! Here's a shot of our profile tool showing the performance [img]{STEAM_CLAN_IMAGE}/35579864/bb7c176be6016e55bb4787cf98eadc38cc593398.png[/img] [h1]The grande finale.[/h1] That was only ONE optimization that we made. With all of the optimizations combined, on xbox One S: [b]Before: 10-12 fps After: 24 fps[/b] We managed to achieve this in a three weeks, so hopefully we continue to see great gains in the future. We can't wait for you to try these out in a future updates, and playing the full version when we reach 1.0! Stay tuned for some content updates, Stephen & The Isto Inc Team