modding:developerinfo:constructions

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

modding:developerinfo:constructions [2018/12/04 11:22]
chregu [Build free streets and tracks]
modding:developerinfo:constructions [2019/03/19 10:18]
Line 1: Line 1:
-===== Constructions ===== 
  
-The concept of constructions,​ introduced with Transport Fever, is very powerful. It allows to configure and create a lot of different building types and assets in just one format. This includes stations, depots, industries, town buildings and different kinds of assets. They are stored in ''​.con''​ files in the folder ''​res\construction\''​. 
- 
- 
-==== Overview ==== 
- 
-The format mainly consists of meta information and an update function. The construction is configured and created with the function. It can return different configurations of the construction depending on the input parameters. It could possibly return a different construction. 
- 
-<code lua> 
-function data() 
- 
-return { 
-  type = "​INDUSTRY",​ 
-  ​ 
-  -- other meta information 
- 
-  params = { },  -- parameters changeable by the player 
-  
-  -- update function, which adjusts the construction according the parameters 
-  updateFn = function(params) 
-    local result = { } 
- 
-    result.models = { { 
-      id = "​industry/​chemical_plant/​building_small.mdl",​ 
-      transf = transf.transl(vec3.new(20,​ -10 , 0))      
-    } } 
- 
-    -- terrain alignment, streets, tracks, stock lists, etc. 
- 
-    return result 
-  end 
-} 
-end 
-</​code>​ 
- 
-==== Reference ==== 
- 
-=== Meta-data === 
- 
-First, you have to specify the type of your construction. 
- 
-Available construction types 
-  * ''​STREET_STATION''​ 
-  * ''​RAIL_STATION''​ 
-  * ''​AIRPORT,​ HARBOR''​ 
-  * ''​STREET_STATION_CARGO''​ 
-  * ''​RAIL_STATION_CARGO''​ 
-  * ''​HARBOR_CARGO''​ 
-  * ''​STREET_DEPOT''​ 
-  * ''​RAIL_DEPOT''​ 
-  * ''​WATER_DEPOT''​ 
-  * ''​INDUSTRY''​ 
-  * ''​ASSET_DEFAULT''​ 
-  * ''​ASSET_TRACK''​ 
-  * ''​TOWN_BUILDING''​ 
- 
-The meta-data keys ''​description'',​ ''​availability''​ and ''​soundConfig''​ are specified the same way as for models. 
- 
-If you would like the player to be able to set some parameters to configure the construction,​ you have to use the ''​params''​ key. The following code shows how we could let the user specify the number of terminals of an airport: 
- 
-{{ :​construction:​construction_param.jpg}} 
- 
-<code lua> 
-params = { 
-  { 
-    key = "​numTerminalsIndex",​ 
-    name = _("​Number of terminals"​),​ 
-    values = { _("​1"​),​ _("​2"​),​ _("​3"​) } 
-  }, 
-} 
-</​code>​ 
- 
-Note: the key is used to get the result (index of the chosen value, starting with 0) from the ''​params''​ table, which is passed to the update function ''​updateFn''​. There it can be used to configure the construction:​ 
- 
-<code lua> 
-updateFn = function(params) 
-  local numTerminals = params.numTerminalsIndex + 1 
-  ​ 
-  -- do something with numTerminals 
-end 
-</​code>​ 
- 
-Further meta-data keys you can specify include: 
-  * ''​buildMode'':​ 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''​). ​ 
-  * ''​categories'':​ An optional list of categories, used to group constructions in the construction menu. 
-  * ''​order'': ​ Used to sort the constructions in the construction list. 
-  * ''​skipCollision'':​ Set to skip collisions when building the construction. 
-  * ''​autoRemovable'':​ Used to allow the construction to be removed, if it collides with something else. 
-  * ''​townBuildingParams'':​ Used for town building constructions. Please refer to the relevant construction files for more details. 
- 
-=== Update function === 
-In this function the construction is configured and specified. You can use the content of the table ''​params''​ to configure the construction. It also contains the selection of the user parameters you have specified in the meta-data. Everything is stored in a table and returned by the function. The structure of the result is explained in the following sections. 
- 
-=== Models === 
-The following code shows how a model is added to a construction:​ 
-<code lua> 
-result.models = { { 
-  id = "​industry/​chemical_plant/​building_small.mdl", ​  -- base-path: res/​models/​model/​ 
-  transf = transf.transl(vec3.new(20,​ -10 , 0))        -- x/y/z coordinates relative to construction center [m] 
-} } 
-</​code>​ 
-There is no limitation in the number of models a construction can contain and the order they were added does not matter. 
- 
-=== Edge Lists === 
-Edge lists are used to add streets and tracks to a construction. The following code adds a street segment and a track segment to the construction:​ 
- 
-<code lua> 
-result.edgeLists = { 
-  -- specify a street segment 
-  { 
-    type = "​STREET", ​                             -- or "​TRACK",​ see code below 
-    params = { 
-      type = "​country_new_small.lua", ​            -- see res/​config/​street/​ 
-      tramTrackType = "​YES" ​                      -- accepted values: "​NO",​ "​YES"​ and "​ELECTRIC"​ 
-    }, 
-    edges = { 
-      -- one entry refers to a position and a tangent 
-      { { .0, -79.0, ​ .0 },  { .0, 15.0, .0 } },  -- node 0 (snap node) 
-      { { .0, -64.0, ​ .0 },  { .0, 15.0, .0 } }   -- node 1 
-    }, 
-    snapNodes = { 0 }  -- node 0 is allowed to snap to other edges of the same type 
-  }, 
-  ​ 
-  -- specify a track segment 
-  { 
-    type = "​TRACK",​ 
-    params = { 
-      type = "​standard.lua", ​                    -- see res/​config/​track/​ 
-      catenary = true 
-    }, 
-    edges = { 
-      { { -19.1, .0, .0 }, { -20.0, .0, .0 } },  -- node 0  
-      { { -39.1, .0, .0 }, { -20.0, .0, .0 } },  -- node 1 (snap node) 
-    }, 
-    snapNodes = { 1 }  -- node 1 is allowed to snap to other edges of the same type 
-  } 
-} 
-</​code>​ 
- 
-=== Edge Objects === 
-Some game objects can be attached to edges, for example signals and way-points. This is also possible for edges contained by constructions,​ as showed in the following code sample: 
-<code lua> 
- 
--- we need some edges to attach edge objects to them 
-taxiway = { } 
- 
--- edge 0 
-taxiway[#​taxiway + 1] = { { 180.0, ​ 20.0,  .0 },  {    .0, -20.0, .0 } }  
-taxiway[#​taxiway + 1] = { { 180.0, ​  ​0.0, ​ .0 },  {    .0, -20.0, .0 } } 
- 
--- edge 1 
-taxiway[#​taxiway + 1] = { { 180.0, ​  ​0.0, ​ .0 },  {    .0, -47.1, .0 } } 
-taxiway[#​taxiway + 1] = { { 150.0, -30.0, ​ .0 },  { -47.1, ​  0.0, .0 } } 
- 
--- add taxi way to edge lists... 
- 
--- attach a signal to one of the above defined edges 
-result.edgeObjects = { 
-{ 
-  edge = 1,                                              -- attach object to edge 1 
-  param = .5,                                            -- param along the edge 
-  left = false, 
-  model = "​station/​airport/​asset/​signal_runway_old.mdl" ​ -- see res/​models/​model/​ 
-} 
-</​code>​ 
- 
-=== Terminal Groups === 
- 
-Please refer to the existing construction files for more details. 
- 
-=== Runways === 
-Runways are used by aircrafts (and ships) for arrival/​departure at an airport (or harbor/​shipyard). They are specified on the nodes/edges given by the edge lists. 
-<code lua> 
-local runway = { } 
- 
--- edge 0 
-runway[#​runway + 1] = { { -180.0, 20.0,  .0 },  {  20.0, .0, .0 } }  -- node 0    
-runway[#​runway + 1] = { { -160.0, 20.0,  .0 },  {  20.0, .0, .0 } }  -- node 1 
- 
--- edge 1 (runway edge) 
-runway[#​runway + 1] = { { -160.0, 20.0,  .0 },  { 320.0, .0, .0 } }  -- node2 (takeoff node) 
-runway[#​runway + 1] = { {  160.0, 20.0,  .0 },  { 320.0, .0, .0 } }  -- node3 (landing node) 
- 
--- edge 2 
-runway[#​runway + 1] = { {  160.0, 20.0,  .0 },  {  20.0, .0, .0 } }  -- node 4 
-runway[#​runway + 1] = { {  180.0, 20.0,  .0 },  {  20.0, .0, .0 } }  -- node 5 
- 
--- add runway to edge lists 
- 
-result.runways = { 
-  { 
-    type = "​LANDING", ​         -- or "​TAKEOFF"​ 
-    node = 3,                  -- node 3 is landing node 
-    edges = { 1 }              -- edge 1 is used for landing 
-  }, 
-  { 
-    type = "​TAKEOFF",​ 
-    node = 2, 
-    edges = { 1 } 
-  } 
-} 
-</​code>​ 
- 
-Note: an aircraft tries to land "in front" of the landing node. After passing it, it will taxi to the terminal. On departure, it will take off after passing the takeoff node. The landing/​takeoff direction is given by the tangent of the first/last taxi way edge. Same holds for ships. 
- 
-=== Stocks Lists === 
-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. 
-<code lua> 
-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, whether they are ordered/​shipped... 
--- ...and which edges are used for stock piling 
-result.stocks = { 
-  { cargoType = "​PLANKS", ​  type = "​RECEIVING", ​ edges = { { 0, 0 } }, 
-  { cargoType = "​STEEL", ​   type = "​RECEIVING", ​ edges = { { 1, 0 } }, 
-  { cargoType = "​PLASTIC", ​ type = "​RECEIVING", ​ edges = { { 2, 0 } }, 
-  { cargoType = "​MACHINES",​ type = "​SENDING", ​   edges = { { 3, 0 } }, 
-  { cargoType = "​TOOLS", ​   type = "​SENDING", ​   edges = { { 4, 0 } } 
-}, 
-</​code>​ 
-''​cargoType''​ can be any type defined in ''​base_config.lua''​. ''​type''​ can be either ''​RECEIVING''​ or ''​SENDING''​. ''​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, the second index to the particular edge in the edge list of that model. 
-== 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 the initial rule for the machine factory and it refers to the above example for the stock lists: 
- 
-<code lua> 
-result.stockRules = { 
-  { input = { { 2, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0 } }, output = { { 0, 0, 0, 0, 1 } }, capacity = 50 }, 
-  { input = { { 2, 1, 0, 0, 0 }, { 0, 1, 1, 0, 0 } }, output = { { 0, 0, 0, 1, 0 } }, capacity = 50 } 
-} 
-</​code>​ 
-The rules are applied independently and at most ''​capacity''​ time a year. Each entry of ''​input''​ or ''​output''​ 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. Further, at least one of the output configurations must be valid, which means that the produced item can be stored. 
- 
-For example, the first rule of the machine factory reads as follows: we need either two planks or one steel to produce one tool and we can produce at most 50 tools per year. 
- 
-== Examples == 
-There are constructions that only produce cargo items, but don't consume anything. For example, the coal mine.  
-<code lua> 
-result.stocks = { 
-  { cargoType = "​COAL",​ type = "​SENDING",​ edges = { ... } } 
-}, 
- 
-result.stockRules = { 
-  { input = { { 0 } }, output = { { 1 } }, capacity = 200 } 
-} 
-</​code>​ 
- 
-Or the farm, which can produce different items: 
- 
-<code lua> 
-result.stocks = { 
-  { cargoType = "​GRAIN",​ type = "​SENDING",​ edges = { ... } }, 
-  { cargoType = "​LIVESTOCK",​ type = "​SENDING",​ edges = { ... } } 
-}, 
- 
-result.stockRules = { 
-  { input = { { 0, 0 } }, output = { { 1, 0 }, { 0, 1 } }, capacity = 100 }  
-} 
-</​code>​ 
- 
-=== Terrain Alignment === 
-<code lua> 
-result.terrainAlignmentLists = { { 
-  type = "​EQUAL", ​              -- accepted values: "​EQUAL",​ "​LESS"​ and "​GREATER"​ 
-  faces = { { { -10, -10, 0 }, { 10, -10, 0 }, { 10, 10, 0 } } }, -- a list of polygons 
-  slopeLow = 0.3, 
-  slopeHigh = 0.6 
-} } 
-</​code>​ 
- 
-=== Ground Faces === 
-<code lua> 
-result.groundFaces = { {  ​ 
-  face = { { -10, -10, 0 }, { 10, -10, 0 }, { 10, 10, 0 } }, 
-  modes = { 
-    { 
-      type = "​FILL", ​           -- accepted values: "​FILL",​ "​STROKE",​ "​STROKE_INNER"​ and "​STROKE_OUTER"​ 
-      key = "​industry_floor" ​   -- ground texture, see res/​config/​ground_texture/​ 
-    } 
-  } 
-} } 
-</​code>​ 
- 
-=== Costs === 
-  * ''​cost''​ 
-  * ''​bulldozeCost''​ 
-  * ''​maintenanceCost''​ 
- 
-==== 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. 
- 
-The example below demonstrates how a segment of track can be built without creating a construction:​ 
- 
-<code lua> 
-function data() 
-return { 
-  type = "​ASSET_DEFAULT",​ 
- 
-  updateFn = function(params) 
-    local result = { } 
-  
-    result.models = { } -- key '​models'​ is required, but MUST be empty 
- 
-    result.edgeLists = { 
-      { 
-        type = "​TRACK",​ 
-        params = { type = "​standard.lua"​ }, 
-        edges = { { { -10, 0, 0}, { 10, 0, 0 } }, { { 10, 0, 0 }, { 10, 0, 0 } } }, 
-        snapNodes = { 0, 1 }, 
-        freeNodes = { 0, 1 } 
-      }, 
-    } 
-    ​ 
-    result.edgeObjects = { 
-      { 
-        edge = 0, 
-        param = .5, 
-        left = false, 
-        model = "​railroad/​signal_new_block.mdl"​ 
-      } 
-    } 
- 
-    return result 
-  end 
-} 
-end 
-</​code>​ 
- 
-To build free streets and tracks it requires: 
-  * the tag ''​models''​ should be set, but must be empty 
-  * only ''​edgeLists''​ and ''​edgeObjects''​ are allowed 
-  * all edges should be "​free"​ 
- 
-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. 
- 
-But on the other hand, 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. 
modding/developerinfo/constructions.txt · Last modified: 2019/03/19 10:18 (external edit)