OpenLoco v25.09 is out!
This is a major milestone of a release. We have finally implemented every single function from the original game. This means that, apart from graphics and sound assets, OpenLoco is now a complete reimplementation of the game! Talking of graphics assets, this release also contains a whole bunch of new OpenGraphics objects as well.
For a summary of changes, please find the changelog on GitHub.
Changes and Features
Rotate Company Headquarters
@LeftOfZen was testing some refactoring to company headquarter ghosts, and noticed that you couldn’t rotate them from the UI. It’s a simple change, but adds to the consistency of the UI.
Improve Zoom to Cursor
Zoom to cursor was implemented many years ago, originally by @AaronVanGeffen on the OpenRCT2 project. Recently, on the OpenRCT2 project, @mixiate vastly simplified and improved the accuracy of the function. Aaron has now backported the improvements to the OpenLoco engine. It’s nice when we can share some code between the projects as the two engines are very very similar.
Disable Currency Selection in Title Screen
@LeeSpork found it odd that you could change the currency on the title screen. It didn’t do anything, but it was odd. Now it’s been disabled. It’s not too surprising this occurred; the title screen is basically displaying a save game like everywhere else. We should really get round to making our own title screen, like we have done for OpenRCT2.
Reimplementation
Implement Create/Remove Road Mod Game Command
These game commands are mostly useless as they’re only used to remove/add the catenary wires on tram tracks. I’m not sure why you would want to remove these wires, as trams require them to run. Either way, the commands existed in the base game so we have also implemented them. There is a huge amount of code for these commands, as they require iterating all connected tram tracks to remove/add the wires. One of the reasons to implement these commands is that their iteration code might be useful for other future features.
Implement Remaining Vehicle Update Functions
There weren’t many vehicle update functions left, but some of them were complex. The most complex were the road vehicle update. In particular was the function that calculated whether the vehicle should try overtake another vehicle. It does this by looking ahead for a slower/stopped vehicle and then lays out a chain of routings to change lane, overtake, then merge back. It did help finally resolve a bunch of unknowns I had with how the routings system worked. Other vehicle functions were the place down vehicle function, which is surprisingly similar to the overtake function, involving looking ahead for a clear section of road/rail to place, then laying out a chain of routings.
At some point I should really write a big blog post on how the routing system works, as it is complex at first sight, but easy enough to understand once you get stuck in.
Implement Update Traffic Handedness
I had left this function to the very, end as it did a bunch of moving about of memory that I didn’t want to implement. Instead, we can just duplicate the memory and reference the correct one based on traffic handedness. But I could only do that when all vehicle update functions were implemented. At the same time, I fixed an original bug where when road vehicles calculate lane occupancy if they are overtaking it would access invalid memory (company AI memory, to be exact). This could cause the check to return unexpected results. I’ve fixed this by ignoring overtaking, but I’m not 100% sure that that is correct. It is at least deterministic now. When overtaking, we should perhaps just say all lanes are occupied. Either way, perhaps something people should test and let us know if its a bit wonky.
Remove All Hooks
With all the functions implemented it was time to finally remove all the hooks into the original game. We are now free to modify interfaces to our hearts content, giving us lots of flexibility for new features. We aren’t fully standalone from the original game yet, as we still share some memory addresses, but it wont take long to change those.
With all the hooks gone we can also start getting x64 builds working, and perhaps even ARM builds.
OpenGraphics
We’ve forgotten to continue posting about OpenGraphics updates but they have been happening over the last few months; there are 24 new objects since we last posted in March about this, and they’re all by just 2 contributors, @shusaura85 and @glenjimen! Here’s a short summary:
Vehicles
@glenjimen figured out how to set up a modern Blender workflow and started generated
some gorgeous vehicles, which all have twice the rotation frames as the vanilla objects
so the look extra smooth in-game. I’ve highlighted the new vehicles/sprites in red in
the below image. Starting at the bottom, we have OG_GRAINHP2.dat
replacing GRAINHP2.dat
,
then OG_GRAINPH1.dat
replacing GRAINHP2.dat
and finally in the top right, we have
OG_GOODS1.dat
replacing GOODS1.dat
:
Road Stations
@shusaura85 replaced all of the vanilla road stations as well as the bus stop with OG versions:







Tunnels
@shusaura85 replaced TUNNEL1.dat
and TUNNEL2.dat
with OG_TUNNEL1.dat
and OG_TUNNEL2.dat
,
respectively. Vanilla shown on the left, OG on the right:
Hill Shapes
The hill shapes object, HS1.dat
, which controls how the vanilla terrain generation works,
was replaced with OG_HS1.dat
by @shusaura85. The new file has many more terrain shapes and
much more natural shapes at that, generating some very nice terrain with vanilla generator.
Vanilla is shown on top here, and the OG replacement on the bottom:
Streetlights
@shusaura85 replaced SLIGHT1.dat
was replaced with OG_SLIGHT1.dat
:
Land
@shusaura85 replaced all of the land types with OG versions:
Cliffs
Land objects have associated cliff objects, so these were also replaced by @shusaura85:
Snow
@shusaura85 replaced SNOW.dat
with OG_SNOW.dat
:
Water
@shusaura85 replaced ` WATER1.dat with
OG_WATER1.dat`: