The m4nfo User manual and Technical Report

Rail types

Defining properties for and handling of rail types

Introduction

The code for rail types consists of three parts:

The definition sets the feature properties of the rail type like its label, related texts, speedlimit, etc. Please note that a rail type definition may only occur after a prior grfinit() function call for the newGRF file.

The rail type's performance functions are used to group sets of graphics sprites from a previous spriteblock(), or to evaluate game-intrinsic variables, and make both of them accessible to the rail type's activation function.

The rail type activation instantiates the rail type by finally assigning graphics sets to a particular rail type element (icon, track underlay, tunnel, catenary, ...). This is done by supplying a block of special functions handling references and rail type elements to the rail type's activation. See below.

Functions

FunctionMeaning
definerailtype(<Label>, <block>)Rail type definition
makerailtype(<Label>, <block>)Rail type activation

Description

definerailtype(<Label>, <block>)

This function defines a rail type. Its parameters are the rail type's label and a block of property-defining functions, where the relative position of the property functions is irrelevant.

Please note that the label has to be quoted like this: {SABE}.

Rail type IDs are newGRF local, with an ID to label mapping. Therefore, to modify an existing rail type, specify its label in definerailtype(). To create a new rail type, again just specify its label in definerailtype(). If a label clashes with another newGRF, then one newGRF will end up modifying the properties instead of creating a new rail type.

Reserved labels for default rail types are: RAIL (normal rail), ELRL (electrified rail), MONO (monorail), MGLV (maglev).

Rail type sets may use up to 16 rail types and should use one of the standardized labels, rather to invent their own ones.

Example (defining new rail type 'DBHE'):
deftxt(rt_tool,
	US, "Electrified main line construction",
	UK, "Electrified main line construction",
	D, "Bau elektrifizierter Hauptbahnen",
	F, UTF8 "Construction de voie ferré (voie principale, électrifié)",
	E, UTF8 "Construccíon de ferrocarril (vía primera, electrificado)",
)

...

definerailtype({DBHE},
	toolbartext(rt_tool)
	menutext(rt_menu)
	vehwindowtext(rt_window)
	autoreplacetext(rt_autoreplace)
	newenginetext(rt_engine)
	compatible_list({"RAIL"}, {"ELRL"}, {"SACE"}) 
	powered_list({"ELRL"})
	railtypeflags(RT_CATY)
	stationtype(RAIL)
	costfactor(15)
	speedlimit(160 km/h)
	acceleration(RAIL)
	mapcolour(176)
)

makerailtype(<Label>, <block>)

This function activates a previously defined rail type. Its parameters are the rail type's label and a block of special rail type feature-associated functions:

FunctionMeaning
link(<ref()>, <rail_type_element>)Linking a chain of graphics or variable dependencies to a specific rail type element
default(<ref()>)Default chain to use with this rail type

Rail type elements assign certain types of graphics defined by their associated chains:

Rail type elementSprite typeNum spritesUsage
RT_ICONIcons and cursors[*]164 rail directions, autorail, depot, tunnel and convert rail. First all icons, then all cursors.
RT_OLAYTrack overlays for junctions and PBS[*]106 flat and 4 slope pieces. Sprites should contain only the track, with no landscape.
RT_ULAYUnderlay[*]166 flat and 4 slope, and 1 X crossing pieces with track, and 5 junction pieces without track. Sprites should contain the track and the 'ballast' below it. No landscape should be drawn.
RT_TNNLTunnel[*]41 sprite for each direction. Sprite is overlay for track in existing tunnel graphics. The original ground sprite is drawn, then the overlay, then possibly a train and the original tunnel head is drawn over the top. This keeps compatibility with different landscape types. Sprite order: SW, NW, NE, SE. If RT_TUPO is defined as well, behaviour is slightly different, see tunnel portal overlay.
RT_WIRECatenary wire28Follows the same layout for wires of the first 28 sprites as Action5 type 5.
RT_PYLNCatenary pylons8Follows the same layout for pylons of the 8 sprites after the wires as Action5 type 5.
RT_BRDGBridge surfaces[*]610 sprites if we ever include diagonal bridges.
RT_XINGLevel crossing overlay[*]101 rail overlay and 4 light sprites for X and Y.
RT_DEPODepots62 sprites for each southern view, 1 sprite for each northern view, following the original layout for depot sprites.
RT_FNCEFences8X, y, vertical, horizontal, SW slope, SE slope, NE slope and NW slope. Follows the same layout as original fence sprites (starting at #1301).
RT_TUPOTunnel portal overlay41 sprite for each direction, order is SW, NW, NE, SE. (Since r23952)
RT_SGNLSignal sprites81 sprite for each direction, order is SW, NE, SE, NW, E, W, S, N. (Since r24367)

[*] These sprites must be provided, the others may be left out if not needed.

Level crossing sprites:

Sprite numberUsage
for xfor y
01Rail overlay
23Northern light
45Eastern light
67Western light
89Southern light

Depot sprites:

Sprite numberUsage
0NE wall for SE-entry depot
1Depot building for SE-entry
2NW wall for SW-entry depot
3Depot building for SW-entry
4Depot building for NE-entry
5Depot building for NW-entry

Tunnel portal overlay:

If this element is defined, tunnels for this rail type will be drawn differently, allowing for custom tunnel portals:

When placing a tunnel, the game first draws a grass underlay base sprite (1), then the sprite returned from RT_TNNL (2). Next, train sprites are drawn (if applicable), then another grass overlay (3), and finally the sprite from RT_TUPO (4). The required grass sprites (1, 3) are provided by the base sprite set (or by custom base sprites) which does not contain any sprites for track or portal, so these have to be provided by the rail type sprite set.


Function tunneltype() can be used to distinguish between several requested tunnel variations. If it returns '0', the tunnel uses a plain portal without any extra features (like tracks above). All other values are reserved for future extensions (e.g. base tunnels).

Signal sprites:

Element to supply custom signal graphics for this rail type. Associated sprite sets for the diverse signal variants, types and states must each consist of 8 sprites, corresponding to the following signal directions, i.e. facing SouthWest, NorthEast, NorthWest, SouthEast, East, West, South, and North. Signal variants are either light - or semaphore signal, signals types are block signal, pre-signals (entry, exit, combo), and PBS signals (1-way, 2-way). Signal state is either "red" or "green", so in total 24 sets with 8 signal sprites each.

Functions signaltype(), signalvariant() and signalstate() return extra information about the signal to be drawn, for the signal's type, variant or state. Function signal() returns combined information about a signal. See example there.

If resolving fails or results in an empty sprite set, the matching base set sprites will be used instead.

Examples

makerailtype(DBHE,
	link(ref(7), RT_ICON)  // icons and cursors
	link(ref(11), RT_OLAY) // track overlays for junctions and PBS
	link(ref(2), RT_ULAY)  // track underlays
	link(ref(3), RT_TNNL)  // tunnels
	link(ref(4), RT_BRDG)  // bridge surfaces
	link(ref(5), RT_XING)  // level crossing overlays
	link(ref(8), RT_DEPO)  // depot sprites
	link(ref(10), RT_PYLN) // catenary pylons
	link(ref(9), RT_WIRE)  // catenary wires
	link(ref(12), RT_FNCE) // track fences
	link(ref(13), RT_TUPO) // tunnel portal
	link(ref(15), RT_SGNL) // custom signals
	default(cbfail())      // s.b.
)

The default would be used for rail type callbacks. However, since there are currently no callbacks for rail types it should always result in a callback failure.