NML Specification

Syntax overview

Declarations

NML is a mix of a declarative and imperative language. When declaring e.g. a property, the general syntax is as follows.

<property-name>: <value>;

The name and value are separated by a colon (':'). The declaration is terminated by a semicolon (';')
Generally, such a declaration is part of a larger block. Blocks may, in some cases, be nested. Example:

item(FEAT_INDUSTRY) {
    property {
        substitute: 0;
        override: 0;
    }
}

This syntax strongly resembles CSS, the language used for declaring style sheets in web pages.

 

Imperative statements

NML also has imperative parts that resemble languages like C or java. Most prominently, one has the option to manipulate grf parameters in all sorts of ways. A simple example:
param[1] = param[0] * 2

This sets grf parameter 1 to be equal to parameter 0 multiplied by 2. In total 64 parameters are available to play with, numbered 0 to 63. Parameters can also be indexed dynamically:
param[2] = param[param[1] + 1]

if/else statements and while-loops are also supported.

Language blocks

The total number of different blocks and statements is relatively limited. A list is supplied below, click the links for more information.

Block type Purpose
if / else Allow conditional execution of parts of the grf
While loops Execute a part of the grf multiple times
Parameter assignments Manipulate grf parameters
Item definitions Define and modify items (e.g. trains)
GRF definitions Define a GRFID, name and description for the grf
Sprite blocks Declare groups of real sprites
Switch blocks Make a choice when selecting graphics