<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://openloco.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://openloco.io/" rel="alternate" type="text/html" /><updated>2026-04-15T19:33:56+00:00</updated><id>https://openloco.io/feed.xml</id><title type="html">OpenLoco</title><subtitle>An open source re-implementation of Chris Sawyer&apos;s Locomotion</subtitle><entry><title type="html">OpenLoco version 26.03.1</title><link href="https://openloco.io/news/2026/04/openloco-v26.03.1.html" rel="alternate" type="text/html" title="OpenLoco version 26.03.1" /><published>2026-04-01T09:00:00+00:00</published><updated>2026-04-01T09:00:00+00:00</updated><id>https://openloco.io/news/2026/04/openloco-v26.03.1</id><content type="html" xml:base="https://openloco.io/news/2026/04/openloco-v26.03.1.html"><![CDATA[<p>OpenLoco v26.03.1 is out! Yeah, only one day after v26.03. Remember how we announced we had
<a href="https://openloco.io/news/2026/03/openloco-v26.03.html#improved-entity-invalidation">improved entity invalidation</a>?
Turns out there was a gaping bug that would occur when the viewport is rotated. Oops.
@ZehMatt quickly patched the issue, but obviously we wish we had caught this before the release.</p>

<p>Please find the <a href="https://openloco.io/download/">download</a> on our website, or read the
<a href="https://github.com/OpenLoco/OpenLoco/blob/v26.03.1/CHANGELOG.md">changelog</a> on GitHub.</p>]]></content><author><name>Aaron van Geffen</name></author><category term="news" /><summary type="html"><![CDATA[OpenLoco v26.03.1 is out! Yeah, only one day after v26.03. Remember how we announced we had improved entity invalidation? Turns out there was a gaping bug that would occur when the viewport is rotated. Oops. @ZehMatt quickly patched the issue, but obviously we wish we had caught this before the release.]]></summary></entry><entry><title type="html">OpenLoco version 26.03</title><link href="https://openloco.io/news/2026/03/openloco-v26.03.html" rel="alternate" type="text/html" title="OpenLoco version 26.03" /><published>2026-03-31T14:30:00+00:00</published><updated>2026-03-31T14:30:00+00:00</updated><id>https://openloco.io/news/2026/03/openloco-v26.03</id><content type="html" xml:base="https://openloco.io/news/2026/03/openloco-v26.03.html"><![CDATA[<p>OpenLoco v26.03 is out! This month’s release focuses on moving to our (graphics) backend to SDL3,
as well as a rework of the audio engine. Some more cool new features have been in the works since last month,
but they haven’t landed yet this month. Please be patient for a while longer :-)</p>

<p>What follows is a quick summary of the new features and bug fixes for this month.</p>

<h2 id="migrate-codebase-to-sdl3">Migrate codebase to SDL3</h2>

<p>When implementing a game, programmers can choose to either target a particular operating system directly,
or use an intermediary layer that makes it possible to target multiple platforms in one go.
To this end, OpenLoco has made use of <a href="https://www.libsdl.org/">SDL</a> since the beginning.
Recently, a major new version of the SDL API was released, meaning old APIs were replaced and new ones added.
To make it possible to leverage the new functionality, we had to rewrite part of our codebase.</p>

<p>The majority set of rewrites was merged early in the month (<a href="https://github.com/OpenLoco/OpenLoco/pull/2882">#2882</a>),
followed by a series of improvements on display handling by new contributor @kevinz26
(<a href="https://github.com/OpenLoco/OpenLoco/pull/3671">#3671</a>). Nice!</p>

<h2 id="audio-volume-can-now-be-set-separately-by-channel">Audio volume can now be set separately by channel</h2>

<p>There are many different kinds of audio in Locomotion. It even includes a jukebox! Like Locomotion,
OpenLoco only had a single volume slider, grouped with the music options. Until this month, that is,
as now you can set a specific volume for each specific kind of audio
(<a href="https://github.com/OpenLoco/OpenLoco/pull/3678">#3678</a>)!</p>

<p><img src="/assets/img/26.03/volume-sliders.png" alt="Volume sliders" /></p>

<h2 id="vehicle-sounds-now-use-reverb-when-entering-or-leaving-a-tunnel">Vehicle sounds now use reverb when entering or leaving a tunnel</h2>

<p>Armed with a newly-refactored audio subsystem (<a href="https://github.com/OpenLoco/OpenLoco/pull/3678">#3678</a>),
@ZehMatt set out to add a new effect to the game: reverb! This is now used for vehicle running sounds
when they are in a tunnel <a href="https://github.com/OpenLoco/OpenLoco/pull/3678">#3678</a>. We think it’s a nice touch!</p>

<p>Here’s what it sounded like in v26.02:</p>
<video style="width: 90%; margin: auto" controls="">
	<source src="/assets/mp4/26.03/output-v26.02-clip.mp4" type="video/mp4" />
	<source src="/assets/webm/26.03/output-v26.02-clip.webm" type="video/webm" />
</video>

<p>And here’s what it sounds like in v26.03:</p>
<video style="width: 90%; margin: auto" controls="">
	<source src="/assets/mp4/26.03/output-v26.03-clip.mp4" type="video/mp4" />
	<source src="/assets/webm/26.03/output-v26.03-clip.webm" type="video/webm" />
</video>

<h2 id="improved-entity-invalidation">Improved entity invalidation</h2>

<p>Normally, tiles are ‘invalidated’ whenever elements or entities on them have changed, requiring them to be redrawn.
However, under some circumstances, e.g. when dragging a vehicle ‘ghost’ around, it was possible for a (ghostly) remnant
of the vehicle to stay behind. It seems we missed a spot, somewhere!</p>

<p>This was reworked by making the invalidation <em>implicit</em> in the entity’s <code class="language-plaintext highlighter-rouge">moveTo</code> call, rather than <em>explicit</em>.
@ZehMatt realised there was an optimisation here: sometimes, a tile was invalidated even if the vehicle hadn’t
actually moved (<a href="https://github.com/OpenLoco/OpenLoco/pull/3312">#3312</a>)!
This probably won’t lead to much of a rendering speedup, but it’s a nice bonus!</p>

<h2 id="news-settings-default-to-newspaper-style-again">News settings default to newspaper style again</h2>

<p>Last November, we reworked the <a href="/news/2025/11/openloco-v25.11.html#rework-remaining-legacy-config-into-modern-config">remaining Locomotion config settings</a>,
folding them into our own, modern OpenLoco config file. We missed an edge case, however.
For <em>new</em> config files, news settings were not initialised correctly.
Indeed, all news settings defaulted to <em>off</em>, rather than the newspaper style players have come to expect. Oops.</p>

<p>New config files will now get the right ‘newspaper’ defaults
(<a href="https://github.com/OpenLoco/OpenLoco/pull/3657">#3657</a>). Unfortunately, we can’t reset the settings
without affecting players with custom news settings, however. So if you’re not seeing news unexpectedly,
please check the news options in the messages window.</p>

<h2 id="new-widget-identification">New widget identification</h2>

<p>When a player interacts with an element in an in-game window, a so-called widget, you often want something to happen.
To do this, the input subsystem relays to the relevant window that a particular widget has been interacted with
in a certain way, so that the window can do what is expected.</p>

<p>Like Locomotion before it, OpenLoco handles this by using a numeric index. Using <code class="language-plaintext highlighter-rouge">enum</code>s,
the first widget in a window is assigned index <code class="language-plaintext highlighter-rouge">0</code>, the next index <code class="language-plaintext highlighter-rouge">1</code>, etc.
This is great if your widgets are sequential, but we would like to move to a
more declarative way of denoting the window layout. Suddenly, widgets are not so sequential any more,
meaning we need a new way to identify them. Enter <code class="language-plaintext highlighter-rouge">WidgetId</code>
<a href="https://github.com/OpenLoco/OpenLoco/pull/3560">#3560</a>.</p>

<p>Instead of simple <code class="language-plaintext highlighter-rouge">enum</code> sequences, <code class="language-plaintext highlighter-rouge">WidgetId</code>s are instantiated using a string, which is hashed to a number at compile time.
This means we still get something that’s easy for machines to compare with, while also making it possible
for interface design to be moved externally to the C++ internals. Something nice to look forward to.</p>

<h2 id="improved-assertions">Improved assertions</h2>

<p>Traditionally, in C and C++, programmers can use <code class="language-plaintext highlighter-rouge">assert</code> to denote what would otherwise be implicit
expectations in source code. For example, you might want to make sure that a particular thing never happens,
e.g. the sky shouldn’t be painted in a green colour, somehow. Such extra checks take time, though, so typically
<code class="language-plaintext highlighter-rouge">assert</code>s are skipped entirely in non-debug builds.</p>

<p>There are times when we <strong>do</strong> want things to fail, though, and when they do, preferably with a bit of
extra information. Enter our own assertion diagnostics
<a href="https://github.com/OpenLoco/OpenLoco/pull/3656">#3656</a>, courtesy of @ZehMatt.
These have the added advantage of saving the source location, so error traces don’t show the error handler
as the source of the error, but the actual location where the assertion was triggered.
Hopefully, these will help narrow down any pesky mistakes in the future!</p>

<h2 id="drawing-circles">Drawing circles</h2>

<p>Locomotion sported a necessary feature for new players: in-game tutorials.
While not really going into the nitty-gritty of the game, they helpfully covered the basics.
Unfortunately, though, they are simply a sequence of mouse pointer locations,
recorded separately for common screen resolutions at the time the game was released:
640×480, 800×600, and 1024×768. If these resolutions seem alien to you, well,
this is what most of us had to contend with back in the day!</p>

<p>In recent discussion, we talked about how best to replace the old ‘mouse’ tutorials.
One idea is to use the new widget identifiers to mark the elements that instead should be clicked
<em>by the player</em> to advance the tutorial.</p>

<p>One way to mark them would be to use circles, someone suggested.
A problem presented itself: oddly enough, we had no primitive yet to draw circles!
@ZehMatt stepped up and implemented one in <a href="https://github.com/OpenLoco/OpenLoco/pull/3559">#3559</a>.</p>

<p>Tutorials haven’t changed yet, and probably won’t for a while. But at least we can now draw circles!</p>

<p><img src="/assets/img/26.03/circles.gif" alt="Basic circles" /></p>

<h2 id="opengraphics">OpenGraphics</h2>

<p>This month saw 3 contributions from @shusaura85:</p>

<p>An updated dry grass object:
<img src="/assets/img/26.03/og_grassbr.png" alt="OG_GRASSBR" /></p>

<p>Two new roads:
<img src="/assets/img/26.03/og_roadone.png" alt="OG_ROADONE" /></p>

<p><img src="/assets/img/26.03/og_roadtmc.png" alt="OG_ROADTMC" /></p>]]></content><author><name>Aaron van Geffen</name></author><category term="news" /><summary type="html"><![CDATA[OpenLoco v26.03 is out! This month’s release focuses on moving to our (graphics) backend to SDL3, as well as a rework of the audio engine. Some more cool new features have been in the works since last month, but they haven’t landed yet this month. Please be patient for a while longer :-)]]></summary></entry><entry><title type="html">OpenLoco version 26.02</title><link href="https://openloco.io/news/2026/02/openloco-v26.02.html" rel="alternate" type="text/html" title="OpenLoco version 26.02" /><published>2026-02-28T07:30:00+00:00</published><updated>2026-02-28T07:30:00+00:00</updated><id>https://openloco.io/news/2026/02/openloco-v26.02</id><content type="html" xml:base="https://openloco.io/news/2026/02/openloco-v26.02.html"><![CDATA[<p>OpenLoco v26.02 is out! This month’s release mostly focuses on bugfixes. People with an eye on our Discord will know
some cool new features are in the works, but they haven’t landed yet this month. The dev team ended up rather busy with Life,
but that just means there is more to look forward to in the upcoming month!</p>

<p>What follows is a quick summary of the bugs and their fixes.</p>

<h2 id="crash-when-hovering-over-stations-with-the-order-tab-open-2205">Crash when hovering over stations with the order tab open (#2205)</h2>

<p>We kept getting weird crash reports that we couldn’t quite place, somehow involving the vehicle order manager.
It had us puzzled for a while, until @Sashna on Discord came up with a reliable way to reproduce the issue.
As it turns out, there was a situation where a pointer to the end of the order table could be reused, leading to
it being incremented past the end of the table! Once this was diagnosed, Duncan was able to come up with
a fix relatively quickly.</p>

<h2 id="the-vsync-setting-is-not-saved-correctly-3626">The vsync setting is not saved correctly (#3626)</h2>

<p>In <a href="https://github.com/OpenLoco/OpenLoco/releases/v26.01/">the previous release</a>,
we introduced an optional vsync cap for the game’s frame rate.
Ironically, the setting was not saving correctly, leading to an uncapped frame rate after restarting the game.
This was a minor issue to resolve, so at least now it actually persists!</p>

<h2 id="constant-alternating-colors-on-vehicles-and-other-things-3627">Constant alternating colors on vehicles and other things (#3627)</h2>

<p>We also introduced <a href="/news/2026/01/openloco-v26.01.html#parallel-drawing">parallel, multi-threaded rendering</a>
in the previous release. However, the remap colours in the game were still <em>sharing</em> a palette buffer.
This led to a race condition for e.g. recoloured vehicles, meaning they would alternate between colours
in certain situations. Ironically, this was flagged as a potential issue ahead of time, but the relevant
‘thread local’ keyword had not been applied. After we identified that this was indeed the cause,
it was another one-line fix.</p>

<h2 id="macos-builds-are-missing-opengraphics-objects-3629">macOS builds are missing OpenGraphics objects (#3629)</h2>

<p>As of December 2025, we have native builds for macOS again. However, as it turns out, the application bundles
were missing our OpenGraphics objects entirely! CMake wizard Duncan dug into this and found the cause to be a bug
to do with CMake presets! A workaround was promptly applied, and our macOS builds now ship with OpenGraphics objects!</p>

<h2 id="can-click-beyond-last-item-in-town-and-industry-list-windows-opening-invalid-windows-3652">Can click beyond last item in town and industry list windows, opening invalid windows (#3652)</h2>

<p>@LeeSpork identified an issue where the town and industry list windows would let the player select ‘items’
where there were none, just after the end of the list. This led to opening invalid windows, often triggering a crash.
Turns out the relevant checks were using <code class="language-plaintext highlighter-rouge">&gt;</code> instead of <code class="language-plaintext highlighter-rouge">&gt;=</code> to check bounds. Foiled again, off-by-one errors!</p>]]></content><author><name>Aaron van Geffen</name></author><category term="news" /><summary type="html"><![CDATA[OpenLoco v26.02 is out! This month’s release mostly focuses on bugfixes. People with an eye on our Discord will know some cool new features are in the works, but they haven’t landed yet this month. The dev team ended up rather busy with Life, but that just means there is more to look forward to in the upcoming month!]]></summary></entry><entry><title type="html">OpenLoco version 26.01</title><link href="https://openloco.io/news/2026/01/openloco-v26.01.html" rel="alternate" type="text/html" title="OpenLoco version 26.01" /><published>2026-01-30T16:00:00+00:00</published><updated>2026-01-30T16:00:00+00:00</updated><id>https://openloco.io/news/2026/01/openloco-v26.01</id><content type="html" xml:base="https://openloco.io/news/2026/01/openloco-v26.01.html"><![CDATA[<p>OpenLoco v26.01 is out! Last month we finally finished making the game binary standalone; this
means we now enter a bit of a refactoring and general code cleanup phase.</p>

<p>Over the next few months, the refactoring will be aimed towards getting ready for a new save format
(NSF). For the NSF, we will be aiming to increase the map size limits, and generally most other
limits. It is not a simple task of just changing some constants though, so don’t expect this to be
completed for a while. Related to the NSF, we will also be looking at introducing a new object
format (NOF). The NOF will allow removing limitations of the DAT format and will hopefully be more
human readable. Much like the NSF, this will take quite some time to fully decide how it will work.</p>

<p>Even when we move to a NSF and NOF, we will still maintain support for the old formats in various
ways, so don’t worry about losing your favourite custom objects.</p>

<p>Other areas for improvement are path finding. I suspect that we won’t be able to improve the land
path finding just yet, without an NSF, but the water path finding should be achievable. If you have
knowledge on pathfinding algorithms, it would be great to hear from you.</p>

<h2 id="openloco">OpenLoco</h2>

<h3 id="parallel-drawing">Parallel drawing</h3>

<p>@ZehMatt added parallel drawing support to OpenLoco
(<a href="https://github.com/OpenLoco/OpenLoco/pull/2825">#2825</a>). For the first time, having a multi-core CPU
will actually improve performance in OpenLoco! The way drawing works in OpenLoco is that the
window is split up into columns of 32 pixels wide (the width of a tile). Each column is drawn
independently of the others. This is trivially parallelisable and @ZehMatt really showed this as
the number of lines of code required to add parallel drawing was just 28!</p>

<p>However, keep in mind that drawing is not always the bottleneck of OpenLoco. Just running the
simulation can be very CPU intensive, and that is not something we can easily parallelise at this time.</p>

<p>Related to this change, @lapingvino on Discord mentioned this change caused dependency issues on
his system. I might have been a little dismissive of the issue at first as we were only using the
C++ standard library parallelism features, but after looking into it properly it did turn out that
GCC’s <code class="language-plaintext highlighter-rouge">libstdc++</code> depends on Intel TBB for parallelism. So if you are using <code class="language-plaintext highlighter-rouge">libstdc++</code> you now need to
remember to have TBB if you want parallel drawing to work
(<a href="https://github.com/OpenLoco/OpenLoco/pull/#3608">#3608</a>).
Unfortunately, GCC will silently remove the parallelism if TBB is not found so we didn’t catch this
on any of our CI systems as they only have the minimum of required dependencies installed.</p>

<h3 id="name-unknown-flags-and-variables">Name unknown flags and variables</h3>

<p>@Cgettys, myself, @shusaura85 all worked on identifying various flags, variables and other unknowns
in the codebase (<a href="https://github.com/OpenLoco/OpenLoco/pull/3512">#3512</a>,
<a href="https://github.com/OpenLoco/OpenLoco/pull/3615">#3615</a>,
<a href="https://github.com/OpenLoco/OpenLoco/pull/3571">#3571</a>,
<a href="https://github.com/OpenLoco/OpenLoco/pull/3600">#3600</a>,
<a href="https://github.com/OpenLoco/OpenLoco/pull/3550">#3550</a>).
Ideally, we would like to have all save file and object file related data
identified before embarking on the NSF and NOF work. It’s not terribly exciting work, but I
personally quite enjoy finally assigning a name to something and understanding how it affects the
simulation.</p>

<h3 id="various-refactoring-and-bugs">Various refactoring and bugs</h3>

<p>@AaronVanGeffen, myself, @ethan-xd, @ZehMatt, @LeeSpork, @LeftOfZen, all worked on various minor
refactoring and minor bugs. Checkout the changelog for details on the bugs.</p>

<h2 id="opengraphics">OpenGraphics</h2>

<p>We made a mistake last month and accidentally didn’t include all of the OpenGraphics objects that had
been created. We have corrected the issue and you should now see all of the objects released last month.</p>

<p>Onto the fun stuff; this months was the most productive month yet! Contributions have been organised by creator below.</p>

<h3 id="phosporus551">@phosporus551</h3>

<p>@phosporus551 had an insane 37 contributions this month:</p>

<p>28 OpenGraphics recreations:</p>

<figure class="third ">
  
    
      <a href="/assets/img/26.01/og_ae47.png" title="OG_AE47">
          <img src="/assets/img/26.01/og_ae47.png" alt="OG_AE47" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_alcocent.png" title="OG_ALCOCENT">
          <img src="/assets/img/26.01/og_alcocent.png" alt="OG_ALCOCENT" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_apt.png" title="OG_APT">
          <img src="/assets/img/26.01/og_apt.png" alt="OG_APT" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_ce68.png" title="OG_CE68">
          <img src="/assets/img/26.01/og_ce68.png" alt="OG_CE68" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_dash7.png" title="OG_DASH7">
          <img src="/assets/img/26.01/og_dash7.png" alt="OG_DASH7" />
      </a>
    
  
    
      <a href="/assets/img/26.01/e8.png" title="E8">
          <img src="/assets/img/26.01/og_e8.png" alt="E8" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_estar.png" title="OG_ESTAR">
          <img src="/assets/img/26.01/og_estar.png" alt="OG_ESTAR" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_flatbeds.png" title="All the new flatbegs">
          <img src="/assets/img/26.01/og_flatbeds.png" alt="OG_FLATBEDS" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_mailus1.png" title="OG_MAILUS1">
          <img src="/assets/img/26.01/og_mailus1.png" alt="OG_MAILUS1" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_mk1.png" title="OG_MK1">
          <img src="/assets/img/26.01/og_mk1.png" alt="OG_MK1" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_mk2.png" title="OG_MK2">
          <img src="/assets/img/26.01/og_mk2.png" alt="OG_MK2" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_pcar1.png" title="OG_PCAR1">
          <img src="/assets/img/26.01/og_pcar1.png" alt="OG_PCAR1" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_pcar2.png" title="OG_PCAR2">
          <img src="/assets/img/26.01/og_pcar2.png" alt="OG_PCAR2" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_pcarus1.png" title="OG_PCARUS1">
          <img src="/assets/img/26.01/og_pcarus1.png" alt="OG_PCARUS1" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_pcarus2.png" title="OG_PCARUS2">
          <img src="/assets/img/26.01/og_pcar2.png" alt="OG_PCARUS2" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_rbe24.png" title="OG_RBE24">
          <img src="/assets/img/26.01/og_rbe24.png" alt="OG_RBE24" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_sd70mac.png" title="OG_SD70MAC">
          <img src="/assets/img/26.01/og_sd70mac.png" alt="OG_SD70MAC" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_swiss1.png" title="OG_SWISS1">
          <img src="/assets/img/26.01/og_swiss1.png" alt="OG_SWISS1" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_swiss2.png" title="OG_SWISS2">
          <img src="/assets/img/26.01/og_swiss2.png" alt="OG_SWISS2" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_swiss3.png" title="OG_SWISS3">
          <img src="/assets/img/26.01/og_swiss3.png" alt="OG_SWISS3" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_swiss5.png" title="OG_SWISS5">
          <img src="/assets/img/26.01/og_swiss5.png" alt="OG_SWISS5" />
      </a>
    
  
    
      <a href="/assets/img/26.01/og_tgv.png" title="OG_TGV">
          <img src="/assets/img/26.01/og_tgv.png" alt="OG_TGV" />
      </a>
    
  
  
</figure>

<p>7 <em>branch new</em> narrow-gauge trains (that don’t replace a vanilla object). These fill a gameplay gap
in the mid tier for narrow-gauge trains. Whilst wider game balance for vehicles still has to be
discussed in more detail, these certainly go a long way to bridging the underpowered nature of
the vanilla narrow-gague vehicle selection.</p>

<p><img src="/assets/img/26.01/og_ng2.png" alt="OG_NG2" /></p>

<p>2 revisions on existing OpenGraphics objects:</p>

<p><img src="/assets/img/26.01/og_hst_mk3_update.png" alt="OG_HST_MK3" /></p>

<h3 id="shusaura85">@shusaura85</h3>

<p>@shusaura85 fixed a vanilla compatiblity issue with level crossings not being able to be placed on the existing <code class="language-plaintext highlighter-rouge">OG_ROADRGH</code>, as well as added <code class="language-plaintext highlighter-rouge">OG_BRDGGIRD</code>:</p>

<p><img src="/assets/img/26.01/og_brdggird.png" alt="OG_BRDGGIRD" /></p>

<h3 id="glenjimen">@glenjimen</h3>

<p>@glenjimen contributed <code class="language-plaintext highlighter-rouge">OG_COAL1</code>:</p>

<p><img src="/assets/img/26.01/og_coal1.png" alt="OG_COAL1" /></p>]]></content><author><name>Duncan Frost</name></author><category term="news" /><summary type="html"><![CDATA[OpenLoco v26.01 is out! Last month we finally finished making the game binary standalone; this means we now enter a bit of a refactoring and general code cleanup phase.]]></summary></entry><entry><title type="html">OpenLoco version 25.12</title><link href="https://openloco.io/news/2025/12/openloco-v25.12.html" rel="alternate" type="text/html" title="OpenLoco version 25.12" /><published>2025-12-20T09:00:00+00:00</published><updated>2025-12-20T09:00:00+00:00</updated><id>https://openloco.io/news/2025/12/openloco-v25.12</id><content type="html" xml:base="https://openloco.io/news/2025/12/openloco-v25.12.html"><![CDATA[<p>OpenLoco v25.12 is out! This release marks a major milestone for the project.
We completed the C++ reimplemention in <a href="/news/2025/09/openloco-v25.09.html">v25.09</a> a few months ago,
but were still dependent on vanilla memory space. This month, we celebrate the complete
reworking of the memory space as well.</p>

<p>In short, this means the game can now be compiled <em>natively</em> for all platforms.
This makes this month’s release available in <strong>64-bits</strong> architecture for Windows, Linux, and macOS.
You can expect builds to be faster, and much easier to port to new operating systems.
Of course, we are extremely happy with this result, and what this means for future possibilities.</p>

<p>In this blog post, we’ll look back on how the memory space was reworked,
as well as some quality-of-life changes that were merged this month,
and the progress the OpenGraphics project has seen. Let’s get going.</p>

<h2 id="big-loco_global-integration-extravaganza">Big loco_global integration extravaganza</h2>

<p>Until this month, we still mirrored the vanilla game’s approached to <em>memory space</em> in most places.
As often talked about in previous blogs, this was done with <code class="language-plaintext highlighter-rouge">loco_global</code> instances.
Last month, we reported on the progress of reworking this, going from
342 <code class="language-plaintext highlighter-rouge">loco_globals</code> in the v25.10 release to just 157 in v25.11…
Remarkably, this month takes us down to <strong>0</strong> <code class="language-plaintext highlighter-rouge">loco_globals</code> — yes, zero!
It was a massive team effort, but it’s paid off massively, making 64-bit builds finally possible.</p>

<p>We usually list PR numbers in our dev log sections, however there were 46 PRs just for
<code class="language-plaintext highlighter-rouge">loco_global</code> removal this month! If you’re curious to see what such PRs look like,
you can find them on GitHub. Follow
<a href="https://github.com/OpenLoco/OpenLoco/pulls?q=is%3Apr+milestone%3Av25.12+interop+OR+global+OR+loco_globals">this link</a>
for a list of the relevant PRs.</p>

<p>To illustrate the growth and removal of <code class="language-plaintext highlighter-rouge">loco_global</code> instances from the project’s inception to now,
please take a look at the graph below. As more of the game became reimplemented, more memory had to be
shared between vanilla functions and our C++ functions, thus increasing the number of <code class="language-plaintext highlighter-rouge">loco_global</code>s.
Only once all vanilla systems had been reimplemented could the relevant memory be fully integrated.
Clearly, the last few months saw the final stretches of this effort.</p>

<p><img src="/assets/img/25.12/loco_globals.png" alt="loco globals over time" /></p>

<h2 id="larger-windows-and-new-window-styles">Larger windows and new window styles</h2>

<p>Compared to other Chris Sawyer games, Locomotion stands out due to its relatively sober window decorations.
In fact, the ‘gradient’ look that characterises them is drawn using just one big sprite! For this reason,
window sizes were limited to a width of 800 pixels — that’s all the sprite afforded!</p>

<p>Of course, nowadays, we have screens that are quite a bit bigger, so we frequently got requests
for windows to be made larger. Well, here we are! Certain windows, e.g. the vehicle list and map window,
can now be resized up to 2000x2000 pixels — much wider than was possible in the original game.</p>

<p>While we were working on this, Aaron had fun playing with introducing some new variants of the default
window frame style. The gradient can now be disabled, resulting in a solid background colour. Moreover,
the frame background can now be made translucent, resulting in a neat effect that we just had to include.
Have a look at the gallery below for some examples.</p>

<figure class="third ">
  
    
      <a href="/assets/img/25.12/window_style_gradient.png" title="Gradient window style">
          <img src="/assets/img/25.12/window_style_gradient.png" alt="" />
      </a>
    
  
    
      <a href="/assets/img/25.12/window_style_solid.png" title="Solid window style">
          <img src="/assets/img/25.12/window_style_solid.png" alt="" />
      </a>
    
  
    
      <a href="/assets/img/25.12/window_style_translucent.png" title="Translucent window style">
          <img src="/assets/img/25.12/window_style_translucent.png" alt="" />
      </a>
    
  
  
</figure>

<h2 id="more-resizeable-windows">More resizeable windows</h2>

<p>Some players have amassed thousands of objects. Even with the filters OpenLoco introduced,
from time to time we received requests to expand the object selection window. With larger windows
now being possible, we’ve opted to make the object selection window resizeable.
The default dimensions haven’t changed, but you can now
<a href="https://github.com/OpenLoco/OpenLoco/pull/3405">resize it (#3405)</a> to be a whopping 2000x2000 pixels,
for all your extreme object listing needs.</p>

<p>It was brought to our attention that the vehicle list was quite glitchy when made <em>smaller</em> than its
default size. We seized the opportunity to rework its resize routines, capitalising on the increased
window limits as well. You can now <a href="https://github.com/OpenLoco/OpenLoco/pull/3531">resize it (#3531)</a>
to be quite a bit taller indeed!</p>

<p>Finally, the music selection window has been reworked by @LeeSpork.
The window now lists the years music applies to, and allows you to order the list by name or year.
This is made even more useful by allowing you to resize the window!
We hope this increases your playlist customisation prowess
<a href="https://github.com/OpenLoco/OpenLoco/pull/3384">quite a bit (#3384)</a>.</p>

<h2 id="doubling-down-on-cmake">Doubling down on CMake</h2>

<p>Over the past few years, we’ve continued to rely on CMake to tie our toolchain together. While initially
we were dabbling with Visual Studio solution files for Windows, and several CMake files for Linux and even macOS,
@Duncanspumpkin unified these to work on all platforms, and we’re now reaping even more the fruits of this labour.
Since we had to rework our CMake toolchain again to make 64-bit builds possible,
we took the opportunity to drop a bunch of now-unnecessary things in the process.
Let’s take them one at a time.</p>

<h3 id="interop-removal">Interop removal</h3>

<p>First off, no longer needing to interop with the vanilla game has allowed us to
<a href="https://github.com/OpenLoco/OpenLoco/pull/3491">remove a fair bit of code (#3491)</a>.
This moment has been highly anticipated, and @Duncanspumpkin was all to eager to get it done.</p>

<h3 id="cmake-presets">CMake presets</h3>

<p>While CMake has been <em>the</em> go-to tool to build OpenLoco for a while, it could be a little confusing
to get it to build so-called <em>cross-platform</em> builds, in this case building 32-bit software on a 64-bit system.
Now that this is no longer necessary, CMake presets could be
<a href="https://github.com/OpenLoco/OpenLoco/pull/3523">simplified quite a bit (#3523)</a>.
The project readme was adjusted accordingly. Whether you’re on Windows, Linux, macOS, or even BSD,
it should be super easy to set up the compiler toolchain now.</p>

<h3 id="linux-builds">Linux builds</h3>

<p>For our <em>continous integration</em> (CI) build platform, we generally rely on <a href="https://github.com/microsoft/vcpkg">vcpkg</a>
to build libraries we depend on, e.g. the SDL2 hardware abstraction layer.
While Linux distributions tend to have their own package manager, you <em>can</em> opt-in to using vcpkg
if the system packages are not up-to-date enough.
All this to say, our ‘vcpkg’ Linux preset has now been
<a href="https://github.com/OpenLoco/OpenLoco/pull/3494">updated to use x64 (#3494)</a> as well.</p>

<h3 id="macos-builds">macOS builds</h3>

<p>The return of macOS builds is something that part of the team has been eagerly anticipating.
Even when the codebase wasn’t <em>entirely</em> ready, Aaron started to hack away at getting
<a href="https://github.com/OpenLoco/OpenLoco/pull/3288">native 64-bit builds (#3288)</a>
for this platform. Much of the work tied in with the <code class="language-plaintext highlighter-rouge">loco_global</code> rework, and was ultimately split off
into their own PRs to ease the review process.
Duncan created a <a href="https://github.com/OpenLoco/OpenLoco/pull/3499">CI job for macOS (#3499)</a>
as well, so we now have regular macOS builds on GitHub again!</p>

<h3 id="header-checks">Header checks</h3>

<p>Finally, @ZehMatt did quite a bit of <a href="https://github.com/OpenLoco/OpenLoco/pull/3532">house cleaning (#3532)</a>,
modernising parts of the <code class="language-plaintext highlighter-rouge">CMakeLists</code> files that were a bit neglected, and reworking the header checks.
These checks are quite important, as they ensure we don’t have any implicit dependencies
between headers. This allows us to keep headers small while not getting surprised when using them.</p>

<h2 id="opengraphics">OpenGraphics</h2>

<p>This month we had 11 vehicle contributions from @glenjimen and a bridge contribution from @shusaura85!</p>

<h3 id="vehicles">Vehicles</h3>

<figure class="third ">
  
    
      <a href="/assets/img/25.12/og_cattlen1.png" title="OG_CATTLEN1">
          <img src="/assets/img/25.12/og_cattlen1.png" alt="OG_CATTLEN1" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_pcarsw1.png" title="OG_PCARSW1">
          <img src="/assets/img/25.12/og_pcarsw1.png" alt="OG_PCARSW1" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_pvan1.png" title="OG_PVAN1">
          <img src="/assets/img/25.12/og_pvan1.png" alt="OG_PVAN1" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_mailsw1.png" title="OG_MAILSW1">
          <img src="/assets/img/25.12/og_mailsw1.png" alt="OG_MAILSW1" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_mailsw4.png" title="OG_MAILSW4">
          <img src="/assets/img/25.12/og_mailsw4.png" alt="OG_MAILSW4" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_mailus2.png" title="OG_MAILUS2">
          <img src="/assets/img/25.12/og_mailus2.png" alt="OG_MAILUS2" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_swiss4.png" title="OG_SWISS4">
          <img src="/assets/img/25.12/og_swiss4.png" alt="OG_SWISS4" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_oiln1.png" title="OG_OILN1">
          <img src="/assets/img/25.12/og_oiln1.png" alt="OG_OILN1" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_oil1.png" title="OG_OIL1">
          <img src="/assets/img/25.12/og_oil1.png" alt="OG_OIL1" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_oil2.png" title="OG_OIL2">
          <img src="/assets/img/25.12/og_oil2.png" alt="OG_OIL2" />
      </a>
    
  
    
      <a href="/assets/img/25.12/og_openn1.png" title="OG_OPENN1">
          <img src="/assets/img/25.12/og_openn1.png" alt="OG_OPENN1" />
      </a>
    
  
  
</figure>

<h3 id="bridges">Bridges</h3>

<p><img src="/assets/img/25.12/og_brdgstar.png" alt="OG_BRDGSTAR" /></p>

<h2 id="happy-holidays">Happy Holidays!</h2>

<p>Thank you for supporting OpenLoco over the years!
We’re very happy with the milestones we’ve reached this year, both on a code and at a community level.
With the end of 2025 in sight, we wish you all happy holidays!</p>

<p><img src="/assets/img/25.12/locoXmasTree.gif" alt="locoXmasTree" /></p>

<p><em>Thanks to @Glenjimen for this little diorama!</em></p>]]></content><author><name>Aaron van Geffen</name></author><category term="news" /><summary type="html"><![CDATA[OpenLoco v25.12 is out! This release marks a major milestone for the project. We completed the C++ reimplemention in v25.09 a few months ago, but were still dependent on vanilla memory space. This month, we celebrate the complete reworking of the memory space as well.]]></summary></entry><entry><title type="html">OpenLoco version 25.11</title><link href="https://openloco.io/news/2025/11/openloco-v25.11.html" rel="alternate" type="text/html" title="OpenLoco version 25.11" /><published>2025-11-05T09:45:00+00:00</published><updated>2025-11-05T09:45:00+00:00</updated><id>https://openloco.io/news/2025/11/openloco-v25.11</id><content type="html" xml:base="https://openloco.io/news/2025/11/openloco-v25.11.html"><![CDATA[<p>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!</p>

<h2 id="prevent-accidental-cargo-removal">Prevent accidental cargo removal</h2>

<p>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,
<a href="https://github.com/OpenLoco/OpenLoco/pull/3323">#3323</a> was filed, which adds a confirmation dialog
to the vehicle component tab. This means changing vehicle/wagon order now prompts for confirmation
<em>if</em> 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.</p>

<p><img src="/assets/img/25.11/refit-prompt.jpg" alt="refit prompt" /></p>

<h2 id="rework-remaining-legacy-config-into-modern-config">Rework remaining legacy config into modern config</h2>

<p>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.</p>

<p>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 <a href="/news/2025/09/openloco-v25.09.html">v25.09</a>, all functions have been
reimplemented, though. To be fully implemented, we have to move on config-wise as well.</p>

<p>As of <a href="https://github.com/OpenLoco/OpenLoco/pull/3323">#3323</a>, all config variables are now
stored in the <code class="language-plaintext highlighter-rouge">openloco.yml</code> file. You can find this in the OpenLoco folder in your user profile
(in Windows, this is <code class="language-plaintext highlighter-rouge">AppData\Roaming</code>). Go take a peek!</p>

<h2 id="show-ai-allocations-as-regular-ghost-elements">Show AI allocations as regular ghost elements</h2>

<p>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.</p>

<p>In <a href="https://github.com/OpenLoco/OpenLoco/pull/3270">#3270</a>, 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.</p>

<p><img src="/assets/img/25.11/ai-ghosts-1.png" alt="ai ghosts" /></p>

<p><img src="/assets/img/25.11/ai-ghosts-2.png" alt="ai ghosts" /></p>

<h2 id="merge-sound-and-music-tabs-in-options-window">Merge sound and music tabs in options window</h2>

<p>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 <a href="https://github.com/OpenLoco/OpenLoco/pull/3326">#3326</a>, the tab was revealed
on the title screen. It was quickly followed by <a href="https://github.com/OpenLoco/OpenLoco/pull/3352">#3352</a>, 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!</p>

<p><img src="/assets/img/25.11/audio-tab.png" alt="audio tab" /></p>

<h2 id="disallow-interfering-with-competitors-roads-and-road-stations">Disallow interfering with competitor’s roads and road stations</h2>

<p>@LeeSpork discovered that it was possible for players to interfere with competitors’ roads.
They quickly filed patches to prevent competitor road removal (<a href="https://github.com/OpenLoco/OpenLoco/pull/3335">#3335</a>),
as well as competitor road station replacement (<a href="https://github.com/OpenLoco/OpenLoco/pull/3336">#3336</a>).
Nice catch!</p>

<h2 id="add-platform-and-arch-to-title-screen">Add platform and arch to title screen</h2>

<p>As we previously mentioned, as of <a href="/news/2025/09/openloco-v25.09.html">v25.09</a>, all game functions have been
reimplemented in C++. We’re not <em>quite</em> at the point where we can make fully working 64-bit builds
(<a href="https://github.com/OpenLoco/OpenLoco/pull/3288">#3288</a>),
however, we realised this would be a good time to add platform and processor/arch information to the title screen.
With <a href="https://github.com/OpenLoco/OpenLoco/pull/3328">#3328</a> merged,
you can now find this info in the lower-left corner, just below the usual version information.</p>

<h2 id="catch-filestream-exceptions-when-loading-from-cli">Catch FileStream exceptions when loading from CLI</h2>

<p>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 <code class="language-plaintext highlighter-rouge">FileStream</code>
exception, but not catch it, crashing the game. This is now mitigated by
<a href="https://github.com/OpenLoco/OpenLoco/pull/3363">#3363</a>, letting the game instead
just log a warning to the console.</p>

<h2 id="rename-a-bunch-of-things">Rename a bunch of things</h2>

<p>Over the course of the literal <em>years</em> 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 (<a href="https://github.com/OpenLoco/OpenLoco/pull/3350">#3350</a>).</p>

<p>Following this example, @AaronVanGeffen set out to rename several <code class="language-plaintext highlighter-rouge">sub_</code> functions, that had
not received a new name in the reverse engineering process
(<a href="https://github.com/OpenLoco/OpenLoco/pull/3359">#3359</a>).
Similarly, one of the first game commands we implemented was the <code class="language-plaintext highlighter-rouge">LoadSaveQuitGame</code>
game command. We now understand this better, leading us to rename its arguments
(<a href="https://github.com/OpenLoco/OpenLoco/pull/3367">#3367</a>).</p>

<h2 id="big-loco_global-integration-extravaganza">Big loco_global integration extravaganza</h2>

<p>As we previously mentioned, as of <a href="/news/2025/09/openloco-v25.09.html">v25.09</a>,
all game functions have been reimplemented in C++. However, we still mirror the vanilla game’s
<em>memory space</em> in several places. As often talked about in previous blogs, this is done with
<code class="language-plaintext highlighter-rouge">loco_global</code> 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 <em>team effort</em> to get there. To illustrate,
while our v25.10 release still had 342 <code class="language-plaintext highlighter-rouge">loco_globals</code>, this month, we’re down to just <strong>157</strong> of them.
This is great progress! Unfortunately, many of the remaining ones are less trivial to tackle…but we’ll get there!</p>

<p>We usually list PR numbers in our dev log sections, however there were 20 PRs just for
<code class="language-plaintext highlighter-rouge">loco_global</code> removal this month! If you’re curious to see what such PRs look like,
you can find them on GitHub. Follow
<a href="https://github.com/OpenLoco/OpenLoco/pulls?q=is%3Apr+milestone%3Av25.11+interop+OR+global+OR+buffer+OR+loco_globals">this link</a>
for a list of the relevant PRs.</p>

<h2 id="opengraphics">OpenGraphics</h2>

<p>Over the last 2 months we’ve have 11 new objects added to the OpenGraphics repo, and 2 updates to existing ones!</p>

<h3 id="roads">Roads</h3>

<ul>
  <li>@shusaura85 replaced <code class="language-plaintext highlighter-rouge">ROADRGH</code> with <code class="language-plaintext highlighter-rouge">OG_ROADRGH</code>:</li>
</ul>

<p><img src="/assets/img/25.11/og_roadrgh.png" alt="OG_ROADRGH" /></p>

<h3 id="bridges">Bridges</h3>

<ul>
  <li>@shusaura85 replaced <code class="language-plaintext highlighter-rouge">BRDGBRCK</code> with <code class="language-plaintext highlighter-rouge">OG_BRDGBRCK</code>:</li>
</ul>

<p><img src="/assets/img/25.11/og_brdgbrck.png" alt="OG_BRDGBRCK" /></p>

<ul>
  <li>@shusaura85 replaced <code class="language-plaintext highlighter-rouge">BRDGWOOD</code> with <code class="language-plaintext highlighter-rouge">OG_BRDGWOOD</code>:</li>
</ul>

<p><img src="/assets/img/25.11/og_brdgwood.png" alt="OG_BRDGWOOD" /></p>

<h3 id="landcliffedge">Land/CliffEdge</h3>

<p>@hibiii added a <em>new</em> land type called <code class="language-plaintext highlighter-rouge">OG_VOID</code>, as well as the corresponding CliffEdge for it, <code class="language-plaintext highlighter-rouge">OG_LSVOID</code>:</p>

<p><img src="/assets/img/25.11/og_void.png" alt="OG_VOID" /></p>

<h3 id="vehicles">Vehicles</h3>

<p>@glenjimen replaced <code class="language-plaintext highlighter-rouge">CATTLE1</code> with <code class="language-plaintext highlighter-rouge">OG_CATTLE1</code>:</p>

<p><img src="/assets/img/25.11/og_cattle1.png" alt="OG_CATTLE1" /></p>

<p>@glenjimen replaced <code class="language-plaintext highlighter-rouge">GOODS3</code> with <code class="language-plaintext highlighter-rouge">OG_GOODS3</code>:</p>

<p><img src="/assets/img/25.11/og_goods3.png" alt="OG_GOODS3" /></p>

<p>@phosporus551 replaced <code class="language-plaintext highlighter-rouge">CL71</code> with <code class="language-plaintext highlighter-rouge">OG_CL71</code>:</p>

<p><img src="/assets/img/25.11/og_cl71.png" alt="OG_CL71" /></p>

<p>@phosporus551 updated <code class="language-plaintext highlighter-rouge">OG_RE441</code> with new sprites from a new rendering pipeline:</p>

<p><img src="/assets/img/25.11/og_re441.png" alt="OG_RE441" /></p>

<p>@phosporus551 replaced <code class="language-plaintext highlighter-rouge">RE442</code> with <code class="language-plaintext highlighter-rouge">OG_RE442</code>:</p>

<p><img src="/assets/img/25.11/og_re442.png" alt="OG_RE444" /></p>

<p>@phosporus551 updated <code class="language-plaintext highlighter-rouge">OG_656</code> with new sprites from a new rendering pipeline:</p>

<p><img src="/assets/img/25.11/og_656.png" alt="OG_656" /></p>

<p>@phosporus551 replaced <code class="language-plaintext highlighter-rouge">460</code> with <code class="language-plaintext highlighter-rouge">OG_460</code>:</p>

<p><img src="/assets/img/25.11/og_460.png" alt="OG_460" /></p>

<p>@phosporus551 replaced <code class="language-plaintext highlighter-rouge">EWIV</code> with <code class="language-plaintext highlighter-rouge">OG_EWIV</code>, as well as the corresponding <code class="language-plaintext highlighter-rouge">EWIVDT</code> with <code class="language-plaintext highlighter-rouge">OG_EWIVDT</code>:</p>

<p><img src="/assets/img/25.11/og_ewiv.png" alt="OG_EWIV" /></p>]]></content><author><name>Aaron van Geffen</name></author><category term="news" /><summary type="html"><![CDATA[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!]]></summary></entry><entry><title type="html">OpenLoco version 25.10</title><link href="https://openloco.io/news/2025/10/openloco-v25.10.html" rel="alternate" type="text/html" title="OpenLoco version 25.10" /><published>2025-10-10T19:15:00+00:00</published><updated>2025-10-10T19:15:00+00:00</updated><id>https://openloco.io/news/2025/10/openloco-v25.10</id><content type="html" xml:base="https://openloco.io/news/2025/10/openloco-v25.10.html"><![CDATA[<p>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.</p>

<h2 id="revert-drawing-widgets-in-relative-positions-3305">Revert drawing widgets in relative positions (#3305)</h2>

<p>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.</p>

<p>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.</p>

<h2 id="fix-keyboard-shortcut-assignment-3309">Fix keyboard shortcut assignment (#3309)</h2>

<p>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 <code class="language-plaintext highlighter-rouge">uint32_t</code> 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…</p>

<h2 id="bump-sfl-library-3310">Bump sfl library (#3310)</h2>

<p>In C++, we have the luxury of a standard library that provides various dynamic container data types,
e.g. <code class="language-plaintext highlighter-rouge">std::string</code> or <code class="language-plaintext highlighter-rouge">std::vector</code>. These provide automatic
<a href="https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization">RAII</a>-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 <a href="https://github.com/slavenf/sfl-library"><code class="language-plaintext highlighter-rouge">sfl</code></a>.
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.</p>

<h2 id="continued-loco_global-integration-efforts">Continued <code class="language-plaintext highlighter-rouge">loco_global</code> integration efforts</h2>

<p>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
<code class="language-plaintext highlighter-rouge">loco_global</code> 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.</p>

<p>Many of the remaining <code class="language-plaintext highlighter-rouge">loco_globals</code> 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.</p>

<p>At the time of writing this blog post, 351 <code class="language-plaintext highlighter-rouge">loco_global</code> instances remain, across 95 files.
Hopefully, by the time the next release turns around, we will have made ample progress in rewriting them.</p>]]></content><author><name>Aaron van Geffen</name></author><category term="news" /><summary type="html"><![CDATA[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.]]></summary></entry><entry><title type="html">OpenLoco version 25.09</title><link href="https://openloco.io/news/2025/09/openloco-v25.09.html" rel="alternate" type="text/html" title="OpenLoco version 25.09" /><published>2025-09-30T15:30:00+00:00</published><updated>2025-09-30T15:30:00+00:00</updated><id>https://openloco.io/news/2025/09/openloco-v25.09</id><content type="html" xml:base="https://openloco.io/news/2025/09/openloco-v25.09.html"><![CDATA[<p>OpenLoco v25.09 is out!</p>

<p>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
<a href="#reimplementation">complete reimplementation</a> of the game!
Talking of graphics assets, this release also contains a whole bunch of
<a href="#opengraphics">new OpenGraphics objects</a> as well.</p>

<p>For a summary of changes, please find the
<a href="https://github.com/OpenLoco/OpenLoco/releases/tag/v25.09">changelog</a> on GitHub.</p>

<h2 id="changes-and-features">Changes and Features</h2>

<h3 id="rotate-company-headquarters">Rotate Company Headquarters</h3>

<p>@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.</p>

<h3 id="improve-zoom-to-cursor">Improve Zoom to Cursor</h3>

<p>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.</p>

<h3 id="disable-currency-selection-in-title-screen">Disable Currency Selection in Title Screen</h3>

<p>@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.</p>

<h2 id="reimplementation">Reimplementation</h2>

<h3 id="implement-createremove-road-mod-game-command">Implement Create/Remove Road Mod Game Command</h3>

<p>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.</p>

<h3 id="implement-remaining-vehicle-update-functions">Implement Remaining Vehicle Update Functions</h3>

<p>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.</p>

<p>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.</p>

<h3 id="implement-update-traffic-handedness">Implement Update Traffic Handedness</h3>

<p>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.</p>

<h3 id="remove-all-hooks">Remove All Hooks</h3>

<p>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.</p>

<p>With all the hooks gone we can also start getting x64 builds working, and perhaps even ARM builds.</p>

<h2 id="opengraphics">OpenGraphics</h2>

<p>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:</p>

<h3 id="vehicles">Vehicles</h3>
<p>@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. The new vehicles/sprites are highlighted in red in
the below image. Starting at the bottom, we have <code class="language-plaintext highlighter-rouge">OG_GRAINHP2.dat</code> replacing <code class="language-plaintext highlighter-rouge">GRAINHP2.dat</code>,
then <code class="language-plaintext highlighter-rouge">OG_GRAINHP1.dat</code> replacing <code class="language-plaintext highlighter-rouge">GRAINHP2.dat</code> and finally in the top right, we have
<code class="language-plaintext highlighter-rouge">OG_GOODS1.dat</code> replacing <code class="language-plaintext highlighter-rouge">GOODS1.dat</code>:</p>

<p><img src="/assets/img/25.09/trains.png" alt="Red carriages show the new OG sprites" /></p>

<h3 id="road-stations">Road Stations</h3>
<p>@shusaura85 replaced all of the vanilla road stations as well as the bus stop with OG versions:</p>

<figure class="third ">
  
    
      <a href="/assets/img/25.09/rdstat1.png">
          <img src="/assets/img/25.09/rdstat1.png" alt="New road station" />
      </a>
    
  
    
      <a href="/assets/img/25.09/rdstat2.png">
          <img src="/assets/img/25.09/rdstat2.png" alt="New road station" />
      </a>
    
  
    
      <a href="/assets/img/25.09/rdstat3.png">
          <img src="/assets/img/25.09/rdstat3.png" alt="New road station" />
      </a>
    
  
    
      <a href="/assets/img/25.09/rdstatl1.png">
          <img src="/assets/img/25.09/rdstatl1.png" alt="New road station" />
      </a>
    
  
    
      <a href="/assets/img/25.09/rdstatl2.png">
          <img src="/assets/img/25.09/rdstatl2.png" alt="New road station" />
      </a>
    
  
    
      <a href="/assets/img/25.09/rdstatl3.png">
          <img src="/assets/img/25.09/rdstatl3.png" alt="New road station" />
      </a>
    
  
    
      <a href="/assets/img/25.09/busstop.png">
          <img src="/assets/img/25.09/busstop.png" alt="New road station" />
      </a>
    
  
  
</figure>

<h3 id="tunnels">Tunnels</h3>
<p>@shusaura85 replaced <code class="language-plaintext highlighter-rouge">TUNNEL1.dat</code> and <code class="language-plaintext highlighter-rouge">TUNNEL2.dat</code> with <code class="language-plaintext highlighter-rouge">OG_TUNNEL1.dat</code> and <code class="language-plaintext highlighter-rouge">OG_TUNNEL2.dat</code>,
respectively. Vanilla shown on the left, OG on the right:</p>

<p><img src="/assets/img/25.09/tunnels.png" alt="tunnels" /></p>

<h3 id="hill-shapes">Hill Shapes</h3>
<p>The hill shapes object, <code class="language-plaintext highlighter-rouge">HS1.dat</code>, which controls how the vanilla terrain generation works,
was replaced with <code class="language-plaintext highlighter-rouge">OG_HS1.dat</code> 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:</p>

<p><img src="/assets/img/25.09/hillshapes.png" alt="hillshapes" /></p>

<h3 id="streetlights">Streetlights</h3>
<p>@shusaura85 replaced <code class="language-plaintext highlighter-rouge">SLIGHT1.dat</code> was replaced with <code class="language-plaintext highlighter-rouge">OG_SLIGHT1.dat</code>:</p>

<p><img src="/assets/img/25.09/streetlights.png" alt="streetlights" /></p>

<h3 id="land">Land</h3>
<p>@shusaura85 replaced all of the land types with OG versions. Top tiles are the vanilla land
sprites, bottom are the OG replacements. The darker cliffs are the replacements:</p>

<p><img src="/assets/img/25.09/land.png" alt="land comparison" /></p>

<h3 id="cliffs">Cliffs</h3>
<p>Land objects have associated cliff objects, so these were also replaced by @shusaura85:</p>

<p><img src="/assets/img/25.09/cliffs.png" alt="cliffs" /></p>

<h3 id="snow">Snow</h3>
<p>@shusaura85 replaced <code class="language-plaintext highlighter-rouge">SNOW.dat</code> with <code class="language-plaintext highlighter-rouge">OG_SNOW.dat</code>:</p>

<p><img src="/assets/img/25.09/snow.png" alt="snow" /></p>

<h3 id="water">Water</h3>
<p>@shusaura85 replaced <code class="language-plaintext highlighter-rouge">WATER1.dat</code> with <code class="language-plaintext highlighter-rouge">OG_WATER1.dat</code>:</p>

<p><img src="/assets/img/25.09/water.png" alt="water" /></p>]]></content><author><name>Duncan Frost</name></author><category term="news" /><summary type="html"><![CDATA[OpenLoco v25.09 is out!]]></summary></entry><entry><title type="html">OpenLoco version 25.08</title><link href="https://openloco.io/news/2025/08/openloco-v25.08.html" rel="alternate" type="text/html" title="OpenLoco version 25.08" /><published>2025-08-26T15:30:00+00:00</published><updated>2025-08-26T15:30:00+00:00</updated><id>https://openloco.io/news/2025/08/openloco-v25.08</id><content type="html" xml:base="https://openloco.io/news/2025/08/openloco-v25.08.html"><![CDATA[<p>OpenLoco v25.08 is out! We have a huge amount of behind the scenes changes for this month.
Company AI is now fully implemented! All vehicle route finding has been implemented! And there
has been a variety of bug fixes. We are now in the very final stages of reimplementing the game
in C++. Hopefully, in the next few months, we will be standalone from the original game (for the
engine), and we can bring native support for 64-bit and maybe even macOS support again.</p>

<p>For a summary of changes, please find the
<a href="https://github.com/OpenLoco/OpenLoco/releases/tag/v25.08">changelog</a> on GitHub.</p>

<h2 id="bug-fixes">Bug Fixes</h2>

<h2 id="company-ai-implementation">Company AI implementation</h2>

<p>The last sections of Company AI have now been merged. The final part was all to do with the path
finding for laying down track and road. I know a lot of people think that the AI path finding is
rubbish, but it does at least mostly work. With it now implemented, we can start to think about how
we could improve it. One idea I’ve had is to borrow the path finding code for use with a normal
player. We could have a point to point pathing mode where it lays down the track for you. This
wouldn’t be too hard to do, and perhaps it will help root out the bugs the AI has when creating a
path.</p>

<p>Another idea I have, for Company AI in particular, is to try make it into a plugin. The idea being
that the community could write their own AI that specialises in particular tasks. It is perhaps
a little early to do just yet, but no harm having a think about what would be needed or require
changing for it to happen.</p>

<h2 id="road-removal-game-command">Road Removal Game Command</h2>

<p>@AaronVanGeffen implemented the road removal game command a few months ago. Unfortunately, it had
a few little issues, and no-one at the time went through and fixed. After finishing the AI, I
was free to fix the remaining issues. There wasn’t anything too revolutionary in the code, but we
did make a very very minor tweak to the road removal cost calculation: it now rounds towards 0
instead of rounding towards -1. I’m sure no one will notice this tiny change, but it simplifies our
code.</p>

<p>With Road Removal implemented, we now have all the core game commands implemented. In theory, you
could play the game without hitting any of the unimplemented ones. However, there are two that you may
hit: the road add/remove mods commands, which are used by tram track to add/remove catenary wires. It’s
pretty useless to have a tram track without catenary wires, though.</p>

<p>Game commands are the core mechanism that makes multiplayer work, so with them mostly all done
now we could start looking at multiplayer properly!</p>

<h2 id="miscellaneous-implementation">Miscellaneous Implementation</h2>

<p>This month we had three contributions outside of the core team that were focused on implementing
functions. Thanks everyone who contributed!</p>

<p>@spacek531 implemented the connect jacobs bogies code a few months ago. Much like road removal, it
had been sitting in the review queue for a while, sorry about that. It is now finally merged.</p>

<p>@fionasoft implemented <code class="language-plaintext highlighter-rouge">destroyTrain</code>, which is the code that handles train crashing. It was a fun
one to test!</p>

<p>@petergaal implemented a number of scenario setup functions. These functions handle working out the
best road for towns to place and initialise some lookup functions that speedup calculations.</p>

<p>I implemented <code class="language-plaintext highlighter-rouge">updateTree</code>, a surprisingly complex update function. Trees, it turns out, can grow,
multiply, die, and be covered in snow. There are a huge amount of things that can trigger the tree
death! And tree death is a whole animation in itself; it’s not just a simple case of removing the
tree.</p>

<h2 id="vehicle-route-finding">Vehicle Route Finding</h2>

<p>With the AI now finished, it was time to move focus to the remaining vehicle functions. The majority
of the remaining vehicle code all had interactions with routing. I had purposely left these
functions until the end to ensure we understood how things worked. I’m still not 100% sure, but I
think I get the gist of it.</p>

<p>All vehicles are comprised of a number of cars and a number of hidden components. All of these 
components have their own positions and are updated separately. They all share what I have called
a routing. A routing is a list of track ids that the vehicle will follow. The maximum length of the
routing is 64 track ids. (This is why you can’t place a train that takes up more than 64 track
pieces.) It’s not quite as simple as ‘head of train is the first routing entry’, though. There is an
invisible component that runs in front of the head of the train (I think) and there is an invisible
component trailing at the back of the train (I think).</p>

<p>Whenever a vehicle comes up to a junction, it has to decide on a routing. This is the route finding
code. It works mostly how you would expect, i.e. find the shortest path to the destination. It can
only look ahead a certain distance, and only a max of 5 functions. It also has to take into account
signals, which will hopefully indicate if there is a train blocking a route. Track and road route
finding look to be mostly the same, but with the additional complexity of signals for track and
multiple lanes for road. There are three variations of the route finding code. One for normal path
finding, one for aimless wandering (when you don’t set orders) and one for longest path. This last
one is a bit curious, and it appears to be used with placing down vehicles. I haven’t quite got to
the bottom of what it is there for yet.</p>

<h2 id="windows-and-ui">Windows and UI</h2>

<p>@LeftOfZen has finally fixed the issue with scrollbars when you have a huge number of items. The
scrollbar should no longer break.</p>

<p>@ZehMatt has been fixing more of the fallout of adjusting how coordinates work, so hopefully now
there aren’t any graphical issues when you have the news window open.
He also identified an issue with the landscape generation window resetting its state every tick,
which presented itself in problems scrolling the terrain options.</p>

<p>Last but not least, @LeeSpork has been adjusting the map window ensuring its minimum size is sensible.</p>

<h2 id="preparation-for-standalone">Preparation for standalone</h2>

<p>As we are nearing the end of the reimplementation effort, we need to start getting ready for being standalone.
This month, @ZehMatt has been replacing stored pointers in object code with memory offsets instead.
This is a neat trick that will simplify the code when we move to 64-bit.</p>

<p>I started looking at how we can track all our reading/writing of original game memory. We will need to make sure
that we don’t read/write in original game memory space if we want to be standalone. It’s a bit of a dull task
but it will help with understanding the code as well.</p>

<h2 id="italian-translation">Italian translation</h2>

<p>New contributor @Martinocom has added an Italian translation to the game. It’s great to have new
contributors and new languages!</p>

<h2 id="infrastructure">Infrastructure</h2>

<p>New contributor @tyrone-sudeium has added a Linux statically linked build type which uses <code class="language-plaintext highlighter-rouge">vcpkg</code> for
dependencies. This works much the same as the Windows build, which is also statically linked. I know
that traditional Linux developers may see this as sacrilege, but it does make things much simpler.
We will of course <strong>not</strong> be removing the existing dynamically linked setup.</p>

<p>@janisozaur has been fixing a few small warnings on newer compilers, ensuring when we update it all
runs smoothly.</p>]]></content><author><name>Duncan Frost</name></author><category term="news" /><summary type="html"><![CDATA[OpenLoco v25.08 is out! We have a huge amount of behind the scenes changes for this month. Company AI is now fully implemented! All vehicle route finding has been implemented! And there has been a variety of bug fixes. We are now in the very final stages of reimplementing the game in C++. Hopefully, in the next few months, we will be standalone from the original game (for the engine), and we can bring native support for 64-bit and maybe even macOS support again.]]></summary></entry><entry><title type="html">OpenLoco version 25.07</title><link href="https://openloco.io/news/2025/07/openloco-v25.07.html" rel="alternate" type="text/html" title="OpenLoco version 25.07" /><published>2025-07-15T15:30:00+00:00</published><updated>2025-07-15T15:30:00+00:00</updated><id>https://openloco.io/news/2025/07/openloco-v25.07</id><content type="html" xml:base="https://openloco.io/news/2025/07/openloco-v25.07.html"><![CDATA[<p>OpenLoco v25.07 is out! This is more a bug fix release for last month, but it does also have a
little more AI implemented. For a summary of changes, please find the
<a href="https://github.com/OpenLoco/OpenLoco/releases/tag/v25.07">changelog</a> on GitHub.</p>

<h2 id="bug-fixes">Bug Fixes</h2>

<p>At the end of last month, I merged a cleanup change that was meant to fix an edge case with
viewports. Unfortunately, it also broke right-click viewport dragging. This has now been fixed.</p>

<p>There was also a bug with the AI, which would cause a crash when the AI was creating an intracity
network. I’m not completely sure what triggers this, but it was a mistake made whilst implementing
the AI.</p>

<h2 id="company-ai-implementation">Company AI implementation</h2>

<p>The Company AI is fully implemented as of today, but it is still under review. In this release, we
have merged the remaining game commands that the AI uses to build. For some reason, the AI has a
combined command for building track/road and stations. They ultimately just call the place
track/road command, followed by the place station command. Ultimately, not too exciting, but
interesting that they exist. Perhaps in the future we could make these commands available to users.
Although, if we did, that would have to correct the cheats the AI has in the commands that let them
place without spending money!</p>]]></content><author><name>Duncan Frost</name></author><category term="news" /><summary type="html"><![CDATA[OpenLoco v25.07 is out! This is more a bug fix release for last month, but it does also have a little more AI implemented. For a summary of changes, please find the changelog on GitHub.]]></summary></entry></feed>