NIMBY Rails

NIMBY Rails

Not enough ratings
Mod development guide
By Weird and Wry
How to create mods for NIMBY Rails.
   
Award
Favorite
Favorited
Unfavorite
Introduction
At this time NIMBY Rails supports adding new train models to the game with Steamworks mods. Other kinds of mods may be added in the future. In this guide I will describe how these mods are structured, how to develop and test them, and how to upload them to Steamworks.
Concepts
Rules
In the game systems, a rule is an object that contains constant, immutable data that controls parameters of the simulation. Mods are just a collection of rules objects written in an easy to edit text format, plus any required data in separate files, like textures.

IDs
Rules objects usually have an ID field, and often make reference to other rules objects by using their ID. When creating your own mods you must pick unique IDs for your rules objects, not used by the game or by other mods. IDs are arbitrarily long strings so it should be easy to come up with both unique and readable IDs.

schema
All the objects declared in the mod have a schema field. This declares the version of the mod structure, and allows the game to load older mods. Use the schema value indicated in the rules tables in the next section.

(E)MUs
At the time of this writting the game only supports train models known as (electrical) multiple unit[en.wikipedia.org]. In MU trains the carriages are self-propelled and are usually part of a single whole train designed to go together. There's still a distinction of carriages for the ends of the train and the inner carriages, and the game has support for this. In the future the game may also support custom train compositions edited in-game by the player.
Train Rules
TrainUnit
The rules object TrainUnit represents the combined concept of a train car and/or locomotive. The game makes no distinction, and a TrainUnit may act as both concepts at the same time, depending on how it is configured. This is modeled after contemporary electrical multiple unit trains (EMU), which can have engines in every car. It is of course possible to declare a TrainUnit with no power if unpowered cars are desired.

Field
Type
Range
Description
schema
integer
1
This guide describes schema version 1
id
string
any string
Global, unique ID that identifies this TrainUnit
name_loc
string
any string
ID used to localize name_en
name_en
string
any string
English name of the carriage
length
meters
1 to 30
Length of the carriage
width
meters
1 to 3.75
Width of the carriage
max_speed
km/h
10 to 10,000
Max allowed speed
power
kW
0 to 100,000
See the description below
empty_mass
kg
1,000 to 100,000,000
Empty mass of the carriage
price
"cash"
0 to 1,000,000,000
Price for one carriage unit
max_pax
passengers
0 to 1,000
Max allowed passengers
cost_per_km
"cash"
0 to 1,000
Price to pay for running this carriage over 1km
cost_per_day
"cash"
0 to 100,000
Price to pay for running this carriage for 1 day
tex_base
relative path
any valid relative path
Base, colorizable texture
tex_top
relative path
any valid relative path
Top texture
tex_decors
relative path list
a list of valid relative paths
List to decorative colorizable textures
tex_m_width
meters
30
This field must be always 30
tex_m_height
meters
3.75
This field must be always 3.75

The power field vs tractive effort
Engines are not currently moddable, so instead the TrainUnit only allows to specify a power output value in kW, then the game applies an internal formula to derive a tractive effort.
// tractive effort = K * (n * P / V) // tractive effort is expressed in N // K = constant // n = efficiency of motors // P = power in W // V = speed in m/s tractive_effort += 3.0681818 * ((0.9f * power) / max_speed);
When deriving this value, keep in mind you are specifying its value per carriage, so divide accordingly for MU trains.

TrainMultipleUnit
A TrainMultipleUnit represents a multiple unit train model, and references TrainUnit objects for the head, cars and tail composition. The game only supports multiple unit trains, and you must declare at least one TrainMultipleUnit if you want to add new trains to the game.

Field
Type
Range
Description
schema
integer
1
This guide describes schema version 1
id
string
any string
Global, unique ID that identifies this TrainMultipleUnit
name_loc
string
any string
ID used to localize name_en
name_en
string
any string
English name of the multiple unit
head_id
string
a valid TrainUnit ID
ID of the TrainUnit positioned in the front
car_id
string
a valid TrainUnit ID
ID of the TrainUnit of the inner carriage
tail_id
string
a valid TrainUnit ID
ID of the TrainUnit of the last carriage
tail_flip
boolean
true or false
Horizontally flip the texture of the tail TrainUnit
min_cars
integer
1 to 30
Minimum amount of inner carriages
max_cars
integer
min_cars to 30
Maximum amount of inner carriages
Mod structure and development
A mod is just a folder that contains a file named mod.txt. This file is formatted using the simple INI syntax[en.wikipedia.org]. Inside mod.txt you must declare at least one ModMeta section, and then one or more rules sections.

Folder structure
Here's how the structure of folders and files looks like when you are developing a mod in your local PC. If you put your mod in the "mods" folder of your local saved games folder, it will show up in game. In this example you are developing a mod inside the folder "nr-example-train".


The only mandatory file is "mod.txt". You can also create any other folders and files required to organize and bundle textures in your mod.

Example mod.txt

This mod.txt file can be found in the example mod github[github.com].

[ModMeta] schema=1 name=Test train mod author=Weird and Wry desc=testing 1 2 3 version=1.0.0 [TrainUnit] schema=1 id=test1_car name_loc=test1_name name_en=TestTrain length=6.5 width=2.4 max_speed=70 power=144 empty_mass=7000 price=1700000 max_pax=45 cost_per_km=5 cost_per_day=700 tex_base=AlstomCitadis/car_0.png tex_top=AlstomCitadis/car_2.png tex_decors=AlstomCitadis/car_1_0.png,AlstomCitadis/car_1_1.png tex_m_width=30 tex_m_height=3.75 [TrainUnit] schema=1 id=test1_head name_loc=test1_name name_en=TestTrain length=6.5 width=2.4 max_speed=70 power=144 empty_mass=7000 price=1700000 max_pax=40 cost_per_km=5 cost_per_day=500 tex_base=AlstomCitadis/loco_0.png tex_top=AlstomCitadis/loco_2.png tex_decors=AlstomCitadis/loco_1_0.png,AlstomCitadis/loco_1_1.png tex_m_width=30 tex_m_height=3.75 [TrainMultipleUnit] schema=1 id=test1_mu name_loc=test1_car_name name_en=TestTrain head_id=test1_head car_id=test1_car tail_id=test1_head tail_flip=true min_cars=1 max_cars=3

ModMeta
The ModMeta section gives some general information that is displayed to the user in the game UI.

Field
Type
Range
Description
schema
integer
1
This guide describes schema version 1
name
string
any string
Mod name used in the in-game UI
author
string
any string
Mod author name used in the in-game UI
desc
string
any string
Mod description used in the in-game UI
version
string
any string
Mod version used in the in-game UI

Steamworks uploader
In order to create and upload your mods to Steamworks, you first need to make sure your mod works properly as a local mod, and have it installed as such. So the first step is to develop your mod as a local mod, in your local mods folder as described in the first section of this chapter.

Once your local mod is ready, you can use the Steamworks mod uploader available in the Main Menu, Options dialog.


By default the mod uploader shows a listing of your authored mods already uploaded in Steamworks, and a series of options.
  • New mod: Create a new mod from an existing local mod
  • Update mod: Update the selected Steamworks mod from an existing local mod
  • View mod in workshop: view the selected Steamworks mod in the Steam overlay
  • Manage workshop: view your private Workshop in the Steam overlay
  • Mod development guide: opens a browser with this guide

When you select "New mod" or "Update mod" the mod editor is displayed:


You must fill all the displayed fields before you can create or update an existing Steamworks mod.
  • Title: mod title to display in the Workshop
  • Visibility: decide if you want to make your mod public or not. You can change this option later if you update your mod again
  • Local mod to upload: select an existing, local, valid mod as the contents for this Steamworks mod
  • Icon file: type a path or open a file picker to select an image to display in the Workshop as the mod icon
  • Description: mod description to display in the Workshop
  • Update note: mod change log to display in the Workshop (only for updates)

You may find it easier and more usable to edit the description and update note fields from the Workshop interface than from the uploader interface, after the uploader is done creating or updating your mod.

Textures
Train units are drawn with 3 texture layers: base, decal and top. Every layer is a full RGBA 32bit PNG image of size 1024x128, which always corresponds to a real world size of 30m x 3.75m. Train units can be shorter and narrower than this size, in that case the unit must be aligned to the left of the image for the X axis, and centered in the Y axis. The real size of the train unit is then declared in the TrainUnit section of the mod.txt file (in meters, never in pixels). Use a conversion factor of 34.13 pixels per meter when drawing the textures.

You can store the PNG files in the mod folder with any name, and with any subfolder structure you wish to use, as long as you use correct relative paths to reference them from the mod.txt file.


The base layer is drawn first, and it can be colorized by the user in the train properties editor. For this reason it is recommended to make this layer grayscale. The colorization function is a simple component-wise color multiplication. Use this layer to represent the bulk of the train unit.


The decal layer is drawn on top of the base layer. It is also colorizable by the user, and uses the same multiplication function. It is possible to declare a series of decal layers in the same TrainUnit by separating them with commas. The user will then be capable of choosing one in the train properties editor. Use this layer as a decoration, to give the user more customization options. The user can also colorize this layer with the line colors.


The top layer is drawn on top of the decal layer, and it is not colorizable. Use this layer for final details and for parts of the train that should never be colorized, like windows.