Table of Contents

Construction Types

There are many different types of construction that are available in different menus and provide different features. To distinguish between the different types, there are different keys for the type property. Constructions in the station menus use:

Construction in the depot menus use:

Industry constructions use the “INDUSTRY” type.

Assets in the asset menu use:

Buildings that are generated by towns use “TOWN_BUILDING”.

“STREET_CONSTRUCTION” is used for street constructions like roundabouts and highway intersections.

Stations

Stations are the constructions where people and cargo items can board and leave vehicles. Like the transport network provider in single meshes, constructions can have streets and tracks too. Therefore there are three blocks in the result:

Runways

The runways block contains 0 or more runway blocks which have several properties related to the entry and exit points of the freely moving planes and ships:

result.runways = {
  {
    edges = { 0, },
    node = 0,
    type = "LANDING",
  },
  {
    edges = { 1, },
    node = 3,
    type = "TAKEOFF",
  },
},

An aircraft tries to land and slow down in front of the landing node. After passing it, it will taxi to the terminal. On departure, it will speed up and take off after passing the takeoff node. The landing/takeoff direction is given by the tangent of the first/last edge in the edges list. If the runway is not longSame holds for ships.

Terminal Groups

For constructions, terminals from the models can be grouped together. This is not neccessary, but it might be helpful e.g. when several models are used to form a platform of a train station.

The result.terminalGroups list may contain zero or more blocks:

result.terminalGroups = {
  {
    terminals = { {5, 0 } }, 
    vehicleNodeOverride = 42
  },
  ...
}

Each block in the list contains two properties:

Please note, that it is currently not possible to select the lane of streets that are defined by edges in the construction for the vehicle node. By default, the vehicleNode will be placed on the first lane that is most likely a sidewalk.

Once a result.terminalGroups block is defined, non grouped terminals are ignored.

Assignment of Terminals to Stations

To distinguish between the passenger and cargo part of a station, the result.stations list is used. It contains a list of sub stations each with their own properties:

result.stations = {
  { 
    terminals = { 0,1 }, 
    tag = 0
  },
  { 
    terminals = { 2,3 }, 
    tag = 1
  },
  ...
}

The same is done for terminals of different carrier types.

Depots

Depots are the places where the vehicles can be bought by the player. The construction files for depots lay in res/construction/depot/. There are no additional property blocks for depots. Instead, a used model has a vehicleDepot block. The updateFn does not contain any special params except the custom parameters of the construction.

Depot Models

To be used as a depot, a model can have an additional metadata block called vehicleDepot.

vehicleDepot = {
  capacity = 5,        --unused
  carrier = "RAIL",
  inNodes = { 0, },
  outNodes = { 0, },
},

The block features three properties that are currently in use:

Events

Depots support some animation events:

Industries

Industries are used for cargo production, conversion and consumption. Their .con files can be found in res/construction/industry/. They have some special properties as well as some specifics regarding the updateFn.

Industry Properties

Beside the general properties like the description block, industries have two additional property blocks:

  ...
  soundConfig = {
    soundSet = { name = "chemical_plant" },
    effects = {
      select =  { "selected_industry_chemicalplant3.wav" }
    }
  },
  placementParams = {
    buildOrder = 14,
    initWeight = 1,
    tags = { "INPUT_OIL", },
    distanceWeights = {
      INPUT_PLASTIC = 1,
      INPUT_OIL = -2,
    },
  },
  ...

The soundConfig block contains two things:

The other block, placementParams is used for the automated distribution of industries over the map. The properties are used to contrain the distribution on dependance of previously built industries. There are:

UpdateFn Parameters

The available parameters for industries are:

In some circumstances, e.g. when an industry is upgraded to a new production level or is influenced by mission scripts, it receives some additional parameters:

It is recommended to support these additional parameters to allow mission or game scripts to adjust the production and consumption of industries. The industryutil.lua in res/scripts/ contains a possible implementation in the addIndustryData function.

UpdateFn Return Properties

Beside the common return properties like models and groundFaces, there are several additional blocks to let a construction consume/produce and store cargo items, you need to specify stocks and stock rules.

Stocks

A stock entry defines for a cargo type whether it's ordered/shipped and on which edges it can be piled up.

result.models = { }
 
-- Add some edges for the stock piles, they can be distributed over an arbitrary number of models.
-- In this example, each model contains exactly one edge, and we add for each cargo type one model.
for i = 1, 5 do
  result.models[#result.models + 1] = { id = "industry/common/stock_lane_8m.mdl", transf = { ... } }
end
 
-- Specify the necessary cargo types and which edges are used for stock piling
result.stocks = {
  { cargoType = "PLANKS",   edges = { { 0, 0 } }, moreCapacity = 100 },
  { cargoType = "STEEL",    edges = { { 1, 0 } },
},

cargoType can be any type defined in base_config.lua. edges stores a list of edges, where the cargo can be piled up. It consists of one or more pairs of indices. The first index refers to a model from result.models, the second index to the particular edge in the edge list of that model. The size of the stock is calculated by the length and widths of each edge. For every 4 m², there is space for one cargo item. If the stock should have more capacity, it can be added with the moreCapacity property.

Rules

So far, the construction knows which cargo types it can receive/send and where it should store them. But it knows nothing about how many cargo items it can produce/consume per year and how the required items relate to the produced items. This is specified by the stock rules. Following code shows a rule that refers to the above example for the stock lists:

result.rule = {
  input = { { 4, 0 }, { 1, 1 } }, 
  output = { MACHINES = 2, }, 
  capacity = 50
},

The number of times that the rule can be processed per year is limited by capacity The rules are applied independently and at most capacity time a year. Each entry of input refers to a specific cargo item configuration. In order the rule can be applied, at least one of the input configurations must be valid. That means these cargo items must be on stock. The first number in a configuration refers to the consumption of items from the first stock, the second number refers to the consumption of items from the second. output is a list of produced cargo items per cargo type.

Examples

There are constructions that only produce cargo items, but don't consume anything. For example, the coal mine.

result.stocks = { }
result.rule = { input = { { } }, output = { COAL = 1 }, capacity = 200 }

Or the steel mill that consumes two of each iron ore and coal to produce one item of steel:

result.stocks = {
  { cargoType = "IRON_ORE", edges = { ... } },
  { cargoType = "COAL", edges = { ... } }
}
result.rule = { input = { { 2, 2 } }, output = { STEEL = 1 }, capacity = 200 }

Events

Industries support some animation events:

Assets

Assets are generic constructions that are mainly used for decorative purposes. They may contain functional elements like edges though.

Depending on the used type they have a slightly different placement behavior. If set to “ASSET_DEFAULT” they can be placed freely. If set to “ASSET_TRACK”, they snap along nearby tracks by default. It can be suppressed by pressing SHIFT while clicking.

Assets have some additional properties as well as parameters for the updateFn. They do not have additional properties for the result data struct.

Asset Properties

The additional properties of assets are:

  ...
  buildMode = "MULTI",
  skipCollision = true,
  autoRemovable = false,
  categories = { "misc" },
  snapping = { 
    rail = true, 
    road = true, 
    water = false 
  },
  ...

The buildMode property specifies, whether one can build one (“SINGLE”) or more constructions (“MULTI”) until the construction menu is closed. It's also possible to build constructions with a brush (“BRUSH”).

To ignore collider information and enable the intersection of models, it is possible to skip collision by setting skipCollision to true.

When assets should be removed when they are in the way for other constructions (both player built and game built ones), the autoRemovable property can be set to true.

To provide additional filter possibilities, it is possible to assign an asset construction to one or more categories. The string keys are added to the categories list.

To allow snapping along tracks, streets or the water surface, the appropriate flags can be set to true in the snapping property.

UpdateFn Parameters

The available parameters for assets are:

Town Buildings

Town buildings are automatically constructed by towns depending on the growth and era. Town buildings have some additional properties and some parameters for their updateFn function.

Town Building Properties

The first additional property is soundConfig:

  ...
  soundConfig = {
    soundSet = { name = "town_building" }
  },
  ...

It contains a block soundSet that has a reference to a soundset relative to res/config/sound_set.

To inform the game for which purposes the house is suitable, there is a townBuildingParams block:

  ...
  townBuildingParams = {
    landUseType = "COMMERCIAL",
    parcelSize = { 1, 1 },
    level = 1,
  },
  ...

This block has three properties:

UpdateFn Parameters

The updateFn parameters for town buildings are:

UpdateFn Return Properties

The returned data struct of town buildings should have the following properties that are described in the construction basics:

In addition, there are several custom properties described below.

Person Capacity

The personCapacity block defines the number of residents that can be covered by this building in the specific type of building:

result.personCapacity = {
  capacity = 2,
  type = "INDUSTRIAL"
},

It contains two properties:

Stocks and Rules

Buildings may request cargo items. Therefore they have stocks and rule blocks too:

result.stocks = {
  {      
    cargoType = "MACHINES",      
    edges = {},      
    moreCapacity = 100,      
    type = "RECEIVING"    
  },
...
},
result.rule = {    
  capacity = 1,    
  consumptionFactor = 1.2,    
  input = { { 1 } },    
  output = {}
},

The details can be found at the industry explanations above.

Scaffold

The scaffolding is shown while the building is constructed. To define its outline, there is a scaffold property:

result.scaffold = {    
  buildingFace = { { { 7.68415, 4.89475, 0 }, { 7.67744, 15.68718, 0 }, { 0.80814, 15.69474, 0 }, ... } },
  height = -1
},

The buildingFace is the bottom polygon around the house. The scaffolding is placed along the edges of this polygon with a slight offset so that it does not collide with the walls. The x and y coordinates are relative to the construction origin, z coordinates are ignored and automatically calculated depending on the terrain. The height value is used to offset the top height of the scaffolding below the roof.

Events

Town buildings support some animation events:

Street Constructions / Track Constructions

Street constructions can be used to provide street templates like larger intersections or roundabouts. To provide additional filter possibilities, it is possible to assign an asset construction to one or more categories. The string keys are added to the categories list property.

Their upgradeFn has only a small set of parameters:

The constructions may either use models or not. See below for information about pure street and track construction templates.

Track constructions work similar but for railway. They appear in the track construction tab in the rail menu. Without mods, this tab is not visible.

A track construction example is available for download.

Build free streets and tracks

It is possible to build streets and tracks without creating an actual construction. This way one can build predefined complex street and track arrangements, which are not locked by a construction. They can be modified or removed as streets and tracks built with the standard building tools by the player at a later time.

The example below demonstrates how a segment of street can be built without creating a construction:

function data()
return {
  type = "ASSET_DEFAULT",
 
  updateFn = function(params)
    local result = { }
 
    result.models = { } -- key 'models' is required, but MUST be empty
 
    result.edgeLists = {
      {
        type = "STREET",
        params = { type = "standard/town_small_new.lua" },
        edges = { { { -10, 0, 0}, { 10, 0, 0 } }, { { 10, 0, 0 }, { 10, 0, 0 } } },
        snapNodes = { 0, 1 },
        freeNodes = { 0, 1 }
      },
    }
 
    return result
  end
}
end

To build free streets and tracks it requires:

To “free” an edge, their nodes should be “free”. Free nodes are either snap nodes (defined in snapNodes) or nodes defined in freeNodes. They can be both at the same time.

It is allowed to “free” some nodes/edges of a regular construction. They wont be owned by the construction, thus if it gets removed, the “free” edges and their nodes remain.