This is an in-depth description of cargo callbacks. More basic information about callbacks can be found here.
A 'callback' is a special action that TTDPatch 'calls' in order to modify various attributes of a feature (e.g., an object) previously defined. An example being the modification of the visual effect of a train vehicle, its speed, or its capacity.
This is done by identifying the incidence and the possible type of a callback in the callback() function. Depending on the type of the callback, control is handed over eventually to a function which handles the callback, or lets it fail. In the latter case, the value previously set by the appropriate property function will be kept using.
This is a list of all available callbacks for cargoes:
| Callback | Description |
| CB_PROFIT | Custom profit calculation |
| CB_RATING | Custom station rating |
CB_PROFIT - custom profit calculation
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.
CB_RATING - custom station rating
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 units | Days | Score (%, rounded) |
| >21 | >52.5 | 0 (0%) |
| 13 .. 21 | 32.5 .. 52.5 | 25 (10%) |
| 7 .. 12 | 17.5 .. 32.5 | 50 (20%) |
| 4 .. 6 | 10 .. 17.5 | 95 (37%) |
| 0 .. 3 | 0 .. 10 | 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 | 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%) | |||
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%.
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.
| 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.
If your company has erected a statue in the nearest town, you get 26 points (10%) bonus to all cargo ratings.
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.
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
The lowest byte of variable 10 contains one of the following values:
| Value | Meaning | |||
| 0x10 | the last vehicle entering the station was a train | |||
| 0x11 | the last vehicle entering the station was a road vehicle | |||
| 0x12 | the last vehicle entering the station was a ship | |||
| 0x13 | the last vehicle entering the station was an aircraft | |||
| 0x00 | 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.