NIMBY Rails devblog 2024-05

End of 1.12 beta

The first half of May was dedicated to 1.12 beta development. Overall the 1.12 launch went quite smooth and it only triggered real problems on extreme saves, like saves with 5k+ stations and/or which had 10k+ activated tiles. In response to this, and to other overall problems with the 1.12 design some changes were made during the beta.

1.12 increased the station catch radius to 3km, but this proved too much. It made large saves activate too many extra tiles, slowing down massively the demand tile rebuild. This demand tile rebuild, new in 1.12, is a preprocess step which precalculates the pax relationship between all tiles of the map. It speeds up immensely the pax simulation, at the price of an extra calculation step when stations are edited. It’s a very worthy tradeoff, but it has quadratic cost, growing with activated tiles. During the beta the radius was tunned down to 2.3km after some empirical testing on some of the largest saves.

A major feature of the 1.12 demand system is (was) the fact that demand between two tiles was completely independent of other tiles. This was accomplished by increasing pax demand rate in a tile proportional to the reachable “rest of world” tiles, in a way that left any existing demand intact. But players strongly rejected this new design after testing it with their saves. So I changed it back to an hybrid system where demand is redistributed when new destinations open up (1.11 style), but it’s also increased a bit, following a logarithm curve.

The other major feature of 1.12, POIs, mas made fully modable. The original plan for 1.12 mods was just to use blueprints, but this has the problem of being a one-off usage by players. After the POIs are created, they cannot be updated by the mod author, either curves or POIs. So a new kind mod was introduced for immutable collections of POIs and demand curves. These remain in control of the mod author so mod updates are possible.

Even after all the fixes and optimizations in the 1.12 beta, large saves still had problems with RAM usage and processing time. The problem was still the quadratic time and space required for the cached NxN relationship mapping between activated tiles. The final major development of the beta was to solve this problem by changing this exhaustive quadratic mapping into a quadtree based system. In this system each activated population tile stores its relationship to other tiles by grouping them together as a single tile from its point of view. The further the tile, the larger the group. Originally this used fixed size tiles depending on the distance but it was later refined to be adaptive based on population. In this example the origin tile is in NYC:

This new system dramatically cut down the required RAM and CPU processing in large saves, at the cost of a more imprecise application of the distance demand curve (weighting by distance is not “drilled down” once a large tile is selected, but population is).

(1.13) Walk legs

1.13 development started even while 1.12 beta was ending, since 1.13 feature set is based on 1.12 development. 1.12 and 1.13 are sister versions, one complimenting the other, but I wanted to split them in half since pax demand changes alone were impactful enough.

A very often requested feature is now present in 1.13: pax can plan a path which includes walking between stations. For any given station, if another station is within its catch radius, or if the station is within the catch radius of the other station, it is considered possible to walk between them, in both directions. There is no need to build any kind of object or to enable any kind of preference in the stations, it is always enabled and automatic.

When pax are in the process of planning a path, they will consider all the outgoing train legs of a station, and starting in 1.13, they also consider walking to all the walkable stations as defined earlier. These new “walk legs” are timed to start immediately when a pax arrives to a station, and have a duration which is equal to walking in a straight line at 1 m/s (this is the same as the “Shortest walk, best path” criteria). This is slow, and in well developed (existing) saves it takes quite a bit of effort to find cases of walk legs in the middle of a normal looking pax path. It is instead more frequent to find things like this:

So what is going on? This screenshot was taken in a well timetabled save which depots most trains at night, in the middle of the night. Pax have managed to find a path even with no trains running, just by chaining walk legs. Avid players will ask, why is the “do not allow paths slower than just walking all the way” filter from 1.12 not applying there. The reason is that filter only works at the moment of spawning pax, and only for “Shortest walk, best path”, and the rest of pax pathfinding does not apply it. I will look into fixing it before 1.13 is public. But even if fixed, this next example will still be possible:

Multiple chained walk legs, with one or a few train legs in the middle. These paths will remain possible in the public 1.13 version, and the reason is that restricting walk legs based on what on the surface are “intuitive” rules like “no more than 1 walk leg” or “do not allow walk legs one after the other” makes the pax pathfinder to become inconsistent. It means pax paths become context-dependent, in the sense that a sub path of the whole path now requires knowledge of the rest of the path to make a decision.

In any case I don’t believe these extreme examples at the margins of the timetable are bad enough to discard this feature. The impact will be reduced with more path filtering as I mentioned earlier. And it of course works as intended when encountering the “normal” case most players have in mind:

It took me awhile to find a save with these cases easily visible, since existing saves are adapted to 1.12 mechanics so they fuse stations or implement shuttle-like lines between nearby stations. Or just fully develop local transit, like real life. But starting with 1.13 I expect more saves to be designed with walk paths in mind, so there will be less need to fuse stations, at least.

There is a noticeable CPU cost associated with this feature. It is very dependent on the saves. Saves with very dense large urban networks are the most affected, since there’s a myriad of possible walking legs to consider on most stations. That being said the impact is lower than, for example, enabling best path on spawn, so for now I am not adding a toggle for this feature.

(1.13) Station halls

Where in the world is a pax walking between stations? They are stored in the hall of the station they are walking towards to. In 1.13 station pax can exist in 2 different places: the platforms (this is the existing 1.12 place to put pax) and the hall. Platforms have limited capacity but halls are unlimited. Stations halls are a new data structure in 1.13. Pax in halls are unable to board trains. Indeed they are completely ignored by trains. It is possible and intended for trains to leave pax on the ground if these pax are in the hall. Pax in halls also have a queue time. After their queue time is finished the pax sim will continuously try to move the pax from the hall to the platforms. In fact a pax can only remain in the hall as long as one of 2 conditions hold: it has a nonzero queue time, or the platforms are full.

When a pax arrives at a station, and the next leg of their path is walking to a nearby station, it is immediately put in the hall of the nearby station. Their hall queue time is equal to the time it takes to walk to the nearby station, so its hall wait emulates the cost of the walk leg.

So, out of the need to put walking pax somewhere, station halls have been born. I can already hear the million suggestions on doing other things with halls, so let me address two obvious ones which are already discarded.

Put newly spawned pax in halls, with the walk time as queue time. This is an obvious one, but it doesn’t work properly. The reason is that newly spawned pax are subjected to a path check to make sure they can be serviced at the current time of the week, not the time after they walk to the station. Why is this important? Because pax pathfinding is very heavily cached, and this cache depends on only storing the currently dominating path. If the cache had to introduce future dominating paths, because pathfinding is now being done with future times, it would stop being effective. It would be ruinous for game performance. Therefore newly spawned pax cannot be put in the hall with a walk queue time. But they can be put with zero queue time! This way, if the platforms are full, they will just stay in the hall until there’s space for them.

Put transfer pax in the hall, with a queue time equivalent to waiting for their train. I would really like to implement this one, and in fact I did, but it’s very bad on some player saves. A significant amount of player saves are completely dependant on the various ways the game has of allowing pax to board late trains, or alterative trains in case their preferred train is delayed. These systems only work if pax are present in the platforms, because they are evaluated on a train-by-train basis, they are never calculated in advance. If late/alternate train boarding did not exist this would be perfect, but these player saves are in a perpetual state of lateness, or the player themselves don’t want to make the effort of timetabling, so transfer pax cannot be put in the hall with the correct time.

That being said, transfer pax can be put with a very short (10s or less) or zero queue time, allowing stations with full platforms to always accept pax. Lost pax due full stations will become a thing of the past in 1.13.

(1.13) YOLOing station capacity

Every 3 or 4 months there’s some thread in the Steam forums asking for more station capacity. These threads remind me of the one more lane bro meme, replacing “one more lane” for “one more 1k pax”. Most of the time I go there and explain why it is in place. In case you’ve never read my explanation here’s my latest one:

The “artificial” limit is there to balance pax boarding flow, max train wait at stations, and not introducing massive lag spikes every time a train arrives to a busy station. Contrary to what is being implied in this thread the assignation of “next train” is not done once, it is constantly being refreshed as trains arrive to the station because trains can be late. Refreshing that decision is slow, therefore it is staggered over time, therefore it dictates a maximum pax boarding flow, which combined with the 3m boarding limit, gives roughly a 10K max amount of pax which could be reviewed over 3m.

Any of these numbers could be bumped up or down with a variety of undesirable and desirable results. The current balance is towards making sure gameplay stays smooth while having the least undesirable results most of the time for most stations and trains.

To add to this explanation, I am kind of baffled that some of the time the players asking for more capacity have throughput problems in their network. Like, if you have problems servicing a network with 10k max pax stored in its stations, what does it make you believe you will have an easier time if it stores 20k? 30k? The 10k limit is helping run your overloaded network!

Well, we are all going to find out, because 1.13 will launch with 100k platform capacity on all stations, and unlimited capacity halls as I mentioned earlier. Also the spawn capacity limit is lifted, and stations can now hold unlimited newly spawned pax in their halls.

How is this possible in the light of my earlier comment in the forums? The 10k and pax boarding flow limits were set years ago, when the pax pathfinder was much less optimized, and the game was way less capable of using multiple CPU cores. The 10k limit is as old as 1.1 and the flow limit was last tweaked in the 1.6 or 1.7 timeframe IIRC. But 1.13 is a beast compared to these old versions. So in addition to increasing the platform limit to 100k, the boarding flow has been increased by 10x, to keep up with the new platform limit. In my testing the slowdown is small in properly designed saves which only exceed 10k pax in a few stations at rush hour, and it is eclipsed by the slowdown introduced by having walking paths.

I fully expect a “3km radius” situation in the 1.13 beta with this feature, with some saves stuck on 100k full platforms and perpetually filling halls, with major slowdowns. These numbers can and will be tweaked during the beta. But in 1.13 every station can be Shinjuku station if you want.