The m4nfo User manual and Technical Report

Properties for ships

Defining properties for ships

Introduction

Properties are defined inside the defineship() function block. Depending on the type of ship and its specification, different properties have to be set. See examples. All ship properties are covered by the property functions below.

Properties

Property function Description
callbacks(<List::Callback>)Set callbacks for ship
capacity(<Word>)Cargo capacity of ship
canalspeed/oceanspeed(<Byte> | <Unit-term>)Canal and ocean speed fractions
cargoaging(<Word>)Set cargo aging factor
cargoclasses(<List::(+|-)CargoClass>)Set cargo classes for ship
cargolist(<List::(+|-)CargoType>)Set cargo list for ship
cargomask(<List::CargoType>)Set cargo mask for ship
cargotype(<CargoType>)Type of cargo this ship might carry
climate(<List::Climate>)Climate(s) available for this ship
flags(<List>)Set special flags for ship
intro(<Date>)Introduction date of ship
lifecycle(<Date> <Word> <Word>)Introduction and withdrawal year of train vehicle
loadamount(<Byte>)Load amount per tick of ship
modlife(<Byte>)Model life of ship
newgraphics([<Veh-ID>])Ship introduces new graphics (or uses graphics of given vehicle)
price(<Byte>)Price factor for ship
refitcost(<Byte> | <Unit-term>)Cost to refit this ship
refittable(<Boolean>)Ship is refittable or not
reliability(<Byte>)Reliability decay speed of ship
retire(<Byte>)Set early retire date for ship
runningcost(<Byte>)Running cost of ship
seteffect(<Effect>)Set effect for ship
sortbefore(<Byte>)How to sort this ship into the purchase list
soundeffect(4 | 5)Sound effect type (4: cargo ship, 5: passenger ship)
speed(<Unit-term>)Max speed of ship
vehlife(<Byte>)life cycle of ship

Description

callbacks(<List::Callback>)

This property takes as its parameter a list of callbacks to use with this ship. The following callbacks may be enabled by this function:

Callback Description
CB_LOAD Load amount
CB_RCAP Set refitted capacity
CB_RCOL Select colour mapping for ship
CB_SOUND Set sound effect
CB_TSFX Show a suffix after the cargo type name

Callbacks CB_ARVS (Autoreplace vehicle selection), CB_PROP (Change ship properties), CB_RCOST (change refitting cost), CB_STOP (Start/stop check), CB_TEXT (Additional text in purchase screen), and CB_32DAY (32-day callback) do not need to be activated in this property function, because they are always active and will be used automatically if needed.

Example (set callbacks for load amount, recolouring and text suffixes):
callbacks(CB_LOAD, CB_RCOL, CB_TSFX)

canalspeed/oceanspeed(<Byte> | <Unit-term>)

These two functions set the fraction of speed for canals/rivers and for the ocean. Speed fraction can be given either as a byte value, with values of [0, .., 64, .., 128, .., 192, .., 255] correlating to speeds of [100%, .., 75%, .., 50%, .., 25%, .., 0.4%], or directly as a percent value. Values will be clamped for both alternatives.

cargoaging(<Word>)

This function specifies the period (in game ticks) after which cargo carried by the ship is 'aged'. Setting the parameter to "0" disables any cargo aging, and by not setting this property, cargo is aged every 185 ticks by default. This property can be modified via callback CB_PROP (using property _CARGOAGING).

This property is only available in OpenTTD since r22713.

cargoclasses(<List::(+|-)CargoClass>)

To make vehicle sets more compatible with future new cargo definitions, this property allows ships to define what type of cargo they should be refittable to. A ship will be refittable to all cargo types that match the classes defined positive (+), except for the ones that are defined negative (-). In addition, afterwards those cargo types listed in property function cargomask() will be toggled. In terms of logic, it is:

Refit list = (<List::+CargoClass> AND NOT <List::-CargoClass>) [XOR cargomask()]

This means, if a cargo type is in the cargoclass list, setting it in cargomask()will disable it again. Conversely, if the cargo type is not in the cargoclass list, setting it in cargomask() will add it. This way, if cargoclasses are unset, cargomask() will retain its original meaning, but it is still able to selectively add or remove certain cargo types even if cargoclasses are used, see example below.

As a consequence, you have both full control over the cargo types that you know of (using cargomask()), and those you don't know of yet (using cargoclasses). Leave the cargos that you don't know of unset in cargomask()), and set/unset the entries for known cargos to add/remove them from cargomask() as appropriate.

Note that cargo types may belong to several classes. This is the reason for making two properties, an additive and a subtractive one, because this way a ship can be specified to be refittable to, for example, all express cargo that does not require refrigeration.

For the cargo types added in this way, the ship will probably have no specific graphics, linked with in makeship(), to show the proper cargo load. In this case, the default will be used, which should therefore be sufficiently generic-looking if possible. However, using the function veh_cargoclass() you can at least select the graphics most appropriate for the cargo type's class.

Example (set cargoclasses for bulk, sheltered and express cargo; don't accept passengers and liquid cargo; and don't accept fish, although it belongs to EXPRESS):
cargoclasses(+BULK, +SHELTER, +EXPRESS, -PASS, -LIQUID)
cargomask(FISH)

cargolist(<List::(+|-)CargoType>)

This function allows to unconditionally include (+) and/or exclude (-) cargo types for refittability, independent of any of the other refit properties or the cargo classes specified. Listed cargo types should be available from the cargo translation table. Non-available cargo types listed will be silently ignored.

This property is only available in OpenTTD since r23291.

Example (setting a cargo list):
cargolist(+GOOD, +WOOL, +WDPR, -LVST, -FERT, -COAL)

flags(<List>)

The parameter of this function is a list containing one or more of the following flags:

FlagMeaning
2CCShip uses two company colours
AUTOREFITTINGAuto-refitting is enabled for refits where CB_RCOST allows it or property function refitcost() specifies zero cost (OpenTTD >r23087)
CARGOMULTIPLIERChange the way cargo capacities are handled during a refit (OpenTTD >r23861)
NOBRKEFFECTDisable breakdown smoke effect. (OpenTTD >r24124)

By autorefitting, a ship may be refitted "on-the-fly", i.e. during a dock visit, before loading. A ship with autorefittng enabled does not need a depot visit to get refitted to a different cargo type.

If cargomultiplier is set, the default cargo type does no longer affect the capacity of other refits. The capacity property and CB_PROP return the capacity in a generic unit ("tons of coal"), independent of the actual transported cargo type. CB_RCAP is called always, i.e. also for the default cargo type and in the purchase list.

These changes allow ships to set specific capacities for cargo types they know (via CB_RCAP), and set a generic capacity (in "tons of coal") for other cargo types. The capacity of unknown cargo types is then controlled by the cargo definition, which also controls the refittability via cargo classes.

lifecycle(<Date>, <Word>, <Word>)

This function offers an alternative way to define the lifecycle of a vehicle. Usually, the definition of a vehicle's lifecycle needs specification of introduction date, vehicle life span, model life span, and early retirement date. All of these dates have to be carefully chosen to get the desired behaviour of the vehicle over time. Use of this function offers an alternative way.

The function needs three points in time as its parameters:

lifecycle(<introduction_date>, <last_building_year>, <withdrawal_year>)

E.g., lifecycle(1910/3/1, 1930, 1945) would be identical to:

intro(1910/3/1)
vehlife(15)
modlife(35)
retire(11)

Please note that neither functions intro(), modlife(), vehlife(), nor retire() should be used together with lifecycle().

price(<Byte>)

The given price is used as a factor which determines how expensive the ship is. The table below gives you some values to use for finding the right price:

Price factorPrice
1$ 508
16$ 8.125
32$ 16.250
128$ 65.000
160$ 81.250
255$ 129.492

Please note that prices are dependent on the game's difficulty settings as well as the base cost set.

refitcost(<Byte> | <Unit-term>)

The refit cost can be given either as a byte number, its maximum value "255" correlating to 1/32 of the ship's purchase price cost base, or directly as a percent value. The given/resulting value will be clamped for both alternatives.

The given cost value can be changed dynamically by using CB_RCOST.

reliability(<Byte>)

The reliability decay speed is set when a new ship is bought, and specifies how quickly the reliability decays after servicing. The initial TTD default for all ships is "20". If a ship goes without servicing for a long time, or if it gets very, very old, this number increases, meaning faster decay and more breakdowns. Larger numbers mean faster decay, smaller number slower decay. If set to "0", reliability never decreases in normal operation.

runningcost(<Byte>)

TTD calculates all costs by multiplying a 32-bit base amount with a byte factor. The base amount is changed according to inflation, whereas the factor remains constant.

The following are some real values for maintenance costs depending on the setting of the above factor. This value is correct for medium difficulty, but increases and decreases for hard and easy difficulties respectively. These are the costs of a new game starting in 1921, because they obviously increase with inflation over time (unless noinflation is turned on).

Running cost base for ships

FactorMaintenance cost
1$ 42
16$ 700
32$ 1.400
128$ 5.600
160$ 7.000
255$ 11.112

Please note that running cost are dependent on the game's difficulty settings as well as the base cost set.

seteffect(<Effect>)

This function sets the visual effect of a ship and repositions it (OpenTTD only). This function enables to change the type of effect as well as its position relative to the ship. Note that there is no default effect for ships.

The position parameter of the effect in the auxiliary functions provides a range from "0" to "15" that is added to the type of the effect. Position "0" corresponds to a point half a ship's length ahead of the ship, "4" is the front of the ship, "8" the middle, "12" the end and "15" is a half length behind the ship. Intermediate values are in-between.

sortbefore(<Veh_ID>)

This is not a property as such, but an action. It forces TTDPatch to shuffle the ship this "property" is being set for in front of the ship with the given ID. The order of this list is only used in the ship purchase window.

For example, setting this property for ship 9 to a value of 7 would lead to the following internal list of ship IDs: ... 5 6 9 7 8 10 11 ...

This property can not simply be overwritten, because the list is already shuffled when trying to do so. It is however possible to reset the list to its original order with a special function resetorder(). Resetting the list should however only be done by sets that contain replacements for all ships.

speed(<Unit-term>)


This property sets the ship's speed, using different units: km/h (kilometers per hour), mph (imperial miles per hour) or kn (knots).