Additions to NewGRF Specifications in JGR's Patchpack in NML

This document describes non-standard additions to the Official OpenTTD NML Specifications which are present in this patchpack and the associated NML fork.

These additions MAY also be present in other patchpacks. They MAY be removed or moved in future, if necessary.

Not all standard NewGRF features are supported by NML, consequently not all non-standard additions to the specifications are supported by this patchpack's associated NML fork, or are listed in this document.
See the associated non-NML document for more details.

All of the non-standard features listed below will automatically emit suitable feature tests, conditionals, etc. such that NewGRFs which use these features will work correctly on OpenTTD versions which do not support these features, including standard trunk OpenTTD and older/other patchpack versions.

All of the non-standard variables listed below will return 0 on OpenTTD versions which do not support these features/variables, including standard trunk OpenTTD and older/other patchpack versions.

Features with separate pages

Sections


Builtin functions

extended_feature_test(feature_name[, min_version[, max_version]])

This returns true if the given extended feature is present and has a version within the specified minimum and maximum (inclusive).
This function should only be used after the grf{} block.
In most cases it is not necessary to use this function, as extended properties (listed below) which are not supported are simply skipped/ignored.

Additional switch types

In addition to SELF and PARENT, switches for vehicle features may use one of the following types below.
(These are mostly the same as in random_switch).
The 'x' parameter (count x vehicles in given direction) is currently required to be a compile-time constant between 0 and 255.

TypeMeaning
BACKWARD_SELF(x)Count x vehicles backward (away from the engine), starting at the vehicle itself
FORWARD_SELF(x)Count x vehicles forward (towards the engine), starting at the vehicle itself
BACKWARD_ENGINE(x)Count x vehicles backward, starting at the leading engine
BACKWARD_SAMEID(x)Count x vehicles backward, starting at the first vehicle in the chain with the same ID

These require the more_varaction2_types feature. If this feature is not present, switches of these types will produce a CB_FAILED result.

Ship callbacks

The articulated_part callback is also available for ships.
Additional ship parts are not used for graphics, they are only used for additional cargo capacity, the default graphics chain is unused.
The default graphics chain for the primary vehicle may check the cargo states of the other ship parts if required.
Additional ship parts may be refitted individually.

This requires the multi_part_ships feature.

From version 3 of the multi_part_ships feature, spritegroup loading/loaded cargo thresholds refer to the entire ship, not just the first vehicle.

Added callback: refit_part_name
This callback is called on the primary vehicle to get the name of each part of the ship (e.g. the name of each cargo hold) in the refit window.
This is not called for ships of only one part.
The callback handler should return a string or CB_RESULT_NO_TEXT.
If this callback is not handled or if CB_RESULT_NO_TEXT is returned, a default name is used.
getbits(extra_callback_info1, 0, 8) contains the index of the part of the ship. The first/primary part is 0, each subsequent part increases the value by 1.

Railtype properties

PropertyValue rangeComment
enable_programmable_pre_signals0 or 1 Enable programmable pre-signal graphics in railtype signals.
Programmable pre-signals have a signal type (getbits(extra_callback_info2, 16, 8)) of 6.
enable_no_entry_signals0 or 1 Enable no-entry signal graphics in railtype signals.
No-entry signals have a signal type (getbits(extra_callback_info2, 16, 8)) of 7.
No-entry signals always have a signal state of red.
enable_restricted_signals0 or 1 Enable restricted signal flag in railtype signals.
When enabled, bit 24 of variable extra_callback_info2 is set if the signal is restricted (has a routing restriction program attached).
When enabled, the "Show restricted electric signals using default graphics" client setting and signal post recolouring is not applied.
This flag must only be set if a different sprite is returned when bit 24 of extra_callback_info2 is set.
enable_signal_recolour0 or 1 Enable recolouring of graphics in railtype signals.
When enabled, in addition to returning a sprite, register 0x100 may be set to the following using STORE_TEMP:
BitsMeaning
0 - 23Recolour sprite to use. Set to 0 for no recolouring.
24 - 31Reserved, set to zero.

If recolouring is not optional, the feature name: action0_railtype_recolour should be checked using the extended_feature_test function and if necessary a suitable fallback used or error message shown.
If the OpenTTD version does not support this property/feature, then the property would ordinarily be ignored/skipped and no recolouring would be done.
extra_aspects0 - 6 The value is the number of additional signal aspects to use (e.g. 4-aspect signalling should use a value of 2).
When set, the lowest byte of extra_callback_info2 (signal state) may have the given number of additional values starting from 02:
ValueMeaning
00Red signal
01Green signal
021st extra aspect (e.g. yellow)
032nd extra aspect (e.g. double yellow)
...Further extra aspects...

The provided value is currently clamped to be within the range 0 - 6 (inclusive).
N.B. Realistic braking must be enabled for additional signal aspects to be used
disable_realistic_braking0 or 1 When this property is set realistic braking is disabled for trains of this railtype even when realistic braking is otherwise in effect.

Railtype variables

Variables in the table below which are not supported by the version of OpenTTD being used return a value of 0.

VariableValue rangeComment
signal_restriction_infobitmask(SIGNAL_RESTRICTION_INFO_XXX, ...) Information about the restricted signal status of the signal being drawn:
RESTRICTED
The signal is restricted (has a routing restriction program attached)
RESERVE_THROUGH_ALWAYS
The attached routing restriction program unconditionally sets reserve through
MAY_REVERSE
The attached routing restriction program may allow trains to reverse behind this signal
signal_contextSIGNAL_CONTEXT_XXX Information about the context of the signal being drawn:
GUI
The signal is being drawn in the GUI (signal window)
TRACK
The signal is being drawn on ordinary rail track
TUNNEL_BRIDGE_ENTRANCE
The signal is being drawn as a tunnel/bridge entrance signal
TUNNEL_BRIDGE_EXIT
The signal is being drawn as a tunnel/bridge exit signal
BRIDGE_MIDDLE
The signal is being drawn on the middle of a bridge
signal_context_is_tunnel0 or 1 The signal is being drawn on a tunnel entrance/exit (not a bridge)
signal_context_info Above signal context variables in one variable (all of the railtype_signal_context variable)
signal_sideSIGNAL_SIDE_XXX
LEFT
Signals are on the left
RIGHT
Signals are on the right
signal_vertical_clearance0 - 255 Pixels of vertical clearance between the signal and any bridge above.
If there is no bridge above, the value is 0xFF.
adjacent_crossingbitmask(RAILTYPE_ADJACENT_CROSSING_XXX, ...) Adjacent level crossing information:
SOUTH
This level crossing tile is part of a continuous adjacent crossing with the tile to the south (SW or SE)
NORTH
This level crossing tile is part of a continuous adjacent crossing with the tile to the north (NW or NE)

Roadtype properties

PropertyValue rangeComment
roadtype_extra_flagsbitmask(ROADTYPE_EXTRA_FLAG_XXX, ...)
NO_SCRIPT_BUILD
Scripts (AI/GS) may not build this roadtype
NO_TOWN_MODIFY
Towns may not modify tiles of this roadtype in any way whatsoever
NO_TUNNELS
Disallow tunnels for this roadtype
NO_TRAIN_COLLISION
Disallow collisions with trains for vehicles of this roadtype
roadtype_collision_modeROADTYPE_COLLISION_MODE_XXX Sets the road vehicle collision mode for road vehicles of this road type.
NORMAL
Normal road vehicle collision rules (this is the default)
NONE
Do not collide at all with other road vehicles
ELEVATED
Collide only with other elevated road vehicles

Tramtype properties

PropertyValue rangeComment
tramtype_extra_flagsbitmask(TRAMTYPE_EXTRA_FLAG_XXX, ...)
NO_SCRIPT_BUILD
Scripts (AI/GS) may not build this tramtype
NO_TOWN_MODIFY
Towns may not modify tiles of this tramtype in any way whatsoever
NO_TUNNELS
Disallow tunnels for this tramtype
NO_TRAIN_COLLISION
Disallow collisions with trains for vehicles of this tramtype
tramtype_collision_modeTRAMTYPE_COLLISION_MODE_XXX Sets the road vehicle collision mode for road vehicles of this tram type.
NORMAL
Normal road vehicle collision rules (this is the default)
NONE
Do not collide at all with other road vehicles
ELEVATED
Collide only with other elevated road vehicles

Object IDs

Object IDs are NewGRF-local and can be freely chosen in the 0..63999 range, as of the more_objects_per_grf feature.
When loaded into a version of OpenTTD without this feature, IDs are limited to the range: 0..254. Any objects with IDs outside this range will be skipped.

Object properties

PropertyValue rangeComment
use_land_ground0 or 1 Sets whether to use the underlying ground as the object ground sprite, ignoring the ground sprite provided in the sprite layout.
When enabled, the ground sprite will be bare ground, grass, snow, desert, etc. as if it were a clear ground tile.
In edge foundation mode, or when foundations are disabled, the ground may be coast/shore when flooded.
edge_foundation_mode[mode0, mode1, mode2, mode3] Enables edge foundation mode for the object.
This property is intended for objects which are positioned at the edge of a tile, and only require a level edge, not a completely level tile.
Foundations will only be added as required to get a suitable level edge.
The format is one mode value per view. If the object has fewer than 4 views then some of the values provided in the property will not be used, and may be 0. All four values must be constants.
Each mode value should be one of:
ValueMeaning
DIAGDIR_NENorth-east edge
DIAGDIR_SESouth-east edge
DIAGDIR_SWSouth-west edge
DIAGDIR_NWNorth-west edge
combined with 0 or more flags using the | operator:
ValueMeaning
OBJECT_EF_FLAG_ADJUST_ZChange z-position for the building sprite to the height of the edge
OBJECT_EF_FLAG_FOUNDATION_LOWERIf the height of the edge is lower than the maximum height of the tile, build a foundation
OBJECT_EF_FLAG_INCLINE_FOUNDATIONUse inclined instead of a flat foundations where possible. (Slopes with one corner raised where the height of the edge is at the maximum height of the tile).
flood_resistant0 or 1 Sets whether the object is flood resistant.
Flood resistance is always enabled for objects which can be built on water.
This property can be used to enable flood resistance without enabling the object to be built on water.
map_tile_typeOBJECT_VIEWPORT_MAP_TILE_TYPE_XXX Set tile type used for display in viewport map mode and the small-map window.
The value should be one of:
ValueMeaningNotes
OBJECT_VIEWPORT_MAP_TILE_TYPE_DEFAULTDefault object
OBJECT_VIEWPORT_MAP_TILE_TYPE_CLEARClear/bare dirtIf use_land_ground is enabled, the underlying ground type will be used instead
OBJECT_VIEWPORT_MAP_TILE_TYPE_GRASSGrass
OBJECT_VIEWPORT_MAP_TILE_TYPE_ROUGHRough ground
OBJECT_VIEWPORT_MAP_TILE_TYPE_ROCKSRocky ground
OBJECT_VIEWPORT_MAP_TILE_TYPE_FIELDSFarm fieldsThe specific type of field can be set using map_tile_subtype
OBJECT_VIEWPORT_MAP_TILE_TYPE_SNOWSnow
OBJECT_VIEWPORT_MAP_TILE_TYPE_DESERTDesert
OBJECT_VIEWPORT_MAP_TILE_TYPE_TREESTreesThe specific tree count and ground type/density can be set using map_tile_subtype
OBJECT_VIEWPORT_MAP_TILE_TYPE_HOUSEHouse
OBJECT_VIEWPORT_MAP_TILE_TYPE_WATERWater
map_tile_subtype0 .. 65535

This can be used to further refine the type set in map_tile_type.

Farm fields:

BitMeaning
0 - 2 Which field type to use

Trees:

BitMeaning
0 - 3 Tree ground type
ValueMeaning
OBJECT_VIEWPORT_MAP_TILE_TYPE_TREE_GROUND_GRASSGrass
OBJECT_VIEWPORT_MAP_TILE_TYPE_TREE_GROUND_ROUGHRough ground
OBJECT_VIEWPORT_MAP_TILE_TYPE_TREE_GROUND_SNOW_DESERTSnow/desert
OBJECT_VIEWPORT_MAP_TILE_TYPE_TREE_GROUND_SHOREShore
OBJECT_VIEWPORT_MAP_TILE_TYPE_TREE_GROUND_ROUGH_SNOWRough snow
4 - 7 Tree ground density (clamped to: 0 - 3)
8 - 11 Number of trees on the tile (clamped to: 1 - 4)

Object variables

Variables in the table below which are not supported by the version of OpenTTD being used return a value of 0.

VariableValue rangeComment
foundation_tile_slopeSLOPE_XXX Slope of the tile after any foundation has been applied.
foundation_change_tile_slopeSLOPE_XXX Slope of the tile after any foundation has been applied xor the slope of the underlying tile.
If this variable is non-zero a foundation is present.
This is useful for xoring with the tile_slope variable, because if this variable is unavailable then the result is still the underlying tile slope.

Airport tile variables

Variables in the table below which are not supported by the version of OpenTTD being used return a value of 0.

VariableValue rangeComment
airport_id0..255 Local GRF ID of the airport type.
airport_layout0..255 Airport layout number (as defined in layouts).

Global variables properties

The variables listed below should set inside an item and property block of the form:

item (FEAT_GLOBALVARS) {
	property {
		...
	}
}

PropertyValue rangeComment
lighthouse_generate_amount0 .. 255Sets the frequency at which lighthouse objects are generated during map generation
transmitter_generate_amount0 .. 255Sets the frequency at which transmitter objects are generated during map generation
extra_station_name[string, bitmask(EXTRA_STATION_NAME_FLAG_XXX, ...)]

This adds an extra station name for use when all the available station names for a given town have been used.
This property may be used as many times as required.
Generally the referenced string should include a {STRING} string code, this is used for the town name.

EXTRA_STATION_NAME_FLAG_RAIL
May be used for rail stations
EXTRA_STATION_NAME_FLAG_ROAD
May be used for road stations
EXTRA_STATION_NAME_FLAG_AIRPORT
May be used for airport stations
EXTRA_STATION_NAME_FLAG_OIL_RIG
May be used for oil rig stations
EXTRA_STATION_NAME_FLAG_DOCK
May be used for dock stations
EXTRA_STATION_NAME_FLAG_HELIPORT
May be used for heliport stations
EXTRA_STATION_NAME_FLAG_TOWN_CENTRE_ONLY
May only be used for stations near the town centre
EXTRA_STATION_NAME_FLAG_NOT_TOWN_CENTRE
May not be used for stations near the town centre
EXTRA_STATION_NAME_FLAG_NEAR_WATER_ONLY
May only be used for stations near water
EXTRA_STATION_NAME_FLAG_NOT_NEAR_WATER
May not be used for stations near water
extra_station_names_probability0 .. 255 Sets the probability that an extra station name is used even when the available default names have not been exhausted.
Some station names are always used first even when this is non-zero.
allow_rocks_in_desert0 or 1 Sets whether rocky tiles are allowed to generate in and remain in desert zones (tropical climate).

Syntax example:

item (FEAT_GLOBALVARS) {
	property {
		lighthouse_generate_amount: 255;
		transmitter_generate_amount: 0;
		extra_station_name: [string(STR_STATION_NAME1), bitmask(EXTRA_STATION_NAME_FLAG_RAIL)];
		extra_station_name: [string(STR_STATION_NAME2), bitmask(EXTRA_STATION_NAME_FLAG_ROAD, EXTRA_STATION_NAME_FLAG_TOWN_CENTRE_ONLY)];
	}
}
		

Replace new sprites

TypeNumber of sprites Comment
PROGRAMMABLE_PRE_SIGNAL32 Programmable pre-signals

Signal graphics come in groups of 16. These groups contain sprites in the same order as sprites 1275-1290 in trg1[r].grf and Action 5 type 4 (signals); red, then green, for each of: SW-facing, NE-facing, NW-facing, SE-facing, E-facing, W-facing, S-facing, N-facing.

GroupContents
0Semaphore programmable pre-signals
1Lighted programmable pre-signals
NO_ENTRY_SIGNAL16 No-entry signals

No-entry signal graphics come in groups of 8. These groups contain sprites in the same order as the red sprites of 1275-1290 in trg1[r].grf and Action 5 type 4 (signals); red only, for each of: SW-facing, NE-facing, NW-facing, SE-facing, E-facing, W-facing, S-facing, N-facing.

GroupContents
0Semaphore no-entry signals
1Lighted no-entry signals
MISC_GUI1 Miscellaneous GUI graphics

There is currently one misc GUI sprite.

ROAD_WAYPOINTS4 Road waypoint graphics

This is the same order and format as the drive-through bus/truck road stop sprites.

Signal graphics using switches

This feature allows signal sprites to be specified using switches in a very similar manner to railtype signals in item (FEAT_RAILTYPES) { graphics { signals: ... } } blocks.
However this applies to all signals, not only those of a particular rail type.
Railtype signal graphics have a higher priority than general signal graphics as set here.

Variables: extra_callback_info1, extra_callback_info2, and terrain_type are the same as for railtype signals.

This feature is not supported by standard OpenTTD or by standard NML.
If the use of this feature is not optional, the feature name: action3_signals_custom_signal_sprites should be checked using the extended_feature_test function and if necessary a suitable fallback used or error message shown.

An item (FEAT_SIGNALS, custom_signals, 0) { } block should be used to define properties and graphics.
The graphics block should contain a single default switch.

PropertyValue rangeComment
enable_programmable_pre_signals0 or 1 Enable programmable pre-signal graphics.
Programmable pre-signals have a signal type (getbits(extra_callback_info2, 16, 8)) of 6.
enable_no_entry_signals0 or 1 Enable no-entry signal graphics.
No-entry signals have a signal type (getbits(extra_callback_info2, 16, 8)) of 7.
No-entry signals always have a signal state of red.
enable_restricted_signals0 or 1 Enable restricted signal flag.
When enabled, bit 24 of variable extra_callback_info2 is set if the signal is restricted (has a routing restriction program attached).
When enabled, the "Show restricted electric signals using default graphics" client setting and signal post recolouring is not applied.
This flag must only be set if a different sprite is returned when bit 24 of extra_callback_info2 is set.
enable_signal_recolour0 or 1 Enable recolouring of graphics
When enabled, in addition to returning a sprite, register 0x100 may be set to the following using STORE_TEMP:
BitsMeaning
0 - 23Recolour sprite to use. Set to 0 for no recolouring.
24 - 31Reserved, set to zero.
extra_aspects0 - 6 The value is the number of additional signal aspects to use (e.g. 4-aspect signalling should use a value of 2).
When set, the lowest byte of extra_callback_info2 (signal state) may have the given number of additional values starting from 02:
ValueMeaning
00Red signal
01Green signal
021st extra aspect (e.g. yellow)
032nd extra aspect (e.g. double yellow)
...Further extra aspects...

The provided value is currently clamped to be within the range 0 - 6 (inclusive).
N.B. Realistic braking must be enabled for additional signal aspects to be used
define_style1 - 255 Define a custom signal style
Signals using this style will only use this GRF, or the default graphics if no graphics are returned.
The value supplied is returned in the signal_style variable.
This property (and related signal style properties) may be used more than once.
The total number of custom signal styles in a game is currently limited to 15.
style_namestring Set the name of the most recently defined style (defined using the define_style property).
This property should be used if using the define_style property, as otherwise the style will have no name.
style_electric_enabledbitmask(SIGNAL_TYPE_XXX, ...) Set which electric signal types may be built using this signal style for the most recently defined style (defined using the define_style property).
At least one of this property and style_semaphore_enabled should be set to a non-zero value, as otherwise no signal types will be enabled for this custom signal style.
If PROG or NO_ENTRY are set, it is not necessary to also set enable_programmable_pre_signals or enable_no_entry_signals.
NORMAL
Normal/block signal
ENTRY
Pre-signal entry
EXIT
Pre-signal exit
COMBO
Pre-signal combo
PBS
Two-way PBS
PBS_ONEWAY
One-way PBS
PROG
Programmable pre-signal
NO_ENTRY
No-entry
style_semaphore_enabledbitmask(SIGNAL_TYPE_XXX, ...) Set which semaphore signal types may be built using this signal style for the most recently defined style (defined using the define_style property).
See style_electric_enabled, above.
style_no_aspect_increase0 or 1 Set whether the most recently defined style (defined using the define_style property) does not increase the signal aspect with respect to the signals either side (i.e. function like a banner repeater).
style_always_reserve_through0 or 1 Set whether reserve through is unconditionally enabled for the most recently defined style (defined using the define_style property).
style_lookahead_extra_aspects0 - 6 or 255 Set the look-ahead extra aspects for the most recently defined style (defined using the define_style property).
This property only makes a difference when the "realistic train braking is aspect limited" game setting is enabled.
This limits the signal aspect which the hypothetical train driver can "read" from the signal without affecting signal aspect propagation to other signals, or variable extra_callback_info2.
Example values could include: 1 for traditional banner repeater signals.
Shunt signals should use style_lookahead_single_signal_only instead.
The value is clamped to be less than or equal to the value set in the extra_aspects property.

As a special case, a value of 255 (0xFF) disables the "realistic train braking is aspect limited" setting entirely for signals using this style.
This should only be used for signal types which are intended to emulate in-cab signalling, instead of the "driver" visually reading a signal.
style_lookahead_single_signal_only0 or 1 Set the look-ahead to single signal only mode for the most recently defined style (defined using the define_style property).
This property only makes a difference when the "realistic train braking is aspect limited" game setting is enabled, or when using a different signal type which uses style_combined_normal_shunt.
This is similar to style_lookahead_extra_aspects with a value of 0, except the lookahead always ends at the next signal, even if that signal type sets style_no_aspect_increase.
If enabled, this property overrides style_lookahead_extra_aspects.
This can be used for shunt signals.
style_combined_normal_shunt0 or 1 Enable functioning as a combined normal aspect and shunt signal for the most recently defined style (defined using the define_style property).
When enabled and displaying a shunt aspect, the signal state in the lowest byte of extra_callback_info2 will have the value: 0xFF.
style_opposite_side0 or 1 Set whether signals should be drawn on the opposite side of the track for the most recently defined style (defined using the define_style property).
style_both_sides0 or 1 Set whether signals should be drawn on both sides of the track for the most recently defined style (defined using the define_style property).
If set, the signal_context_is_second variable is true when drawing the second signal.
If this and style_opposite_side are both set, the first signal is drawn on the opposite side and the second signal is drawn on the usual side.
style_realistic_braking_only0 or 1 Set whether signals using this style may only be built when realistic braking is enabled, for the most recently defined style (defined using the define_style property).
no_default_style0 or 1 When enabled, custom signal graphics from this GRF are only used for custom signal styles, not the default style

VariableValue rangeComment
signal_restriction_infobitmask(SIGNAL_RESTRICTION_INFO_XXX, ...) Information about the restricted signal status of the signal being drawn:
RESTRICTED
The signal is restricted (has a routing restriction program attached)
RESERVE_THROUGH_ALWAYS
The attached routing restriction program unconditionally sets reserve through
MAY_REVERSE
The attached routing restriction program may allow trains to reverse behind this signal
signal_contextSIGNAL_CONTEXT_XXX Information about the context of the signal being drawn:
GUI
The signal is being drawn in the GUI (signal window)
TRACK
The signal is being drawn on ordinary rail track
TUNNEL_BRIDGE_ENTRANCE
The signal is being drawn as a tunnel/bridge entrance signal
TUNNEL_BRIDGE_EXIT
The signal is being drawn as a tunnel/bridge exit signal
BRIDGE_MIDDLE
The signal is being drawn on the middle of a bridge
signal_context_is_tunnel0 or 1 The signal is being drawn on a tunnel entrance/exit (not a bridge)
signal_context_is_second0 or 1 The second signal is being drawn (on the opposite side to the first signal), see the style_both_sides property
signal_context_info Above signal context variables in one variable (all of the signals_signal_context variable)
signal_sideSIGNAL_SIDE_XXX
LEFT
Signals are on the left
RIGHT
Signals are on the right
signal_style0 - 255 The style ID defined using define_style for signals using a custom style, or 0 for signals using the default style
signal_vertical_clearance0 - 255 Pixels of vertical clearance between the signal and any bridge above.
If there is no bridge above, the value is 0xFF.

Custom signal sprites example:

grf {
	...
}

if (!extended_feature_test("action3_signals_custom_signal_sprites")) {
	error(FATAL, string(STR_UNSUPPORTED_VERSION));
}

switch (FEAT_SIGNALS, SELF, switch_signals, ...) {
	...
}


item (FEAT_SIGNALS, custom_signals, 0) {
	property {
		enable_signal_recolour: 1;
	}

	graphics {
		switch_signals;
	}
}