OpenLoco v25.10 is out! This release contains fixes for crashes that could occur when secondary viewports moving into view, such as with the news window. In the background, work on separating our codebase from the vanilla game’s memory space also continues.

Revert drawing widgets in relative positions (#3305)

In previous releases, we’ve been reworking how the in-game windows and their widgets are organised. Notably, this May, we changed how these are drawn. Unfortunately, this has turned out buggier than we had originally expected. While we made several attempts to fix the issues, they have proven non-trivial to address.

As it stands now, it seems we were a bit too eager for these changes to be made, while the drawing engine isn’t as separated as much as we would like. We therefore made the decision to revert the changes from earlier this year, and work on refactors to make them actually meet underlying assumptions in the —hopefully— near future.

Fix keyboard shortcut assignment (#3309)

Over the course of recent months, we reworked part of the input manager. This component is responsible for processing keyboard and mouse input events from the OS, and delegates them to the relevant game components. One of these delegates is the shortcut manager. For the previous release, we received reports that it was no longer possible to bind keyboard shortcuts that used modifier keys (e.g. ctrl, shift). As it turns out, the two parameters involved with shortcuts (charCode and keyCode) had been accidentally swapped! Because both parameters use a uint32_t type, the compiler was fine with it. For now, the bug has been fixed, but you can bet we’ll switch to stronger types for these in the future…

Bump sfl library (#3310)

In C++, we have the luxury of a standard library that provides various dynamic container data types, e.g. std::string or std::vector. These provide automatic RAII-based memory management, which means we don’t have to manually allocate or free the memory involved. For developers, this is generally advantageous over more lower-level languages like C. However, in certain situations, there is a fair bit of runtime overhead involved with (heap) memory allocation. Sometimes, you’d just like to use a container in static memory, or even stack memory. Enter sfl. This library provides ample well-tested containers that don’t require runtime memory allocation, or only require it under certain conditions. We’ve started to use it in various places with notable performance improvements! If you’re doing (game) development yourself, it’s definitely worth a look.

Continued loco_global integration efforts

As of last month, we have finished reimplementing all C++ functions, but our reimplementation still refers to vanilla 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. Such wrappers allowed us to start using strongly typed C++ from the get go, instead of having to rely on raw addresses for longer.

Many of the remaining loco_globals can be ‘integrated’ into static memory space as-is. However, extra care needs to be taken when more than one compilation unit refers to the same bit of memory space. For example, certain windows remember where the last ‘ghost’ element was placed. However, some game commands update those very same memory addresses. In such instances, this needs to be reworked, so there is only one real memory owner.

At the time of writing this blog post, 351 loco_global instances remain, across 95 files. Hopefully, by the time the next release turns around, we will have made ample progress in rewriting them.

Updated: