OpenRCT2's v0.4.26 behind the scenes
Our game is an open source re-implementation of RollerCoaster Tycoon 2 with many added features and fixes added over the past 11 years1 which surely made it gain some weight. That doesn’t mean we still don’t want it running on low-end systems2 so LRFLEW went for a ride and applied a few semaglutide pens to some files we generate making them up to 30% smaller while compressing and decompressing up to 12 times faster!
Let’s dive into such an amazing change, shall we? If your answer was: “Hell no, you clown, I’d rather read the pull requests myself”, here you go:
- Refactor Compression and Streams, and Add IStream Direct Interface - #24701
- Don’t Double-Compress Park Chunks in Replay File - #24728
- Use ZStandard Compression for PARK and PARKREP Files #24734
Here we go 🎢
Compression & OpenRCT2
When you’re playing there are multiple situations where we might create a file, here are some of them:
- Creating game saves/scenarios (
*.park
) - Recording a replay (
*.parkrec
) - Crashing the game3 (
*.sad
*.dmp
and friends)
They each have different constraints for speed and size: replays are usually done on demand and people can wait for longer for them to be saved, especially because they can be bigger, whereas you don’t want the game stuttering every time it is auto-saving, so tuning the compression and decompression is a tough job! For this work, LRFLEW tackled the first two items, since they are the most common.
Compression on v0.4.25
At this version we were using zlib as our compression library. It is a battle-proven algorithm, around since 1995 and effectively a de-facto standard which you can easily find built-in into many operational systems and that is likely being used right now by more than one of your running applications.
It continues to be so pervasive even though it is 30 years old because many of the competing implementations that arose since then would either achieve higher compression at slower runtimes, or faster execution at the expense of less compression.
Compression on v0.4.26
Many big-tech companies have poured endless resources on developing better compression algorithms, as sending or keeping data around can become quite expensive. Some of them have open-sourced these technologies, with Google opening up Brotli to the world and Meta releasing Zstandard (aka Zstd). While the former can achieve amazing compression rates, it usually is at the expense of running times and since it would not be a panacea for the usages outlined in the beginning of this section, we settled for the latter.
Here is how ZStandard fares against zlib in terms of speed and size to compress a file:
And this is how much faster it can decompress these files:
(Images taken from Zstd website)
Results
These algorithms are very customizable and you can pick a higher level of compression to get a smaller resulting file if you’re willing to wait for longer. On Zstd these levels range from 1 to 22, so there was a lot of measuring and tuning to do. Thankfully LRFLEW did that meticulously and reported back, here’s a table summarizing it all:
Compression Situation | Zstd level | Size Improvement | Speed Improvement |
---|---|---|---|
Automatic Saving | 4 | 12.5% smaller | 12.8x faster |
Manually Saving | 7 | 20.5% smaller | 4.5x faster |
Creating Replays | 18 | 28.0% smaller | 1.7x faster |
Note: Decompressing became roughly 3.5x faster across the board regardless of the situation.
For all we know, everyone should see OpenRCT2 occupying less space on your drives from now on, as well as creating and opening these file types faster. It’s what we call a perfect “drop-in replacement”!
Compressing existing saves
If you want you can even compress saves you haven't been playing lately, by using OpenRCT2's executable and doing:
openrct2 convert source_park_path [destination_park_path]
This will open the save and recompress it with the new algorithm on the destination path (or in the same file if you don't provide a destination), generating up to 50% space saving. If you're really a *.park
hoarder you can optionally provide --compress-level X
where X ranges from 1 to 19 for further savings.
Acknowledgments
If it is still not yet clear, give a huge shoutout to LRFLEW for chasing this. Not only he had to write comprehensive changes to the codebase to achieve it, but did so with patience of writing detailed reports of the findings, separating it into smaller pull requests where applicable and monitoring potential fallout after merge to do hot fixes. Welcome back, friend!
How can I help?
- Play OpenRCT2 and have fun
- Spread the word of our game
- Support the developers that have GitHub Sponsor programs turned on
- On the compressing domain, we can still investigate:
- Whether we can also apply Zstd to crash reports
- If we want to start compressing other assets like object or parkpatch JSONs
- Whether we want to release assets from Open* repositories in another format, and as such make it faster to download during build, potentially speeding up development and CI/CD checks
- Open up an issue or pull request if you find another opportunity!
-
Yes, it is that old, soon it’ll be able to get a driver’s license in some countries.↩︎
-
We found out recently that someone had ported it to ArkOS to run on things like R35S.↩︎
-
We’d hope this would only ever happen to your coasters, but unfortunately it is not true.↩︎