Difference between revisions of "NML:Houses"

From GRFSpecs
Jump to navigationJump to search
(Update information about callbacks)
 
(23 intermediate revisions by 8 users not shown)
Line 1: Line 1:
 
{{NMLNavPropVarCB}}
 
{{NMLNavPropVarCB}}
  +
==House IDs==
  +
House IDs are local to the NewGRF, you are free to choose any ID in the 0..255-range. You should start your item definition with the 'substitute'-property, which allocates a new house. The value of this property should be the ID of a [[NML:List_of_default_house_properties|default house type]], which will be used instead of your item if it is not available for whatever reason (for example, missing NewGRF).
  +
  +
Although the majority of all original houses occupy a single tile, it is possible to define a larger house of up to 2x2 tiles. For this, you should set the fourth 'size' parameter in the item-block. Valid values are HOUSE_SIZE_XXX, XXX = <nowiki>[1X1 | 1X2 | 2X1 | 2X2]</nowiki>. This size should match the size of the substitute house type.
  +
  +
Note, setting the 4th parameter requires to also set the 3rd parameter. If you want automatic id assignment (mind the notes on the [[NML:Item|Item page]]), you need to set the 3rd parameter to -1. Example:
  +
<pre style="color:blue">
  +
item(FEAT_HOUSES, item_brewery, -1, HOUSE_SIZE_2X2) {
  +
}
  +
</pre>
  +
  +
===Multi-tile houses===
  +
Internally, due to the way NewGRF houses work, a multi-tile house will occupy more than one item ID. If you assign item ID X to a house, item IDs X+1 (for a 2-tile house) and (X+1) .. (X+3) (for a 4-tile house) will also be used. Normally you don't have to care about this, but there are two exceptions:
  +
* If you manually assign numeric ids to your houses. You are recommended to just set all ids to -1 and let NML figure it out for you.
  +
* When working with several variables that work with house type IDs. Keep in mind that tiles of a multi-tile house may have IDs X .. X + N - 1, with X being the assigned id and N the number of house tiles.
   
 
==House properties==
 
==House properties==
   
{| class="t"
+
{| class="wikitable sortable"
 
! property
 
! property
 
! value range
 
! value range
 
! comment
 
! comment
 
|-
 
| substitute
 
| 0 ... 109
 
| Number of the default house that replaces this one, if this house is not available for some reason. '''This property ''must'' be set first, before any other properties or graphics.''' All properties of the old type are copied to your new house, except for the church / stadium flags (see below). The old house must have the same size as the new house, see the list of [[NML:List_of_default_house_properties|default house types]] for a list of possible substitute IDs.
 
|-
 
|-
 
| name
 
| name
 
| string
 
| string
 
| for example string(STR_NAME_EIFFEL_TOWER)
 
| for example string(STR_NAME_EIFFEL_TOWER)
|-
 
| substitute
 
| 0 ... 109
 
| Number of the default house that replaces this one, if this house is not available for some reason. This property ''must'' be set first, before any other properties or graphics. All properties of the old type are copied to your new house, except for the church / stadium flags (see below). The old house must have the same size as the new house, see the list of [[NML:List_of_default_house_properties|default house types]] for a list of possible substitute IDs.
 
 
|-
 
|-
 
| override
 
| override
 
| 0 ... 109
 
| 0 ... 109
| id of the default house which this house replaces. This will cause your house to be placed instead of the default house. This is ignored, if the default house has already been overridden. You can define this property multiple times. Your house and the overridden house must have the same size, see the list of [[NML:List_of_default_house_properties|default house types]].
+
| id of the default house which this house replaces (and thus disabling the default). This is ignored, if the default house has already been overridden (disabling it another time is pointless). You can define this property multiple times. Your house and the overridden house must have the same size, see the list of [[NML:List_of_default_house_properties|default house types]].
 
|-
 
|-
 
| building_flags.
 
| building_flags.
Line 26: Line 41:
 
:Can only be built on flat terrain. Note that 2x2 buildings will always only be built on flat land, even if this bit isn't set.
 
:Can only be built on flat terrain. Note that 2x2 buildings will always only be built on flat land, even if this bit isn't set.
 
;HOUSE_FLAG_ANIMATE
 
;HOUSE_FLAG_ANIMATE
  +
:Enable animation unconditionally on (the beginning of) construction. If not set, animation can still be started (conditionally) via the callbacks <code style="color:darkgreen">anim_control</code>, <code style="color:darkgreen">construction_anim</code> or <code style="color:darkgreen">watched_cargo_accepted</code>.
:Enable animation
 
 
;HOUSE_FLAG_CHURCH
 
;HOUSE_FLAG_CHURCH
 
:House is a church (only 1 will be built per town)
 
:House is a church (only 1 will be built per town)
Line 42: Line 57:
 
| population
 
| population
 
| 0 ... 255
 
| 0 ... 255
| number of inhabitants the building adds to the town, if present
+
| Number of inhabitants the building adds to the town, if present. This also affects how many passengers the house generates, unless the <code>cargo_production</code> callback is used.
 
|-
 
|-
 
| mail_multiplier
 
| mail_multiplier
 
| 0 ... 255
 
| 0 ... 255
  +
| Affects how much mail the building generates. Not used if the <code>cargo_production</code> callback is used.
|
 
 
|-
 
|-
 
| accepted_cargos
 
| accepted_cargos
| Array with up to 3 [cargo_id, amount]-pairs.
+
| Array with up to 3 [cargo_id, amount]-pairs.
  +
{{nml|0.5}}{{ottdp|1.9|no}} Array with up to 16 [cargo_id, amount]-pairs.
 
| The cargos that are accepted by each tile of the house. CargoID is a cargo type from your cargo translation table, amount is the acceptance of the given cargo in 1/8 units.<br /> Example: to make a tile fully accept both PASS and MAIL you could use this: <code style="color:darkgreen"><nowiki>accepted_cargos: [[PASS, 8], [MAIL, 8]];</nowiki></code><br /> Example: for a house tile that doesn't accept any cargos at all you'd use: <code style="color:darkgreen">accepted_cargos: [];</code>
 
| The cargos that are accepted by each tile of the house. CargoID is a cargo type from your cargo translation table, amount is the acceptance of the given cargo in 1/8 units.<br /> Example: to make a tile fully accept both PASS and MAIL you could use this: <code style="color:darkgreen"><nowiki>accepted_cargos: [[PASS, 8], [MAIL, 8]];</nowiki></code><br /> Example: for a house tile that doesn't accept any cargos at all you'd use: <code style="color:darkgreen">accepted_cargos: [];</code>
 
|-
 
|-
Line 61: Line 77:
 
|-
 
|-
 
| probability
 
| probability
| 0 ... 16 (float)
+
| 0 ... 15 (float)
 
| Probability with respect to the default houses (=1). Mind that these are relative probabilities with respect to all houses defined. If all probabilities are defined as 16, they'll all have the same probability as if they had all a probability of 1.
 
| Probability with respect to the default houses (=1). Mind that these are relative probabilities with respect to all houses defined. If all probabilities are defined as 16, they'll all have the same probability as if they had all a probability of 1.
 
|-
 
|-
Line 94: Line 110:
 
| refresh_multiplier
 
| refresh_multiplier
 
| 0 ... 63
 
| 0 ... 63
| Defines the frequency with which the tile will be re-randomized which has an impact for random animation.
+
| Defines the frequency with which the tile will be re-randomized which has an impact for random animation. The tile will be processed by the periodic tile processing loop every (X + 1)*256 ticks, with X being the value of this property.
 
|-
 
|-
 
| animation_info
 
| animation_info
Line 121: Line 137:
 
==House variables==
 
==House variables==
   
{| class="t"
+
{| class="wikitable sortable"
 
! name
 
! name
 
! value range
 
! value range
Line 133: Line 149:
 
| 0..3
 
| 0..3
 
| Some pseudo-random bits, based on the tile position. TTD houses use this to randomize their appearance.
 
| Some pseudo-random bits, based on the tile position. TTD houses use this to randomize their appearance.
  +
|-
  +
| random_bits
  +
| 0..255
  +
| 8 random bits, also used for [[NML:Random_switch|random switch]]-blocks. Initially these are the same for all tiles of a multi-tile house.
 
|-
 
|-
 
| age
 
| age
Line 139: Line 159:
 
|-
 
|-
 
| town_zone
 
| town_zone
 
| [[NML:List of town zones|town zone]]
|
 
[[NML:List of town zones|town zone]]
 
 
| The town zone of the current tile
 
| The town zone of the current tile
 
|-
 
|-
Line 157: Line 176:
 
| same_class_count_town
 
| same_class_count_town
 
| 0..255
 
| 0..255
| Number of the houses with the same <code style="color:darkgreen">building_class</code> in the same town as this house
+
| Number of the houses with the same <code style="color:darkgreen">building_class</code> in the same town as this house. The class of the north tile of the use is used for this purpose, as other tiles don't normally have a class.
 
|-
 
|-
 
| same_class_count_map
 
| same_class_count_map
 
| 0..255
 
| 0..255
| Number of the houses with the same <code style="color:darkgreen">building_class</code> on the entire map
+
| Number of the houses with the same <code style="color:darkgreen">building_class</code> on the entire map. The class of the north tile of the use is used for this purpose, as other tiles don't normally have a class.
 
|-
 
|-
 
| generating_town
 
| generating_town
Line 172: Line 191:
 
|-
 
|-
 
| x_coordinate
 
| x_coordinate
| 0..2047
+
| 0..4095
 
| X-coordinate (top right -&gt; bottom left) of the tile on the map
 
| X-coordinate (top right -&gt; bottom left) of the tile on the map
 
|-
 
|-
 
| y_coordinate
 
| y_coordinate
| 0..2047
+
| 0..4095
 
| Y-coordinate (top left -&gt; bottom right) of the tile on the map
 
| Y-coordinate (top left -&gt; bottom right) of the tile on the map
  +
|-
  +
| relative_x
  +
| 0..1
  +
| X-coordinate (top right -&gt; bottom left) of the tile relative to the northernmost tile.
  +
|-
  +
| relative_y
  +
| 0..1
  +
| Y-coordinate (top left -&gt; bottom right) of the tile relative to the northernmost tile.
  +
|-
  +
| relative_pos
  +
| 0xYYXX
 
|
  +
A combination of relative_x and relative_y in the format 0xYYXX. Useful if you want to check for a single position. The [[NML:Builtin functions|builtin function]] relative_coord(x, y) may be useful when making comparisons.
  +
|-
  +
| house_tile
  +
| HOUSE_TILE_XXX, XXX = <nowiki>[NORTH | EAST | WEST | SOUTH]</nowiki>
  +
| What tile of a multi-tile house this is.
  +
|-
  +
| house_type_id
  +
| 0..255
  +
| Item ID of this house type, that was assigned to the item. See the note above about [[#Multi-tile houses|multi-tile houses]].
 
|}
 
|}
   
   
 
The following variables require one or more arguments
 
The following variables require one or more arguments
{| class="t"
+
{| class="wikitable sortable"
 
! name
 
! name
 
! arguments
 
! arguments
Line 193: Line 233:
 
| Number of old houses with a given ID in the same town as the current house
 
| Number of old houses with a given ID in the same town as the current house
 
|-
 
|-
  +
| old_house_count_map
| old_house_count_town
 
 
| ID of old house type (0..109)
 
| ID of old house type (0..109)
 
| 0..255
 
| 0..255
Line 201: Line 241:
 
| ID of house defined in this NewGRF (0..255)
 
| ID of house defined in this NewGRF (0..255)
 
| 0..255
 
| 0..255
| Number of houses with a given ID in the same town as the current house
+
| Number of houses with a given ID in the same town as the current house.
 
|-
 
|-
 
| other_house_count_map
 
| other_house_count_map
Line 280: Line 320:
 
|-
 
|-
 
| nearest_house_matching_criterion
 
| nearest_house_matching_criterion
| radius (1..63) and criterion (SEARCH_HOUSE_BY_XXX, XXX = [<nowiki>ID | CLASS | GRFID</nowiki>])
+
| radius (1..63) and criterion (SEARCH_HOUSE_BY_XXX, XXX = [<nowiki>TYPE | CLASS | GRFID</nowiki>])
 
| 1..63, or 0 if not found
 
| 1..63, or 0 if not found
| Perform a circular search for a house matching either the id, <code style="color:darkgreen">building_class</code> or GRFID of this house, depending on the second parameter. The first parameter specifies the maximum search radius. Return value is the Manhattan distance of the closest matching house tile, or 0 if no match was found. Note that tiles of the originating house never match.
+
| Perform a circular search for a house matching either the id, <code style="color:darkgreen">building_class</code> or GRFID of this house, depending on the second parameter. The first parameter specifies the maximum search radius. Return value is the Manhattan distance of the closest matching house tile, or 0 if no match was found. Note that tiles of the originating house never match. See also the note above about [[#Multi-tile houses|multi-tile houses]].
 
|-
 
|-
 
| nearby_tile_house_id
 
| nearby_tile_house_id
 
| x- and y-offset (both signed, range -8..7)
 
| x- and y-offset (both signed, range -8..7)
 
| -1, or 0 .. 767
 
| -1, or 0 .. 767
| Return value is -1 if the tile is not a house tile, X (0..255) if the tile contains old house type X, 256+X if the tile contains a house from this NewGRF with ID X, 512+X if the tile contains a house from a different NewGRF with ID X.
+
| Return value is -1 if the tile is not a house tile, X (0..255) if the tile contains old house type X, 256+X if the tile contains a house from this NewGRF with ID X, 512+X if the tile contains a house from a different NewGRF with ID X. See the note above about [[#Multi-tile houses|multi-tile houses]].
 
|-
 
|-
 
| nearby_tile_house_class
 
| nearby_tile_house_class
 
| x- and y-offset (both signed, range -8..7)
 
| x- and y-offset (both signed, range -8..7)
 
| -1, 0, or 256 .. 767
 
| -1, 0, or 256 .. 767
| Return value is -1 if the tile is not a house tile, 0 if the house tile does not have a class (this includes all old house types), 256+X (X = 0..255) if the house has been defined by this NewGRF with <code style="color:darkgreen">building_class</code> X or 512+X if the house has been defined by a different NewGRF with <code style="color:darkgreen">building_class</code> X.
+
| Return value is -1 if the tile is not a house tile, 0 if the house tile does not have a class (this includes all old house types), 256+X (X = 0..255) if the house has been defined by this NewGRF with <code style="color:darkgreen">building_class</code> X or 512+X if the house has been defined by a different NewGRF with <code style="color:darkgreen">building_class</code> X. Note that for a multi-tile house, generally only the north tile has a sensible class value.
 
|-
 
|-
 
| nearby_tile_house_grfid
 
| nearby_tile_house_grfid
Line 304: Line 344:
 
Unless noted otherwise, callbacks may be called for any of the tiles of a multi-tile house.
 
Unless noted otherwise, callbacks may be called for any of the tiles of a multi-tile house.
   
{| class="t"
+
{| class="wikitable sortable"
 
! callback
 
! callback
 
! return value
 
! return value
Line 324: Line 364:
 
| anim_next_frame
 
| anim_next_frame
 
| Next animation frame or CB_RESULT_XXX
 
| Next animation frame or CB_RESULT_XXX
| Called for every animation frame, returns the next frame to display. Alternatively, return CB_RESULT_NEXT_FRAME or CB_RESULT_STOP_ANIMATION to show the next frame or stop animation, respectively. <code>extra_callback_info1</code> contains 32 random bits, if enabled in the <code>building_flags</code> property. Returning a sound effect in the high byte will cause that sound effect to be played.
+
| Called for every animation frame, returns the next frame to display. Alternatively, return CB_RESULT_NEXT_FRAME or CB_RESULT_STOP_ANIMATION to show the next frame or stop animation, respectively. Returning a sound effect in the high byte will cause that sound effect to be played.
  +
* <code>extra_callback_info1</code>: 32 random bits, if enabled in the <code>building_flags</code> property.
  +
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.
 
|-
 
|-
 
| anim_control
 
| anim_control
 
| Next animation frame or CB_RESULT_XXX
 
| Next animation frame or CB_RESULT_XXX
| Called every 256 ticks. Return the animation frame to show, or CB_RESULT_XXX with XXX = [CB_RESULT_START_ANIMATION | STOP_ANIMATION | DO_NOTHING] to respectively start the animation in its current frame, stop the animation or do nothing. <code>extra_callback_info1</code> contains 32 random bits. The low 16 bits are always different for each house tile, but the high 16 bits are the same for each tile if synchronized animation is enabled in the <code>building_flags</code>-property. Returning a sound effect in the high byte will cause that sound effect to be played.
+
| Called every 256 ticks. Return the animation frame to show, or CB_RESULT_XXX with XXX = <nowiki>[CB_RESULT_START_ANIMATION | STOP_ANIMATION | DO_NOTHING]</nowiki> to respectively start the animation in its current frame, stop the animation or do nothing. Returning a sound effect in the high byte will cause that sound effect to be played.
  +
* <code>extra_callback_info1</code>: 32 random bits. The low 16 bits are always different for each house tile, but the high 16 bits are the same for each tile if synchronized animation is enabled in the <code>building_flags</code>-property.
  +
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_anim
 
| construction_anim
Line 351: Line 395:
 
|-
 
|-
 
| cargo_production
 
| cargo_production
| (cargo_type * 256) + amount
+
| (cargo_type * 256) + amount, or <code>CB_RESULT_HOUSE_NO_MORE_PRODUCTION</code>
| Called every 256 ticks. Called multiple times until 0x20FF is returned. The high byte of the result contains a cargo type, the low byte contains the amount of that cargo to produce. <code>extra_callback_info1</code> contains the number of iterations so far, <code>extra_callback_info2</code> contains random bits.
+
| Called every 256 ticks. The return value specifies what cargo and what amount is produced. The callback is called multiple times until <code>CB_RESULT_HOUSE_NO_MORE_PRODUCTION</code> is returned.
  +
* <code>getbits(extra_callback_info1, 0, 8)</code>: The number of iterations so far.
  +
* <code>extra_callback_info2</code>: 32 random bits.
 
|-
 
|-
 
| foundations
 
| foundations

Latest revision as of 13:18, 2 August 2024

Props, Vars and CBs

House IDs

House IDs are local to the NewGRF, you are free to choose any ID in the 0..255-range. You should start your item definition with the 'substitute'-property, which allocates a new house. The value of this property should be the ID of a default house type, which will be used instead of your item if it is not available for whatever reason (for example, missing NewGRF).

Although the majority of all original houses occupy a single tile, it is possible to define a larger house of up to 2x2 tiles. For this, you should set the fourth 'size' parameter in the item-block. Valid values are HOUSE_SIZE_XXX, XXX = [1X1 | 1X2 | 2X1 | 2X2]. This size should match the size of the substitute house type.

Note, setting the 4th parameter requires to also set the 3rd parameter. If you want automatic id assignment (mind the notes on the Item page), you need to set the 3rd parameter to -1. Example:

 item(FEAT_HOUSES, item_brewery, -1, HOUSE_SIZE_2X2) {
 }

Multi-tile houses

Internally, due to the way NewGRF houses work, a multi-tile house will occupy more than one item ID. If you assign item ID X to a house, item IDs X+1 (for a 2-tile house) and (X+1) .. (X+3) (for a 4-tile house) will also be used. Normally you don't have to care about this, but there are two exceptions:

  • If you manually assign numeric ids to your houses. You are recommended to just set all ids to -1 and let NML figure it out for you.
  • When working with several variables that work with house type IDs. Keep in mind that tiles of a multi-tile house may have IDs X .. X + N - 1, with X being the assigned id and N the number of house tiles.

House properties

property value range comment
substitute 0 ... 109 Number of the default house that replaces this one, if this house is not available for some reason. This property must be set first, before any other properties or graphics. All properties of the old type are copied to your new house, except for the church / stadium flags (see below). The old house must have the same size as the new house, see the list of default house types for a list of possible substitute IDs.
name string for example string(STR_NAME_EIFFEL_TOWER)
override 0 ... 109 id of the default house which this house replaces (and thus disabling the default). This is ignored, if the default house has already been overridden (disabling it another time is pointless). You can define this property multiple times. Your house and the overridden house must have the same size, see the list of default house types.
building_flags. bitmask(HOUSE_FLAG_XXX,...)
HOUSE_FLAG_NOT_SLOPED
Can only be built on flat terrain. Note that 2x2 buildings will always only be built on flat land, even if this bit isn't set.
HOUSE_FLAG_ANIMATE
Enable animation unconditionally on (the beginning of) construction. If not set, animation can still be started (conditionally) via the callbacks anim_control, construction_anim or watched_cargo_accepted.
HOUSE_FLAG_CHURCH
House is a church (only 1 will be built per town)
HOUSE_FLAG_STADIUM
House is a stadium (only 1 will be built per town)
HOUSE_FLAG_ONLY_SE
Can only be built in the scenario editor
HOUSE_FLAG_PROTECTED
Will not be removed by the game
HOUSE_FLAG_SYNC_CALLBACK
Animation callback anim_control is called at the same time for all tiles.
HOUSE_FLAG_RANDOM_ANIMATION
Enable random bits in the anim_next_frame-callback.
population 0 ... 255 Number of inhabitants the building adds to the town, if present. This also affects how many passengers the house generates, unless the cargo_production callback is used.
mail_multiplier 0 ... 255 Affects how much mail the building generates. Not used if the cargo_production callback is used.
accepted_cargos Array with up to 3 [cargo_id, amount]-pairs.

NML 0.5Supported by OpenTTD 1.91.9 Not supported by TTDPatch Array with up to 16 [cargo_id, amount]-pairs.

The cargos that are accepted by each tile of the house. CargoID is a cargo type from your cargo translation table, amount is the acceptance of the given cargo in 1/8 units.
Example: to make a tile fully accept both PASS and MAIL you could use this: accepted_cargos: [[PASS, 8], [MAIL, 8]];
Example: for a house tile that doesn't accept any cargos at all you'd use: accepted_cargos: [];
local_authority_impact 0 ... 65525 amount of happiness decrease of the city council, if the building is destroyed. Town ratings can vary between -1000 (appalling) and +1000 (outstanding).
removal_cost_multiplier 0 ... 255
probability 0 ... 15 (float) Probability with respect to the default houses (=1). Mind that these are relative probabilities with respect to all houses defined. If all probabilities are defined as 16, they'll all have the same probability as if they had all a probability of 1.
years_available array of two int [xx, yy] where xx and yy indicate the introduction year and the last year the building can be built
minimum_lifetime 0 ... 255 number of years the building will remain at least
availability_mask

[bitmask(town zones), bitmask(CLIMATE_XXX, ...)]

An array with two bitmasks, the first bitmask is a mask of town zones where this house is available. The second bitmask is a mask of climates combined with the special value ABOVE_SNOWLINE which you need to set for houses available in the arctic climate above the snowline.
Examples:

  • Available in the centre town zone in toyland only: [bitmask(TOWNZONE_CENTRE), bitmask(CLIMATE_TOYLAND)]
  • Available in all town zones in the arctic climate both above and below the snowline: [ALL_TOWNZONES, bitmask(CLIMATE_ARCTIC, ABOVE_SNOWLINE)]
  • Available everywhere except on the town edge: [ALL_TOWNZONES & ~bitmask(TOWNZONE_EDGE), ALL_CLIMATES | bitmask(ABOVE_SNOWLINE)
callback_flags bitmask(HOUSE_CBF_XX)

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

random_colours array of 4, each COLOUR_XXX

colour values in an array, refer to the table here for a list of possible values.

refresh_multiplier 0 ... 63 Defines the frequency with which the tile will be re-randomized which has an impact for random animation. The tile will be processed by the periodic tile processing loop every (X + 1)*256 ticks, with X being the value of this property.
animation_info Array [ANIMATION_XXX, frame-count]

Type of animation and its length (1...128 frames):

ANIMATION_LOOPING
ANIMATION_NON_LOOPING
animation_speed 2 ... 16

Speed of animation, see animation speed table for the meaning of the values.

building_class 0 .. 254 An arbitrary number. You can check for the presence of buildings of the same class when building new buildings or using animation. Only the north tile of a multi-tile building is assigned a class.
watched_cargo_types array of values from your cargo table Supported by OpenTTD 1.2 (r23072)1.2 Supported by TTDPatch 2.6 (r1677)2.6List of cargo types to watch, to be used with the watched_cargo_accepted callback.

House variables

name value range comment
construction_state 0..3 Current construction state of the house tile. 0..2 = under construction, 3 = finished.
pseudo_random_bits 0..3 Some pseudo-random bits, based on the tile position. TTD houses use this to randomize their appearance.
random_bits 0..255 8 random bits, also used for random switch-blocks. Initially these are the same for all tiles of a multi-tile house.
age 0..255 Age of the house in years, limited to 255
town_zone town zone The town zone of the current tile
terrain_type TILETYPE_XX TILETYPE_NORMAL, TILETYPE_DESERT, TILETYPE_RAIN_FOREST, TILETYPE_SNOW
same_house_count_town 0..255 Number of the houses with the same ID in the same town as this house
same_house_count_map 0..255 Number of the houses with the same ID on the entire map
same_class_count_town 0..255 Number of the houses with the same building_class in the same town as this house. The class of the north tile of the use is used for this purpose, as other tiles don't normally have a class.
same_class_count_map 0..255 Number of the houses with the same building_class on the entire map. The class of the north tile of the use is used for this purpose, as other tiles don't normally have a class.
generating_town [0 | 1] 1 a random town is currently being created, 0 otherwise. Note that while generating a random town, town variables population and building_count are incorrect. The population variable contains the population of buildings generated yet, the final value may be larger. The building_count is surely higher than the final value will be.
animation_frame 0..255 Current animation frame
x_coordinate 0..4095 X-coordinate (top right -> bottom left) of the tile on the map
y_coordinate 0..4095 Y-coordinate (top left -> bottom right) of the tile on the map
relative_x 0..1 X-coordinate (top right -> bottom left) of the tile relative to the northernmost tile.
relative_y 0..1 Y-coordinate (top left -> bottom right) of the tile relative to the northernmost tile.
relative_pos 0xYYXX

A combination of relative_x and relative_y in the format 0xYYXX. Useful if you want to check for a single position. The builtin function relative_coord(x, y) may be useful when making comparisons.

house_tile HOUSE_TILE_XXX, XXX = [NORTH | EAST | WEST | SOUTH] What tile of a multi-tile house this is.
house_type_id 0..255 Item ID of this house type, that was assigned to the item. See the note above about multi-tile houses.


The following variables require one or more arguments

name arguments value range comment
old_house_count_town ID of old house type (0..109) 0..255 Number of old houses with a given ID in the same town as the current house
old_house_count_map ID of old house type (0..109) 0..255 Number of old houses with a given ID on the whole map
other_house_count_town ID of house defined in this NewGRF (0..255) 0..255 Number of houses with a given ID in the same town as the current house.
other_house_count_map ID of house defined in this NewGRF (0..255) 0..255 Number of houses with a given ID on the whole map
other_class_count_town ID of house defined in this NewGRF (0..255) 0..255 Number of houses, with the same class as the house with the given ID, in the same town as the current house
other_class_count_map ID of house defined in this NewGRF (0..255) 0..255 Number of houses, with the same class as the house with the given ID, on the whole map
nearby_tile_slope x- and y-offset (both signed, range -8..7) SLOPE_XXX See tile slopes for an overview of possible values
nearby_tile_is_water x- and y-offset (both signed, range -8..7) [0 | 1] 1 if the tile is water, 0 otherwise
nearby_tile_terrain_type x- and y-offset (both signed, range -8..7) TILETYPE_XX TILETYPE_NORMAL, TILETYPE_DESERT, TILETYPE_RAIN_FOREST, TILETYPE_SNOW
nearby_tile_water_class x- and y-offset (both signed, range -8..7) WATER_CLASS_XXX XXX = [NONE | SEA | CANAL | RIVER] Note that tiles for which nearby_tile_is_water is 0 may still have a water class, e.g. industry tiles with water beneath them.
nearby_tile_height x- and y-offset (both signed, range -8..7) 0..255 (currently limited to 0..15) Height of the lowest corner of the tile. 1 unit is one height level of 8 pixels.
nearby_tile_class x- and y-offset (both signed, range -8..7)

Tile class

nearby_tile_animation_frame x- and y-offset (both signed, range -8..7) 0..255 Animation frame of the given tile
cargo_accepted_nearby_ever cargo type, x- and y-offset [1] [0 | 1] 1 if the given cargo type was ever accepted at a nearby station, 0 otherwise
cargo_accepted_nearby_last_month cargo type, x- and y-offset [1] [0 | 1] 1 if the given cargo type was accepted at a nearby station in the last month, 0 otherwise
cargo_accepted_nearby_this_month cargo type, x- and y-offset [1] [0 | 1] 1 if the given cargo type was ever accepted at a nearby station in this month, 0 otherwise
cargo_accepted_nearby_last_bigtick cargo type, x- and y-offset [1] [0 | 1] 1 if the given cargo type was ever accepted at a nearby station since the last periodic processing, which happens every 250 ticks. 0 otherwise
cargo_accepted_nearby_watched cargo type, x- and y-offset [1] [0 | 1] 1 if the given cargo type was one of the cargo types that triggered the watched_cargo_accepted-callback (only during this callback), 0 otherwise
nearest_house_matching_criterion radius (1..63) and criterion (SEARCH_HOUSE_BY_XXX, XXX = [TYPE | CLASS | GRFID]) 1..63, or 0 if not found Perform a circular search for a house matching either the id, building_class or GRFID of this house, depending on the second parameter. The first parameter specifies the maximum search radius. Return value is the Manhattan distance of the closest matching house tile, or 0 if no match was found. Note that tiles of the originating house never match. See also the note above about multi-tile houses.
nearby_tile_house_id x- and y-offset (both signed, range -8..7) -1, or 0 .. 767 Return value is -1 if the tile is not a house tile, X (0..255) if the tile contains old house type X, 256+X if the tile contains a house from this NewGRF with ID X, 512+X if the tile contains a house from a different NewGRF with ID X. See the note above about multi-tile houses.
nearby_tile_house_class x- and y-offset (both signed, range -8..7) -1, 0, or 256 .. 767 Return value is -1 if the tile is not a house tile, 0 if the house tile does not have a class (this includes all old house types), 256+X (X = 0..255) if the house has been defined by this NewGRF with building_class X or 512+X if the house has been defined by a different NewGRF with building_class X. Note that for a multi-tile house, generally only the north tile has a sensible class value.
nearby_tile_house_grfid x- and y-offset (both signed, range -8..7) -1, 0 or a GRFID Return value is -1 if the tile is not a house tile, 0 if the house tile contains an old house type, or else the GRFID of the NewGRF defining the house.
  1. 1.0 1.1 1.2 1.3 1.4 Cargo type should be from your cargo translation table. X- and y-offset are optional, if provided both must be in range -128..127. A station is considered nearby if the tile is in the station's acceptance area. This is the purpose of the x- and y-offset, as other tiles may have other stations nearby.

House callbacks

Unless noted otherwise, callbacks may be called for any of the tiles of a multi-tile house.

callback return value comment
default Sprite layout Graphics for the house tile
graphics_xxx, xxx = [north | east | south | west] Sprite layout Tile-specific graphics for one of the tiles of a multi-tile house. Of course, this is callback is called for that tile only.
random_trigger N/A

See random switch for more information.

anim_next_frame Next animation frame or CB_RESULT_XXX Called for every animation frame, returns the next frame to display. Alternatively, return CB_RESULT_NEXT_FRAME or CB_RESULT_STOP_ANIMATION to show the next frame or stop animation, respectively. Returning a sound effect in the high byte will cause that sound effect to be played.
  • extra_callback_info1: 32 random bits, if enabled in the building_flags property.

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.

anim_control Next animation frame or CB_RESULT_XXX Called every 256 ticks. Return the animation frame to show, or CB_RESULT_XXX with XXX = [CB_RESULT_START_ANIMATION | STOP_ANIMATION | DO_NOTHING] to respectively start the animation in its current frame, stop the animation or do nothing. Returning a sound effect in the high byte will cause that sound effect to be played.
  • extra_callback_info1: 32 random bits. The low 16 bits are always different for each house tile, but the high 16 bits are the same for each tile if synchronized animation is enabled in the building_flags-property.

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_anim Same as anim_control Works the same as the anim_control callback, except that it's called when the construction state changes.
watched_cargo_accepted Same as anim_control Works the same as the anim_control callback, except that it's called when one of the watched cargo types is accepted.
anim_speed 0 .. 16 Decide the time an animation frame should last. Return value is interpreted as (num_ticks = 2^anim_speed), which each tick lasting 30 ms. Avoid using this callback if possible, since it has to be called each tick for every animated tile. This can be used to create animation frames that last between 30 ms and 33 minutes.
cargo_type_accept type1 + (type2 << 5) + (type3 << 10) Decide the cargo types that this tile accepts. If this callback is not implemented or fails, the values from accepted_cargo are used instead. Bits 0..4: First cargo type. Bits 5..9: Second cargo type. Bits 10..14: Third cargo type.
cargo_amount_accept amt1 + (amt2 << 4) + (amt3 << 8) Acceptance for each cargo amount in 1/8th. If this callback is not implemented or fails, the values from the acceptance properties are used instead. Cargo types are from the cargo_type_accept callback, or the accepted_cargo property if that callback failed. Bits 0..3: Acceptance of first cargo type. Bits 4..7: Acceptance of second cargo type. Bits 8..11: Acceptance of third cargo type.
cargo_production (cargo_type * 256) + amount, or CB_RESULT_HOUSE_NO_MORE_PRODUCTION Called every 256 ticks. The return value specifies what cargo and what amount is produced. The callback is called multiple times until CB_RESULT_HOUSE_NO_MORE_PRODUCTION is returned.
  • getbits(extra_callback_info1, 0, 8): The number of iterations so far.
  • extra_callback_info2: 32 random bits.
foundations CB_RESULT[_NO]_FOUNDATIONS Return CB_RESULT_FOUNDATIONS to draw standard foundations (default) or CB_RESULT_NO_FOUNDATIONS to not draw them.
autoslope CB_RESULT[_NO]_AUTOSLOPE Return CB_RESULT_AUTOSLOPE to allow autoslope (altering the ground below a tile) or CB_RESULT_NO_AUTOSLOPE to disallow it.
name String Name of the building (when using tile query tool)
colour Palette number

Used to recolour the building. See here here for an overview of default palettes.

construction_check 0 or 1 Return 1 to allow building the house or 0 to disallow. Called only for the north tile.
destruction 0 or 1 Called periodically. Return 0 to keep the building or 1 to destroy it. Called only for the north tile.
protection 0 or 1 Return 0 to allow destruction, or 1 to disallow