1. NIMBY Rails
  2. News

NIMBY Rails News

Version 1.18.30

- Stop selection signals now again perform a (possibly redundant and unnecessary) goal stop selection at the last possible moment, both from a stop or a pass-by.
- Fix: queue_train_drive_to() was fully resetting the Motion::drive component and zeroing the stored waiting signal ID. If the train was positioned exactly at or an infinitesimal distance distance ahead of the signal (which is legal) it caused the train to skip the signal wait.
- Fix: dead end point mode tracks set as parallel of a point mode track did a poor job of matching the tangent of the parent track
- Fix: push-pull capability was cached in the Motion Dynamics instance, but it could become stale after certain editing operations. Now this flag is never cached and it is instead always calculated on demand. It is now also possible to check this flag in the train editor, as additional information in the "Composition" item. By hovering the mouse over this new text a debug report with all the flags involved in the push-pull decision is also displayed.
- Fix: queue_train_drive_to() called for trains in a timed stop should not try to start a drive, it should just store the new_destination component. Additionally when finishing a timed stop, check if a new_destination component already exists in Motion, and do not create a new one for the next line destination (but still advance the run_dispatch state).
- Fix: in some cases, do not extend lifetimes when the result of an expression has value storage, fixing some too strict compiler errors in statements like m = m + k.
- Fix: display "description" for Vec struct fields as a tooltip on the title header
- Fix: train lateness information in the ended_drive component was being cleared in some cases
- Fix: train lateness accounting was off by a factor of 10x due to some extra zero
- Fix: just dispatched trains had a lingering, useless dispatch_cooldown component

Version 1.18.27

- Fix: script operator precedence for "!" and unary "-" was incorrect. You might need to review your code if you used these operators without parentheses.
- Fix: crash when loading saves with potentially invalid demand curves
- Fix: show again reservations on the map but only if the map reservation mode is enabled

Version 1.18.26

- Remove debug display of train reservations on the map
- Fix: shared simulation multiplayer did not properly sync train motion state
- Fix: wrong auto scroll listing position in some cases
- Fix: more instances of possible crashes while pausing the game, disabling train mods, and then editing trains which were using these mods
- Fix: rare crash while rebuilding timetables

Version 1.18

[p]Version 1.18 is finally released. This version has been a long time under development, also with a very long beta period, due to the complexity of its main feature, NimbyScript. Until 1.17 game mods have been limited to changing textures and adding new static rules (in the form of new trains, tracks, etc), with no new mechanics possible. NimbyScript adds programmability to game mods, allowing them to add new mechanics to the simulation.[/p][p]Some signal and script mods are already available in the Workshop, and more will appear in the future. I want to thank all mod developers (scripting or not) for their hard work in providing mods for my game. NimbyScript, its API and signal mods have been designed with their feedback over the past few months.[/p][p] [/p]
Signal texture mods
[p]
Mods can now offer new textures (or collections of textures) for signals. In 1.18 the visuals of signals have been completely made independent of their function and logic. The core simulation keeps the existing textures and rules, but by using mods you can now put any texture you wish on any signal. Multiple signals states can also be textured as desired, both the default 2 states for path signals and any amount of custom states if the mod also provides a signal texture script.

[/p]
NimbyScript
[p]
NimbyScript is a custom programing language for developing scripts for NIMBY Rails. It is quite limited compared to general purpose languages, but in exchange it has nearly the same speed as compiled C code, because is actually compiled as C code on loading the script. To ensure the future evolution of the language it has not been designed as special purpose. For example concepts like Train or Station are expressed as types, not as a first level entities of the language.

You can read the NimbyScript guide and its API reference in the official wiki:

https://wiki.nimbyrails.com/NimbyScript

The Steam modding guide explains how to make script mods:

[dynamiclink][/dynamiclink]
For your personal saves, you can make private mods which reside in the "mods" folder of your saved games folder. A copy of the script is also stored in the save, so save sharing and multiplayer remain functional even when using private and unsubscribed Workshop scripts.

Scripts are displayed in the UI as "Extensions". These new extensions appear in some editors, like Signal properties panel or the train editor panel. Players first enable an extension in the list, then the extension can be further configured with its own UI in the same panel.

[/p]
NimbyScript APIs
[p]
There's many new features in the train simulation for 1.18, but most of them are exclusive to NimbyScript. This will allow modders to precisely express certain features the way they see fit, within the confines of the API.

[/p][h2]Changing the result of a path signal check[/h2][p]
All path signals can now call into one or more scripts to change the result of a "pass" check into a "stop" check. Scripts can use any logic they want for this extra check, including checking other trains, the simulation time, looking up tags,

[/p][h2]Path change from any signal[/h2][p]
All path signals can now also be path change signals by using scripts. Scripts can return a new goal position for the train checking the signal. The train will automatically pathfind to the new goal position and if it reaches it, it will also automatically pathfind toward its line stop goal. The goal position of the train can be changed an unlimited amount of times by any amount of signals or scripts, and it will always pathfind itself back to the line stop when needed.

[/p][h2]Lookahead system[/h2][p]
Trains periodically scan their future path for up to 15km, and invoke a script for each path signal hit during this scan. These scripts in return can set speed limits for the train, which unlike a red signal, apply immediately and from any distance. This allow to emulate signal aspects which limit the train speed rather than just stopping it. The lookahead system can also be used to passively gather information for signal texture states.

[/p][h2]Marker reservations[/h2][p]
A new "blank" signal, the marker, is now provided. This signal is very useful as a passive sensor for scripts, and it will be used like this most of the time. But it also has an active capability: it can "fake" a reservation at its point of the track. This allows to extend reservations beyond signals with the use of scripts which get called when a reservation probe runs on top of the marker signal.

[/p][h2]Custom signal texture state[/h2][p]
The decision to which texture show for any given signal can be fully customized by scripts. Scripts can reference any amount of states declared in a signal texture mod to change the signal texture, under any logic they desire. This works for all signals, not just path signals.

[/p][h2]Shift assignation condition modifications and vetoing[/h2][p]
When the shift dispatch system is trying to find a shift for a train, and it finds a suitable candidate, it will now call a script with all the gathered information. The script can then veto this decision to force the system to keep looking for a different shift.

The initial setup for the shift dispatch process can also be scripted. The system will first prepare a default setup with all the relevant information, like simulation time and train location, and a script can then force it to ignore some of that information so more shifts are considered, or modify some of the information, so for example shifts in the past are also considered.

[/p][h2]Interventions and teleporting[/h2][p]
Lower frequency scripts with access to the more powerful SimController API can issue unlimited interventions, teleports and drive orders to trains.

[/p][h2]Schedule-less line running[/h2][p]
Scripts can force a train to run a specific line at any time, ignoring the schedule system. This is useful for technical maneuvers and for roleplaying non-pax operations. These trains can even carry pax if there exists any shift with the same line scheduled a similar time, mostly useful to issue extra trains in high TPH services like subways.

[/p][h2]Hitching and train reconfiguration[/h2][p]Trains can now have up to 8 different post-purchase configurations. These configurations are player-edited, in the train editor. They cannot append new cars or reorder them, only remove them from the purchased configurations. Scripts are then able to switch the train into any of these 8 configurations. For example a train could be reconfigured to to not have a locomotive prior to coupling. [/p][p][/p][p]Train coupling is now possible, and controlled by scripts. This is internally called "hitching" since "coupling" is already being used for car coupling in train compositions. The concept of "train coupling" is extremely complex when every possibility is considered, and it's unworkable to try to fit them into the UI/UX and the schedule system. So instead coupling is only offered to scripts, with an API which allows to couple any train to any other train (including multiple trains), optionally changing its orientation. Combined with reconfiguration this enables many coupling concepts. The coupling and uncoupling process will be controlled by scripts, so the specific mechanics are left to mod developers.[/p][p][/p]
Timing changes
[p]In order to enable scripts to set arbitrary speed limitations at any time, the train dynamics formulas had to be changed and simplified. This means some saves will see a subset of their line and shift timing change, and might need manual adjustment.[/p]

Devblog for September 2025

[p]Signal scripting is finally in a finished enough state to create new signals! During September a lot of decisions to adjust NimbyScript for general usability were made, and the first 3 examples of real new signaling features were implemented: custom path reservation boundaries, custom signal checks, and the holy grail, path changing signals with no restrictions, fully independent of lines and schedules. Read and see more in the devblog:[/p][p]https://carloscarrasco.com/nimby-rails-september-2025/[/p]