Dev blog 107 - Porting Fun, Vol. 3
This post was written by Robert, one of our programmers.
Hi again!
Robert here, programmer at & founder of Room-C. At long last, it's my turn to write a blog post again! A while back, I wrote about porting the game to Linux and macOS.
In the meantime, we decided to expand into consoles as well. But rather than talk about consoles themselves, I wanted to make an overview of all the great things that came out of the console porting efforts that made the PC/Mac version better, too! So, here goes:
But let me break down a few techniques we used!
Phew, that was a lot! Hope you enjoyed this overview. For any questions, feel free to join our Discord server.
Robert
Hi again!
Robert here, programmer at & founder of Room-C. At long last, it's my turn to write a blog post again! A while back, I wrote about porting the game to Linux and macOS.
In the meantime, we decided to expand into consoles as well. But rather than talk about consoles themselves, I wanted to make an overview of all the great things that came out of the console porting efforts that made the PC/Mac version better, too! So, here goes:
- Gamepad support
Well, duh! :) Can't have a console port without them. But I daresay, after several iterations, we got the gamepad controls to a point where it's quite nice to play with a controller even on PC/Mac. - UI improvements
There's a couple of big things that happened here.- Dynamic UI scaling
We knew we wanted to support resolutions like 1080p and 4K. So instead of just keeping the UI tiny and small on 4K, or scaling it up naively to cause blurry text, we made sure to support this properly and deliver crisp, legible UI and fonts on any resolution. - TV mode
But what if you play the game on a TV? For me at least, my TV is a lot further away from my eyes than my PC monitor. So even though the TV is bigger, the picture still seems smaller. And that means we had to upscale the UI even further, to make sure our text-and-UI heavy game is legible even when played from the couch. How does this benefit PC players, you ask? Well, there's Steam's Big Picture mode, which we were able to add support for easily. - UI clutter reduction
Last but not least, simply scaling the UI up revealed design problems. We had a lot of stuff on our tooltips! Too much for it all to fit, in fact. It took some creative thinking to reorganize and simplify, to reduce clutter while still being informative. That alone was a major improvement for all players anywhere!
- Dynamic UI scaling
- Optimizations
Now, this is a huge topic. In short, we were able to get pretty big gains in performance, while also reducing memory usage quite a bit. On top of that, we made sure there are no performance swings - all areas of the game, even during spell casting and wrecking the destructible environment - retain consistently good frame rates. This means the game now runs better and smoother than ever, even on older PC/Mac hardware.
But let me break down a few techniques we used!
- Code optimization
Good ol' profiling your code, looking for bottlenecks. Rewriting slow functions, getting a few FPS here, a few FPS there. Consoles helped here because they amplify problems. What might be a tad slower on PC, ended up being noticeably slower on consoles.
The hottest topic here was probably AI, which on most PCs would take no more than a few seconds, maybe five at most, per enemy. On consoles, you'd be waiting up to 15 seconds per enemy!
Through careful optimization, both in code and in AI config, we were able to reduce AI think times by 50-70%, so again, even on PC/Mac, it should feel much faster and smoother. - Texture optimization
Oversized textures mostly have to do with wasting precious memory, but they also affect performance. By "oversized", I mean using textures which have too many pixels for the size of the object on the screen.
Imagine a small rock, which uses up a small area on the screen, say 100x75 pixels. It makes no sense to apply a 2048x2048 texture to it, right? You can't even see those pixels.
So, I created a tool in our Editor to visualize texture density in shades of gray. The lighter the image, the higher the density. That made it easy to spot light (dense) spots in any scene, at a glance. - Mesh optimization
With meshes, it's a similar story. Why waste thousands of vertices on an object which only takes up a small area on the screen? Also, excessively dense meshes affect performance more so than memory, so there were big gains to be made.
However, decimating a mesh is not as simple as downsampling a texture. Luckily, our Editor already had a powerful QEM (Quadric Error Metric) mesh decimator built-in.
But - we have upwards of 800 unique meshes in the game. How do we process them all, making sure we decimate each one just enough, but not too much to introduce visible artifacts? Well - we write a tool, of course. :) And so, I wrote an automated tool which tries to guess an appropriate decimation factor, applies the decimation, and takes screenshots of the mesh from all six cardinal directions (north, south, east, west, up, down). If the before and after screenshots don't differ by more than some percentage of pixels (say, 3%) - the decimation factor is accepted.
Then it's a simple matter of trying an increasingly or decreasingly aggressive decimation factor until a sweet spot is found. Voila! You let the tool run for a day, and you have meshes guaranteed to use up as few vertices as possible without visible artifacts.
This gave us FPS boosts of up to +50% on lower end hardware. - Shader optimization
We have a custom terrain system which allows level designers to directly paint layered materials on the terrain, such as grass, mud or rock, via a special mask texture. The shader then applies these materials and the transitions between them, using the mask.
We were able to reduce memory usage quite a bit by compressing the mask, and optimizing the shader itself. This also made loading times faster, not to mention rendering itself. - Misc optimizations
Finally, there's lots of things which don't fit any of the big categories. For example: destruction effects! We noticed these can cause performance drops, and identified the issue to be physics-engine-related, due to spawning large numbers of inter-colliding physics-driven objects. Rather than just reducing the number of said objects (which would make the effects look flat), we found ways to reduce the impact on physics computations without sacrificing the number of visible object parts. So much so, that performance drops due to destruction FX are now negligible on any platform.
Phew, that was a lot! Hope you enjoyed this overview. For any questions, feel free to join our Discord server.
Robert