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 VarAction2s, the second byte of the matching entry has to have bit 7 set to identify it as a callback result.
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. In total a callback has 15 bit result values, where 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.
GRFv≤7 For GRF version 7 and below not all 15 bit values are available as return values, only values between 00 and 7EFF. 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.
GRFv≥8 For GRF version 8 and above this compatibility layer has been removed. Callbacks can return all 15 bit values between 00 and 7FFF.
To check for a specific callback, use an VariationalAction2 or VarAction2Advanced to check for variable 0C.
- Variable 0C contains the callback number.
- Variable 0C is a word, thus the VarAction2 must use type 85.
- Results can be specified directly using 8xxx values (see above), or with 8xxx value in subsequent (Basic/Variational/Random)Action2 which are referenced as usual with their set-id.
- The default case of the VarAction2 must point to the regular graphics chain, so that unknown/future callbacks results in a "callback failure" result.
Example:
<Sprite-number> * <Length> 02 <feature> <set-id> 85 0C 00 \wxFFFF <nvar> (<set-id/result> \wx <callback> \wx <callback>){n} <set-id of graphics chain>
The format for VarAction2 is explained in detail on the VariationalAction2 page.
Note: Some NewGRFs still use type 81 for callbacks. However, testing callbacks with type 81 has been depreciated since 2005/2006 and should not be used. It only still works because new callback IDs were assigned in a backwards-compatible way.
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 | Select sprite layout |
15 | Vehicles | Refitted capacity callback |
16 | Trains | Build articulated engines |
17 | Houses | House construction check |
18 | Several [1] | 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 [1] | 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 [1] | 1.2 2.6 Ambient sound effects |
145 | Cargoes | Custom station rating calculation |
146 | New Signals [1] | 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 | 1.1 Decide drawing default foundations |
152 | Airport tiles | 1.1 Animation control |
153 | Airport tiles | 1.1 Next Animation frame |
154 | Airport tiles | 1.1 Length of animation frame |
155 | Airports | 1.1 Extra information about airport layout in the build gui |
156 | Airports | 1.1 Airport layout name |
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 |
15E | Vehicles | 1.2 Refit cost factor |
15F | Industries | 1.3 Set initial production level on construction |
Visual effect and wagon power (10)
Features: | trains, road vehicles, ships |
Purchase list | no |
Variable 10 | n/a |
Variable 18 | n/a |
Result | selected effect |
Fail result means | default properties |
Return registers | n/a |
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 (1.1 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 (11)
GRFv≤7 This callback is only called for GRF version 7 and below. GRFv≥8 For GRF version 8 and above use callback 36.
This callback is used instead of train property 21 resp. road vehicle property 23 whenever the vehicle leaves a depot or is displayed inside a depot. If the callback fails, the value of the property is used instead.
The callback result may change only when whole vehicle chain is inside a depot. If your vehicle supports autorefit, and the length can change on refitting, you have to use callback 15E to prevent the refitting.
Load amount (12)
GRFv≤7 This callback is only called for GRF version 7 and below. GRFv≥8 For GRF version 8 and above use callback 36.
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 (13)
This sets whether a station can be constructed or not, i.e. whether it can be selected in the station construction window. Returning 1 as callback return indicates the station can be built, and a return code of 0 removes the station from the selection.
GRFv≤7 Note that GRF versions 7 and lower only distinguished zero and non-zero return values.
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. 2.5 It is a 15 bit callback since TTDPatch 2.0.1 alpha 40, and allows return values up to 7EFF=32511 units of cargo. 1.2 Via misc. vehicle flag 5 this callback can also be enabled if the vehicle is not refitted and carrying the default cargo. See the vehicle refitting page for details
Information about the new cargo type is available in variable 47.
Additionally vehicle variable B9 (for a VarAction2) 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 (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 as long as the callback says so.
GRFv≤7 For GRF version 7 and below the return value uses 8 bits. Bit 0 to 6 define the ID of the vehicle to add. If 80 is added to the ID, the vehicle will be reversed. Returning FF means to finish the articulated vehicle, and not attach more parts.
GRFv≥8 For GRF version 8 and above the return value uses 15 bits. Bit 0 to 13 define the ID of the vehicle to add. If 4000 is added to the ID, the vehicle will be reversed. Returning 7FFF means to finish the articulated vehicle, and not attach more parts.
Note that since the train is not yet built, you cannot use train variables in action 2. Instead, use the first byte of variable 10 (extra callback info 1), which is set to 01 for the first articulated part, 02 for the second and so on.
0.6 2.5 If more than the first vehicle contains cargo, the callback must work in the buy menu as well. 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 1 to allow building and 0 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.
GRFv≤7 Note that GRF versions 7 and lower only distinguished zero and non-zero return values.
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 (ID). For new industries the substitute type is returned starting with OpenTTD r20108.[1] |
84 | B | destination industry type (ID). For new industries the substitute type is returned starting with OpenTTD r20108.[1] |
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 0 to disallow purchase, or 1 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.
GRFv≤7 Note that GRF versions 7 and lower only distinguished zero and non-zero return values for "Check".
Cargo Subtype Display (19)
NOTE: As of OpenTTD 13, this feature is considered deprecated for most uses. Use variants instead.
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 says to stop. 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.
GRFv≤7 For GRF version 7 and below the valid return values are:
00..FE | Use subtype from text D0xx (D000..D0FE) |
FF | Stop calling. |
GRFv≥8 For GRF version 8 and above the valid return values are:
00..3FF | Use subtype from text D0xx (D000..D3FF) |
400 | Stop calling. |
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. |
2.5 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, bit 2 of property 13 for stations, or bit 12 of property 10 for objects.
Like all animation callbacks, if the high byte of the result is nonzero, it will be interpreted as a sound effect number, and the corresponding sound effect will be played at the tile.
Note: Every time the animation frame is changed the map tile will be refreshed, even if the selected graphics stay the same. Therefore using the animation frame as a timer should be avoided, and animation triggers should be preferred instead.
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, stations, airport tiles and objects). 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.
- Except for CB 1B (houses), the low byte of variable 18 contains the reason (animation trigger) for the call. This is formatted as the number of the bit that was set in the relevant action 0 property. The other bits may contain additional information specific for the trigger/reason.
Feature Callback Animation triggers Houses 1B none Industry tiles 25 Property 11 Stations 140 Property 18 Airport tiles 152 Property 11 Objects 159 Property 13
- Except for CB 1B (houses), the callbacks are always used when defined, no bit in the action 0 property needs to be set to activate them.
- 2.5 Since TTDPatch 2.5 beta 2, these callbacks get random bits in variable 10, to allow randomizing changes.
- For callback 1B (houses), 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 CB 25 (industry tiles), 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 CB 140 (stations), the high 16 bits are the same for all tiles triggered, while the low 16 bits are different for each tile.
- Like all animation callbacks, if the high byte of the result is nonzero, it will be interpreted as a sound effect number, and the corresponding sound effect will be played at the tile.
Note: Every time the animation frame is changed the map tile will be refreshed, even if the selected graphics stay the same. Therefore using the animation frame as a timer should be avoided, and animation triggers should be preferred instead.
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.
Like all animation callbacks, if the high byte of the result is nonzero, it will be interpreted as a sound effect number, and the corresponding sound effect will be played at the 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 VarAction2s 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.
2.5 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.
So, overall the callback is evaluated this way:
- The Action 3 is used from the regular engine (livery overrides have no influence).
- The cargotype to use in Action 3 is taken from the wagon.
- VarAction2 types 81, 85, 89 refer to the wagon.
- VarAction2 types 82, 85, 8A refer to the engine.
GRFv≤7 For GRF version 7 and below the valid return values are:
Return | Meaning |
---|---|
00..FC | Disallow attaching and use the D0xx (D000..D0FC) text ID as second line of an error message, |
FD | Disallow attaching with the standard message (incompatible rail types) |
FE | Allow attaching[1] |
FF | Allow attaching if the rail types match (default) |
GRFv≥8 For GRF version 8 and above the valid return values are:
Return | Meaning |
---|---|
00..3FF | Disallow attaching and use the D0xx (D000..D3FF) text ID as second line of an error message, |
400 | Allow attaching if the rail types match (default) |
401 | Allow attaching[1] |
402 | Disallow attaching with the standard message (incompatible rail types) |
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.
2.5 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. Return 0 to do nothing, or 1 to remove the building 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.
GRFv≤7 Note that GRF versions 7 and lower only distinguished zero and non-zero return values.
Industry availability (22)
Called when TTDPatch needs to know if a given industry type is available.
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.
GRFv≤7 For GRF version 7 and below the callback should return zero to make your type available, or any nonzero value to disable it.
GRFv≥8 For GRF version 8 and above the callback should return one of these values:
0000 Disallow construction 0001..00FF Allow construction, and use the returned value as probability for appearance on the map. (Instead of using property 17 or 18.) 0100 Allow construction; use the appearance probability from property 17 resp. 18.
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 can be used to append text below the vehicle information in the purchase screen. The callback is always used when defined, no bit in the action 0 property needs to be set to activate it.
A text string for the feature in the D0XX range must be defined before using this callback. The return value of this callback is the XX of a D0XX string ID.
As of r1908, text IDs D100..D3FF may also be returned.
GRFv≥8 Since GRF version 8 the value 400 can be returned to display no text. In older versions it is necessary to fail the callback.
1.2 Since OpenTTD r23045 the contents of registers 100h..105h are copied onto the text reference stack.
Lines are wrapped automatically, or may be broken explicitly using the newline character 0D. 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.
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.
Example for setting additional text for a road vehicle:
// Define string with ID D001 for featur 01. Bit 7 of the language byte must be set to 1, because the string ID is a word. 4 * 32 04 01 83 01 \wxD001 "Hint: This is a " 0D "new line." 00 // The callback 5 * 14 02 01 10 85 0C 00 \wxFFFF 01 \wx8001 \wx23 \wx23 02 00
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 | Version | Meaning |
---|---|---|---|
40+x | Not accessible | ||
5F | 1.1 | 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
| |
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 | 0.6 2.6 | 32 random bits |
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.
1.1 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:
0.6 2.6 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:
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 TTDPatch 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 level more smoothly. The production level 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
GRFv≥7 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 VarAction2 with nvar=0). Original passenger/mail generation algorithm is described here.
Uses 15 return bits.
GRFv≥7 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. The callback should return zero if the tile isn't suitable, or any other value if it is suitable.
GRFv≥7 The meaning of the returned value is different in GRF version 7; it works the same way as callback 28. 2.6 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.
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. Variable 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.
1.1 Since OpenTTD r19744, you can access the random bits of the industry (it would get after construction) via industry variable 5F resp. RandomAction2 type 83.
2.6 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.
1.1 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.
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 0 to disable the default slope graphics and 1 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 TTDPatch and OpenTTD up to 0.7 do not have suitable foundation graphics for steep slopes. In any way, variable 60 comes in handy when selecting the correct foundation to draw.
GRFv≤7 Note that GRF versions 7 and lower only distinguished zero and non-zero return values.
Vehicle 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).
GRFv≤7 For GRF version 7 and below the valid return values are:
00..FE | Display error message using D0xx (D000..D0FE) text as second line. |
FF | Start/stop action shall succeed. |
100..1FE | Display error message using D0xx (D100..D1FE) text as second line. |
200..2FE | Display error message using D0xx (D200..D2FE) text as second line. |
300..3FE | Display error message using D0xx (D300..D3FE) text as second line. |
GRFv≥8 For GRF version 8 and above the valid return values are:
00..3FF | Display error message using D0xx (D000..D3FF) text as second line. |
400 | Start/stop action shall 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 (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 the lowest byte of 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.
Lowest byte of variable 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 | 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 and 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 lowest byte of 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 | Version | Property | Remarks |
---|---|---|---|
Trains (00) | 1.2 GRFv≥8 | 07 (Load amount) | See also callback 12 |
0.6 2.5 | 09 (Speed) | ||
0.6 2.5 | 0B (Power) | ||
0.6 2.6 | 0D (Running cost factor) | ||
0.6 2.6 | 14 (Cargo capacity) | See also callback 15 | |
0.6 2.5 | 16 (Weight) | ||
0.6 | 17 (Cost factor) | ||
0.6 2.5 | 1F (Tractive effort) | ||
1.2 GRFv≥8 | 21 (Short wagons) [1] | See also callback 11 | |
22 (Visual effect & powered wagons) | Changeable via callback 10 | ||
0.6 2.5 | 25 (User data) | ||
1.2 | 2B (Custom cargo ageing period) | ||
12 | 2E (Maximum curve speed modifier) | ||
Road Vehicles (01) | 1.2 GRFv≥8 | 07 (Load amount) | See also callback 12 |
1.0 | 09 (Running cost factor) | ||
0.6 | 0F (Cargo capacity) | See also callback 15 | |
0.6 | 11 (Cost factor) | ||
1.1 | 13 (Power) | ||
1.1 | 14 (Weight) | ||
1.1 | 15 (Speed) | ||
1.1 | 18 (Tractive effort) | ||
21 (Visual effect) | Changeable via callback 10 | ||
1.2 | 22 (Custom cargo ageing period) | ||
1.2 GRFv≥8 | 23 (Short wagons)[1] | See also callback 11 | |
Ships (02) | 1.2 GRFv≥8 | 07 (Load amount) | See also callback 12 |
0.6 2.6 | 0A (Cost factor) | ||
0.6 2.5 | 0B (Speed) | ||
0.6 2.6 | 0D (Cargo capacity) | See also callback 15 | |
0.6 2.6 | 0F (Running cost factor) | ||
1C (Visual effect) | Changeable via callback 10 | ||
1.2 | 1D (Custom cargo ageing period) | ||
Planes (03) | 1.2 GRFv≥8 | 07 (Load amount) | See also callback 12 |
0.6 | 0B (Cost factor) | ||
0.6 2.5 | 0C (Speed) | ||
0.6 2.6 | 0E (Running cost factor) | ||
1.0 | 0F (Primary cargo capacity) | See also callback 15 | |
1.0 | 11 (Secondary cargo capacity) | ||
1.2 | 1C (Custom cargo ageing period) | ||
1.2 | 1F (Aircraft range) |
- ↑ 1.0 1.1 These properties may only change their value when the vehicle is inside a depot. That means, if your vehicle supports autorefit and refitting can change these properties, you must use callback 15E to prevent the refitting.
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.
GRFv≤7 For GRF version 7 and below the valid return values are:
00..FE | Display D0xx (D000..D0FE) text. |
FF | Display no text. |
100..1FE | Display D0xx (D100..D1FE) text. |
200..2FE | Display D0xx (D200..D2FE) text. |
300..3FE | Display D0xx (D300..D3FE) text. |
GRFv≥8 For GRF version 8 and above the valid return values are:
During the callback, variable 18 specifies which cargo sub-type is queried. The meaning of variable 18 changes with industry property 1A flag 18.
Bits 0..7 of var. 18 can have the following values:
- If property 1A flag 18 is clear.
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 |
Number | Meaning |
---|---|
00 | Return subtext for an accepted cargo type. Use bits 16..23 to distinguish them. |
01 | Return subtext for a produced cargo type. Use bits 16..23 to distinguish them. |
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 |
Bit 16..23 of var. 18 contain the cargo type from the CTT (only if property 1A flag 18 is set).
Other bits of var. 18 are reserved for future use.
1.0 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.
GRFv≥8 For GRF version 8 and above you can return 400 to display no text (instead of failing the callback).
Callback 38 is available from TTDPatch 2.0.1 a72 and above. 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.
GRFv≥8 For GRF version 8 and above you can return 400 to display no text (instead of failing the callback).
0.6 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.
0.6 2.6 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.)
This callback is available from 2.5 TTDPatch 2.0.1 a72 and above
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 0 to avoid planting fields and 1 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 0 to avoid cutting a tree and 1 to try cutting one. The callback is called every 256 ticks for a given industry. In TTDPatch and OpenTTD prior to r22673, 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.
This callback is available from 2.5 TTDPatch 2.0.1 a73 and above
GRFv≤7 Note that GRF versions 7 and lower only distinguished zero and non-zero return values for effect 0 and 1.
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 0. Returning 1 will disallow land modifications.
GRFv≤7 Note that GRF versions 7 and lower only distinguished zero and non-zero return values.
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.)
This callback is available from 2.5 TTDPatch 2.5 beta 4 and above
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:
- GRFv≤7 For GRF version 7 and below: THRRxxxt
- GRFv≥8 For GRF version 8 and above: xTHHRRtt
Field | Meaning |
---|---|
T | Tile class, 0=bare land, 4=trees, 6=water |
HH |
GRFv≤7 Height of north corner of tile (multiple of 8) |
RR | 8 random bits |
xxx | Reserved |
tt |
|
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 VarAction2 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 the lowest byte of variable 10 (extra callback info 1) to decide if the sprite number needs an offset.
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. Like all animation callbacks, if the high byte of the result is nonzero, it will be interpreted as a sound effect number, and the corresponding sound effect will be played at the tile.
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.
Station slope check (149)
This callback is called for each tile where the new station part will be built.
GRFv≤7 For GRF version 7 and below the return values are the same as for callback 28, but with bit 10 inverted for backwards compatibility. This means that success is 0 instead of 0x400 while custom GRF texts start at 0x400 instead of 0. Return value 1 stands for "Land sloped in wrong direction" instead of "Site unsuitable". Note that earlier version of OpenTTD before r22658 and TTDPatch only support 0 for success and 1 for error.
GRFv≥8 For GRF version 8 and above the return values are the same as for callback 28. Return value 401 stands for "Land sloped in wrong direction" instead of "Site unsuitable".
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.
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.
This callback is available from 2.6 TTDPatch 2.6 r1712 and above
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. However, you are only allowed to reduce the number of accepted/produced cargos. Industry properties 25 and 26 should always be a superset of the returned cargotypes.
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 |
The callback results replace the content of properties 25 and 26. If you use these callbacks, it is recommended to not use industry properties 12..13, 1C..1E and 27..28, which depend on the order of cargotypes, but instead use production callback version 2.
1.9 If industry property 1A flag 18 is clear, these callbacks are called at most for 3 input and 2 output cargos. If flag 18 is set, this compatibility restriction is removed and the callbacks are called more often.
In both cases return FFh as the last element to terminate the lists.
House customized building name (14D)
This callback is activated from the Tile Description Query tool, when enquiring a house. Bit 0 of 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).
GRFv≥8 For GRF version 8 and above you can also return 400 to display the name from the property. (instead of failing the callback).
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.
GRFv≥8 For GRF version 8 and above you can return 400 to display no text (instead of failing the callback).
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.
GRFv≥8 For GRF version 8 and above you can return 400 to display no text (instead of failing the callback).
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.
Object slope check (157)
This callback is called for each tile where the new object will be built.
GRFv≤7 For GRF version 7 and below the return values are the same as for callback 28, but with bit 10 inverted for backwards compatibility. This means that success is 0 instead of 0x400 while custom GRF texts start at 0x400 instead of 0. Return value 1 stands for "Land sloped in wrong direction" instead of "Site unsuitable". Note that earlier version of OpenTTD before r22658 and TTDPatch only support 0 for success and 1 for error.
GRFv≥8 For GRF version 8 and above the return values are the same as for callback 28. Return value 401 stands for "Land sloped in wrong direction" instead of "Site unsuitable".
Since the object isn't built yet, only some variables are available. In OpenTTD these are: 41, 42, 44, 45, 46, 48, 60 - 62 and 64. Additionally you get the following information:
- Variable 10:
Bits | Meaning |
---|---|
0..3 | Relative X position of the tile within the object |
4..7 | Relative Y position of the tile within the object |
8..31 | Reserved; must be masked |
- Variable 18:
Bits | Meaning |
---|---|
0..4 | Slope of the tile |
5..31 | Reserved; must be masked |
Decide object colour (15B)
This callback allows you to set/modify the colour of an object upon construction. The lowest byte of 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).
Refit cost factor (15E)
This callback can be used to override the refit cost property of vehicles. This callback will also be called in purchase list scope, so either limit the used variables to what is available in the purchase list or branch on the special purchase list cargo type.
Variable 10 contains information about the target cargo type similar to variable 47.
Format: ccccwwtt
Variable | Value |
---|---|
tt | The cargo type being refitted to; translated if a translation table has been installed |
ww | Subtype being refitted to |
cccc | The cargo class value of the cargo being refitted to |
Return values:
- Bits 0-13: Signed refit cost factor, cost base depends on the vehicle type and is the same as for the refit cost property. Negative cost factors allow refit revenue.
- Bit 14: If set, the refit is allowed as an auto-refit as long as bit 4 of the miscellaneous flags is set as well.
Do not allow autorefit if the length of the vehicle will change (e.g. using cb36 to set length). Vehicle length may not change in stations.
If the callback fails, the value of the refit cost property is used.
Set initial production level on construction (15F)
This callback is called on constructon of industries, if bit 6 of property 22 is set. Similar to callback 29 result 0F it sets the production level. You can use variable B3 to check the reason for the construction of the industry.
Variable 18 contains 32 random bits.
The result of the callback consists of:
Bits | Meaning |
---|---|
0-7 | Production level; must be in range 04..80h; default value when not using this callback is 10h. |
8-14 | Reserved, must be set to zero. |