The m4nfo User manual and Technical Report

Properties for road vehicles

Defining properties for road vehicles

Introduction

Properties are defined inside the definevehicle() function block. Depending on the type of vehicle (bus or truck) and its specification needs, different properties have to be set. See the diverse examples. All road vehicle properties are covered by the property functions below.

Properties

Property function Description
airdrag(<Byte>)Airdrag for this vehicle
callbacks(<List::Callback>)Set callbacks for this vehicle
capacity(<Byte>)Cargo capacity of road vehicle
cargoaging(<Word>)Set cargo aging factor
cargoclasses(<List::(+|-)CargoClass>)Set cargo classes for this vehicle
cargolist(<List::(+|-)CargoType>)Set cargo list for this vehicle
cargomask(<List::CargoType>)Set cargo mask for this vehicle
cargotype(<CargoType>)Type of cargo this road vehicle might carry
climate(<List::Climate>)Climate(s) available for using road vehicle
effort(<Unit-term> | <Byte>)Tractive effort for this vehicle
flags(<List>)Set special flags for this vehicle
intro(<Date>)Introduction date of road vehicle
lifecycle(<Date> <Word> <Word>)Introduction and withdrawal year of train vehicle
loadamount(<Byte>)Load amount per tick of road vehicle
modlife(<Byte>)Model life of road vehicle
newgraphics([<Veh-ID>])Vehicle introduces new graphics (or uses graphics of given vehicle)
power(<Unit-term>)Max power of road vehicle
price(<Byte>)Price factor for road vehicle
refitcost(<Byte> | <Unit-term>)Cost to refit this vehicle
reliability(<Byte>)Reliability decay speed of vehicle
retire(<Byte>)Set early retire date for this vehicle
runningcost(<Byte>)Running cost of road vehicle
runningcosttable(<Byte>)Set the running cost amount table
seteffect(<Effect>)Set effect for this vehicle
soundeffect(<Sound-ID>)Set sound effect for this vehicle
sortbefore(<Byte>)How to sort this vehicle into the purchase list
speed(<Unit-term>)Max speed of road vehicle
userdata(<Byte>)Set user-defined data for this vehicle
vehlife(<Byte>)Vehicle life of road vehicle
weight(<Unit-term>)Weight of road vehicle

Description

airdrag(<Byte>)

This property sets the air drag coefficient c2 used for the realistic acceleration model, from 1 (no airdrag) to 255 (most air drag) in arbitrary units. 0 means to use the default value that depends on the top speed (to simulate the fact that high-speed engines are generally more streamlined).

The default values are the following:

Top speed (mph/1.6)<16162432486496128192256...
c2192128966448322416128

For higher speeds, the series is continued in the same manner.

Air drag in Newtons will then be c2 * v2 with v in m/s, although it is probably futile to attempt to make c2 a realistic number due to the lack of TTD's consistent scaling. If a road vehicle doesn't reach its historical top speed, you might try setting the value of prop. 20 one or two steps lower than the default above, otherwise it's probably a good idea to leave it at the default.

callbacks(<List::Callback>)

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

Callback Description
CB_POWR Powered wagons and visual effect
CB_WLEN Wagon length
CB_LOAD Load amount
CB_RCAP Set refitted capacity
CB_ARTI Build articulated engines
CB_TSFX Show a suffix after the cargo type name
CB_RCOL Select colour mapping for vehicle
CB_SOUND Set sound effect

Callbacks CB_ARVS (Autoreplace vehicle selection), CB_ATAC (Can wagon be attached?), CB_PROP (Change Vehicle 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 length, power, recolouring and text suffixes):
callbacks(CB_WLEN, CB_POWR, CB_RCOL, CB_TSFX)

cargoaging(<Word>)

This function specifies the period (in game ticks) after which cargo carried by the vehicle 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 vehicles to define what type of cargo they should be refittable to. A wagon 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 vehicle 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 vehicle will probably have no specific graphics, linked with in makevehicle(), 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)

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

The parameter of this function is either the tractive effort given in kilo Newtons (or kp or lbf), or a coefficient specifying what fraction of the vehicle weight is equal to the maximum tractive effort. This might be useful if there are no realistic tractive effort numbers available for the vehicle in question.

For a coefficient of 255 (0xFF), the tractive effort is equal to the vehicle weight, for 128 (0x80), it is half, and so on. If this property function is not set at all, a default of 76 (0x4C) is used, corresponding to a coefficient of friction of 0.30.

Example (set tractive effort):
effort(2000 kp) // tractive effort of 2000 kilo ponds
effort(200 kN) // tractive effort of 200 kilo Newtons
effort(76) // tractive effort corresponding to friction of 0.3
effort(0x4c) // ditto

flags(<List>)

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

FlagMeaning
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)
TRAMTRACKVehicle is a tram/light rail vehicle and requires tram tracks to operate
2CCVehicle uses two company colours

By autorefitting, a vehicle may be refitted "on-the-fly", i.e. during a station visit, before loading. A vehicle 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 vehicles 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().

power(<Unit-term>)


This function sets the vehicle's power which may be given in different units: hp (imperial horse power), PS (metric horse power), or kW (kilowatt).

Please note that TTDPatch uses properties "power" and "weight" only if road vehicles are set to "realistic acceleration" in the NewCurveAndMountainHandling switch. They are ignored otherwise.

OpenTTD uses these properties always, if they are defined.

price(<Byte>)

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

Price factorPrice
1$ 108
16$ 1,750
32$ 3,500
128$ 14,000
255$ 27,890

Please note that prices are dependent on the game's difficulty setting 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 50% of the vehicle'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 vehicle is bought, and specifies how quickly the reliability decays after servicing. The initial TTD default for all vehicles is "20". If a vehicle 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.

For the running costs of road vehicles, a special table of base amounts is available at address 0x4C48 (see runningcostbase()).

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

seteffect(<Effect>)

See the equivalent train property function for information about usage of this function. For road vehicles, there is no default effect, therefore values of 0 .. 0x0F will show no visual effect. NOPOWER currently has no meaning and should be left at 0.

soundeffect(<Sound-ID>)

This function sets the default sound effect for a road vehicle:

BusTruck
BUS_STARTTRUCK_START
BUS_STARTHORNTRUCK_STARTHORN

sortbefore(<Veh_ID>)

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

For example, setting this property for vehicle 9 to a value of 7 would lead to the following internal list of vehicle 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 road vehicles.

speed(<Unit-term>)

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

userdata(<Byte>)

This function sets a user-defined bit mask in a static way. Its values may be interpreted either as bits or numerical values, depending on the function used to access the user data: function getubits() returns the user data as a bit pattern, but function getubyte() returns the data as a numerical value. The user data area may be written dynamically by using functions setubit()/clrubit() or setubyte() (even concurrently) while being in a callback CB_PROP chain, see there.

For an example, see here.

weight(<Unit-term>)

In addition to the usual unit of "tons", the weight of a road vehicle may be given by the "kg" unit as well.