OpenLoco v24.07 is out! All changes under the hood this month, with one or two bug fixes.

For a complete summary of changes, please find the changelog on GitHub.

Switch to Static Libraries (#2545)

When creating programs you often have a choice between dynamic linking or statically linking. If you statically link you have only the one binary file, if you dynamically link you’ll have multiple binary dynamic link libraries (.dll / .so) and your binary. The idea of dynamic linking is that if your system has these libraries already installed system wide then you don’t need to ship them with your binary. This allows for patching vulnerabilities in third-parties without having to update your main binary file. The disadvantage is that you don’t know the version that the system will have. There are other advantages/disadvantages of static/dynamic linking but its outside of the scope of this blog. OpenLoco on Windows and Linux up until now had gone for dynamically linking all third-party libraries. For Windows we package all the third-party libraries with the application which should mean we don’t have any version issues.

With the v24.06 release it was found that OpenLoco would crash on startup of the audio engine. The audio engine is powered by OpenAl-soft. When we replaced the OpenAl-soft .dll with the v24.05 version there was no crash. We hadn’t changed the version of OpenAl-soft but what had changed was we compiled with a more modern MS VC++ compiler. The new compiler used a newer C++ standard library version. The one .dll we don’t ship with OpenLoco is the VC++ library file msvcp140.dll. Usually if you have a mismatch between what was compiled and what is installed system wide you’ll get a failure to start your program. Unfortunately though in this case it could still start-up on older versions of msvcp140.dll but it would crash if it tried to create a std::mutex. OpenAl-soft happened to use a std::mutex in its startup function causing the crash.

We had a number of options for how to fix this:

  • Ship the MS VC++ redistributable installer with OpenLoco and install it on use
  • Inform Users to install the latest MS VC++ redistributable
  • Switch to statically linking MS VC++

As we don’t currently have an installer for OpenLoco shipping the redistributable would be a little odd and our users would probably not run the installer. Informing users to install the latest would probably be forgotten and lead to cryptic bug reports. That left the final option of statically linking. So that is what we have done to resolve the issue. The neat thing is that now we only have the one .dll file and the one .exe file (OpenLoco.dll, OpenLoco.exe) in the zip file.

Game Commands: Place Vehicle (#2508)

A little quiet on the game commands front this month. I implemented the main place vehicle game command. There wasn’t much of note in it that wasn’t already known, but now it’s all running in C++, making it easier to extend in the future.

Implement Graphics Engine Consumer Functions (#2513, #2517, #2524)

With the whole graphics engine implemented, we really want to break it out of the main library and start improving it. Before we can do that properly we need to have implmented all users of the graphics engine. This month, I implemented the draw vehicle overview, draw vehicle in-line and draw road preview functions. There isn’t very much at all now that is left to implement that consumes the graphics engine, so hopefully very soon we can start the improvements.

Implement Misc Setup Functions (#2515, #2518, #2519)

@ZehMatt implemented a number of setup functions this month. They aren’t terribly exciting, generally just zeroing out certain memory on scenario start, but its all important work to reach a state where we are standalone.

Graphics Engine Improvements (#2516, #2530, #2533)

@ZehMatt the graphics engine expert made a few further improvements to the graphics engine this month, mainly tidying things up after last months big re-work.

Use TilePos2 for Heightmap Access (#2511)

@ShuraxN continued his contributions from last month. this time tidying up how we access the heightmap in the Scenario Editor. When we implemented these functions, we hadn’t decided what fundamental type we were going to use for (x, y) coordinates, so made a new type just for heightmap. Later on, when we had decided on TilePos2, no one had gone back to the heightmap code and made it use them. That is finally addressed and we can sleep happy knowing the codebase is a tiny bit more consistent.

Company Update Functions (#2528, #2484)

On Discord, @Phobos2390 asked the question:

Has the actual calculation of performance index been ported?

The answer was no, but could easily be done as we knew which function it was. So I decided to go and implement it. @Phobos2390 was wanting it implemented so that he could make a tool to identify why you have the rating you have. With it now implemented, we are looking forward to what @Phobos2390 comes up with.

Animation Update Functions (#2531, #2536)

Whenever there is an animation on a tile element, there is a corresponding animation update function. This function handles invalidating the screen and updating the frame of the animation. This month we finished off the last of the animation functions: Signal, Level Crossing, Airport, Port. It has helped understand more of how the Airport and Port object format works. So if you are working on a custom one of those objects I suggest having a look at the implementation.

Updated: