m4nfo is built around functions. I.e., there are no assignments in m4nfo, everything is done by calling functions and setting parameters.
There are different classes of functions:
Property functions are exclusively used inside the "definition" of a feature. They are used to handle properties of the feature in question, like introduction date, top speed or wagon capacity in case of a vehicle, number or length of platforms in case of a station, number of inhabitants or town zone of construction in case of a building, maintenance cost or speed limit in case of a rail type, etc.
Many property functions are the same for TTD's various features, like climate(), flags(), callbacks() or timeframe() in the example above, but others are specific for certain features.
Also, some of the constants used as parameters for property functions might be identical for various features, like flag or callback values, but others might not.
Sprite layout functions deal with the arrangement of sprites, considering their constituent graphics, coordinates and 3D-information. This is quite different for TTD's features: while a vehicle is composed only from one sprite (per direction of travel), a house, a station, an industry or an object are usually composed of many tiles which might include many sprites per tile.
In addition, every tile has a 3D bounding box. This is fixed for vehicles, but has to be specified for "buildings" like houses, stations, industry tiles or objects.
Sprite layout format is the same for houses, industry tiles and objects, and comes in two different variants:
The example above defines a set of sprites for one tile, consisting of a ground sprite ("WATER") together with a building sprite ("2", a piece of a mole), another building sprite ("LIGREEN5", a mole light), and a child sprite without 3D information ("ANIMGREEN", the animated light of the mole light).
m4nfo provides a set of functions to handle those sprite layouts, to define ground or building sprites (in normal, transparent or recolour mode), and to define coordinate offsets and extents. These are explained in detail in their respective entries in this manual, e.g. here, here, or here.
Plain nfo provides variables which may be read and processed dynamically to access certain attributes for the feature in question. In contrast, m4nfo supplies a function for every nfo variable, and in cases where nfo wraps more than one value in a variable, m4nfo either provides extra functions or supports the original nfo scheme of shifting and AND-masking the variable's value by auxiliary function shiftmask().
The diagram on the left shows how m4nfo "translates" plain nfo variables:
nfo (top), 'pseudo code' (middle), m4nfo (bottom).
Apart from the variable/function substitution, in a m4nfo "block" the reference to another block goes first before the evaluated function result, because of ergonomic reasons: it's far easier to keep track of the 'chain' of defs and refs when these are shown on the start of lines than to try to spot them somewhere inside a long block line.
Auxiliary functions are used inside the context of performance functions, most probably inside
their parameter lists to evaluate or arrange special parameters.
Most prominent member of this class of functions might be function shiftmask() which is used to adjust a performance function's result to a more useful range. This function takes two parameters: the first one defines the value to right-shift the result of the function, and the second parameter gives the value with which to AND the result after shifting.
Other members of this class are functions which pack or unpack coordinate parameters, like nibble() or pos(), or auxiliary functions adjusting spriteset() to different TTD features, like load() and move(), or little() and lots().
These are feature-dependant functions like random functions, sound-related functions, cargo or rail type translation tables, etc.
Most of these would be able to be used with more than one of TTD's features.
These are feature-independant functions, like error handling, branching inside the newGRF, definition of text strings, etc.
definehouse(_HOUSE1,
substitutetype(8, 8)
climate(TEMPERATE, ARCTIC)
housename(smallhouse)
size(1,2)
population(30)
mailgen(4)
passaccept(4)
mailaccept(0, 4)
rating(500)
removalcost(10)
probability(8)
timeframe(1.1.1880 .. 1.1.1930)
lifespan(80)
flags(FLAT, HISTORIC)
callbacks(CB_BUILD, CB_AUTOSLOPE)
)
def(51) spriteset(
set(normal(WATER), normal(2), xyz(0,0,0), dxdydz(16,16,6))
set(normal(LIGREEN5), xyz(1,5,6), dxdydz(8,8,16))
set(normal(ANIMGREEN), xyoff(4,2))
)