In m4nfo, industries are using five types of functions:
Functions for tile layout definition
For industries, the tile layout defines what industry tiles should be displayed, and where they are to be displayed inside the industry.
The industry's tile layout is loosely based on that of stations, at least on the tile level, since industries don't have graphics' sprites themselves.
Offsets are counted from the northernmost tile of the industry (see picture on the left), specifying the position of the current tile. Both values are taken as a signed Byte, but cannot go negative except the special case mentioned below (<check>).
<tile-id> is the ID of an already defined new industry tile. Function ttdtile() takes an original TTD industry tile as its parameter.
<check> is an empty parameter. In this special case, the given tile is checked for clearance, but nothing will be placed on it. This is useful to ensure some free space around the industry. This is the only case where <xoff> and/or <yoff> can be negative. If <xoff> is negative, <yoff> must be one lower than the wanted value.
layout_table(_SALTER, layout( tile(xy(0,0), 0) // shed tile(xy(0,1), 1) // depot tile(xy(1,0), 0) // shed tile(xy(1,1), 2) // track top tile(xy(1,2), 0) tile(xy(1,3), 0) tile(xy(1,4), 0) tile(xy(2,0), 0) // shed tile(xy(2,1), 3) // track bottom tile(xy(2,2), 0) tile(xy(2,3), 0) tile(xy(2,4), 0) ) )
layout_table(_BREWERY, layout( tile(xy(0,0), 0) tile(xy(0,1), 1) tile(xy(1,0), 2) tile(xy(1,1), 3) ) layout( tile(xy(0,0), 4) tile(xy(0,1), 3) tile(xy(1,0), 1) tile(xy(1,1), 2) ) )
Functions for industries performance
These functions are used to evaluate game-intrinsic variables, and make them accessible to the industry's activation function. A typical application would use a multitude of these functions linked together to form a "chain", connecting the graphics' sprites of an industry tile with its activation function. See here for an example.
| Function | Description |
| anim_frame(<Coordinate>, <block>) | Get current animation frame |
| callback(<block>) | Check incidence (and type) of callback |
| cargodate(<block>) | Date when cargo accepted |
| cargosubtext(<block>) | Associate cargo subtext for cargo type |
| cargosubtextdisplay(<block>) | Set display window for cargo subtext |
| cargowaiting([1 .. 3], <block>) | Waiting cargo |
| cargoproduced(1 | 2, THISMONTH | LASTMONTH, <block>) | Amounts of cargo produced |
| cargotransported(1 | 2, THISMONTH | LASTMONTH, <block>) | Amounts of cargo transported |
| cargofraction(1 | 2, <block>) | Fractions of cargo transported |
| colour(<block>) | Colour of industry buildings that support variable colouring scheme |
| daysbuilt(<block>) | Date when industry was built in days since 1920 |
| distindustry(<Industry-ID>, <block>) | Distance of nearest industry with given type |
| distland(<block>) | Manhattan distance of closest dry/land tile |
| disttown(<block>) | Manhattan distance of closest town |
| else | This is really a void statement |
| effect(<block>) | Special effect when in CB_EFFECTS |
| height(<Coordinate>, <block>) | Get height of lowest corner of tile |
| history(<block>) | Construction history |
| industrycount(<Industry-ID>, <block>) | Count of industry |
| lastproductionyear(<block>) | Last year anything was produced (base +1920) |
| layoutnum(<block>) | Layout number |
| lclass(<Coordinate>, <block>) | Get landscape class of tile |
| owner(<block>) | Industry owner information |
| playerinfo(<block>) | Player info |
| prodcallback(<version>, subtractin(<Word>, <Word>, <Word>), addout(<Word>, <Word>), <Boolean>) | Production callback |
| prodcallback_info(EVENT | NUMBER | REPEAT, <block>) | Production callback info |
| prodcounter(<block>) | Production counter, decremented on every tick, used for timing of primary industry production |
| randombits([<Coordinate>,] <block>) | Get random bits at specified tile when in callback |
| slope(<Coordinate>, <block>) | Get slope info of given tile |
| status(<block>) | Status when trying to build industry |
| terrain(<Coordinate>, <block>) | Get terrain type |
| tileid(<block>) | Get industry tile ID at offset |
| townzone(<block>) | Get town zone of closest town |
| water(<Coordinate>, <block>) | Returns 1 if flat water, else 0 |
| waterclass(<Coordinate>, <block>) | Returns "class" of water |
| yearbuilt(<block>) | Date when industry was built in days since year 0 |
| Auxiliary functions | |
| nibble(<Coordinate>) | Get position information from x/y coordinates |
| pos(<Coordinate>) | Construct position information from x/y coordinate |
anim_frame(<Coordinate>, <block>)
The coordinate parameter of this function is an offset from the northernmost tile of the industry. Coordinates must be given by the auxiliary function pos(<x>, <y>,)
This function returns the same values as function anim_frame() for industry tiles.
This function checks for a callback incidence, and if so, returns the type of the incurred callback. See example above.
This function returns the date when cargo was last accepted in days since 1920.
This function assigns cargo subtexts from input/output cargo types. See CB_CARGOSUBTEXT for return values.
This function assigns the window to display a cargo subtext in. See CB_CARGOSUBTEXT for return values.
cargowaiting([1 .. 3], <block>)
If a production callback (CB_ARRIVE or CB_PERIODIC) is set in property function callbacks(), this function returns the amount of incoming cargo, set by first parameter, waiting to be processed. Return values are capped at 0xFFFF (65535).
cargoproduced(1 | 2, THISMONTH | LASTMONTH, <block>)
This function returns the amount of cargo produced either for the first or second cargo, and either for this month or the last month.
cargotransported(1 | 2, THISMONTH | LASTMONTH, <block>)
This function returns the amount of cargo transported either for the first or second cargo, and either for this month or the last month.
This function returns the fractions of cargo transported last month, either for the first or second cargo. A return value of 0xff means 100% of the produced cargo has been transported.
This function retuens the date when this industry was built in days since 1920. In TTDPatch, industry age is limited to 65535 days (approximately 180 years), i.e., the build date is never more than 65535 days ago.
distindustry(<Industry-ID>, <block>)
The parameter of this function is an industry-ID same as for industry property function conflicting(): either the ID of a new type with bit 7 set, or the ID of an old type. The returned value is 0xFFFFFFFF if there are no industries with the given type (not counting the current one, if it has the given type); otherwise, the returned value is the Manhattan distance of the closest industry with the given type.
This function works the same way as function xxx() does during callback CB_LOCATION: if your industry is built on water, it gives the distance of the closest dry land tile, otherwise it gives the distance of the closest water tile. However, you can't use this function during callback CB_LOCATION; you must always use xxx().
disttown(<Coordinate>, <block>)
This function returns the Manhattan distance of the closest town. The coordinate parameter means the offset from the northernmost tile of the industry.
As usual, coordinates must be given by the auxiliary function pos(<x>, <y>,)
This function returns the event resulting in building an industry when in a CB_LOCATION callback, see there.
This function returns the height of the lowest corner of the tile at the given coordinate. The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)
This function returns information about the industry's histoy, i.e. how it got onto the map. The following values are possible:
| Value | Meaning |
| 0 | Unknown - This industry was built with newindustries being off, or in a TTDPatch version prior to 2.0.1 alpha 74 |
| 1 | Created during normal gameplay, either by a player or the in-game random industry generator |
| 2 | Created during random map generation |
| 3 | Created in the scenario editor |
In case 1, you can use function owner() to find out whether the industry was funded by a player or by the random generator.
industrycount(<industry-type>, <block>)
This function returns the number of instances of the industry type given per parameter
This function returns the number of the current layout. The first layout will return "1", the second "2", etc. In other words, this is one larger than what function _layoutnum() returns during callback CB_LOCATION.
If the industry was created using an earlier version of TTDPatch than 2.6 r1594, or while newindustries was off, the result will be zero.
This function returns the landscape class of the tile at the given coordinate: The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)
| Value | Label | Description |
| 0 | LC_TERRAIN | bare land, grass, rocks, fields |
| 1 | LC_RAIL | railway track, with and w/o signals, fences |
| 2 | LC_ROAD | road, level crossings, depots |
| 3 | LC_HOUSE | town buildings |
| 4 | LC_TREES | climate-dependent trees |
| 5 | LC_STATIONTILE | railway station, airport, lorry and bus station, ship dock |
| 6 | LC_WATER | water, coast, river bank, ship depot |
| 7 | LC_VOID | invisible border at bottom edges of map |
| 8 | LC_INDUSTRYTILE | industry tile types |
| 9 | LC_TUNNELBRIDGE | railway or road tunnel, bridge |
| 10 | LC_OBJECT | transmitter, lighthouse, statue, company-owned land, headquarter |
Since TTDPatch 2.0.1 alpha 74, this function returns the ID of the company that funded the industry, or 0x10 if the industry was generated randomly. If the industry was built using an earlier TTDPatch version or with newindustries turned off, the return value will be 0x10 either.
[### not implemented yet]
randombits([<Coordinate>,] <block>)
This function returns the random bits for the given industry tile. The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)
If there's an industry tile on that offset and it belongs to the current industry, the return value will contain the random bits of that tile. Otherwise, the value will be zero.
terrain(<Coordinate>, <block>)
This function returns the terrain type for the current tile. Values are NORMAL, DESERT, RAINFOREST, and SNOW (on or above snowline).
The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)
This function returns the tile-ID of an industry tile at the given coordinate. The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)
The return value may be:
townzone(<Coordinate>, <block>)
This function returns the town zone of the selected tile. The coordinate parameter means the offset from the northernmost tile of the industry. Coordinates must be given by auxiliary function pos(<x>, <y>,)
The return value may be:
| Value | Meaning |
| TZ_CENTRE | Innermost zone, street lights |
| TZ_COMMERCIAL | Trees |
| TZ_RESIDENTIAL | Paved roads |
| TZ_PERIPHERY | Plain roads |
| TZ_OUTSKIRTS |
This function returns a value of "1" if the tile given by <coordinate> is built on flat water, else "0" is returned. Again, the coordinate parameter means the offset from the northernmost tile of the industry, and coordinates must be given by auxiliary function pos(<x>, <y>,)
waterclass(<Coordinate>, <block>)
This function returns the "water class" of the tile given by <coordinate>. Water class values are as follows:
| Value | Meaning | |
| 0 | WC_LAND | Undefined / land |
| 1 | WC_SEA | Sea, ocean |
| 2 | WC_CANAL | Canal |
| 3 | WC_RIVER | River |
Again, the coordinate parameter needs to be given by the auxiliary function pos(<x>, <y>), and are counted from the northernmost tile of the industry.
Date when industry was built in years since 1920, derived from daysbuilt().
Industry Production Callback
Defining the industry production callback
Industries don't have graphics directly associated with them (they have graphics through their tiles), so they don't have functions to define the layout of sprites either. However, unlike other TTD features, they have yet another type of callback for a special purpose: the "production callback", which defines exactly how an industry is producing cargo. Unlike normal callbacks, the latter needs more than the 15 bits a normal callback can return.
When an industry has defined CB_ARRIVE or CB_PERIODIC by property function callbacks(), its way of production is modified. Instead of processing the incoming cargo instantly, it remembers how many units of cargo are waiting, and applies the production callback mechanism to decide how much cargo has to be produced.
The production callback is handled inside the usual chain of control. Typically, there will be a sub-chain of multiple performance functions before the final function handling the production callback. Production callbacks should be handled in the same way as normal callbacks, i.e. using function callback().
There are two versions of the production callback, version 0 needs WORD-sized cargo amounts both for the input and output parameters, as well as for the repeat parameter; and version 1 needs register numbers for registers that contain the cargo amounts and repeat parameter: this allows dynamic computation of all three parameter types.
prodcallback(<version>, subtractin(<Word>, <Word>, <Word>), addout(<Word>, <Word>), <Boolean>)
First parameter is the production callback version number.
If version is 0, cargo amounts to be subtracted and added must be unsigned Words.
The total amount of cargo waiting cannot go negative. If you specify more than the amount actually waiting, the incoming amount will be zeroed instead. You can use negative values to increase the amount of cargo waiting, though.
If <repeat> is 1, the callback will be repeated; if it is 0, it will not.
Using the version 1 format, available since TTDPatch 2.6 r1307, you can decide the instructions for cargo amounts and callback repetition dynamically. Instead of constants, you give numbers of registers that contain the needed values; you can compute these values earlier in the chain of control. Registers are 4 bytes long and are considered to be signed. Negative <add_out> values don't make sense and are ignored. The results are clamped to the allowed range, 0 .. 65535 for both incoming and outgoing cargo amounts.
Since TTDPatch 2.5 beta 5, you can request some random bits by function randombits() by setting RANDOMBITS in property function flags(). These bits won't be re-randomized when you call the callback again by setting a non-zero <repeat> value; they're randomized only for the first call.
During this callback, function prodcallback_info() returns additional information about the current production callback:
| Parameter | Meaning |
| EVENT | The reason the callback is called: "0" if it was called because of incoming cargo (CB_ARRIVE), "1" if it was called in the periodic processing (CB_PROCESSING). |
| NUMBER | How many times the callback was already called in this loop, i.e. "0" for the first call, "1" for the second, etc. |
| REPEAT | The <repeat> value of the previous call, or "0" if this is the first call. This can be used to have state information during the loop since you can pass information to the next iteration. (Since TTDPatch 2.0.1 alpha 73) |
This pair of functions is used to evaluate coordinate offsets for some of the houseinfo_*() functions. They work in a somewhat "inverse" way.
nibble(<Coordinate>)
This function is used to check a returned byte-packed coordinate value in the usual form (<x>, <y>). Parameter range is [-8 ... +7], both for x- and y-offsets. For an example see here.
pos(<Coordinate>)
This function supplies the given coordinates in a byte-packed form to another function. Parameter range is [-8 ... +7], both for x- and y-coordinates. Please note that the coordinate (0,0) refers to the current tile itself. For an example see here.