Callbacks
Introduction
A callback is a special action 2 that the patch "calls" in order to modify various features, an example being the visual effect of train vehicles. See the callback tutorial on how to use them.
In the final action 2 of a chain of variational action 2s, the second byte of the matching entry has to have bit 7 set to identify it as a callback result. (Previously, it was required that the second byte be FF, but now only bit 7 needs to be set.)
For example, 04 00 is not a callback result (but it may be the ID of another chained action 2), whereas 04 80 is a callback result with a value of 4. For some callbacks, 15 bit results are possible, in which case the upper 7 bits are stored in the second byte. For example, 54 C2 is a callback result with a value of 4254=16980, where again the second byte has bit 7 set, changing the 42 into C2.
For compatibility with earlier patch versions, FF in the high byte is taken to mean the same thing as 80, so 04 FF also has a callback result of 4. Note that if your grf file needs to be compatible with versions before TTDPatch 2.0.1 alpha 40, you must set the high byte to FF, and so can use only 8 bit results.
List of callbacks
The following callbacks are defined by the patch. The number of the callback is what will be stored in variable 0C so that you can return the right results if you have several callbacks. All callbacks are explained in more detail below.
PLEASE NOTE: Since TTDPatch 2.5 beta 5, the size of variable 0C has changed, and now there are word-sized callback numbers as well. To maintain backwards compatibility, only callbacks 10..3F can be checked using a byte-sized check. Callbacks 140 and above, on the other hand, must be checked using a word or dword sized check, to make sure they are identified uniquely.
Number | Feature(s) | Meaning | |
---|---|---|---|
10 | Vehicles | Visual effect and wagon power | |
11 | Vehicles | Wagon length | |
12 | Vehicles | Load amount | |
13 | Stations | Station availability | |
14 | Stations | Use callback to select sprite layout | |
15 | Vehicles | Set refitted capacity | |
16 | Trains | Build articulated engines | |
17 | Houses | House construction check | |
18 | Several (G*) | AI construction/purchase selection | |
19 | Vehicles | Cargo sub-type display | |
1A | Houses | Next animation frame | |
1B | Houses | Animation control | |
1C | Houses | Construction stage changes | |
1D | Trains | Can wagon be attached | |
1E | Houses | Decide colour of building | |
1F | Houses | Cargo acceptance | |
20 | Houses | Length of animation frame | |
21 | Houses | Trigger building destruction | |
22 | Industries | Availability | |
23 | Vehicles | Additional text in purchase screen | |
24 | Stations | Custom station layout | |
25 | Industry tiles | Animation control | |
26 | Industry tiles | Next animation frame | |
27 | Industry tiles | Length of animation frame | |
28 | Industries | Industry location permissibility | |
29 | Industries | Random production change | |
2A | Houses | Get accepted cargo types | |
2B | Industry tiles | Decide cargo acceptance | |
2C | Industry tiles | Get accepted cargo types | |
2D | Vehicles | Select colour mapping for vehicle | |
2E | Houses | Custom cargo production | |
2F | Industry tiles | Custom shape check | |
30 | Industry tiles | Decide drawing default foundations | |
31 | Vehicles | Start/stop check | |
32 | Vehicles | 32-day callback | |
33 | Several | Sound effect callback | |
34 | Vehicles (G*) | Autoreplace vehicle selection | |
35 | Industries | Monthly random production change | |
36 | Vehicles | Change vehicle Properties | |
37 | Industries | Cargo sub-type display | |
38 | Industries | Show additional text in fund window | |
39 | Cargoes | Custom profit calculation | |
3A | Industries | Show additional text in industry window | |
3B | Industries | Control special effects | |
3C | Industry tiles | Disable autosloping | |
3D | Industries | Opt out of accepting cargo | |
40..13F | --Reserved-- | ||
140 | Stations | Animation control | |
141 | Stations | Next animation frame | |
142 | Stations | Length of animation frame | |
143 | Houses | Protect building conditionally | |
144 | Sounds (G*) | Ambient sound effects | |
145 | Cargoes | Custom station rating calculation | |
146 | New Signals (G*) | New signals sprite drawing | |
147 | Canals | Add sprite offset | |
148 | Houses | Watched cargo accepted | |
149 | Stations | Land slope check | |
14A | Industries | Decide industry color | |
14B | Industries | Decide input cargo types | |
14C | Industries | Decide output cargo types | |
14D | Houses | Customized building name | |
14E | Houses | Decide drawing default foundations | |
14F | Houses | Disable autosloping | |
150 | Airport tiles | Decide drawing default foundations | |
152 | Airport tiles | Animation control (OpenTTD > r19197) | |
153 | Airport tiles | Next Animation frame (OpenTTD > r19197) | |
154 | Airport tiles | Length of animation frame (OpenTTD > r19197) | |
155 | Airports | Extra information about airport layout in the build gui (OpenTTD > r20372) | |
156 | Airports | Airport layout name (OpenTTD > r20373) | |
157 | Objects | Land slope check | |
158 | Objects | Next animation frame | |
159 | Objects | Animation control | |
15A | Objects | Length of animation frame | |
15B | Objects | Decide colour of building | |
15C | Objects | Show additional text in building window | |
15D | Objects | Disable autosloping |
(*) Generic callbacks are called for the feature, not any specific vehicle ID. Read the Action 3 entry on how to define these.
Visual effect and wagon power (10)
This callback is used to determine the visual effect to use for a vehicle and whether a train wagon is powered (adding power and weight to the train).
The 'powered wagon'-flag only applies for train wagons that would by default be powered (i.e. property 1B is set).
The visual effect applies to all train vehicles (since OpenTTD r21238 for road vehicles and ships as well).
The callback is only called when loading a game, when the train reverses, or when rearranging the train in a depot.
In OpenTTD the 'visual effect' is also updated when the vehicle enters track of a different railtype. The 'powered wagon'-flag may not change in that case.
If the callback fails for any reason (e.g. not defined, action 2 does not return callback result etc.), the value of the corresponding action 0 property ( train property 22, road vehicle property 21, ship property 1C ) is used instead. For possible return values, refer to these properties as well.
Wagon length callback (11)
This callback is used instead of property 21 whenever the train leaves a depot or is displayed inside a depot. If the callback fails, the value of property 21 is used instead.
Road vehicles do not have a property for this purpose. If the callback fails, a length of 8/8 is used.
The callback result may change only when whole vehicle chain is inside a depot.
Load amount callback (12)
This callback is used instead of property 07 when loading a game or rearranging a train in a depot (or when buying other vehicles). If the callback fails, the value of property 07 is used instead.
Note: For aircraft carrying both passengers and mail this callback is broken (wrt. mail) in TTDPatch and OpenTTD before r14672.
Since OpenTTD r14672 the callback is called for passengers and for mail. The mail compartment behaves like a wagon attached to a train engine. I.e. to read general variables of the aircraft you have to use varaction2 type 82/86/8A (related object), as most variables are not valid for the mail compartment.
Finally to distinguish the passenger and the mail part you can use variable 47 or even 40.
Station availability callback (13)
This sets whether a station can be constructed or not, i.e. whether it can be selected in the station construction window. A non-zero callback return indicates the station can be built, and a return code of zero removes the station from the selection.
Station sprite layout (14)
Callback 14 selects an entry from the sprite layout (set by prop. 09 or the default if unset), and if its return value is invalid then the sprite layout given from the tile type will be used. You can use this to have more than 4 different sprite sets to choose from.
Bit 0 (station orientation) of the return value is ignored, and instead set to bit 0 of the actual tile, so that you do not have to check the orientation explicitly and return the two corresponding values, instead just organize the layouts such that even numbers correspond to X orientation (NE-SW) and odd numbers corresponding to Y orientation (NW-SE).
The effect is like having additional tile types that are however not actually built, but only show different graphics depending on this callback.
Refitted capacity callback (15)
This callback is used when a vehicle is refitted, to find the new capacity. It is a 15 bit callback since TTDPatch 2.0.1 alpha 40, and allows return values up to 7EFF=32511 units of cargo.
Vehicle variable B9 (for a variational action 2) will be set to the new, climate-specific cargo type (column 3, type B in the cargo type list), or to FF when only checking whether the vehicle is refittable.
Unlike regular refitted capacities (including those from callback 36), the return value is not subject to the usual division of capacities for cargoes other than passengers on trains and planes, instead the capacity is used exactly as returned by the callback. See also the summary page about vehicle refitting.
Articulated engine callback (16)
This allows building articulated engines or wagons, i.e. vehicles made from several individual vehicles. If this callback is in use, additional vehicles will be added until the callback returns FF.
The callback return is interpreted as the ID of the vehicle to add. If 80 is added to the ID, the vehicle will be reversed (as if Ctrl was held while bought).
Note that since the train is not yet built, you cannot use train variables in action 2. Instead, use variable 10 (extra callback info 1), which is set to 01 for the first articulated part, 02 for the second and so on.
If more than the first vehicle contains cargo, the callback must work in the buy menu as well. (This is only supported since 2.5 beta 8.) This means that it will be called with cargo type FF in the action 3. Otherwise, the cargo amount shown in the buy menu will only be for the first part of the articulated vehicle.
In OpenTTD the cargo class of the first road vehicles is used to determine whether the vehicle can stop at bus or truck stops regardless of the capacity of the first vehicle. If the cargo class bit for passengers is set it can go to bus stops when the is not set it can go to truck stops. See also the page about vehicle refitting.
House construction check (17)
This callback is used to determine if the given building type can be built on a position. It should return a nonzero value to allow building and zero to cancel it.
Since the building is not created yet, you can't use variables 40 and 41 (they return zero). You can use variable 42, 43, 44, 45 and all town variables, though. Since OpenTTD r19744 you can also access the random bits via RandomAction2 or variable 5F.
Property 0A and 13 are checked even if the callback returns a nonzero value; they can cancel building as well.
For multi-tile buildings, this callback is always called for the north tile type, but the position you can access through variables 40, 42 and 43 is not guaranteed to be the final position of the north tile. It is guaranteed, though, that if the building really gets built, one of its tiles will occupy that tile. So, for example, if you return zero for desert tiles, this neither means that your building won't occupy any desert tiles, nor that its north tile will be on a non-desert tile; it only means that at least one tile of the building will be on a non-desert tile. (e.g. it can still be built on the very edge of a desert) This restriction was removed in OpenTTD r13489, the callback is now called for the final position of the north tile.
AI construction/purchase selection (18)
This generic feature callback is called for various decisions when the AI is constructing a new route. For example, normally the AI has a hardcoded list of wagons for each cargo type, but with this callback you can make the selection depend on source and destination industries as well as service distance among other things.
Since the vehicle hasn't been bought yet, you cannot use the usual 40+x or 80+x vehicle variables, instead you have the following:
Variable | Size | Content |
---|---|---|
80 | B | cargo type (climate specific, column 3, type B in the cargo type list) |
81 | B | cargo type (climate independent, column 1, type A in the cargo type list) |
82 | B | default selection |
83 | B | source industry type. For new industries the substitute type is returned starting with OpenTTD r20108. |
84 | B | destination industry type. For new industries the substitute type is returned starting with OpenTTD r20108. |
85 | B | distance between source and destination, in (dx+dy)/2 |
86 | B | AI construction event |
87 | B | Construction number; for wagons: number of wagon; for stations 0=source station, 1=destination station |
88 | B | Station size in form NL; N=number of platforms, L=length |
40 | D | xxxxxxTT, TT=cargo slot from cargo translation table or same as var.81 if no table, available since r1167/2.5b9 |
The callback will be called for following construction events, stored in variable 86:
Group | Feature | Var.86 | Type | Description |
---|---|---|---|---|
Trains | 00 | 00 | Check | Regular rail engine |
01 | Check | Electric rail engine | ||
02 | Check | Monorail engine | ||
03 | Check | Maglev engine | ||
08 | Get | Regular rail wagon | ||
09 | Get | Electric rail wagon | ||
0A | Get | Monorail wagon | ||
0B | Get | Maglev wagon | ||
0F | Get | Track type to build | ||
Road Vehicles | 01 | 00 | Check | Road vehicle |
01 | Get | First road vehicle ID to try | ||
02 | Get | Number of road vehicles to try | ||
Ships | 02 | 00 | Check | Ship |
01 | Get | First ship ID to try | ||
02 | Get | Number of ships to try | ||
Aircraft | 03 | 00 | Check | Aircraft |
Stations | 04 | 00 | Get | Station ID |
Notes:
- "Check" means to check if it should try to buy this vehicle (with ID in var.82). Return 00 to disallow purchase, or a non-zero value to allow it. If allowed, the computer will buy the highest-cost (or AI rank for train engines) vehicle it can find that is available and has high enough reliability.
- "Get" means to find out which ID (etc.) to use. The default in var.82 is what it will use if the callback fails.
- For train engines and aircraft, the AI always checks all available engines.
- For road vehicles and ships, the AI has a built-in list of vehicles to try, you can use callback event 01 and 02 to change that list.
- For trains, the track types (0=regular, 1=electric, 2=monorail, 3=maglev) are automatically mapped as appropriate depending on the electrifiedrailways/unifiedmaglev switches. For best results, assume that all four are available. The game will then use the correct one if it is not available.
This callback is "chained", i.e. if a result is not a callback result (high bit is not set), then the request is passed on to the previous generic callback handler, i.e. they are checked in reverse order. This makes it possible to leave certain decisions to the previous handler and allows some cooperation between several .grf files.
Cargo Subtype Display (19)
This callback allows you to display some text after the cargo name when refitting, and in the vehicle capacity display. This is useful to distinguish several subtypes of a certain cargo, e.g. goods could be cars, petroleum, sheet metal etc.
The return value must be the number of a D0xx string set by an action 4 in the same .grf file. For example, if you set text ID D006 to some text, return 06 in this callback will make it displayed after the cargo name.
Normally, you would use the vehicle refit cycle/sub type variable F2 to distinguish the various subtypes. During refitting, the callback is called with successively increased values of variable F2, until the callback returns FF. All the returned variations are then displayed as refitting options, with all options that have the same cargo type and callback result (irrespective of refit cycle) grouped together in the same line.
Next animation frame (1A/26/141/153/158)
Called in every animation frame, this callback returns the number of the next frame to display. Additionally, it can return these special values:
Value | Meaning |
---|---|
FF | stop animation. The current frame stays on screen until the animation is restarted. |
FE | continue with next frame as usual. You can return this for stages where you don't want to do anything special. |
From TTDPatch 2.5 beta 2, you can ask for random bits in variable 10. To enable this, set bit 3 of property 19 for houses, bit 0 of property 12 for industry tiles, or bit 2 of property 13 for stations.
Additionally all animation callbacks also allow to trigger sound effects as described in Callback 148.
Animation control (1B/25/140/152/159)
Called periodically, in a time interval specified in property 16 (houses) or when an animation trigger happens (industry tiles and stations). Returns the number of the frame the animation should jump to, or one of the following special values:
Value | Meaning |
---|---|
FF | stop animation in its current frame |
FE | start animation with its current frame |
FD | leave the animation in its current state (do nothing) |
For multi-tile town buildings, property 19/bit 2 modifies this callback slightly, see details there.
For industry tiles and stations, the low byte of variable 18 contains the reason for the call, i.e. the bit number of the event from property 11 or property 18, accordingly.
Unlike callback 1B, callbacks 25, 140 and 159 are always used when defined, no bit in the action 0 property needs to be set to activate them.
Since TTDPatch 2.5 beta 2, this callback gets random bits in variable 10, to allow randomizing changes.
For callback 1B, the exact randomness depends on bit 2 of property 19 (synchronized callback 1B). If the callback is synchronized, the high 16 bits will be the same for all tiles and the low 16 bits will be different for each tile. Otherwise, all 32 bits will be independent for each tile.
For callback 25, the randomness depends on the type of the event. For triggers that happen for the whole industry (triggers 2, 3 and 4), the high 16 bits will be the same for all tiles, while the low 16 bits will be different. For other triggers, all 32 bits are independent.
For callback 140, the high 16 bits are the same for all tiles triggered, while the low 16 bits are different for each tile.
Additionally all animation callbacks also allow to trigger sound effects as described in Callback 148.
Construction stage changes (1C)
Called when the building changes its construction stage (during normal gameplay, that means exactly four times). Can return the same values as callback 1B. Variable 40 contains the new stage. You can return FF for stages that don't have animated graphics to save resources.
Watched cargo accepted (148)
Called when a cargo type specified in property 20 is accepted by a house tile, or to be more specific, in a station that has the house tile in its acceptance area. It will be called for each tile of a multi-tile building whenever a tile with property 20 accepts cargo. This means if more than one tile has cargoes specified in property 20, the callback can be called multiple times on the same tile in the same tick. The low word of variable 18 contains the offset of the trigger tile relative to the current tile; the low byte contains the X offset, the high byte the Y offset. (0 means it's the same tile, negative coordinates mean it's northward, positive southward.) With this, you can tell apart the callings within the same tick. The high word of variable 18 contains random bits, the bits are the same for each tile of multi-tile buildings. The return values can be the same as for callback 1B.
Due to implementation details, up to 250 game ticks can pass between the actual acceptance and triggering this callback.
This callback isn't available if the station2 structure isn't present - see the property 20 entry for more information.
If any of the above animation callbacks return a nonzero value in the high byte, it will be interpreted as a sound effect number, and the corresponding sound effect will be played on the house tile.
Can wagon be attached (1D)
This callback is called for the train engine (i.e. from the engine's action 3) when attaching a new vehicle to the current train and determines whether it may in fact be attached to the train. The callback is always used when defined, no bit in the action 0 property needs to be set to activate it.
You may use variational action 2s to check variables 40+x and 80+x. For var. action 2 type 81 (vehicle), they refer to variables of the wagon that is to be attached, not the engine it is being attached to, so you can check the wagon's properties like the cargo type to see whether it is appropriate for the given train engine.
Var. action 2 type 82 (engine) refers to the engine the wagon is being attached to, starting from version TTDPatch 2.0.1 alpha 46. This allows you to for example find out the length of the train it is being attached to. In earlier patch versions, it refers to the engine of the source consist (or the wagon if the wagon is not attached to anything else), which was not really helpful.
Return values:
Return | Meaning |
---|---|
xx | Disallow attaching and use the D0xx text ID as second line of an error message, |
FD | Disallow attaching with the standard message (incompatible rail types) |
FE | Allow attaching |
FF | Allow attaching if the rail types match (default) |
It you return FE, you would allow attaching for example a monorail wagon to a regular rail vehicle, so if that's not what you intend, return FF.
Building colour (1E)
Called to decide what colour mapping the building should use. Should return the number of the colour mapping to be used, for example, 775 for blue->dark blue mapping.
This can be useful if you want something more complex than four random colours.
From TTDPatch 2.0.1 alpha 67, you can return a value of col2*16+col1 plus bit 14 set, where col1 and col2 are two company colours. For example, a return value of 73 C0 uses col1=3=yellow and col2=7=dark green. If no two-company-colour maps have been installed, the colours from prop. 17 are used instead.
Uses 15 return bits.
Cargo acceptance (1F)
Called to decide what the building tile can accept. Uses 15 return bits. The returned word should have the layout of Sgmp, where the letters mean the following:
Symbol | Meaning |
---|---|
S | 1 if the building should accept food/fizzy drinks instead of goods |
g | If S is 1, the food acceptance in 1/8 units |
If S is 0, the goods acceptance in 1/8 units | |
m | mail acceptance in 1/8 units |
p | passenger acceptance in 1/8 units |
So, for example, giving the ID 8426h means "4/8 goods, 2/8 mail, 6/8 passenger", while giving the ID 9205 means "2/8 food, 5/8 passenger".
If property 1E and/or callback 2A is used, the meaning changes slightly. In this case, p means the acceptance of the first cargo type given, m means the same for the second cargo type, and g is the same for the third cargo type, while S must be zero.
Length of animation frame (20/27/142/154/15A)
Called to decide how long the current animation frame should last. The value of the delay should be given in the same way as for property 1B/10/17. Decreasing the return value speeds the animation up instantly. Increasing, on the other hand, doesn't slow it down instantly: the actual duration of the current frame will be somewhere between the old and the new delays. The new delay is applied correctly for later frames.
Note: This is one of the most time consuming callbacks as it is called for every animated tile every ≈30 milliseconds. For better performance try to avoid using it where reasonable, e.g. try to use only the properties and put multiple identical looking animation frames after each other.
Trigger building destruction (21)
Called periodically, in a time interval specified by property 16. If it returns a nonzero value, the building gets removed from the map as if the town decided to destroy it. You can use this for example to remove a historical building, since those cannot be normally removed by towns.
Industry availability (22)
Called when TTDPatch needs to know if a given industry type is available.
Return zero to make your type available, or any nonzero value to disable it. This callback is intended for limiting your type as a whole, so you can't access any industry-specific variables, just the global ones. A good example for the use of this callback is a nuclear power plant that isn't allowed to appear before 1970.
During this callback, variable 18 (extra callback info 2) can contain the following values:
Variable 18 | Meaning |
---|---|
0 | TTD is generating a map and needs to know if your type can appear. |
1 | TTD decided to build a new random industry during regular gameplay and needs to know if it can choose your type. |
2 | The user tries to build/prospect for your industry via the new industry window. TTD needs to know if the player is allowed to do this. |
Additional text in purchase screen (23)
This callback is called when TTDPatch displays the vehicle stats of any vehicle in its purchase screen. The return value is the "xx" of a D0xx text ID to be shown below all other stats. The callback is always used when defined, no bit in the action 0 property needs to be set to activate it. As of r1908, text IDs D100..D3FF may also be returned.
How many lines are available depends on the type of vehicle and its other properties, for instance the presence or absence of a "refittable to" line or powered wagons etc. Lines are wrapped automatically, or may be broken explicitly using the newline character 0D.
If cargo FF (buy menu sprite) is handled explicitly for a vehicle, then the varaction 2 handling callback 23 must be in the buy menu varaction 2 chain.
Custom station layout (24)
After applying the values from station prop. 0E, this callback is used to further customize the tile layout.
It is called once for every tile that is being built, and returns the new tile type to build in its place or to leave the tile as defined by prop. 0E or TTD's default if the callback fails. The only possible return values are 00, 02, 04 and 06. Their meaning is the same as in prop. 0E.
Since the station hasn't yet been built, variables 40+x and 80+x are not available, instead variable 10 (extra callback info 1) contains the same information as variable 41 would contain. For the same reason, it uses the same cargo type in action 3 as the construction menu does (i.e., type FF if defined or else the default).
This callback is used always and does not need setting a bit in the action 0 property to activate it.
Industry location permissibility (28)
Called to decide if the industry can be built on a given spot. Since the industry isn't built yet, you can only use a small subset of the data: you can access the data of the nearest town via action 2/type 82 without any problems, but action 2/type 81 will access different variables than it would normally access:
Variable | Size | Meaning |
---|---|---|
40+x | Not accessible | |
5F | Since OpenTTD r19744: Random bits the industry starts with after construction. Accessible via RandomAction2 as well. | |
60+x | Only var. 62 and vars 64..68 can be used | |
80 | W | Coordinates of the selected position |
86 | B | Number of the selected layout, according to property 0A |
87 | B | Ground type of the selected spot (see canal variable 81 for details) |
88 | B | Town zone of the selected spot (see house variable 42 for details) |
89 | B | Distance between the closest town and the selected position. |
8A | B | Height of the lowest corner of the tile (between 00h and 80h, one land height unit equals 8 units) |
8B | W | Distance to the closest water tile if property 1A bit 2 is clear (built on land); distance to the closest empty dry land tile if property 1A bit 2 is clear (built on water) |
8D | W | Square of the Euclidean distance between the closest town and the selected position |
8F | D | 32 random bits (since r1816 and r11985) |
Unless explicitly noted, distances are Manhattan distance, not Euclidean distance, ie. |x-x0|+|y-y0| instead of sqrt((x-x0)^2+(y-y0)^2)
Variable 8B will always be below 80h if prop 1A bit 2 is clear. If bit 2 is set, 8B will be set to its max of 200h in the pathological case of an all-water map.
During this callback, variable 18 (extra callback info 2) contains the following values for OpenTTD r20942 and later:
Variable 18 | Meaning |
---|---|
0 | TTD is generating a map. |
1 | TTD decided to build a new random industry during regular gameplay. |
2 | The user tries to build your industry via the new industry window. |
3 | The user tries to prospect for your industry via the new industry window. |
This callback must return a 15-bit value, which is interpreted as follows:
Value | Meaning |
---|---|
0000-03ff | Industry can't be built, display the misc. GRF text Dxxx as error message |
0400 | Industry can be built |
0401 | Industry can't be built, display the default "site unsuitable" error message. |
0402 | Industry can't be built, display the "...can only be built in rainforest areas" error message. |
0403 | Industry can't be built, display the "...can only be built in desert areas" error message. |
Since TTDPatch r1755, you can use the text reference stack for your error messages, similarly to callback 3A. The only difference is that only 4 registers are copied instead of 6 because error messages support 20 bytes of reference stack only, and two of those bytes may be used by TTD.
Random production change (29)
Called when TTD chooses the industry for a random production change. Variable 18 contains 32 random bits to help randomizing the decision. The callback must return one of the following results:
Value | Meaning | Min. Version |
---|---|---|
00 | Do nothing | |
01 | Halve industry production. If production goes below the quarter of the default, the industry is closed instead, as if you returned 03. | |
02 | Double industry production if it hasn't reached eight times of the original yet. | |
03 | The industry announces imminent closure, and is physically removed from the map next month. | |
04 | Do the standard random production change as if this industry was a primary one. | |
05 | Divide production by 4 | |
06 | Divide production by 8 | |
07 | Divide production by 16 | |
08 | Divide production by 32 | |
09 | Multiply production by 4 | |
0A | Multiply production by 8 | |
0B | Multiply production by 16 | |
0C | Multiply production by 32 | |
0D | Decrement production by 1 | OpenTTD r11532, TTDPatch 2.6 r2046 |
0E | Increment production by 1 | OpenTTD r11532, TTDPatch 2.6 r2046 |
0F | Set production as returned in bits 16..23 of register 0x100 (clamped to 4..128) | OpenTTD r14561, TTDPatch 2.6 r2068 |
Since TTDPatch 2.5 beta 1, you can set bit 7 of this value to suppress the news message announcing the production change. Be careful with this, especially for closedown messages; most players wouldn't like those being suppressed.
For return values 05..0C, the double/halve news messages are displayed. You should probably replace the defaults with some text that doesn't explicitly say "double" or "halve", or use the message override feature (see below). If a divide operation brings the production below the quarter of the default, the industry is closed down instead. Multiply operations that would bring the production above 8 times of the original will only increase it to that value.
Since r1306, you can override the default news messages that appear after production changes. To do this, you must set bit 8 of the returned result, and put the textID into the low word of GRF register 100h (the high word of the register is ignored). The textID can be of a default TTD text or a DCxx text; it cannot be a D0xx text. If the given action generates a message, it will be the one you specified. It may, however, not generate messages at all; for example, operation 04 may decide not to change the production, and then your message won't be shown. There is one exception: operation 00 would never generate a message, but it still will when bit 8 is set. This is useful in conjunction with callback 35, to tell the player about things that don't change the production multiplier, but are still important enough to require a news message.
Using return values 0Dh, 0Eh and 0Fh you can adjust production rates more smoothly. The production rate is a value between 04h and 80h (initial value 10h). Returning 0Dh when the production is at 4 will close the industry. But returning 0Fh will never close the industry, instead the value is clamped to the allowed range. Note that OpenTTD before r15103 did not properly updated production rates provided by properties 12 and 13.
Get accepted cargo types (2A/2C)
Called when TTD needs to know what cargoes a house/industry tile can accept. The bits of the result must be filled in the following way:
Bit range | Meaning |
---|---|
0..4 | First cargo type |
5..9 | Second cargo type |
10..14 | Third cargo type |
If the callback fails, the according values from property 1E is used instead for houses, and properties 0A..0C for industry tiles. This callback is most useful in combination with callback 1F/2B, so you can fully control the acceptance of your house/industry, even allowing dynamic changes
From GRF version 7 and above, the interpretation of the returned value changes: instead of climate-dependent cargo slot numbers, you have to return climate-independent cargo IDs. If your GRF has a cargo translation table, then this ID is the index in that table; otherwise, it's the cargo bit. Acceptance of cargoes not currently present will automatically be disabled.
Decide cargo acceptance (2B)
Called to get the amount of acceptance for the industry tile. The cargo types are defined by properties 0A..0C, or callback 2C if enabled. The callback must return a 15-bit value in the following format:
Bit range | Meaning |
---|---|
0..3 | Acceptance for the first cargo (0..8) |
4..7 | Acceptance for the second cargo (0..8) |
8..11 | Acceptance for the third cargo (0..8) |
If the callback fails, properties 0A..0C are used instead.
Select colour mapping for vehicle (2D)
Called while drawing the vehicle. Should return the number of the colour mapping to be used on the vehicle sprite, for example, 775 for blue->dark blue mapping. If the callback fails, the company colour of the owner is used. Since mapping 775 doesn't change any colours, you can return it to disable the company colours and leave all magic blue in your sprite alone.
If bit 14 is set, the company colour will be added to the resulting sprite number. This means the given sprite and the 15 following sprites must be colour maps, one for each of the 16 possible player colours. If the vehicle also has misc.flags bit 1 set (two company colours), the sprite and the 255 following sprites must be appropriate colour maps. Alternatively, use a return value of 00 C0 to use the default two-colour maps.
Uses 15 return bits.
The return value is cached to speed up sprite processing, and only updated via callback 32 bit 1 (or when loading/starting a game or rearranging the consist).
Custom cargo production (2E)
This callback can be used to customize cargo production of house tiles. It is called every 256 ticks when the tile can produce cargo. Because a tile can produce many types of cargo, this callback is called in a loop until it returns 20FFh (the loop count is limited to 256 to avoid endless loops). If the returned value is not 20FFh, the high byte must be a cargo type and the low byte must be the amount to be distributed. You can return a cargo type more than once if needed, so you can distribute more than 255 units from it. During the callback, the lowest byte of variable 10 contains the number of iterations happened so far and variable 18 contains a random value to help randomizing the production. (The old code randomizes production to make it look more natural, you can do the same via a variational action 2 with nvar=0)
This is how the original passenger generation is done: In each periodic processing (i.e. every 256 ticks), a random value 0<=X<=255 is generated for each house tile. If X isn't smaller than the population of the tile, no passengers are generated. Otherwise, X/8+1 passengers are generated (rounded down). If there is a recession going on, the number of generated passengers is halved, but this division gets rounded up instead of down. Mail generation happens in a similar manner, but with a new random value, and checking against the mail generation multiplier instead of the population.
Uses 15 return bits
From GRF version 7 and above, the interpretation of the high byte in the returned value changes: instead of a climate-dependent cargo slot number, you have to return a climate-independent cargo ID. If your GRF has a cargo translation table, then this ID is the index in that table; otherwise, it's the cargo bit. Trying to produce a cargo not currently present is not an error, but will be ignored.
Custom shape check (2F)
This callback is called when TTD checks if a given tile is suitable for the industry tile. Since the tile isn't built yet, you can use variables 41, 42, 43, and 60 only, and you can't access any industry variables, either. Since OpenTTD r19744 however, you can access the random bits of the industry (it would get after construction) via industry variable 5F resp. RandomAction2 type 83. Var. 60 is the most useful here, since you can check the slope of the tile, or even the nearby tiles. This callback is the only way to allow your tile to be built on steep slopes. The callback should return zero if the tile isn't suitable, or any other value if it is suitable.
Since TTDPatch 2.6 r1728, the lowest byte of variable 18 contains the layout number selected for the industry. The other bits of variable 18 remain undefined for now.
Since OpenTTD r20942, the second lowest byte of variable 18 contains the trigger event of the industry construction. The values are the same as the lowest byte of variable 18 of callback 28.
Important: The meaning of the returned value will change in GRF version 7; it will work the same way as callback 28. Also, since TTDPatch r1755, you can use the text reference stack for your error messages, similarly to callback 3A. The only difference is that only 4 registers are copied instead of 6; see callback 28 for details.
PLEASE NOTE: When this callback is called, TTD is just checking, and hasn't placed any industry tiles yet. Therefore, bit 8 (tile belongs to the same industry as current) of variable 60 will always be clear, even for the current tile.
Decide drawing default foundations (30/14E/150)
This callback is called when TTD starts drawing the industry/house/airport tile on sloped land. It should return zero to disable the default slope graphics and any other value to enable them.
If you chose to disable the foundation, you can draw your own by specifying
- no ground sprite, i.e. a sprite number 00 00 00 00,
- then a foundation sprite with bit 30 set to make foundations visible even in transparent mode, and the normal TTD foundation height of 7px,
- then the normal graphics with bounding boxes adjusted with regards to the foundation sprite:
100 * 4 01 09 02 01 // foundation 101 C:\ttdlx\newgrf\sprites\slope.pcx 220 130 09 40 63 -30 -9 // building 102 C:\ttdlx\newgrf\sprites\slope.pcx 80 130 09 31 64 -31 0 103 * 28 02 09 00 02 00 00 00 00 // no groundsprite 00 00 00 C0 00 00 00 10 10 07 // foundation 01 00 00 80 00 00 08 10 10 10 // building
Please note that TTD doesn't have suitable foundation graphics for steep slopes. In any way, variable 60 comes in handy when selecting the correct foundation to draw.
Start/stop check (31)
This callback is called whenever a player (or the AI) tries to start or stop a vehicle. This is mainly useful for preventing vehicles from leaving the depot unless a given condition is met. To check whether a vehicle is being started or stopped, check bit 1 of variable B2. If set, the vehicle is currently stopped and if clear, the vehicle is moving (or at least, not stopped manually).
The return value is a D0xx text to use as second line of an error message, or FF to indicate that the start/stop action should succeed. The callback is always used when defined, no bit in the action 0 property needs to be set to activate it.
32-day callback (32)
This callback is called every 32 game days for each vehicle, although not for all vehicles on the same day. The callback is always used when defined, no bit in the action 0 property needs to be set to activate it.
The return value is a bit mask of the following bits:
Bit | Value | Meaning |
---|---|---|
0 | 1 | Trigger vehicle trigger 10 |
1 | 2 | Update colour map via callback 2D |
If no bits are set, nothing happens.
Sound effect callback (33)
This callback is called for all vehicles and as generic callback for bridges, for various events that support playing sound effects. The type of event is stored in variable 10.
The 15-bit return value is the sound effect number. Values from 0 to 72 (dec) are TTD's built-in sound effects, values beyond that refer to the sounds from Action 11.
If the callback returns a failure code (not a callback result), the default TTD sound effect will be played. If the callback returns a sound number that is neither a TTD sound, nor a sound from action 11, nothing will be played.
Var. 10 | Event |
---|---|
1 | Start sound, called when leaving a station or depot, take-off sound for planes |
2 | Tunnel sound, called when vehicle enters tunnel |
3 | Breakdown sound, called when vehicle breaks down (not for planes) |
4 | Running sound, called once per engine tick, but no more than once per vehicle motion |
5 | Touchdown sound, for planes only (obviously) |
6 | Train visual effect generation (steam plume, diesel smoke, electric spark) |
7 | Running sound, called every 16 engine ticks if in motion |
8 | Stopped sound, called every 16 engine ticks if stopped (e.g. at signal/in station) |
9 | Load/unload sound, called when consist loads or unloads cargo |
10 | Bridge sound, called as generic feature 06 callback every time a consist moves on a bridge. Variables 40+x, 60+x and 80+x refer to the vehicle and bits 0..7 of variable 18 hold the bridge type |
For the running sounds, it is advisable to check the motion counter and to only return a successful sound effect number every so many vehicle motion ticks. This way, the sounds will be played more frequently the faster the train is. Alternatively, you can check the tick counter variable and play the sound effect every so many engine ticks, so that it is played at a constant rate, or, of course, switch between both modes depending on vehicle speed.
Note that if the planespeed switch is active, planes move the given number of times per engine tick. This means that their motion counter increases faster than for other vehicles, and thus to get reliable sound effects you need to divide the motion counter by the planespeed setting (readable via action D) before checking the value.
Autoreplace vehicle selection (34)
This callback is called whenever an old vehicle needs replacing. It returns the vehicle IDs to upgrade the current vehicle to. The vehicle variables are available as usual to decide which IDs would be appropriate to upgrade to.
The callback is repeatedly called, with the iteration number stored in variable 10. The .grf file should return all possible IDs one by one, with the best ones listed first. The patch will use the first vehicle from the list that is available to the player and has the required minimum reliability as set by the autoreplace switch, and abort the callback sequence at this point.
The callback sequence is also aborted when the returned ID is equal to the current vehicle ID. This is to prevent downgrading, and so you must take care to always return the ID of the vehicle for which the callback is called at the appropriate place in the sequence.
If the callback fails, i.e. if no suitable ID could be found by any of the callbacks in the generic chain, the vehicle is not upgraded, and is simply renewed instead. If an ID is available but the player lacks the cash to upgrade, the patch waits for the cash to become available instead of either picking a worse engine or renewing the vehicle.
For trains, each engine head will be replaced by one vehicle of the new type. As such, it is advisable for only return "compatible" IDs for trains that require a particular construction or arrangement of engine heads.
The callback is always used when defined, no bit in the action 0 property needs to be set to activate it.
Monthly random production change (35)
Works exactly the same way as callback 29, except that it's called every month, allowing more frequent production changes.
Change vehicle properties (36)
This common callback allows modification of certain properties of a vehicle for which there exists no specific callback (like CBs 10, 11, 12). The low byte of variable 10 holds the property number from Action 0.
The following properties are supported:
Feature | Property | Minimum version | OpenTTD rev | |
---|---|---|---|---|
Trains (00) | 07 (Load amount) | - | - | Changeable via callback 12 |
09 (Speed) | 2.5 beta 6 | r9671 | ||
0B (Power) | 2.5 beta 6 | r9671 | ||
0D (Running cost factor) | 2.6 rev 1420 | r9671 | ||
14 (Cargo capacity) | 2.6 rev 1966 | r9828 | See also callback 15 | |
16 (Weight) | 2.6 rev 1887 | r9780 | ||
17 (Cost factor) | r9806 | |||
1F (Tractive effort) | 2.5 beta 6 | r9671 | ||
21 (Short wagons) | - | - | Changeable via callback 11 | |
22 (Visual effect & powered wagons) | - | - | Changeable via callback 10 | |
25 (User data) | 2.5 beta 6 | r11431 | ||
Road Vehicles (01) | 07 (Load amount) | - | - | Changeable via callback 12 |
09 (Running cost factor) | r18011 | |||
0F (Cargo capacity) | r9828 | See also callback 15 | ||
11 (Cost factor) | r9806 | |||
13 (Power) | r21058 | |||
14 (Weight) | r21058 | |||
15 (Speed) | r21100 | |||
18 (Tractive effort) | r21058 | |||
Ships (02) | 07 (Load amount) | - | - | Changeable via callback 12 |
0A (Cost factor) | TTDPatch 2.6 rev 1990 | r9806 | ||
0B (Speed) | 2.5 beta 6 | r9671 | ||
0D (Cargo capacity) | TTDPatch 2.6 rev 1990 | r9828 | See also callback 15 | |
0F (Running cost factor) | TTDPatch 2.6 rev 1510 | r9808 | ||
Planes (03) | 07 (Load amount) | - | - | Changeable via callback 12 |
0B (Cost factor) | r9806 | |||
0C (Speed) | 2.5 beta 6 | r9671 | ||
0E (Running cost factor) | 2.6 r1507 | r9678 | ||
0F (Passenger capacity) | r19218 | See also callback 15 | ||
11 (Mail capacity) | r19218 |
Most properties will only change when the vehicle is bought, serviced (enters a depot), visits a station or on loading of a saved game. Other ones such as TE are called every time a TE calculation is run.
If the callback fails, the corresponding value from the action 0 property will be used. The callback is always used when defined, no bit in the action 0 property needs to be set to activate it.
Before r1758 (both 2.5 and TTDPatch 2.6), callback 36 was sometimes called with the 40+x and 80+x variables unavailable when they should have been available, or with not all 80+x variables properly initialized, causing some 40+x variables to be unsafe.
About the capacity properties see also the summary page about vehicle refitting.
Cargo sub-type display for industries (37)
This callback allows you to display some text after the cargo name in the industry fund window and in industry windows. Just like callback 19, the return value must be the number of a D0xx string set by an action 4 in the same .grf file. Returning FFh causes no text to be displayed.
During the callback, the lowest byte of var. 18 can have the following values:
Number | Meaning |
---|---|
00 | Return subtext for first accepted cargo type |
01 | Return subtext for second accepted cargo type |
02 | Return subtext for third accepted cargo type |
03 | Return subtext for first produced cargo type |
04 | Return subtext for second produced cargo type |
Bits 8..15 of var. 18 can have the following values:
Number | Meaning |
---|---|
00 | The text is to be displayed in the industry fund window. The industry isn't built yet, so you can't access the industry variables |
01 | The text is to be displayed in the window of the industry. You can use the industry variables here. |
02 | The text is to be displayed in the industry directory window. You can use the industry variables here. |
other values | Reserved for future use |
Other bits of var. 18 are reserved for future use.
Since OpenTTD r17802, the contents of registers 100h..105h are copied onto the text reference stack.
Show additional text in fund/building window (38/15C)
This callback allows you to display extra information in the industry fund and object building windows. The return value should be the number of a D0xx text to be displayed. The text must begin with a colouring special character and should not be longer than three lines (automatic line breaks are provided, but you can use char 0D for a manual line break). Since the industry isn't built yet, you can't access any industry variables during this callback. Same holds for objects.
Since OpenTTD r20086 and TTDPatch r2354, the contents of registers 100h..105h are copied onto the text reference stack.
Custom profit calculation for cargoes (39)
This callback is called every time cargo is delivered to a station, to get how much income the player should get. The low word of var. 18 contains the distance of the transfer, byte 3 contains the amount of cargo moved and the highest byte contains the time spent en-route (a unit of time is +185 ticks, or ca. 2.5 days). The result should be a signed multiplier that gets multiplied by the amount of cargo moved and the price factor, then gets divided by 8192. Since the highest bit must always be set for a callback result, TTDPatch checks for the second highest bit (bit 14) for the sign. Returning a negative value means that the player has to pay for the transfer instead of getting money from it. For example, the maximum returnable value of 16383 means that the player gets twice the price factor for every unit.
Show additional text in industry window (3A)
This callback allows you to display extra information in the industry window about the state of your industry. The return value should be the number of a D0xx text to be displayed. The text must begin with a colouring special character and should not be longer than one line. For example, you can use this callback to display the current production limit of a secondary industry.
Note that since r11987, OpenTTD allows resizing the window when this callback is enabled. It allows to specify a text containing more than one line.
Since TTDPatch 2.6 r1370, the contents of registers 100h..105h are copied onto the text reference stack. This allows you to display dynamically calculated values in the text by using the according StringCodes. Please note, though, that the text handler will see it as an array of bytes, not as an array of DWORDs, so you will have to pack two words into a register when you use codes that read words from the stack. In the case of \7D (which gets a byte), you may have to pack more into a register, but it's probably easier to use \7C instead. Please also note that you can use \80 to display textIDs calculated on the fly, but DCxx textIDs won't work correctly. When you need to choose from your own texts dynamically, you must use D0xx IDs, and add 400h to them. (That is, use D400 to refer to D000, D401 for D001 etc.)
Control special industry effects (3B)
This callback allows you to control some aspects of the special effects enabled in property 1A. The lowest byte of variable 18 always contains the number of the special effect, which equals to the bit number being set in property 1A. Currently only effect 0 (plant fields periodically) and effect 1 (cut nearby trees periodically) are supported.
- For effect 0 you should return zero to avoid planting fields and any other value to plant a field. The callback is called every 256 ticks for a given industry. Variable 10 contains 32 random bits that can be used to randomize the behaviour. Industry variable AAh (word) can be used to make the plantings rarer, but please note that the low byte is always zero at this point. The default behaviour is giving 1/8 chance to plant a new field every 256 ticks.
- For effect 1 you should return zero to avoid cutting a tree and any other value to try cutting one. The callback is called every 256 ticks for a given industry. You don't get random values this case, but you can still use variable AAh; the low byte is always zero here as well. The default behaviour is trying to cut a tree every 512 ticks.
Disable autosloping (3C/14F/15D)
With this callback, you can prevent the autoslope feature from altering the ground below a house/industry/object tile. To allow altering the ground, return zero. Returning anything other than zero will disallow land modifications.
Opt out of accepting cargo (3D)
With this callback, the industry can refuse accepting a cargo even if it's one of the input cargo types. If there's another industry nearby that accepts this cargo, that one will get it.
The lowest byte of var. 18 contains the ID of the cargo delivered. If your GRF has a cargo translation table installed, you will get the index from that table; otherwise, you will get the cargo bit associated with the cargo type. You must return zero if you don't want to accept the cargo, or 1 to accept it. Other return values are reserved for future use.
This callback should be used in conjunction with callback 2B, since the acceptance of the tiles and the acceptance of the industry itself should always agree. If you disable accepting a cargo via callback 3D, but forget to remove the acceptance from the tiles, the station will keep accepting the cargo and the player will keep getting the money, but the industry won't receive the cargo. On the other hand, if you remove acceptance from the tiles, but forget using callback 3D, your industry may still get the cargo. (For example, there may be another industry nearby whose tiles accept the cargo. This makes the station accept the cargo, and send it to the nearest industry, which happens to be yours, even though its tiles don't accept the cargo.)
Protect building conditionally (143)
This callback is called when someone tries to remove the building from the map. You can use this callback to prevent the town or AI players from removing the building if certain conditions are met. You can return 0 to allow the destruction, or 1 to disallow it, except for human players, who can always remove any building.
If you always return 1 from this callback, you achieve the same effect as turning on bit 1 of property 19. When this callback is enabled, bit 1 of property 19 is ignored. If the callback fails, the destruction is allowed.
For multi-tile buildings, the callback will be called for the type of the tile the player wants to destroy. Therefore, to get consistent behaviour, you must enable this callback for every tile and respond it the same way no matter which tile it is called for.
Since TTDPatch 2.6 r1705, you can use this callback to prevent building "town" industries (banks, water towers, etc.) over your house. The lowest byte of variable 10 is zero for "normal" demolition and one when TTD wants to remove the house for the sake of a new industry. Other values of variable 10 are reserved for future use.
Ambient sound effects (144)
This callback is a generic callback for feature 0C (new sounds) used for playing ambient sound effects.
The 15-bit return value is the sound effect number. Values from 0 to 72 (dec) are TTD's built-in sound effects, values beyond that refer to the sounds from Action 11.
To decide whether to play a sound, and what sound to play, Var.Action 2 variable 10 holds the following information: THRRxxxt
Field | Meaning |
---|---|
T | Tile class, 0=bare land, 4=trees, 6=water |
H | Height of north corner of tile |
RR | 8 random bits |
xxx | Reserved |
t | Terrain type; 0 normal (grass), 1 desert, 2 rainforest, 4 on or above snowline |
This callback must be enabled by bit 4 in action D var 9E.
Custom station rating calculation (145)
This callback allows you to modify part of the station cargo rating calculation for your cargo. To understand how to use it, you must first understand how the default rating calculation works:
Internally, the station rating is stored in a byte, 0 meaning 0% and 255 meaning 100%. The rating is calculated as the sum of the following components:
Time since the cargo was last picked up
Time units (days) | Score (%, rounded) |
---|---|
>21 (>52.5 days) | 0 (0%) |
13..21 (32.5 days..52.5 days) | 25 (10%) |
7..12 (17.5 days..32.5 days) | 50 (20%) |
4..6 (10 days..17.5 days) | 95 (37%) |
0..3 (0 days..10 days) | 130 (51%) |
The time unit used equals 185 engine ticks, or 2.5 TTD days. For ships, the time units are divided by 4 before calculating this component, so ships have four times more time before the ratings start dropping.
Amount of cargo waiting
Amount of cargo | Score (%, rounded) |
---|---|
>1500 | -90 (-35%) |
1001..1500 | -35 (-14%) |
601..1000 | 0 (0%) |
301..600 | 10 (4%) |
101..300 | 30 (12%) |
0..100 | 40 (16%) |
Max. speed of the last vehicle picking up the cargo
This calculation is somewhat complicated. The maximum speed of the vehicle is expressed in "speed units". For trains and road vehicles, the speed unit is 1 km/h; for ships, it's 0.5 km/h; for aircraft, it's 8 mph. If the max. speed is above 255 speed units, 255 is used instead. If the vehicle is slower than 85 units, no points are awarded; otherwise, you get (speed_units-85)/4 points. Therefore, the maximum you can get is 42 points, or 16%.
Age of the last carrier picking up the cargo
The original calculation goes like this:
Age of vehicle (years) | Score (%, rounded) |
---|---|
2 | 10 (4%) |
1 | 20 (8%) |
0 | 33 (13%) |
If the newagerating switch is turned on, the calculation changes. You get 33 points for vehicles younger than 5 years, and get 0 points for vehicles older than 21 years. Between these two ages, score drops slowly, by 2 points per year.
Bonus for AI companies
AI intelligence setting | Score (%, rounded) |
---|---|
Low | 0 (0%) |
Medium | 31 (12%) |
High | 63 (25%) |
That is, AI players cheat to get good ratings for their brain-dead routes.
Bonus for statue in nearest town
If your company has erected a statue in the nearest town, you get 26 points (10%) bonus to all cargo ratings.
Clamping
If a human player does everything perfectly, the maximum rating she can get is 271 points, while the worst possible transport service gets -90 points; for "highly intelligent" AI players, the corresponding values are 334 and -27, respectively. The resulting value gets clamped to the 0..255 range. TTD makes sure the ratings change slowly, but steadily: every 2.5 days, the actual rating moves towards the value calculated above, by no more than 2 points. For example, you 'd need at least 320 days to go from 0% to 100%, even if your service is perfect. When a cargo type first appears at a station, its rating is set to 175 points (69%), so it takes some time until it gets adjusted to the actual parameters of the service.
Callback effect
The callback allows you to replace the first three components (days since last pickup, amount waiting and max. speed of last vehicle) in the calculation above. If your callback succeeds, the first three components are skipped and the returned value is used instead their results. Bit 14 is considered the sign bit, so you can return negative numbers (and need not to worry about calculated callback results yielding a negative result, as long as you stay in the range -16384..16383). During the callback, variable 18 has the value ssaaaatt, where
- tt is the time since the cargo was last picked up, in the time units described above (1 unit = 2.5 days independent of vehicle type)
- aaaa is the amount of cargo waiting
- ss is the speed of the last vehicle picking the cargo up, in the speed units described above (if no vehicle entered the station yet, the value is FFh)
The lowest byte of variable 10 contains one of the following values:
value | meaning |
---|---|
10h | the last vehicle entering the station was a train |
11h | the last vehicle entering the station was a road vehicle |
12h | the last vehicle entering the station was a ship |
13h | the last vehicle entering the station was an aircraft |
00h | no vehicle entered the station yet, or the last one entering was sold |
Please note that there's only one "last vehicle" field per station, so the vehicle this refers to may not have picked up any of your cargo. The original TTD calculation doesn't care about this and just uses the field to get the vehicle type used in the first component.
Currently, you can only use variables 10 and 18 for your decision, since neither vehicle nor station variables are available for a cargo callback. As soon as the architecture of TTDPatch allows this, the callback will be given access to the station and the last vehicle that entered.
New signals sprite drawing callback (146)
This is a generic callback, and thus a generic action 3 must be used. It must be processed by a variational action 2 feature 0E, as indicated in the following link: VarAction2NewSignals.
Add sprite offset callback (147)
Add an offset to the default sprite number to be drawn.
Feature | Accessible Variables |
---|---|
Canals | 80+x variables are accessible by Canals. See VarAction2Canals |
The default number is accessible in variable 10 (extra callback info 1) to decide if the sprite number needs an offset.
Land slope check (149/157)
This callback is called for each tile where the new station part will be built. It can return zero to accept the current tile or one to make the station building fail with the "Land sloped in wrong direction" error message. Other return values are reserved for future use, don't use them for now.
Since the station isn't built yet, no 8x variables can be accessed. Only variables 43 and 67 will work from the 4x and 6x variables. You get the following information, though:
- variable 18:
bit numbers | Meaning |
---|---|
0..7 | offset of current tile on the platform, 0 is the northmost tile |
8..15 | bits 8..15: current platform number, 0 is the northmost platform |
16..23 | total length of station being built |
24..31 | total number of platforms being built |
- variable 10:
bit numbers | Meaning |
---|---|
4..7 | Slope info of the current tile:
|
0..3 | the same information, but "mirrored" (bit 0 and 2 swapped) if the station is built in the NW-SE orientation. This allows you to check slopes without checking the orientation explicitly. |
other bits | reserved for future use |
The callback is called only after the normal checks TTD does for slopes, so it's not possible
to allow a slope that isn't allowed by default; you can only narrow the set of allowed slopes. If the callback fails, the tile will be accepted. It is, however, called for flat tiles, so you can force your station to sloped land. You can't access the station info even if the platform is added to an existing rail station or is overbuilding station tiles. That's because TTD will decide this later in the code, after the slope is already accepted.
This is called if available just before object construction, it does not require that any flags be set in the action0.
Please note that for Objects only the low byte of variable 18 is valid (Offset from north tile (origin), stored as YX) and that variable 10 does not have the reversed version, and bits 0 - 3 contain the actual raised corners (same order as bits 4 - 7).
Decide industry colour (14A)
This callback is called when the industry is being constructed, to override the selected colour of the industry (variable A8). This colour will be used for tile sprites that request recolouring, but don't supply a recolour sprite number. The following industry variables aren't yet filled and contain random junk: 86..87, 93, 9E..A1, A9. (You probably wouldn't need to read anything but 86..87 anyway, since these fields contain information about the past, and the industry doesn't yet have a past.) Industry tiles aren't placed yet, either.
Variables A7 and A8 are filled, however, and provide useful information. Variable A7 contains the number of the funder company, or 10h if the industry wasn't funded. Variable A8 contains the number of the colour scheme randomly picked by TTD, it's between 0 and 15. If you don't want to change the colour picked by default, you can either make the callback fail or just return variable A8 unchanged.
Only the lowest four bits of the returned value are used, the other bits are reserved for future use. Those four bits are copied into variable A8 after the callback returns. You can either use industry variable 45 to get the company colour of the funder (if there's any), use a random action2 to select a random colour scheme from a given list, or of course decide on global variables like position or game year.
Decide input and output cargo types (14B,14C)
These callbacks are called when the industry is built, and allow customizing the input and output cargo types dynamically. Both callbacks are called repeatedly, with the lowest byte of variable 10 starting from zero and increasing after every call; you should return a cargo type each time, or FFh to terminate the list. (A failed callback terminates the list, too.) The same limitations apply as for callback 14A: industry tiles aren't yet placed, and some industry variables contain junk. You can use random action2s, however. The interpretation of the returned value depends on two factors: the current GRF version number and the presence of a cargo translation table:
GRF version | Has cargo translation table | Interpretation |
---|---|---|
6 or below | Climate-dependent cargo slot number | |
7 or above | No | Cargo bit |
7 or above | Yes | Index in the translation table |
Although currently callback 14B is called no more than three times, and callback 14C no more than twice, this may change between versions/implementations, to allow more input/output types. To be safe, you should return FFh as the last element even when you use all three input types or both output types.
House customized building name (14D)
This callback is activated from the Tile Description Query tool, when enquiring a house. Variable 10 will be set to 1 if the house is complete, otherwise it will be 0. The return value is the "xx" of a D0xx text ID. If the callback fails, the Query tool will use the house name set in property 12 (Building name ID).
Since this callback is not performed frequently, you do not need to specify a mask. It will always be performed, and the name will only change when successful.
Available for OpenTTD since r15172, and for TTDPatch since TTDPatch 2.6r2249
Extra information about airport layout in the build gui (155)
This callback allows you to display some extra text in the build airport gui. It should return a D0xx StringID. This callback is always called when available, you do not need to set a bit in any action0 property to enable it. Available for OpenTTD since r20272
Airport layout name (156)
This callback allows you to show a name for an airport layout. It should return a D0xx StringID. This callback is always called when available, you do not need to set a bit in any action0 property to enable it. Available for OpenTTD since r20273.
Decide object colour (15B)
This callback allows you to set/modify the colour of an object upon construction. Variable 10 contains the current company colour or a random colour for when there is no company, i.e. in the scenario editor. If the object wants a 2CC colour mapping two nibbles, i.e. two colours, are passed in variable 10, otherwise one nibble (colour).