From GRFSpecs
Jump to navigationJump to search
Props, Vars and CBs

Cargo IDs

For cargos, the item ID corresponds to the cargo type slot of the cargo. TTD default cargos occupy slots 0-11, so if you want to define a new cargo be sure to set this ID to 12 or higher. It is recommended to set the 'number'-property to the same value as the item ID.

Cargo properties

name value range comment
number 0..63 Number of the cargo for bitmasks. Prior to Supported by OpenTTD 1.91.9 this was clamped to 0..31. This mostly affects old NewGRFs that don't have a cargo translation table.
type_name string String to use as cargo type name. Example: "Passengers". The list of default TTD strings contains the strings used by the default cargos (TTD_STR_CARGO_PLURAL_XXX), which may be re-used.
unit_name string String to use for the name of one unit from the cargo type. Currently used for subsidies only (First Passenger service to..). Example string: "Passenger". The list of default TTD strings contains the strings used by the default cargos (TTD_STR_CARGO_SINGULAR_XXX), which may be re-used.
units_of_cargo string String used to show the "short cargo" form for cargo units, e.g. "10 tonnes" or "20.000 litres". Example: "{COMMA} item{P "" s}". The list of default TTD strings contains the strings used by the default cargos (TTD_STR_PASSENGERS and further), which may be re-used.
items_of_cargo string String used to show the "long cargo" form for cargo units, e.g. "10 tonnes of coal" or "20.000 litres of water". Example: "{COMMA} item{P "" s} of livestock". The list of default TTD strings contains the strings used by the default cargos (TTD_STR_QUANTITY_XXX), which may be re-used.
type_abbreviation string String used for the two-letter cargo type abbreviation. Must start with a {TINYFONT} string-code. Example: "{TINYFONT}XX". Make sure to avoid multiple cargos having the same abbreviation. The list of default TTD strings contains the strings used by the default cargos (TTD_STR_ABBREV_XXX), which may be re-used.
sprite sprite TTD sprite number for the icon of the cargo. Alternatively, set to NEW_CARGO_SPRITE and use a graphics block to define a custom sprite.
weight float 0..255 Weight of one unit of the cargo (in tons)
penalty_lowerbound 0..255 Delivery time until penalty is applied. The units depend on the vehicle used (see vehicle property 'cargo_age_period'), by default 1 unit = 2.5 days.
single_penalty_length 0..255 Length of the interval where a single penalty is applied
price_factor float Payment for delivering 10 units of cargo across a distance of 20 squares (in British Pounds), when delivering in less than 'penalty_lowerbound' time (no time penalty).
station_list_colour 0..255

Colour for the station list window (index from the default (DOS) palette)

cargo_payment_list_colour 0..255

Colour for the cargo payment list window (index from the default (DOS) palette)

is_freight 0 or 1 Freight status (for the freighttrains switch); 0=not freight, 1=is freight

bitmask(cargo classes)

Cargo classes
cargo_label 4 letters Cargo label, as used in the cargo table
town_growth_effect TOWNGROWTH_XXX

Effect for town growth, see Cargo effects on town growth

town_growth_multiplier float 0..255 Not supported by OpenTTD Multiplier for town growth. To be used in conjuction with town_growth_effect, when that is not TOWNGROWTH_NONE. For example, a value of 4 makes your cargo have the same effect on town growth as 4 units of food/goods/etc.
callback_flags bitmask(flags)

Do not set this, unless you use old-style callbacks.

capacity_multiplier float 0 .. 255 Supported by OpenTTD 1.2 (r22860)1.2 This defines the capacity of vehicles carrying this cargo type, if the vehicle sets no specific capacity to this specific cargo type. Set this property to the amount of cargo a vehicle shall carry, which can carry 1 ton of coal or 1000 thousand litres of water (whatever comparison is more suitable for your cargotype). Depending on whether your cargo type is light or heavy you should set this property either comparing the weight or the volume. Default values are 4 for passengers, 2 for mail, goods and sweets and 1 for all other cargos.

Cargo payment is computed from price_factor, amount of cargo transported, distance, and a time delivery factor. Unit of the delivery time is 185 ticks, roughly 2.5 days. The factor is constant (with value 255) if delivery time is less than penalty_lowerbound. It goes down with rate 1 between penalty_lowerbound + single_penalty_length, and goes down with rate 2 if the delivery time is even longer. Time delivery factor is never less than 31.

Cargo classes

Available cargo classes are listed in the following table. Cargos may be in more than one class. Cargo classes are always used as a bitmask, use the built-in function bitmask(). For example, bitmask(CC_EXPRESS, CC_REFRIGERATED) is used for food.

name type of cargo
CC_PASSENGERS passengers, also tourists (ECS)
CC_MAIL mail
CC_EXPRESS express goods, also tourists (ECS)
CC_ARMOURED valuables, diamonds, gold and alike
CC_BULK coal, ore, grain,...
CC_PIECE_GOODS containers, crates, livestock
CC_LIQUID oil, milk, water, ...
CC_REFRIGERATED food, milk, ...
CC_HAZARDOUS chemicals?, uranium, ...
CC_COVERED grain, cement, fruit, ...
CC_OVERSIZED vehicles, ...
CC_POWDERIZED cement, ...
sugar cane, wool or straw bales, ...
CC_SPECIAL Special cargo, used for refit tricks. (e.g. regearing in NARS)
NO_CARGO_CLASS Special value that you can used to instead of 0.
ALL_NORMAL_CARGO_CLASSES Bitmask of all cargo classes except CC_SPECIAL. This is the same as bitmask(CC_PASSENGERS, CC_MAIL, ..., CC_OVERSIZED). Note: This is already a bitmask, don't use the bitmask(..) function with this.
ALL_CARGO_CLASSES bitmask(CC_SPECIAL) Note: This is already a bitmask, don't use the bitmask(..) function with this.

Cargo effects on town growth

value effect
TOWNGROWTH_PASSENGERS Affect towns as passengers do
TOWNGROWTH_MAIL Affect towns as mail does
TOWNGROWTH_GOODS Affect towns as goods/candy does
TOWNGROWTH_WATER Affect towns as water does (second required cargo for towngrowth in the desert)
TOWNGROWTH_FOOD Affect towns as food/fizzy drinks do (first required cargo for towngrowth in desert/above snowline)
TOWNGROWTH_NONE Don't affect town growth (default)

If no cargos in the game are defined as TOWNGROWTH_FOOD, towns above the snowline will not require food to grow. If no cargos in the game are defined as TOWNGROWTH_FOOD or TOWNGROWTH_WATER, towns in desert will not require food or water to grow. This can be used positively for gameplay purposes, and is otherwise worth being aware of as an unintended side effect when designing cargos.

There are some additional effects of these flags on subsidies and town cargo transport statistics. See the nfo docs for details: https://newgrf-specs.tt-wiki.net/wiki/Action0/Cargos#Substitute_type_and_multiplier_for_town_growth_.2818.2C_19.29

Cargo variables

Cargos have no variables (yet).

Cargo callbacks

callback return value comment
default Sprite set (with 1 sprite) Graphics for the cargo icon (only if property sprite is set to NEW_CARGO_SPRITE)
station_rating -16384 .. 16383 See detailed explanation below
profit -12748 .. 12748 Called whenever cargo is delivered.
  • getbits(extra_callback_info2, 0, 16): The manhattan distance the cargo was transported.
  • getbits(extra_callback_info2, 16, 8): The amount of cargo delivered.
  • getbits(extra_callback_info2, 24, 8): The time spent en-route (1 unit = 2.5 days).

The returned value is multiplied by the amount and the price_factor to determine the income the player receives. Returning negative values is possible, it makes players pay for the delivery.

Station rating callback

The station rating callback is quite complicated and deserves some detailed explanation. The default station rating calculation works as follows:

Internally, station rating is byte with values 0 .. 255, representing respectively 0% and 100%. Every 2.5 days, the transportation 'performance' is calculated using some factors outlined below. The station rating is then set to this performance value, with the caveat that the rating change cannot exceed 2 points. Therefore, rating changes are always slow, this callback cannot change this. The initial rating is 175 points (69%). The following factors are parts of the performance, their effects are summed.

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

Age of vehicle (years) Score (%, rounded)
2 10 (4%)
1 20 (8%)
0 33 (13%)

In TTDPatch this changes when the 'newagerating' switch is enabled

Bonus for AI companies (TTDPatch only)

AI intelligence setting Score (%, rounded)
Low 0 (0%)
Medium 31 (12%)
High 63 (25%)

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.

Callback parameters

  • getbits(extra_callback_info1, 0, 8):
    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
    0 no vehicle entered the station yet, or (TTDPatch) the last one entering was sold

    Please note that there's only one "last vehicle type" field per station, so the vehicle this refers to may not have picked up any of your cargo.

  • getbits(extra_callback_info2, 0, 8): The time since the cargo was last picked up, in the time units described above (1 unit = 2.5 days independent of vehicle type)
  • getbits(extra_callback_info2, 8, 16): The amount of cargo waiting.
  • getbits(extra_callback_info2, 24, 8): 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 0xFF).

Effect of callback

The return value of the callback replaces the first three components (time since pickup, amount of cargo, max speed) of the calculation. The bonus for statues, TTDPatch AIs and new vehicles is always in effect, you cannot (yet) change this.