Guide to railtypes

From GRFSpecs
Jump to navigationJump to search

Trains and Railtypes both affect where a train can run and not, on top of this trains also need the correct railtypes to be defined in order to show up. This means that train and railtype sets need to coordinate so that the expected behavior can be reached.

This guide is writen for nml but it should be possible to follow if you subsititute the nml properties with the NFO ones, see below:

WIP

The railtypetable

The railtypetable maps the track type specified in the property track_type to a railtype label. NML will only use the RAIL, MONO and MGLV labels if no railtypetable is provided.

For more info see NMLTutorial/Railtypetable and NML:Railtypetable-Roadtypetable-Tramtypetable

Railtype properties

The following properties are relevant for how vehicles and railtypes interact with each other:

property comment
label names of default rail types: "RAIL", "ELRL", "MONO", "MGLV". See the List of railtype labels in the NewGRF Specs for currently defined custom labels.
compatible_railtype_list Provide a list of rail types that trains of this type can also run on. e.g. ["RAIL", "ELRL", "MONO"]. Note that when routing trains, the compatibility is only evaluated for the lead engine of a consist. This means that trains will run on incompatible rail types if they are in a consist where the lead engine is compatible with the rail type. This applies to both engines and wagons.
powered_railtype_list Provide a list of rail types that trains of this type are powered on.
alternative_railtype_list

Supported by OpenTTD 1.2 (r23758)1.2 List of rail types which this rail type will act as fallback for, if the corresponding rail type is not defined separately


Trains with only one track type

item (FEAT_TRAINS, train) {
	properties {
		track_type: REF_TO_RAILTYPE_TABLE;
	}
}

By default OpenTTD will always make sure the railtypes RAIL, ELRL, MONO and MGLV exist, as such you are free to use these as you see fit.

Tracks not provided by default

You may very well want more types of tracks that those provided by OpenTTD for this you will need to use a trackset. They define more tracks with their own labels. We can't possibly know which tracks to use and which tracks exist. To solve this the Standardized Railtype Scheme was created, it defines generic interpertaions of certain labels so that trainsets and tracksets can trust that things will work as expected. You don't have to use the standard but it is highly recommended as it will allow your set to work with almost all tracksets, else you might have to make your own. There are also a few labels not in the standard which can be found at TracktypeLabels.

A given may not exist at all times however which will mean your train won't show up in game. To solve this you can use the fallback syntax in the trailtype table which is as follows:

railtypetable {
	RAILTYPE: [SAAN, RAIL]
}

This is quite powerful, but it does not affect compatibility for that you should instead read the section below about multiple track types on one train. You should also consider if you want and need the track type to have fallbacks, narrow gauge vehicles probably don't need to show up on standard gauge tracks for example.

Trains with multiple track types

Some trains of yours might need to have multiple railtypes in order to work. Examples of this include UK thameslink trains and the russian EP10.

For this we need the following railtypetable which uses labels from the standardized railtype scheme.

railtypetable {
	DC_3KV: [SAAD, SAAE, ELRL],
	AC_25KV: [SAAA, SAAE, ELRL],
	DC_3RD: [SAA3, "3RDR"]
}

Thameslink train

item (FEAT_TRAINS, train2) {
	properties {
		track_type: [AC_25, DC_3RD];
	}
}

EP10 train

item (FEAT_TRAINS, train3) {
	properties {
		track_type: [AC_25, DC_3KV];
	}
}

The thameslink train will work without issue in this example however the EP10 will not. This is because if a trackset provides tracks for 25 kv ac (SAAA) and 15 kv ac. In that case the DC_3KV track type would become SAAE which is allowed on 15 kv ac tracks, this isn't intended as we only want the train to use SAAE when both SAAD and SAAA don't exist. This could be eliviated by not including SAAE and ELRL in the track type definition, but then the train will not show up on the default tracks. Another solution is to use if blocks to change the used track type. In the future it may be possible that nmlc is extended to allow testing for both SAAA and SAAD in the railtypetable before falling back, until then the below provided solution will have to be used.

 railtypetable {
 	DC_3KV: [SAAD],
 	AC_25KV: [SAAA],
 	ACDC: [SAAE, ELRL]
 }
  
 if (railtype_available("SAAA") || railtype_available("SAAD")) {
 	item (FEAT_TRAINS, train3) {
 		properties {
 			track_type: [AC_25, DC_3KV];
  		}
     	}
 } else {
 	item (FEAT_TRAINS, train3) {
 		properties {
 			track_type: ACDC;
 		}
 	}
 }

Changing speed and/or power of trains based on railtype

One might be interested in implementing a train which speed and/or power depends on the voltage in the overhead line electrification. In order for this to work properly the newgrf needs to test the track with var 63 or NML tile_powers_railtype. In practice this will look like the following:

tile_powers_railtype("ELRL")

Below is a more complex example from RUKTS code, where a train with a diesel generator has higher speed on high voltage ac tracks. We need to test for only SAAA if it is avaliable, as otherwise we would have the train gain the benefits on all electrified tracks. If it however isn't avaliable we still want to know if the track is electrified which is why we have the second part. This is only neccesary if your set cares about voltages.

railtype_available("SAAA") ? tile_powers_railtype("SAAA") : (tile_powers_railtype("SAAE") || tile_powers_railtype("ELRL"))

Rack rail

There are two different types of rack rail engines, pure rack and rack and adhesion. Pure rack engines may only move on tracks fitted with racks (xRxx) whilst rack and adhesion engines may also move on regular tracks but at a lower tractive effort.

Rack rail is currently implemented in the speed class as a "special type", this is unfurtunate as the speed class would otherwise be trackset private.

Alternative 1

Pure rack engines

These engines should use *R** as label. A trackset could then prevent these trains from traversing *A** tracks.

Rack and adhesion engines

These engines should use *A** as label and test for *R** using var 63 or NML tile_powers_railtype. This assumes the trackset will allow *A** on *R**.

Issues

  • Currently French Set Rails (the most popular rack-rail set) implements compatibility both ways which makes pure rack systems impossible.
  • French Narrow Gauge Trains Set uses NRAN for rack and adhesion engines so tracksets can not support it as intended and pure rack systems at the same time.

Alternative 2

Pure rack engines

These engines should use *r** (not in scheme) as label. A trackset would then prevent these trains from traversing *A** tracks but allow them on *R**.

Rack and adhesion engines

These engines should use *R** as label and test for *r** using var 63 or NML tile_powers_railtype. Tracksets will allow *R** on *A** and *r**.

Issues

  • Requires more track types than alternative 1.