NIMBY Rails devblog 2021-03

NIMBY Rails v1.1 series is ending soon, v1.2 series starts in April

March was focused on polishing v1.1. This effort is meant to make sure v1.1 is enjoyable within its feature scope, without ballooning on new features that will require scrapping or reworking in future major versions. v1.1 is now very stable, relatively bug free and supports an order of magnitude bigger builds than back in January.

I still have some odds and ends I want to review for inclusion in v1.1, and some more performance work which benefits from the simpler v1.1 mechanics, but it won’t be much longer in the works, because v1.2 will start development in April. v1.2 will bring much deeper (and risky) changes to the game compared to v1.1, starting by single track. But for now, let’s see what the final full month of v1.1 brought.

Pax pathfinder v2 is implemented, now with multithreading

The new pax pathfinder described last month is now implemented in the game, with some minor simplifications. I was able to cut down the different required node types to two, and only needed to store one kind edge, while keeping the same expressivity of the original design. Combined with some fixes to the local pax AI, it has enabled a large improvement to the planning capabilities of pax. Its implementation also set the foundations for asynchronous pathfinding, which I implemented at the end of the month.

The new asynchronous pathfinder helper, which warms up the pathfinder cache by speculating what pathfinding the pax inside a train and the pax it will find in its next station are going to require, has made the game an order of magnitude faster. It works by offloading the pathfinding to separate worker threads, and does so before the train arrives at the station. Its results are then aggregated in the already implemented global pax pathfinding cache, avoiding any synchronization delays. The AI is still capable of doing synchronous pathfinding when the required if the results are not ready, so there was zero impact to the AI code complexity.

Pax pathfinder v2.5 is planned (with risk of slipping to v1.2)

A fundamental optimization to the v2.0 pathfinder is simplifying the graph so it only contains transfer stations. I decided against doing so in the v2.0 implementation, since I first wanted to make sure the basic idea was correct. The v2.0 graph is also simpler to reason about and the code is more straightforward. The transfer station simplification will imply adding new nodes that contain the concept of “blob of stations” for all the leg series in a line that have no transfers, and researching if optimized structures for the required sum of times between stations are worth doing.

This and other optimizations to the pax pathfinder will be vital when fixed timetables are implemented, since then it will likely be impossible to cache the results, being dependent on the time of day. There is already a smaller scale situation similar to this with the “biased” case for pax pathfinding (“find shortest path between A and B, but only when riding this train from station A in this direction, and never passing by station A again”). These biased queries end up being so unique that they may as well be uncacheable, and in this case the cache acts more like a results queue from the asynchronous workers. It may be well the case that in the future the only pax pathfinding that is ever performed is by these workers, and trains actually wait for them to finish the job.

Dynamic texture manager for train mods

Trains do not have any texture limits anymore, and the game can handle thousands of different train models if desired. This was achieved by making train textures completely dynamic, capable of being loaded on demand and then unloaded when not needed anymore, at any time. Going forward other systems will migrate to this new texture manager, like the track textures, to also enable any amount of track mods.

Filters for train mod schema v2

While train mod schema v2 was enabled in February, not all v2 features were implemented from the start. March did some catch up in this front and train model filters were implemented in the train purchase screen.

New train speed control and calculator

After some discussion in the forums, combined with some previous notes I had, it emerged that a correct, simple solution to the leg timing problem was to impose a minimum speed to the train. This way it will always keep the pace even if some slow section of the leg is at the end of it. This is now the way leg timing works: the train always keeps the configured min speed, and if it’s late with respect to the input timing (with a simple distance vs time formula), then it speeds up. In the calculator side, the min speed is taken as the max speed instead, with the train always accelerating towards that speed but not going past it (and of course taking into account all the other speed limits due to curves and track types). This combination of factors, and after some fixes, has enabled super accurate leg timings. In absence of blocking traffic the game is capable of running a train for 70 km with under 2s of error with respect to its configured leg time.

Asset listing with realtime stats

A very often requested feature was implemented: asset listings, with support for station listings. This is now implemented and it can display any of the accounting items that apply to the selected object kind, or some of the new realtime stats:

These new stats measure the instant state of the object, and some of them also the state from other objects, like for example scanning the entire pax population of the game to discover which pax have a given station as destination. The data in the game is structured for efficiency, not for analytics, so this has a sizeable performance hit, but it was possible to limit this hit to only happen when this listing is shown on screen.

Various QoL

There was a lot of small and some not so small QoL improvements, and two important ones are the platforms tab and the new “show trip” tab:

The platform listing in the station info window shows all the platforms, with their line stops, and the trains whose next stop is said platform, along with some timing info for the train. The interval timers are also shown. It’s not the same as an arrivals/departures listing but it’s halfway there.

The new “show trip” panel now has timing information and it’s a lot clearer on the transfers. It’s a direct visualization of the paths the v2 pax pathfinder produces.