NML documentation

# Preface

NewGRF files are files containing sprites and pseudo-sprites that can be used to describe extra vehicles, industries, cargoes etc. for use in OpenTTD and TTDPatch. The most used tool to encode/decode GRF files is GRFCodec (nightly download). GRFCodec can read NFO files and convert them to GRF files (GRF file format). NFO is a low-level language that is tied to the GRF spec. It uses hexadecimal numbers by default in most places and doesn't have any textual identifiers. While the language is very powerful, it's also hard to learn. NML was started mainly to provide a higher level language so coding GRF files will become accessible to more people.

A good place to discuss NewGRFs which are being developed are the tt-forums, especially the NewGRF sub-sections. Questions concerning setup up of NewGRF projects, programming or drawing or just discussing features and presenting work being done are well-placed there. When you are satisfied with a NewGRF and consider it tested enough that it really can be considered to be played with by the general public, you can publish your NewGRF in the NewGRF releases sub-forum and you might also consider to publish it to the Online Content Server of OpenTTD, so that other players can easily download your NewGRF and use it for future games. It will increase the popularity and use of your NewGRF tremendously.

# Getting started

NML is a a python-based compiler, capable to compile NML files (along with their associated language, sound and graphic files) into grf and / or nfo files. Windows users can install the windows binary which contains a binary which bundles all required libraries. Users on other OS need to install them separately, best by means of their packet manager. In order to work, the following items are required:

- python
  - any version from 2.5 through 2.7 will do, but not 3.x
  - downloadable from from http://www.python.org/)
  - Advise for windows users: apparently you can prevent a lot of problems by installing the 32bit version of python, even if you have a 64bit windows installation. Installing PIL might be troublesome if you do install the 64bit version of python.
- python image library
  - downloadable from http://www.pythonware.com/products/pil/
- ply
  - downloadable from http://www.dabeaz.com/ply/
- NML itself
  - the latest (nightly) build can be downloaded from http://bundles.openttdcoop.org/nml/nightlies/LATEST/

If you don't install these with the packet manager of your choice (or there is none like on windows and you don't use the pre-compiled binary file), you should install these libraries as well as NML itself using `python setup.py install` from your command prompt.

To verify that everything is installed, enter `nmlc --version` in your command line. This should output the version of NML as well as the version of the installed libraries.

Examples for small NML "projects" are found in the `regression` folder of NML. Generally it's assumed that the language files are in a separate language folder `lang`, thus a simple project may look like this:

    mynewgrf.nml
    graphics.png
    funny_sound.wav

    lang/default.lng

The compiler itself `nmlc` is a command line tool and can take a number of parameters, at least the nml filename which it shall process, e.g. `nmlc mynewgrf.nml` will compile your nml file into the grf-file `mynewgrf.grf`.

The full syntax is:

    Usage: nmlc [options] <filename>
    Where <filename> is the nml file to parse

    Options:
      --version             show program's version number and exit
      -h, --help            show this help message and exit
      -d, --debug           write the AST to stdout
      -s, --stack           Dump stack when an error occurs
      --grf=<file>          write the resulting grf to <file>
      --nfo=<file>          write nfo output to <file>
      -c                    crop extraneous transparent blue from real sprites
      -u                    save uncompressed data in the grf file
      --nml=<file>          write optimized nml to <file>
      -o <file>, --output=<file>
                            write output(nfo/grf) to <file>
      -t <file>, --custom-tags=<file>
                            Load custom tags from <file> [default:
                            custom_tags.txt]
      -l <dir>, --lang-dir=<dir>
                            Load language files from directory <dir> [default:
                            lang]

# Graphic files

All graphic files must be in a format that can be loaded by the python imaging library and they must have a valid palette. You can chose either the DOS palette (recommended as it contains a few more colours) or the windows palette.

Palette files for several editors:

- Dos palette for GIMP
- Windows palette for GIMP
- Windows palette for Photoshop

Note: Windows versions do NOT support graphics in the pcx format due to missiong support within the PIL.

# Language structure

## Blocks

NML files are mainly composed from blocks. A block starts with the type of the block, optional arguments and then the contents enclosed by curly braces. Nearly all NML files will start with a grf-block. The grf-block takes no parameters and is one of the simplest blocks there is. Following is an example grf-block.

    grf {
    	grfid : "AB\02\03";
    	name : string(STR_GRF_NAME);
    	desc : string(STR_GRF_DESCRIPTION);
    	version: 10;
    	min_compatible_version: 5;
    }

Let's look at this code line for line.

    grf {

This block is a grf-block. A grf-block has no parameters. The '{' is the start of the block content.

    	grfid : "AB\02\03";

This line sets the grfid of the resulting grf. The value is the letters AB followed by a byte with value 2 and then another one with value 3. The semicolon marks the end of the statement.

    	name : string(STR_GRF_NAME);

The name of the grf. In NML nearly all strings are put in language files. The format of the language files is described in another section. For now just assume a string with the name `STR_GRF_NAME` exists. To reference a string from the language file you use `string(<stringname>)` where `<stringname>` should be replaced by the actual name of the string.

    	desc : string(STR_GRF_DESCRIPTION);

This looks a lot like the previous line, only it sets the description instead of the name.

    	version : 10;

For a new grf you should set the version to 1. Every time you release a new version you should increase the version field by at least 1.

    	min_compatible_version : 5;

For a new grf you should set the min_compatible_version to 1. Every time you change something in your newgrf which makes it incompatible to previous versions, you should set min_compatible_version to the current version. Changes which make a NewGRF incompatible to previous versions are most functional changes to existing behaviour, among others: changing vehicleIDs as well as some of their properties, changing industry layouts, railtype compatibility, changing (de-)activation conditions... Adding new, additional things and expanding existing behaviour (without changing the current one) is mostly considered safe).

    }

This marks the end of the last-opened block, in this case the grf-block.

## Features

NewGRFs can be used to modify various types of items. Examples include trains, stations and industries. Such a type of item is called a feature. The following table contains a list of features and their identifiers. These identifiers may be used to refer to the feature when needed.

Name | Description
--- | ---
FEAT_TRAINS | Trains
FEAT_ROADVEHS | Road vehicles
FEAT_SHIPS | Ships
FEAT_AIRCRAFT | Aircraft
FEAT_STATIONS | Train stations
FEAT_CANALS | Canals
FEAT_BRIDGES | Bridges
FEAT_HOUSES | Town houses
FEAT_GLOBALVARS | Various global variables
FEAT_INDUSTRYTILES | Industry tiles (visible part of industries)
FEAT_INDUSTRIES | Industries
FEAT_CARGOS | Cargo types
FEAT_SOUNDEFFECTS | Sound effects
FEAT_AIRPORTS | Airports
FEAT_SIGNALS | Train signals
FEAT_OBJECTS | Non-interactive objects (example: lighthouse)
FEAT_RAILTYPES | Rail types
FEAT_AIRPORTTILES | Airport tiles (visible part of airports)

# Block syntax

In the next sections you'll often see a word enclosed by the less-than and greater-than symbols. These words should not be written literally, instead they reference to another block/item you should put there. The following words will be used:

<literal-string>
  A string enclosed by quotes, for example `"this is a literal string"`
<string>
  A string defined in the language file, for example `string(STR_GRF_NAME)`
<expression>
  An expression, this can be a computation or single value constructed using <number>, <float>, <parameter>, <variable>, <function-call>
<ID>
  The name of an item or block. IDs should start with a letter or underscore. The rest of the ID may consist of letters, underscores and numbers.

If something is enclosed by square brackets [] it's optional.

## GRF

    grf {
    	grfid: <literal-string>;
    	name: <string>;
    	desc: <string>;
    	version: <expression>;
    	min_compatible_version: <expression>;
    	<param { ... }>
    }

Example:

    grf {
    	grfid: "AB\03\02";
    	name: string(STR_GRF_NAME);
    	desc: string(STR_GRF_DESC);
    	version: 1;
    	min_compatible_version: 1;
    }

### GRF parameters

As part of the grf block you can specify some parameter settings that the user will be able to change as part of the newgrf configuration. These can for example be used to disable parts of your NewGRF or to change between multiple graphics in case that's not possible at runtime. In general the settings (sub-)block looks like

    param {
    	<name> {
    		type:    <type>;
    		name:    <string>;
    		desc:    <string>;
    		min_value: <expression>;
    		max_value: <expression>;
    		def_value: <expression>;
    		names: {
    			0: <string>;
    			1: <string>;
    			.
    			.
    			.
    		};
    	}
    }

Looking at the single entries:

    <type>

This defines the parameter type. Possible values are `bool` for on/off statements or `int` for positive integer values

    name

This gives the parameter name as shown in the parameter configuration dialogue of OpenTTD.

    desc

This gives the description which is displayed when the parameter is selected. Here you can explain the meaning and impact it will have

    min_value

The minimum acceptable value for the parameter (makes only sense for type int)

    max_value

The maximum acceptable value for the parameter (makes only sense for type int)

    def_value

This sets the default value for this parameter. If left out, the default value of 0 will be used.

    names

If you chose type `int` and the numbers themselves are only used internally, have no direct numerical meaning and are better explained in words, you can use this to associate the single numbers with a string which describes it and is shown to the user instead of the value. A simple example:

    param {
    	param_provide {
    		type:    int;
    		name:    string(STR_PARAM_PROVIDE);
    		desc:    string(STR_PARAM_PROVIDE_DESC);
    		min_value: 0;
    		max_value: 1;
    		def_value: 0;
    		names: {
    			0: string(STR_PARAM_PROVIDE_ENGINES_AND_WAGONS);
    			1: string(STR_PARAM_PROVIDE_WAGONS_ONLY);
    		};
    	}

## Item

    item (<expression> [, <ID> [, <expression>]]) {
    	(<property-block>|<graphics-block>|<livery_override-block>)+
    }

The first argument is the feature of the item, the second (optional) argument is the name used to identify the object throughout the NML file and the third (optional) argument is the numerical id you want to use for this item. Example:

    item (FEAT_ROADVEHS, hereford_tram) {
    	property {
    		name:               string(STR_NAME_HEREFORD_TRAM);
    		climates_available: ALL_CLIMATES;
    		introduction_date:  date(1940,1,1);
    		speed:              60 km/h;
    	}
    }

### Property

    property {
    	(<ID>: (<string>|(<expression> [<unit>]));)+
    }

This one looks a lot more complicated than it actually is. A property-block contains one or more assignments. Each assignment starts with the name of the property that is changed followed by a colon. After the colon follows the value and you end the line with a semicolon. The type of the value depends on the property, some properties require a string as value and some an expression. For some properties you can optionally specify a unit that is used to convert the value to the unit that is written to the output file. You can only use a unit if the expression is constant. List of valid units

### Graphics

### Livery override

Same cars, different engine, different car sprites

A livery override block offers the option to change the look and behaviour of a wagon depending on the engine it is attached to. E.g. passenger wagons could adapt their livery to match the engine, to make the consist look like a multiple-unit train. The spritegroup needs to be defined before it can be used in a livery override. A livery override block is always part of the engine definition and looks like

    livery_override (vehicleID) {
    	spritegroup_name
    }

For an example see the spritegroup

## Realsprites

Several features will need to reference actual graphics from files you created. You can provide real sprites in many different formats, all detailed below. There is a lot of information you'll need to provide. Most important are the filename and the location of the sprite in that file. Since most blocks that reference realsprites will allow you to specify a default filename, you don't often need to give a filename for every separate sprite.

Allowed formats:

    [left_x, upper_y, width, height, offset_x, offset_y]
    [left_x, upper_y, width, height, offset_x, offset_y, compression]
    [left_x, upper_y, width, height, offset_x, offset_y, filename]
    [left_x, upper_y, width, height, offset_x, offset_y, compression, filename]
    [offset_x, offset_y]
    [offset_x, offset_y, compression]
    [offset_x, offset_y, filename]
    [offset_x, offset_y, compression, filename]

If you don't specify left_x, upper_y, width and height it'll default to the complete file. If you don't specify the filename it'll take the filename from the block containing this realsprite. It's a fatal error not to specify a filename for either the block containing a realsprite or the realsprite itself. For possible values of compression, see the table below.

For all parameters you can use expressions as complex as you want as long as they can be resolved at compiletime. That means you're free to use for example template parameters, but letting the offset depend on a parameter is not allowed.

The following table contains a list of compression flags. Multiple flags may be combined using the binary-OR (|) operator.

Name | Description
--- | ---
NORMAL (default) or TILE | Compression algorithm to use for the sprite. TILE compression may be more efficient for sprites with large chunks of transparant blue, such as tiles or diagonal vehicle views.
COMPRESSED or UNCOMPRESSED (default) | Whether to store the sprite compressed or uncompressed in memory. Storing compressed is saves memory for large, little-used sprites.
CROP (default) or NOCROP | Whether to crop the sprites when the -c command line option is set.

Example:

    [0, 0, 64, 31, -31, 0, TILE]

## Recolour sprites

Recolour sprites are special sprites that are used to recolour other sprites, for example to apply company colours. It's basically a remapping of the colour table.

    recolour_sprite {
    	0xC6: 0x28;
    	0xC7: 0xF5;
    	0xC8..0xCD: 0x0A..0x0F;
    }

The above example will remap colour 0xC6 as 0x28, 0xC7 as 0xF5 and the range 0xC8 to 0xCD to the colours 0x0A..0x0F. This is one of the company colour recolour sprites defined in the baseset. Please note that in NML every recolour sprite will use the DOS palette. If your actual graphics files use te windows palette, nmlc will silently convert the recolour sprite to the windows palette before writing it to the output file.

## Template

NML allows to define templates for use in spritesets, which can be referred to when defining real sprites, avoiding repetitive declaratin of the same alignment (e.g. when coding different train wagons of the same size).

    template templatename([param [, param [, param...]]]) {
    	list of realsprites
    	...
    }

For an example see below.

## Spriteset

A spriteset associates a name with a number piece of an existing image file and describes the offsets with respect to some origin the graphics will be painted within the game. Different features and situations require that a single set has a certain amount of actual sprites associated. E.g. a vehicle usually requires eight sprites in order to provide on view for each of the eight possible ingame orientations of a vehicle.

    spriteset (SPRITESET_NAME, graphics_file) {
    	list of realsprites
    	...
    }

## Spritegroup

A spritegroup associates the several spritesets for use and futher reference in the graphics block of an item block.

    spritegroup spritegroup_name {
    	block_name: spriteset_names
    }

The block_names vary by the feature:

### Spritegroups for vehicles

For vehicles a typical spritegroup looks like

    spritegroup spritegroup_name {
    	loading: [spriteset_name [, spriteset_name [, spriteset_name [, spriteset_name]]]]
    	loaded: [spriteset_name [, spriteset_name [, spriteset_name [, spriteset_name]]]]
    }

Vehicles take two different spritesets, `loading` shows the vehicle while it is loading within the station and `loaded` shows the vehicle while it is travelling. Each of those can be an array of up to 4 individual spritesets and must at least be one. They're used to show different graphics depending on how much the vehicle is loaded with increasing load from left to right. If only one spriteset is given it will always be used. A simple example for defining a train engine with a livery override. The passenger wagon shows different sprites whether it is travelling empty or is filled with people.

    // Define the sprites for the engine
    template tmpl_train_length78(x, y) {
    	[x,     y,  8,22,   -3,-10]
    	[x+ 16, y, 21,15,  -14, -7]
    	[x+ 48, y, 31,12,  -16, -8]
    	[x+ 96, y, 21,16,   -6, -7]
    	[x+118, y,  8,24,   -3,-10]
    	[x+144, y, 21,16,  -15, -6]
    	[x+196, y, 32,12,  -16, -8]
    	[x+224, y, 21,15,   -6, -7]
    }

    spriteset(turbotrain_engine_set, "src/gfx/turbotrain.png") {
    	tmpl_train_length78(142, 118)
    }
    // Define the sprites for the passenger wagon when used with this engine
    // Loading sprites with open doors
    spriteset(turbotrain_passenger_loading_set, "src/gfx/turbotrain.png") {
    	tmpl_train_length78(142, 139)
    }
    // Passenger wagon is empty. No people shown
    spriteset(turbotrain_passenger_traveling_empty_set, "src/gfx/turbotrain.png") {
    	tmpl_train_length78(142, 159)
    }
    // Passenger wagon is full. Show people through the window
    spriteset(turbotrain_passenger_traveling_full_set, "src/gfx/turbotrain.png") {
    // has slightly different dimensions, don't use template
    	[142,159,  8,21,   -3,-10]
    	[158,159, 20,15,  -13, -7]
    	[190,159, 28,10,  -12, -6]
    	[238,159, 20,16,   -6, -7]
    	[270,159,  8,21,   -3,-10]
    	[286,159, 20,15,  -15, -6]
    	[318,159, 28,10,  -16, -6]
    	[366,159, 20,16,   -6, -7]
    }

    // Associate graphics with the engine for the different loading stages
    spritegroup turbotrain_engine_group {
    	loading: turbotrain_engine_set;
    	loaded: turbotrain_engine_set;
    }
    // Associate graphics with the wagon for the different loading stages
    spritegroup turbotrain_passenger_group {
    	loading: turbotrain_passenger_set;
    	loaded: [turbotrain_passenger_traveling_empty_set, turbotrain_passenger_traveling_full_set];
    }

    // Define new graphics for the turbotrain (it has vehicleID 20):
    item(FEAT_TRAINS, turbotrain, 20) {
    	property {
    		sprite_id:                    SPRITE_ID_NEW_TRAIN;    // We have our own sprites
    		misc_flags:                   bitmask(TRAIN_FLAG_MU); // We use special sprites for passenger and mail wagons
    	}
    	graphics {                           // graphics for engine
    		turbotrain_engine_group;
    	}
    	livery_override(passenger_wagon) {   // graphics for alternative look of passenger wagon when used with this engine
    		turbotrain_passenger_group;
    	}
    }

### Spritegroups for railtypes

Only the block_name `default` is used and it only takes one spriteset.

    spritegroup gui_normal_modern_TTD_group {
    	default: gui_normal_modern_TTD;
    }

## Spritelayouts for industry, airport and object tiles

Industries and airports don't have sprite groups, but they define layouts on how sprites are supposed to be arranged. A `spritelayout` can combine multiple sprites into one entity which are then drawn to represent everything that will be drawn on a particular tile. A simple example to illustrate how it works:

    A simple example to illustrate how it works:
    spritelayout airport_building1 {
    	ground { ttdsprite: GROUNDSPRITE_NORMAL; }
    	childsprite {
    		sprite: spr_small_dirt_ne; // custom spriteset
    		always_draw: 1; // also draw in transparent mode
    	}
    	building {
    		ttdsprite: 0xA67; // reuse this existing base set sprite
    		xoffset: 0x0F;
    		xextent: 1;
    		zextent: 6;
    		recolour_mode: RECOLOUR_REMAP;
    		palette: PALETTE_USE_DEFAULT;
    	}
    }

The sprite layout is composed of one or more sprites. Each sprite is defined by a `ground`, `building` or `childsprite` block. What block to use depends on how the sprite is to be placed on the tile.

- `ground` sprites are drawn at the base of the tile, like grass and concrete, rails etc. in normal TTD. With a few exceptions (e.g. when using custom foundations), you should always provide a ground sprite, even when the building above fully covers it. This because in transparent mode, the building becomes invisible. A tile can only have one ground sprite.
- `building` sprites are drawn on top of the ground sprite. To determine their location and drawing order (what goes in front of what), they have a 3D bounding box.
- With `childsprite`(s), you can effectively compose sprites from multiple parts. When placing these after a building sprite, they will use the same bounding box as the previous building sprite. When placing them before the first building sprite, they will have no bounding box, as if they would use the 'bounding box' of the ground tile. Multiple childsprites may be used per ground / building sprite.

Per sprite, a number of parameters may be set. These are listed below. First, to specify what sprite is to be drawn, you need to set either `sprite` or `ttdsprite`, but not both.

- `ttdsprite`: sets the TTD sprite number to use, usually from the base set. Pre-defined constants for some base set sprites are:
  - `GROUNDSPRITE_NORMAL` default terrain type for that climate (temperate, toyland: normal, arctic: without snow, tropical: rainforest).
  - `GROUNDSPRITE_DESERT` desert tile
  - `GROUNDSPRITE_SNOW` snowy ground tile
  - `GROUNDSPRITE_CONCRETE` concrete ground tile
  - `GROUNDSPRITE_WATER` flat water tile
  - `GROUNDSPRITE_CLEARED` ground tile that has just been bulldozed (with brown colour)
- `sprite`: selects a spriteset to use. When the value is just a spriteset identifier, it will use the first sprite from that set. If you supply an argument (e.g. `sprite: some_sprite_set(2);`), the corresponding sprite from the sprite set will be used, with an argument of 0 corresponding to the first sprite.

Next, a couple of attributes allow changing altering the way this sprite is displayed:

- `recolour_mode`: Available recolour modes are
  - `RECOLOUR_NONE`: Use no colour translation
  - `RECOLOUR_REMAP`: Use a colour translation table as defined by `palette`. This tables maps all colours of the sprite to a new colour.
  - `RECOLOUR_TRANSPARENT`: Draw the sprite in transparant mode, using a colour translation table as defined by `palette`. Normally the palette will be set to PALETTE_TO_TRANSPARANT to draw all underlying colours somewhat darker. Note that the selected palette is applied to the colours of the underlying sprite, whatever that happens to be. The supplied sprite is only used to determine what pixels to recolour.
- `palette`: This defines the palette which is used for the colour translation, which e.g. allows to use a random company colour. For default values see the appendix on available palettes.
- `always_draw`: If set to 1, this sprite will also be drawn when the user has enabled transparant mode. The default value is 0.

How to position the sprite depends on the type of sprite:

- `ground`: Ground sprites cannot be positioned.
- `building`: A three-dimensional bounding box may be defined. The X-axis runs from top-right to bottom-left and the Y-axis from top-left to bottom-right. The Z axis is vertical. All units are relative to the tile, with a tile being 16 units in the X and Y directions. Extending the bounding box over the edges of a tile is possible, but not recommended as it may lead to glitches. To define the bounding box, the following attributes can be used:
  - `xoffset`: Offset from the northwestern edge to the start of the bounding box (X).
  - `yoffset`: Offset from the northeastern edge to the start of the bounding box (Y).
  - `zoffset`: Offset from the lowest tile corner (with foundation added) to the start of the bounding box (Z).
  - `xextent`: Size of the bounding box, in the X-direction.
  - `yextent`: Size of the bounding box, in the Y-direction.
  - `zextent`: Size of the bounding box, in the Z-direction.
- `childsprite`: Child sprites may be positioned relative to their 'parent' sprite that defines the bounding box. `xoffset` and `yoffset` may be set to specify an offset in pixels between the origin of the parent and child sprite. When the parent sprite is the ground sprite, TTDPatch does not support offsets other than 0,0. Note that all child sprites should fit inside the bounding box of the parent sprite to avoid visual glitches.

## Tilelayout for industries and airports

A tile layout describes which industry or airport tiles are associated with which position relative to the northernmost (north being the top of the screen) edge of the industry or airport as a whole. A typical example looks like:

    tilelayout small_airport_layout_north {
    	rotation: DIRECTION_NORTH;
    	0, 0: small_airport_tiles_hangar;
    	1, 0: small_airport_tiles_terminal;
    	2, 0: small_airport_tiles_terminal;
    	3, 0: small_airport_tiles_terminal;
    	0, 1: small_airport_tiles_taxi;
    	1, 1: small_airport_tiles_taxi;
    	2, 1: small_airport_tiles_taxi;
    	3, 1: small_airport_tiles_taxi;
    	0, 2: small_airport_tiles_runway;
    	1, 2: small_airport_tiles_runway;
    	2, 2: small_airport_tiles_runway;
    	3, 2: small_airport_tiles_runway;
    }

The actual layout is a list of `x-coordinate, y-coordinate: tile;` where the x- and y-directions refer to the usual directions: x is top-right (North-East) to bottom-left (South-West) and the y-direction is perpendicular to that bottom-right (South-East) to top-left (North-West).

Airports additionally have to define a `rotation` which is one of the default directions. Note that only the four main compass directions are valid. Industries may not define a rotation.

## Switch

    switch (<expression>, (SELF|PARENT), <ID>, <expression>) {
    	(<range>: <return_value>;)*
    	<return_value>;
    }

The four parameters have the following meaning:

- `<expression>`: The feature for which this switch is used (see Features).
- `(SELF|PARENT)`Which variables to use. SELF uses the variables of the item itself, while PARENT uses the variables of a related object. This related object differs per feature, refer to the table below.
- `<ID>`Name of this switch block. This (unique) name can be used to refer to the block from other switch- or graphics-blocks.
- `<expression>`The expression that will be evaluated to make a decision. This expression may contain variables. Instead of a single expression this may also be an array of expressions. In that case all of the array elements are evaluated in order and the last one is used to make a decision.

Feature | SELF | PARENT | permanent storage
--- | --- | --- | ---
FEAT_TRAINS | Engine / wagon / articulated part itself | Front engine | no
FEAT_ROADVEHS | Road vehicle part | First road vehicle part | no
FEAT_SHIPS | Ship | Ship | no
FEAT_AIRCRAFT | Aircraft (a) | Aircraft | no
FEAT_STATIONS | Station tile | Town | no
FEAT_CANALS | Canal tile | N/A | no
FEAT_BRIDGES | Bridge | Town | no
FEAT_HOUSES | House tile | Town | no
FEAT_GLOBALVARS | N/A | N/A | no
FEAT_INDUSTRYTILES | Industry tile | Industry to which the tile belongs | no
FEAT_INDUSTRIES | Industry | Town | yes
FEAT_CARGOS | Cargo type | N/A | no
FEAT_SOUNDEFFECTS | N/A | N/A | no
FEAT_AIRPORTS | Airport | N/A | yes
FEAT_SIGNALS | N/A | N/A | no
FEAT_OBJECTS | Object tile | Town | no
FEAT_RAILTYPES | Rail tile | N/A | no
FEAT_AIRPORTTILES | Airport tile | Airport | no

(a) Except for mail capacity callbacks, where it refers to the mail compartment. To refer to the aircraft itself, use PARENT scope there.

`<range>` can either be a single number or two numbers separated by two dots. In the first case, the range matches if the result of the computation is equal to the supplied value. If a range (`a .. b`) is supplied, it matches if the computed result is within that range. If several lines of the switch block match the expression being tested the first applicable result will be returned.

Possible values for `<return_value>`e are the following:

- `<ID>;` chains to the (random-)switch or spritegroup with the given ID.
- `return (<expression>|<string>);` returns the given expression or string as a result of the callback.
- `return;` returns the computed value directly as a callback result. Note that the maximum value for callback results is 32511 (0x7EFF).
- `CB_FAILED;` stops processing and returns an explicit failure code.

Some example code is given below. Note that the code does not have an actual meaning, it is merely meant to demonstrate all the various options available.

    switch (FEAT_TRAINS, PARENT, some_vehicle_switch, (position_in_consist + param[1]) % 4) {
    	0..2: return string(STRING_FOO_BAR); //return a text message
    	3: return; //return the computed value
    	5..300: return 42; //42 is always a good answer
    	400: other_switch; //chain to some other switch block
    	CB_FAILED; //return a failure result
    }

You can also use temporary variables and with some features also pemanent variables to store and retrieve some values by means of `STORE_TEMP(value, register)`, `LOAD_TEMP(register)` and `STORE_PERM(value, register)` and `LOAD_PERM(register[, grfid])` respectively. Using temporary storage is useful when you want to use the result of an expensive calculation in various decisions (switches) within the chain (like for example the number of a certain wagon type within a train). Permanent storage might be useful to control the long-term behaviour of an object. Note that it is only available for industries, airports and towns. For towns, you can optionally specify a grfid to load registers belonging to a different grf. Note that accessing (both reading and writing) permanent town registers thrashes the contents of temporary register 0x100.

## Produce

The `produce` block is only available for industries and describes how the industry consumes incoming and creates outgoing cargo. The syntax is

    produce (<ID>, <consume_1>, <consume_2>, <consume_3>, <produce_1>, <produce_2> [, run_again]);

where

- `ID` is a unique name of the block
- `consume_1`, `consume_2`, `consume_3` are expressions which give the amount of the respective input cargo consumed during this call of the produce block. The given amounts are subtracted from the stockpile of cargo waiting to be processed.
- `produce_1`, `produce_2` are expressions which give the amount of the produced (outgoing) cargos in the produce block.
- `run_again` is a boolean expression which evaluates to either 0 or 1. It indicates whether the produce block shall be called again. Thus you can tune the produce block to process the minimal amount of cargo and call it as often as needed to consume the required amount of input cargo and produce the appropriate amount of output cargos.

The produce block should be the default result of the switch-chain for an industry, equivalent to a spriteblock for vehicles or spritelayout for industry tiles. An example on how it can be used without actually processing cargo but counting the time an industry exists unserviced:

    /* Every month, the counter is increased. The counter is reset to zero whenever the power plant
     * receives cargo. When the counter reaches 61, the industry will close when the random production
     * change callback is called. */

    /* When we receive cargo, the counter is reset. */
    produce(power_plant_cargo_arrive_produce, 0, 0, 0, 0, STORE_PERM(0, 0x00));

    /* Every month the counter is increased. */
    switch (FEAT_INDUSTRIES, SELF, power_plant_monthly_prod_change_switch, STORE_PERM(LOAD_PERM(0x00) + 1, 0x00)) {
    	return CB_RESULT_IND_PROD_NO_CHANGE;
    }

    /* Only check industry closure if the counter is greater than 60. */
    switch (FEAT_INDUSTRIES, SELF, power_plant_random_prod_change_switch, LOAD_PERM(0x00)) {
    	0..60: return CB_RESULT_IND_PROD_NO_CHANGE;
    	return CB_RESULT_IND_PROD_CLOSE;
    }

    switch (FEAT_INDUSTRIES, SELF, power_plant_callback_switch, current_callback) {
    	IND_CB_MONTHLY_PROD_CHANGE: power_plant_monthly_prod_change_switch;
    	IND_CB_RANDOM_PROD_CHANGE:  power_plant_random_prod_change_switch;
    	power_plant_cargo_arrive_produce;
    }

    item(FEAT_INDUSTRIES, industry_power_plant, INDUSTRYTYPE_POWER_PLANT) {
    	properties {
    		callback_flags:             bitmask(IND_CBF_PROD_CB_CARGO_ARRIVE,
    		                                    IND_CBF_MONTHLY_PROD_CHANGE,
    		                                    IND_CBF_RANDOM_PROD_CHANGE);
    	}
    	graphics {
    		power_plant_callback_switch;
    	}
    }

## Random switch

While a switch-block allows making a predictable decision, a random_switch allows a randomised choice between several options.

    random_switch (<feature>, <type>, <ID>[, <triggers>]) {
    	(<independent>: <other_random>;)*
    	(<dependent>: <other_random>;)*
    	(<probability>: <return_value>;)+
    }

The first parameter `<feature>` specifies the feature to use. `<type>`, the second parameter, is used to define what random data is used. The supported combinations are listed in the following table. The amount of random data is given in the third column. The maximum number of possible combinations is equal to 2^x, with x being the number of random bits. The last column specifies the object of which the random data is used.

Feature | Type | # of random bits | Random data used
--- | --- | --- | ---
Vehicles | SELF | 8 | Vehicle itself
Vehicles | PARENT | 8 | Leading engine
Vehicles | BACKWARD_SELF(x) | 8 | Count x vehicles backward (away from the engine), starting at the vehicle itself (a)
Vehicles | FORWARD_SELF(x) | 8 | Count x vehicles forward (towards the engine), starting at the vehicle itself (a)
Vehicles | BACKWARD_ENGINE(x) | 8 | Count x vehicles backward, starting at the leading engine (a)
Vehicles | BACKWARD_SAMEID(x) | 8 | Count x vehicles backward, starting at the first vehicle in the chain with the same ID (a)
Stations / airport tiles | SELF | 16 | Station
Stations / airport tiles | TILE | 4 | Specific station tile
Canals | SELF | 8 | Canal tile
Houses | SELF | 8 | House tile (b)
Industry tiles | SELF | 8 | Industry tile
Industry tiles | PARENT | 16 | Industry as a whole
Industries | SELF | 16 | Industry (same as above)
Objects | SELF | 8 | Object tile (different per tile)
Rail types | SELF | 2 | Rail tile (pseudo-random, based on location)

(a) x can be any expression. It may access parameters or registers, but variable accesses are not possible.

(b) The random bits are initially the same for all tiles of a multi-tile house.

The third parameter `<ID>` can be used to refer to this block from other (random-)switch-blocks. The last parameter `<triggers>` is optional and allows re-randomizing when certain conditions occur. The events and accompanying trigger names are given in the following tables. To re-randomize graphics when any of a set of events occurs, use `bitmask(TRIGGER_A, TRIGGER_B, .. , TRIGGER_Z)` To re-randomize only when all of the events have occured, add `TRIGGER_ALL_NEEDED` to the list of used triggers, e.g. use `bitmask(TRIGGER_ALL_NEEDED, TRIGGER_A, ...)`

Vehicle triggers
Trigger | Event
--- | ---
TRIGGER_VEHICLE_NEW_LOAD | Vehicle gets new load of cargo (only after it was empty)
TRIGGER_VEHICLE_SERVICE | Vehicle enters a depot and is serviced
TRIGGER_VEHICLE_UNLOAD_ALL | The consist has unloaded all cargo (use with type 'SELF')
TRIGGER_VEHICLE_ANY_LOAD | Any vehicle of the consist receives cargo (use with type 'SELF')
TRIGGER_VEHICLE_32_CALLBACK | 32-day callback returned 1

To re-randomize when the consist has been emptied and then receives new cargo, use `bitmask(TRIGGER_VEHICLE_UNLOAD_ALL, TRIGGER_VEHICLE_ANY_LOAD, TRIGGER_ALL_NEEDED)`

Station triggers
Trigger | Event
--- | ---
TRIGGER_STATION_NEW_CARGO | New cargo waiting
TRIGGER_STATION_NO_MORE_CARGO | No more cargo waiting
TRIGGER_STATION_TRAIN_ARRIVES | Train arrives (starts loading/unloading)
TRIGGER_STATION_TRAIN_LEAVES | Train leaves (done loading/unloading)
TRIGGER_STATION_TRAIN_LOADS_UNLOADS | Train loads/unloads cargo
TRIGGER_STATION_TRAIN_RESERVES | Train reserves platform using PBS

The last four triggers in the table only trigger on the platform on which they occur.

House triggers
Trigger | Event
--- | ---
TRIGGER_HOUSE_TILELOOP | The house tile is processed in the periodic tile-processing loop
TRIGGER_HOUSE_TOP_TILELOOP | The top tile of the house is processed in the periodic tile-processing loop

Using `TRIGGER_HOUSE_TOP_TILELOOP`, it is possible to re-randomize the whole building as one unit. All tiles of a multi-tile house will get the same new random data.

Industry tile triggers
Trigger | Event
--- | ---
TRIGGER_INDUSTRYTILE_TILELOOP | The industry tile is processed in the periodic tile-processing loop
TRIGGER_INDUSTRYTILE_256_TICKS | Triggers simultaneously for all tiles of the industry every 256 ticks. If the industry is a primary one, output cargo is generated at the same time.
TRIGGER_INDUSTRYTILE_CARGO_DELIVERY | Cargo is delivered to the industry. If the industry is a processing one, output cargo is generated at the same time.

`<independent>: <other_random>;` makes sure that this random_switch block and `<other_random>` use different (non-intersecting) random data. This allows making multiple randomized decisions that are independent of each other.

`<dependent>: <other_random>;`, on the other hand, lets this random_switch block and `<other_random>` use the same random data. To make this possible, it should not require more random data (i.e. have a higher sum of probabilities) than the block it is dependent on.

Both of these options require enough random data to be available. Also, the combination must make sense. For example, if A is dependent on B and B is dependent on C, then A cannot be independent of C.

Following this, there is a list of options, one of which will be chosen randomly. The syntax is `<probability>: <return_value>;`. The relative probability that this option will be chosen is given by `<probability>`. The chance is equal to the probability divided by the sum of all probabilities. If this sum is not equal to a power of two (2, 4, 8, 16, ...), then rounding is done and the probabilities may be inexact. For information about `<return_value>`, see the switch-block.

Note that re-randomizing is done only during a special callback, CB_RANDOM_TRIGGER. This callback is called whenever a trigger event occurs. As a consequence, it's absolutely necessary for the random_switch block to be in executed during this callback, or trigger-based re-randomizing won't take place. Also, the callback may not fail (end with CB_FAILED), so return an arbitrary value or even a sprite set instead. This return value is not used anywhere.

Let's conclude with an example:

    random_switch (FEAT_TRAINS, SELF, random_42, bitmask(TRIGGER_VEHICLE_UNLOAD_ALL, TRIGGER_VEHICLE_ANY_LOAD, TRIGGER_ALL_NEEDED)) {
    	/* re-randomize when vehicle has been emptied and then received new cargo */
    	independent: random_43; // decision should be independent from random_43, which is defined elsewhere
    	6: group_open;          // 6/11 chance to display open wagon
    	3: group_closed;        // 3/11 chance to display closed wagon (with cover)
    	2: group_halfopen;      // 2/11 chance to display a half-covered wagon
    }

## Cargotable

    cargotable {
    	ID [, ID]*
    }

The cargotable is a list of 4-byte long IDs or literal strings. For example:

    cargotable {
    	PASS, MAIL, GOOD, COAL
    }

## Railtypetable

    railtypetable {
    	ITEM [, ITEM]*
    }

Each `ITEM` can be either a 4-byte long Identifier or string or it can have this format:

    ID : [ ID[, ID]* ]

The first ID is the name (doesn't have to be 4-bytes long), the other iDs are a list of labels that are assigned to the given name if they are available.

    railtypetable {
    	RAIL,
    	ELRL,
    	"3RDR",
    	RT_SHINY_RAIL: [SHNY, RAIL]
    }

The label 3RDR is written as a string because an identifier can't start with a numeric value. To reference it later you can write `railtype("3RDR")`. If another grf defines a railtype with label SHNY then RT_SHINY_RAIL will refer to that track type. If the railtype SHNY is not available then trains using RT_SHINY_RAIL as track type will fallback to RAIL.

## If/else

    if (expression) {
    	block;
    } else {
    	block;
    }

For example:

    if (param[1] == 1) {
    	param[2] = 3
    } else {
    	param[2] = 5
    }

## While

## Error

The general form of an error statement is:

    error(level, message[, extra_text[, parameter1[, parameter2]]])

where level is the severity of the message and one of `NOTICE, WARNING, ERROR, FATAL`. The message can be either a custom defined string which can contain up to two parameters or it can be one of the pre-defined strings which already have translations. The first {STRING}-code will always be replaced by the NewGRF name. The second {STRING}-code will be replaced by the value of 'extra_text'. Extra_text can be a string defined in the language files or it can be a literal string, in which case it cannot be translated. You should only use a literal string in those cases where you are sure it doesn't have to be translated, for example to provide a version string like "0.7.0".

name | actual text | Contents of extra_text
--- | --- | ---
REQUIRES_TTDPATCH | "{STRING} requires at least TTDPatch version {STRING}" | version string
REQUIRES_DOS_WINDOWS | "{STRING} is for the {STRING} version of TTD." | [DOS | Windows] Palette type
USED_WITH | "{STRING} is designed to be used with {STRING}" | switchname + value, e.g. "multihead 0". This is designed to be used for incompatible settings that you can check via ttdpatch_flags.
INVALID_PARAMETER | "Invalid parameter for {STRING}: parameter {STRING} ({PARAM})" | extra_text should be the parameter number written out as string. {PARAM} is replaced by parameter1. filled in.
MUST_LOAD_BEFORE | "{STRING} must be loaded before {STRING}." | NewGRF name
MUST_LOAD_AFTER | "{STRING} must be loaded after {STRING}." | NewGRF name
REQUIRES_OPENTTD | "{STRING} requires OpenTTD version {STRING} or better." | version string
string(STR_MY_ERROR_MESSAGE) | (user-defined string) | The message-string can use the code {STRING} up to 2 times, the first usage will be replaced by the NewGRF name and the second usage by 'extra_text'. After 2 {STRING}-codes you can include up to 2 {PARAM}-codes that will be replaced by the contents of parameter1 and parameter2.

For example:

    error(NOTICE, USED_WITH, string(STR_REGRESSION_CARE));
    error(FATAL, string(STR_REGRESSION_ERROR), string(STR_ANSWER), 14, param[1] + 12 * param[2]);

## Disable items

With a `disable_item` statement, it's possible to disable one or more existing items. This works for vehicles, houses, industries, cargos and airports. The general syntax is:

    disable_item(feature[, first_id[, last_id]]);

`feature` specifies the feature of the item(s) to disable. If no further arguments are given, all default items of that feature are disabled. If one more argument (`first_id`) is given, only that ID is disabled. With two more arguments, all items from `first_id` up to and including `last_id` are disabled. For lists of default IDs, consult the documentation about that feature. An example:

    /* disable all monorail and maglev vehicles */
    disable(FEAT_TRAINS, 54, 115);

## Deactivate other NewGRFs

## Testing for other NewGRFs

See the builtin functions for the functions grf_XXX. Additionally - when the presence of a NewGRF is established - their parameters can be of interest and queried. The general syntax is

    identifier = param[<grfID>, <param#>]

For example

    other_newgrfs_param0 = param["NML\01", 0];
    other_newgrf_no_high_cost = param["NML\01", 1] < 5;

reads parameter 1 (the first one, counting starts at 0) from the NewGRF with the grfID "NML\01".

## Overriding vehicles from other NewGRFs

If one wants to modify vehicles defined in another NewGRF it has to be stated explicitly by the `engine_override` command that this is desired. If stated, all vehicles defined within the overriding NewGRF will try to override the vehicle with the same ID within the overridden NewGRF. This can be used to modify single properties of these only. This function is intended for NewGRFs that modify parts of other NewGRFs, e.g. the ECS extension for the DBSetXL.

The syntax is as follows:

    engine_override(targetID);
    engine_override(sourceID, targetID);

The targetID must be the grfID of the NewGRF whose vehicles are supposed to be changed via the engine override. The sourceID is the grfID of the NewGRF defining the overriding vehicles. If not set explicitly, the grfID of the NewGRF containing this statement is used.

## Sprite replacement

This section covers the three available methods to replace sprites. Which one to use depends on the type of sprites you want to replace. The following sections will outline the detailed functionality of these blocks and when to use them.

### Replace TTD sprites

Using a `replace` block, it is possible to replace TTD's built-in sprites. The syntax is as follows:

    replace(<sprite-id>, <image-file>) {
    	list of realsprites
    }

The first parameter `<sprite-id>` indicates the sprite number of the first sprite to replace. Sprite numbers are equal to the sprite numbers in the base graphics file. The OpenGFX author overview can be used as a reference to look up these sprite numbers. The second parameter `<image-file>` specifies the image file that contains the new sprites. A series of real sprites has to be specified between the curly braces (`{` and `}`). The first sprite in this list replaces the sprite with id `sprite-id`, the second replaces `sprite-id + 1` and so on. Sprite templates can be used as well. For example:

    // Rail overlays for crossings
    replace (1005, "src/gfx/rails_overlays.png") {
    		[ 20,198, 40,21, -20,  5]
    		[ 71,198, 40,21, -20,  5]
    		[117,198, 40, 7, -20,  5]
    		[165,198, 40, 7, -20, 21]
    		[216,198, 12,19,  10,  5]
    		[248,198, 12,19, -24, 11]
    }

### Replace new sprites

Over time, several features have been added to TTDPatch and OpenTTD that require new sprites. As these sprites are not present in the original base graphics, they cannot be replaced using a normal `replace` block. Instead, a `replacenew` block has to be used. The semantics are like this:

    replacenew(<type>, <image-file>[, <offset>]) {
    	list of realsprites
    }

The `<type>` parameter indicates the type of sprites that will be replaced. It should be an identifier from the first column of the following table.

Type | Number of sprites
--- | ---
PRE_SIGNAL | 48
PRE_SIGNAL_SEMAPHORE | 112
PRE_SIGNAL_SEMAPHORE_PBS | 240
CATENARY | 48
FOUNDATIONS_SLOPES | 74
FOUNDATIONS_SLOPES_HALFTILES | 90
TTDP_GUI_25 | 73
TTDP_GUI | 93
CANALS | 65
ONE_WAY_ROAD | 6
COLOURMAP_2CC | 256
TRAMWAY | 113
SNOWY_TEMPERATE_TREES | 133
COAST_TILES | 16
COAST_TILES_BASEGFX | 10
COAST_TILES_DIAGONAL | 18
NEW_SIGNALS | any (a)
SLOPED_RAILS | 12
AIRPORTS | 15
ROAD_STOPS | 8
AQUEDUCTS | 8
AUTORAIL | 55
FLAGS | 36 (b)
OTTD_GUI | 160 (b)
AIRPORT_PREVIEW | 9 (b)

(a) Any number of sprites is allowed here, however both OpenTTD and NML don't (yet) support the other features required to use these sprites.

(b) Any number of sprites can be specified up to the stated maximum. Furthermore the `offset` variable can be used, see below for more info.

The amount of sprites has to be equal to the number given in the table, except in the cases of (a) and (b). Having less sprites results in an error. Having more sprites is allowed to provide future compatibility, but a warning will be issued.

Parameter two `<image-file>` is a literal (quoted) string that specifies the file where the sprites are located.

Parameter `<offset>` is optional and has a default value of 0. Values greater than zero are only allowed in the case of the sprite types marked with (b). Setting this value sets an offset into the block of sprites, so only a subset of the sprites (starting at `offset`) will be replaced.

### Add font glpyhs

A `font-glpyh` block makes it possible to provide sprites for glyphs that don't have sprites in normal TTD. The syntax is as follows:

    font_glpyh (<font-size>, <base-char>, <image-file>) {
    	list of realsprites
    }

The first parameter (`<font-size>`) should be an identifier of the font size to use. Valid values are `SMALL`, `NORMAL` and `LARGE`.

The second parameter (`<base-char>`) is the number corresponding to the first character to provide a sprite for. Valid values are all unicode code points in the Basic Multilingual Plane (0-0xFFFF)

Parameter three `<image-file>` is a literal (quoted) string that specifies the file where the sprites are located.

`<real-sprites>` should be a list of real sprites. The first real sprite will be used for the character with code `base-char;`, the second for `base-char + 1` and so on. These sprites should only use colour palette indices 0 (transparent), 1 (foreground), and 2 (shadow). If the shadow colour is used, sprite compression flag 'TILE' must NOT be set.

## 32bpp sprites

A `alt_sprites` block allows you to specify alternative 32bpp sprites that are drop-in replacements for some real sprites in your grf. The syntax is as follows:

    alt_sprites(block_name, zoom_level[, filename]) {
    	list of realsprites
    }

block_name is the name of the replace/replace_new/fontglyph/spriteset-block for which you want to provide 32bpp sprites. zoom_level can be one of `ZOOM_LEVEL_NORMAL, ZOOM_LEVEL_Z0, ZOOM_LEVEL_Z1 or ZOOM_LEVEL_Z2`. Please note that `ZOOM_LEVEL_NORMAL` and `ZOOM_LEVEL_Z2` are exactly the same. Specifying a filename is optional, it's only useful if you have multiple sprites in the same file. If every sprite is in a separate file you'll have to specify the filename for each realsprite anyway, so you can leave it out of the alt_sprites-block.

## Town names

To define randomly generated town names, the `town_names` block should be used. Such blocks can be used in two ways, as generator of (partial) town names for another block, or as top-level town names block, a starting point of town names in the grf file. You must have at least one starting point, but you can have more than one.

The general syntax of a town names block is:

    town_names[(<name>)] {
    	[styles : <string>]
    	<part> <part> ....
    }

The optional `<name>` defines the name of the block. Such a name is used to refer to this block from another town names block. For top-level town names blocks, it is often left out. Note that in that case, you must also leave out the parentheses.

The optional `<string>` defines how the town names are called in the menu. It may only be defined in a top-names block. To make the name available in all languages, it is probably a good idea to at least define a menu name for the generic language.

### Town names parts

A `town_names` block has one or more `<part>`s. Each part defines a piece of a town name. All pieces together form the name generated by the block.

An example of a part is:

    {
    	text("name1", 1),
    	text("name2", 2),
    	town_names(othernames, 3)
    }

The simplest form is just a list of `text(...)`entries. Each entry contains a possible value of piece, and a probability of picking that name. The `town_names(<name>, <probability>)`calls a previous `town_names` block (called 'othernames' in the example), and returns the value generated there. A part should have at least one. At least up to 255 entries will always work. If a part contains even more entries, NML tries to make it fit by creating sub-blocks. If that fails, you will get an error.

The numbers are the probabilities. In the example, the sum of all values is 6, which means that `name1` is picked with 1/6 chance, `name2` has a 2/6 chance, and a name generated from the previous `town_names` block has a 3/6 chance.

## Parameter assignment

    param[<expression>] = <expression>;

Set a parameter to the given expression. Neither of the two expressions has to be constant, the following is perfectly valid:

    param[param[2] + 1] = param[3] * param[4];

## Sound support

Sounds are supported by means of the `sounds` block. An example of a sounds block that defines two new sounds is:

    sounds {
    	load_soundfile("whistle.wav");
    	import_sound(0x87654321, 3);
    }

The block starts with the keyword `sounds`, followed by one or more sound definitions. A sound definition either loads a sound file (like the `load_soundfile("whistle.wav");` which includes the whistle.wav file), or it refers to a sound from another NewGRF file (like the `import_sound(0x87654321, 3);` which imports the fourth sound (index 3) from the NewGRF file with ID `0x87654321`). Importing sounds does not make copies of the data, thus saving memory space.

You can have at most one `sounds` block in a NewGRF file. When using a sound from a sound block, the first sound gets number `73`, the second sound gets number `74`, and so on. Note that this is different from the numbering that you use when importing a sound from another NewGRF, as counting starts at `0` in that case.

All loaded sound files must be 8-bit mono sound files in WAV format, PCM encoding. There are two allowed frequencies: 11025 Hz and 22050 Hz. Due to some limitations of the NewGRF format, the file size cannot exceed 64KB.

## Setting base costs

A number of base costs define how much everything costs in (O)TTD(P). Each cost in-game is determined by a fixed factor multiplied by a base cost. Setting base cost to 0 leaves this cost unchanged. Incrementing it by one doubles the cost, so e.g. a setting of 3 results in a cost that is 8x higher. Setting a negative value reduces the cost in the same manner, e.g. a value of -4 results in 1/16th of the cost. The minimum and maximum values are -8 (1/256th) and 16 (65536x), respectively. Some example code:

    basecost {
    	PR_BUILD_TUNNEL: 2;   // tunnel cost x4
    	PR_BUILD_BRIDGE: -3;  // bridge cost x1/8
    	PR_RUNNING: param[1]; // all running costs are set by the factor in grf parameter 1
    	param[2]: param[3];   // base cost with the number given by param 2 is set to the factor in param 3.
    }

This table lists all base costs that can be set. They can be referred to using either the number in the first or the identifier in the second column. Using an identifier from the third column, it is possible to set an entire category of base costs at once.

Note that all costs are subject to modification by the game difficulty settings. Inflation (if enabled) will increase all costs over time. Recent versions of OpenTTD have affected the behaviour of many base costs, refer to the notes below the cost table for more information.

# Units

# Expressions

## Elementary values

Elementary values in expressions are

Element | Syntax (Python RE) | Description
--- | --- | ---
Decimal number | [0-9]+ | one or more digits
Hexadecimal number | 0x[0-9A-Fa-f]+ | "0x" followed by one or more hexadecimal digits
Floating point number | [0-9]+\.[0-9]+ | a decimal number, a dot, and another decimal number. Only supported for some properties that expect a floating point number.
Identifier | [a-zA-Z_][a-zA-Z0-9_]* | a letter or underscore, optionally followed by more letters, digits, or underscore characters
String | "([^"\\]|\\.)*" | A double quote character, followed by zero or more characters, ending with another double quote character. A character in-between is any single character except a double quote or a back-slash ("\"). It can also be "\\", "\n", "\t", or "\[0-9A-Fa-f][0-9A-Fa-f]" (a back-slash followed by exactly two hexadecimal digits).
Setting | an Identifier | The name of a GRF setting
Parameter | param[<num>] | Read/write the parameter with the given number.
Parameter from another GRF | param[<grfid>, <num>] | Read the value of a parameter of another grf
Unit | nfo|mph|km/h|m/s|hp|ton | One of the strings "nfo", "mph", "km/h", "m/s", "hp", or "ton" (without quotes). Used to set several properties.

You can combine those elementary values using operators like you're used to from other languages. The following operators are supported: +, -, *, /, %, &, |, ^, &&, ||, <<, >>, ==, !=, <=, >=, <, >

## Builtin functions

Available builtin functions are

Function | Description
--- | ---
min(v1, v2) | Return the smallest value
max(v1, v2) | Return the biggest value
date(year, month, day) | If all values are constants, returns the number of days since year 0. If the year is a variable, the month and day should be 1.
day_of_year(month, day) | Return the day of the year since January 1st. Both values must be compile-time constants.
bitmask(bitpos1, ...) | Compose an integer by switching the bits at the given positions on.
STORE_TEMP(value, address) | Store value in temporary storage
STORE_PERM(value, address) | Store value in permanent storage (industries, airports, towns only). Note that accessing permanent town registers thrashes the contents of temporary register 0x100.
LOAD_TEMP(address) | Get value from temporary storage
LOAD_PERM(address [, grfid]) | Get value from permanent storage (industries, airports, towns only). For towns only, specifying a grfid (optional) allows reading the storage of other grfs. Note that accessing permanent town registers thrashes the contents of temporary register 0x100.
hasbit(value, bit_num) | Test whether a bit in a value is on
version_openttd(major, minor, revision[, build]) | Return the constant representing an OpenTTD version
cargotype_available(cargotype) | Check if a certain cargo type is available in this game. cargotype must be a literal string of length 4.
railtype_available(railtype) | Check if a railtype is available in this game. railtype must be a literal string of length 4.
grf_current_status(grfid[, mask]) | 1 if the given GRF is currently active 0, otherwise. If mask is set, only the bits set in the mask will be tested. Both parameters must be a literal string of length 4.
grf_future_status(grfid[, mask]) | Same as above, but tests whether the grf will become active instead of whether it's currently active.
grf_order_behind(grfid[, mask]) | Same as above, but tests whether current grf will become active in the order behind the referenced grf.
visual_effect_and_powered(effect, offset, powered | Helper function for the train property visual_effect_and_powered and the VEH_CB_VISUAL_EFFECT_AND_POWERED callback.
str2number(4-byte long string) | Interpret the given string as a dword and return the value as integer.
cargotype(4-byte long string) | Return the index of the given cargo type in the cargo translation table.
railtype(4-byte long string) | Return the index of the given railtype in the railtype translation table.
reserve_sprites(number of sprites) | Reserve a number of sprites in the TTD sprite range. This is needed if you want to use your own recolour sprites. Example:
    param[10] = reserve_sprites(1);
    replace(param[10]) {
    	recolour_sprite {
    		// your colour remap.
    	}
    }
    spritelayout xyz {
    	building {
    		...
    		recolour: param[10];
    	}
    }
CMP(param1, param2) | Compares param1 and param2 (considering them as signed values). Returns CMP_LESS if param1 is less than param2, CMP_EQUAL if they are equal and CMP_GREATER if param1 is greater than param2.
UCMP(param1, param2) | Compares param1 and param2 (considering them as unsigned values). Returns CMP_LESS if param1 is less than param2, CMP_EQUAL if they are equal and CMP_GREATER if param1 is greater than param2.
rotate(value, amount) | Rotates value to the right amount steps. This is always a 32 bits rotation.