OpenLoco v25.11 is out! This release introduces some neat quality-of-life features to the game, as well as several bug fixes. More importantly, we continue our efforts of reworking the game’s memory space, and the OpenGraphics project is also seeing big progress. Let’s dig in!
Prevent accidental cargo removal
New contributor @luciditee got back into the game recently, and fell into the age-old trap where changing vehicles would remove all of their cargo. Never again, they declared. And so, #3323 was filed, which adds a confirmation dialog to the vehicle component tab. This means changing vehicle/wagon order now prompts for confirmation if the vehicle is currently transporting cargo. A similar prompt is displayed when refitting a vehicle to transport different cargo, as can be seen in the screenshot below.

Rework remaining legacy config into modern config
Since we started work on OpenLoco, the game has always had two config files: one for the ‘new’ options OpenLoco introduces, and one for the vanilla game’s settings. Over time, some variables were moved over (e.g. shortcuts), but it was generally a matter of two worlds.
The main reason for this was that we were still dealing with vanilla game functions that we hadn’t yet reimplemented in C++. These functions were still expecting to be able to read from the old config location! As of v25.09, all functions have been reimplemented, though. To be fully implemented, we have to move on config-wise as well.
As of #3323, all config variables are now
stored in the openloco.yml file. You can find this in the OpenLoco folder in your user profile
(in Windows, this is AppData\Roaming). Go take a peek!
Show AI allocations as regular ghost elements
Despite their flaws, some people like playing the game with AI companies enabled. However, sometimes, there is considerable delay between the AI planning a route and actually building it. In the mean time, the planned route is reserved using invisible elements. This may be frustrating, as players aren’t allowed to build over them.
In #3270, a new option was introduced to make these planned routes visible as ‘ghost’ elements, much like how players’ construction tiles show up. Note that this option is off by default, as we consider it a bit of a cheat. Below are a few screenshots of what it looks like.


Merge sound and music tabs in options window
This month, @LeeSpork continues their quest of making the OpenLoco jukebox experience as smooth as possible. A longstanding request was to make the music options, and therefore the music volume settings, accessible from the title screen. In #3326, the tab was revealed on the title screen. It was quickly followed by #3352, though, which merges the relatively short ‘sound’ tab into the ‘music’ tab, which is now called ‘audio’. There are already plans for separate volume controls, e.g. for music and sound effects, so watch this space!

Disallow interfering with competitor’s roads and road stations
@LeeSpork discovered that it was possible for players to interfere with competitors’ roads. They quickly filed patches to prevent competitor road removal (#3335), as well as competitor road station replacement (#3336). Nice catch!
Add platform and arch to title screen
As we previously mentioned, as of v25.09, all game functions have been reimplemented in C++. We’re not quite at the point where we can make fully working 64-bit builds (#3288), however, we realised this would be a good time to add platform and processor/arch information to the title screen. With #3328 merged, you can now find this info in the lower-left corner, just below the usual version information.
Catch FileStream exceptions when loading from CLI
This may be a bit obscure, but have you ever tried to load OpenLoco with command-line arguments?
As long as you’re passing arguments the game understands, with files that exist, the game
is happy to process everything. If it doesn’t understand an argument, the game assumes you’re
trying to load a file, though. If this ‘file’ doesn’t exist, the game would throw a FileStream
exception, but not catch it, crashing the game. This is now mitigated by
#3363, letting the game instead
just log a warning to the console.
Rename a bunch of things
Over the course of the literal years we’ve worked on OpenLoco, some parts of the codebase have basically not been touched since they were initially implemented. With the benefit of understanding the codebase better, some things could be named better, in retrospect. This month, some community members expressed interest in understanding the path/signal/routing functions, for example. To make them easier to understand, @duncanspumpkin has renamed a bunch of variables (#3350).
Following this example, @AaronVanGeffen set out to rename several sub_ functions, that had
not received a new name in the reverse engineering process
(#3359).
Similarly, one of the first game commands we implemented was the LoadSaveQuitGame
game command. We now understand this better, leading us to rename its arguments
(#3367).
Big loco_global integration extravaganza
As we previously mentioned, as of v25.09,
all game functions have been reimplemented in C++. However, we still mirror the vanilla game’s
memory space in several places. As often talked about in previous blogs, this is done with
loco_global instances. When the project started off, these were introduced as a high-level wrapper
around a particular memory address. We’re now at the point where the remaining wrappers
can be reworked. As you might imagine, this is quite a bit of work, still.
Fortunately, this month, we’ve seen a lot of team effort to get there. To illustrate,
while our v25.10 release still had 342 loco_globals, this month, we’re down to just 157 of them.
This is great progress! Unfortunately, many of the remaining ones are less trivial to tackle…but we’ll get there!
We usually list PR numbers in our dev log sections, however there were 20 PRs just for
loco_global removal this month! If you’re curious to see what such PRs look like,
you can find them on GitHub. Follow
this link
for a list of the relevant PRs.
OpenGraphics
Over the last 2 months we’ve have 11 new objects added to the OpenGraphics repo, and 2 updates to existing ones!
Roads
- @shusaura85 replaced
ROADRGHwithOG_ROADRGH:

Bridges
- @shusaura85 replaced
BRDGBRCKwithOG_BRDGBRCK:

- @shusaura85 replaced
BRDGWOODwithOG_BRDGWOOD:

Land/CliffEdge
@hibiii added a new land type called OG_VOID, as well as the corresponding CliffEdge for it, OG_LSVOID:

Vehicles
@glenjimen replaced CATTLE1 with OG_CATTLE1:

@glenjimen replaced GOODS3 with OG_GOODS3:

@phosporus551 replaced CL71 with OG_CL71:

@phosporus551 updated OG_RE441 with new sprites from a new rendering pipeline:

@phosporus551 replaced RE442 with OG_RE442:

@phosporus551 updated OG_656 with new sprites from a new rendering pipeline:

@phosporus551 replaced 460 with OG_460:

@phosporus551 replaced EWIV with OG_EWIV, as well as the corresponding EWIVDT with OG_EWIVDT:
