Map exchange string format: Difference between revisions

From Official Factorio Wiki
Jump to navigation Jump to search
(Removed {{Languages}})
 
(40 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{Languages}}
This is a technical description of the map exchange string format, used to share map generating configurations with other users. This format is also used to store these settings inside save files for future chunk generation.


This is a technical description of the map exchange string format, used to share map generating configurations with other users.
Factorio line wraps the entire map exchange string after 57 characters during export (55 code characters + '\r\n', which is fairly standard), but ignores all whitespace during import. The outer layer of the map exchange string format includes three angle brackets on either side: ">>>" and "<<<", which must be present for Factorio to accept the string. Between those two tokens is the map exchange data, encoded using base 64 as defined by [https://tools.ietf.org/html/rfc4648#section-4 RFC 4648] (or [https://tools.ietf.org/html/rfc3548#section-3 3548], [https://tools.ietf.org/html/rfc2535#page-42 2535], [https://tools.ietf.org/html/rfc2045#section-6.8 2045], [https://tools.ietf.org/html/rfc1421#section-4.3.2.4 1421], et al).


Factorio line wraps the entire map exchange string after 55 characters during export, but ignores all whitespace during import. The outer layer of the map exchange string format includes three angle brackets on either side: ">>>" and "<<<", which must be present for Factorio to accept the string. Between those two tokens is the map exchange data, encoded using base 64 as defined by [https://tools.ietf.org/html/rfc4648#section-4 RFC 4648] (or [https://tools.ietf.org/html/rfc3548#section-3 3548], [https://tools.ietf.org/html/rfc2535#page-42 2535], [https://tools.ietf.org/html/rfc2045#section-6.8 2045], [https://tools.ietf.org/html/rfc1421#section-4.3.2.4 1421], et al).  
See the page on [[Data types|data types]] for an explanation of the different types of data used in this document.


This document will use the terms "int" to refer to 4 byte numbers and "short" to refer to 2 byte numbers. All numerical values are stored in unsigned [https://en.wikipedia.org/wiki/Endianness#Little-endian little-endian] format. "boolean" is a single byte that represents true if equal to 1, otherwise it is equal to false. "string"s are [https://en.wikipedia.org/wiki/String_(computer_science)#Length-prefixed Pascal-style int length prefixed strings]. The format described below is valid at least for Factorio 0.14.x, older versions may use a different encoding scheme.
== Factorio 0.16 and Beyond ==
 
Beginning with Factorio 0.16.0, two important changes are made to the encoding of the map exchange string data:
 
# The map exchange data inside the Base 64 encoding is further encoded using the [https://en.wikipedia.org/wiki/Zlib zlib] compression algorithm. The best way to determine the encoding is to first attempt to parse the map exchange string using zlib, and if that fails, try again using the 0.14+ rules.
# All numeric data fields longer than 1 byte are encoding using a custom-built variable length integer format described by Factorio developer [[User:Rseding91|Rseding]] at [[Data_types#Space_Optimized]]. For appropriate Factorio versions, '''all''' such data types (int, short, dict, etc) used in this document represent values encoded using this approach, ''unless otherwise specifically noted''.
 
After taking these considerations into your codec, proceed using the 0.14+ rules below.  


== Factorio 0.14 and Beyond ==
== Factorio 0.14 and Beyond ==
Line 14: Line 21:
! Type !! Description
! Type !! Description
|-
|-
| short[4]
| [[Data types#short|short]][4]
| The [[Version_String_Format|version string]] of Factorio that generated this string, used to determine encoding format.
| The [[Version_string_format|version string]] of Factorio that generated this string, used to determine encoding format. This field is never [[Data_types#Space_Optimized|space optimized]].
|-
|-
| byte[*]
| byte[*]
Line 23: Line 30:
| [[#0.15 Map Settings|0.15.x Map Settings]]. If present, this chunk consists of the remainder of the data (minus the checksum).
| [[#0.15 Map Settings|0.15.x Map Settings]]. If present, this chunk consists of the remainder of the data (minus the checksum).
|-
|-
| int
| [[Data types#uint|uint]]
| [https://en.wikipedia.org/wiki/Cyclic_redundancy_check CRC32 checksum] of all preceding data, as defined by ANSI X3.66 / FIPS 71 / ITU-T V.42 (the same one used by [https://en.wikipedia.org/wiki/Zlib zlib], ethernet, etc.)
| [https://en.wikipedia.org/wiki/Cyclic_redundancy_check CRC32 checksum] of all preceding data, as defined by ANSI X3.66 / FIPS 71 / ITU-T V.42 (the same one used by [https://en.wikipedia.org/wiki/Zlib zlib], ethernet, etc.)
|}
|}
Line 29: Line 36:
== Map Gen Settings ==
== Map Gen Settings ==


This format is very similar to, but not identical to, [http://lua-api.factorio.com/latest/Concepts.html#MapGenSettings MapGenSettings] - it is missing both the "terrain_segmentation" and "shift" fields.
This format matches [http://lua-api.factorio.com/latest/Concepts.html#MapGenSettings MapGenSettings].


For the purpose of the "autoplace_controls" field, a dictionary is an array-like structure, where the number of dictionary entries are encoded at the beginning of the dictionary as an integer (int). Following is a sequence of (key, value) pairs, with the specified data types - e.g. a dictionary[string, int] would consist of a sequence of (string, int) pairs.
The "From" column denotes the earliest Factorio version in which that field is present. Most of them are currently labeled as "≤0.14", which means the field was present from ''at least'' 0.14. If you have more specific information, please edit this page!


{| class="wikitable"
{| class="wikitable"
! Type !! LUA key !! Description
! Type !! LUA key !! From !! Description
|-
|-
| byte
| [[Data types#byte|byte]]
|
| terrain_segmentation
| ≤0.14
| [[Water]] [[#Map_Gen_Size|frequency]].
| [[Water]] [[#Map_Gen_Size|frequency]].
|-
|-
| byte
| [[Data types#byte|byte]]
| water
| water
| ≤0.14
| [[Water]] [[#Map_Gen_Size|size]].
| [[Water]] [[#Map_Gen_Size|size]].
|-
|-
| dict<string, [[#Autoplace_Control|byte[3]]]>
| [[Data types#dict|dict]]<[[Data types#string|string]], [[#Autoplace_Control|byte[3]]]>
| autoplace_controls
| autoplace_controls
| An dictionary of [[#Autoplace_Control|Autoplace Controls]], with string keys, where the key represents the ore name.  Factorio doesn’t care what order this dictionary is in, but it always alphabetizes during export. Vanilla has seven resources: [[Coal|coal]], [[Copper ore|copper-ore]], [[Crude Oil|crude-oil]], [[Enemies|enemy-base]], [[Iron ore|iron-ore]], [[Stone|stone]], and [[Uranium ore|uranium-ore]]. Unknown ores are ignored and missing ores are set to their defaults.
| ≤0.14
| An dictionary of [[#Autoplace_Control|Autoplace Controls]], with string keys, where the key represents the resource name.  Factorio doesn’t care what order this dictionary is in, but it always alphabetizes during export. Vanilla has seven resources: [[Coal|coal]], [[Copper ore|copper-ore]], [[Crude oil|crude-oil]], [[Enemies|enemy-base]], [[Iron ore|iron-ore]], [[Stone|stone]], and [[Uranium ore|uranium-ore]]. Unknown ores are ignored and missing ores are set to their defaults.
Factorio 0.16.x adds addition terrain related autoplace features: desert, dirt, grass, sand, trees. With the exception of trees, these resources ignore their richness and as such are not configuration using the map gen GUI, and always have a richness value of 3 ("Regular").
|-
| [[Data types#byte|byte]][2]
| TODO
| 0.16.0
| TODO...
|-
|-
| int
| [[Data types#int|uint]]
| seed
| seed
| [[World generator#Map Seed|Map seed]].
| ≤0.14
| [[Map generator#Manual_configuration|Map seed]]. This field is never [[Data_types#Space_Optimized|space optimized]].
|-
| ''none''
| shift
| ≤0.14
| This field isn't present in the binary format! But it is part of the Lua structure - by default it's derived from the map seed. I'll slap the algorithm here soon(tm).
|-
|-
| int
| [[Data types#int|uint]]
| width
| width
| [[World generator#Map-width and -height|Map width]].
| ≤0.14
| [[Map generator#Advanced|Map width]]. This field is never [[Data_types#Space_Optimized|space optimized]].
|-
|-
| int
| [[Data types#int|uint]]
| height
| height
| [[World generator#Map-width and -height|Map height]].
| ≤0.14
| [[Map generator#Advanced|Map height]]. This field is never [[Data_types#Space_Optimized|space optimized]].
|-
|-
| byte
| [[Data types#byte|byte]]
| starting_area
| starting_area
| [[World generator#Starting area|Starting area]] [[#Map_Gen_Size|size]].
| ≤0.14
| [[Map generator#Enemy|Starting area]] [[#Map_Gen_Size|size]].
|-
|-
| boolean
| [[Data types#bool|boolean]]
| peaceful_mode
| peaceful_mode
| [[World generator#Peaceful mode|Peaceful mode]]. Enabled if set to 1, disabled otherwise.
| ≤0.14
| [[Map generator#Enemy|Peaceful mode]]. Enabled if set to 1, disabled otherwise.
|}
|}


== 0.15 Map Settings ==
== 0.15 Map Settings ==


All of the following data fields (until noted at the end) have a special encapsulation format. Preceding each value is a single byte that states whether or not the value is present. If the byte is equal to zero, then the field value is not present. Otherwise, then the field's value follows. In this section, the data type "double" refers to the [https://en.wikipedia.org/wiki/Double-precision_floating-point_format 64-bit floating point format described by IEEE 754].
All of the following data fields (until noted at the end) have a special encapsulation format. Preceding each value is a single byte that states whether or not the value is present. If the byte is equal to zero, then the field value is not present. Otherwise, then the field's value follows.  


In the LUA structure, this information is stored in the "[http://lua-api.factorio.com/latest/LuaGameScript.html#LuaGameScript.map_settings game.map_settings]" table, which is created by the "[http://lua-api.factorio.com/latest/Concepts.html#MapSettings MapSettings]" prototype. Each section in the table below represents a nested sub-table in "map-settings", where the LUA key listed is the key of the table, and all subsequent fields are part of the sub-table. See data/base/prototypes/map-settings.lua for a description of all attributes (some of that information has now been copied to this page).
In the LUA structure, this information is stored in the "[http://lua-api.factorio.com/latest/LuaGameScript.html#LuaGameScript.map_settings game.map_settings]" table, which is created by the "[http://lua-api.factorio.com/latest/Concepts.html#MapSettings MapSettings]" prototype. Each section in the table below represents a nested sub-table in "map-settings", where the LUA key listed is the key of the table, and all subsequent fields are part of the sub-table. See data/base/prototypes/map-settings.lua for a description of all attributes (some of that information has now been copied to this page).


Fields marked with a check (✓) in the "GUI" column are configurable in the [[World_generator#How_it_works|new game map generator GUI]].
Fields marked with a check (✓) in the "GUI" column are configurable in the [[Map generator#Manual configuration|new game map generator GUI]].


{| class="wikitable mw-collapsible mw-collapsed"
{| class="wikitable mw-collapsible mw-collapsed"
Line 82: Line 108:
! * !! ✓ !! pollution !! Pollution
! * !! ✓ !! pollution !! Pollution
|-
|-
| boolean || ✓ || enabled || Pollution enabled.
| [[Data types#bool|boolean]] || ✓ || enabled || Pollution enabled.
|-  
|-  
| double || ✓ || diffusion_ratio || The amount of pollution that is diffused into neighboring chunk per second.
| [[Data types#double|double]] || ✓ || diffusion_ratio || The amount of pollution that is diffused into neighboring chunk per second.
|-  
|-  
| double || || min_to_diffuse || This many PUs must be on the chunk to start diffusing.
| [[Data types#double|double]] || || min_to_diffuse || This many PUs must be on the chunk to start diffusing.
|-
|-
| double || ✓ || ageing || [Modifier of] the pollution eaten by a chunks tiles.
| [[Data types#double|double]] || ✓ || ageing || [Modifier of] the pollution eaten by a chunks tiles.
|-  
|-  
| double || || expected_max_per_chunk || Anything bigger than this is visualised as this value.
| [[Data types#double|double]] || || expected_max_per_chunk || Anything bigger than this is visualised as this value.
|-  
|-  
| double || || min_to_show_per_chunk || Anything lower than this (but > 0) is visualised as this value.
| [[Data types#double|double]] || || min_to_show_per_chunk || Anything lower than this (but > 0) is visualised as this value.
|-
|-
| double || ✓ || min_pollution_to_damage_trees || Any pollution above this amount starts to damage trees.
| [[Data types#double|double]] || ✓ || min_pollution_to_damage_trees || Any pollution above this amount starts to damage trees.
|-  
|-  
| double || || pollution_with_max_forest_damage || ???
| [[Data types#double|double]] || || pollution_with_max_forest_damage || ???
|-  
|-  
| double || || pollution_per_tree_damage || ???
| [[Data types#double|double]] || || pollution_per_tree_damage || ???
|-  
|-  
| double || ✓ || pollution_restored_per_tree_damage || The amount of pollution absorbed by a tree when it is damaged by pollution.
| [[Data types#double|double]] || ✓ || pollution_restored_per_tree_damage || The amount of pollution absorbed by a tree when it is damaged by pollution.
|-  
|-  
| double || || max_pollution_to_restore_trees || ???
| [[Data types#double|double]] || || max_pollution_to_restore_trees || ???
|-
|-
! * !! !! steering.default !! Steering (Default)
! * !! !! steering.default !! Steering (Default)
|-  
|-  
| double || || ??? || ???
| [[Data types#double|double]] || || ??? || ???
|-  
|-  
| double || || ??? || ???
| [[Data types#double|double]] || || ??? || ???
|-  
|-  
| double || || separation_force || ???
| [[Data types#double|double]] || || separation_force || ???
|-  
|-  
| boolean || || force_unit_fuzzy_goto_behavior || ???
| [[Data types#bool|boolean]] || || force_unit_fuzzy_goto_behavior || ???
|-
|-
! * !! !! steering.moving !! Steering (Moving)
! * !! !! steering.moving !! Steering (Moving)
|-  
|-  
| double || || ??? || ???
| [[Data types#double|double]] || || ??? || ???
|-  
|-  
| double || || ??? || ???
| [[Data types#double|double]] || || ??? || ???
|-  
|-  
| double || || separation_force || ???
| [[Data types#double|double]] || || separation_force || ???
|-  
|-  
| boolean || || force_unit_fuzzy_goto_behavior || ???
| [[Data types#bool|boolean]] || || force_unit_fuzzy_goto_behavior || ???
|-  
|-  
! * !! ✓ !! enemy_evolution !! Evolution
! * !! ✓ !! enemy_evolution !! Evolution
|-  
|-  
| boolean || ✓ || enabled || Evolution enabled.
| [[Data types#bool|boolean]] || ✓ || enabled || Evolution enabled.
|-  
|-  
| double || ✓ || time_factor || Percent increase in the evolve factor for every second.
| [[Data types#double|double]] || ✓ || time_factor || Percent increase in the evolve factor for every second.
|-  
|-  
| double || ✓ || destroy_factor || Percent increase in the evolve factor for every destroyed spawner.
| [[Data types#double|double]] || ✓ || destroy_factor || Percent increase in the evolve factor for every destroyed spawner.
|-  
|-  
| double || ✓ || pollution_factor || Percent increase in the evolve factor for every 1000 PU [produced].
| [[Data types#double|double]] || ✓ || pollution_factor || Percent increase in the evolve factor for every 1000 PU [produced].
|-  
|-  
! * !! ✓ !! enemy_expansion !! Enemy Expansion
! * !! ✓ !! enemy_expansion !! Enemy Expansion
|-
|-
| boolean || ✓ || enabled || Enemy expansion enabled.
| [[Data types#bool|boolean]] || ✓ || enabled || Enemy expansion enabled.
|-
|-
| int || ✓ || max_expansion_distance || Distance in chunks from the furthest base around.
| [[Data types#int|int]] || ✓ || max_expansion_distance || Distance in chunks from the furthest base around.
|-
|-
| int || || friendly_base_influence_radius || ???
| [[Data types#int|int]] || || friendly_base_influence_radius || ???
|-
|-
| int || || enemy_building_influence_radius || ???
| [[Data types#int|int]] || || enemy_building_influence_radius || ???
|-
|-
| double || || building_coefficient ||+ rowspan=4 | Expansion algorithm. See LUA file for details.
| [[Data types#double|double]] || || building_coefficient ||+ rowspan=4 | Expansion algorithm. See LUA file for details.
|-
|-
| double || || other_base_coefficient  
| [[Data types#double|double]] || || other_base_coefficient  
|-
|-
| double || || neighbouring_chunk_coefficient  
| [[Data types#double|double]] || || neighbouring_chunk_coefficient  
|-
|-
| double || || neighbouring_base_chunk_coefficient
| [[Data types#double|double]] || || neighbouring_base_chunk_coefficient
|-
|-
| double || || max_colliding_tiles_coefficient || A chunk has to have at most this much percent unbuildable tiles for it to be considered a candidate.
| [[Data types#double|double]] || || max_colliding_tiles_coefficient || A chunk has to have at most this much percent unbuildable tiles for it to be considered a candidate.
|-
|-
| int || ✓ || settler_group_min_size ||+ rowspan=2 | Size of the group that goes to build new base (in game this is multiplied by the evolution factor).
| [[Data types#int|int]] || ✓ || settler_group_min_size ||+ rowspan=2 | Size of the group that goes to build new base (in game this is multiplied by the evolution factor).
|-
|-
| int || ✓ || settler_group_max_size
| [[Data types#int|int]] || ✓ || settler_group_max_size
|-
|-
| int || ✓ || min_expansion_cooldown || Minimum cooldown.
| [[Data types#int|int]] || ✓ || min_expansion_cooldown || Minimum cooldown.
|-
|-
| int || ✓ || max_expansion_cooldown || Maximum cooldown.
| [[Data types#int|int]] || ✓ || max_expansion_cooldown || Maximum cooldown.
|-  
|-  
! * !! !! unit_group !! Unit Group
! * !! !! unit_group !! Unit Group
|-
|-
| int || || min_group_gathering_time ||+ rowspan=2 | A pollution triggered group's waiting time is a random time between min and max gathering time.
| [[Data types#int|int]] || || min_group_gathering_time ||+ rowspan=2 | A pollution triggered group's waiting time is a random time between min and max gathering time.
|-
|-
| int || || max_group_gathering_time  
| [[Data types#int|int]] || || max_group_gathering_time  
|-
|-
| int || || max_wait_time_for_late_members || After the gathering is finished the group can still wait for late members, but it doesn't accept new ones anymore.
| [[Data types#int|int]] || || max_wait_time_for_late_members || After the gathering is finished the group can still wait for late members, but it doesn't accept new ones anymore.
|-
|-
| double || || max_group_radius ||+ rowspan=2 | Limits for group radius.
| [[Data types#double|double]] || || max_group_radius ||+ rowspan=2 | Limits for group radius.
|-
|-
| double || || min_group_radius
| [[Data types#double|double]] || || min_group_radius
|-
|-
| double || || max_member_speedup_when_behind || When a member falls behind the group he can speedup up till this much of his regular speed.
| [[Data types#double|double]] || || max_member_speedup_when_behind || When a member falls behind the group he can speedup up till this much of his regular speed.
|-
|-
| double || || max_member_slowdown_when_ahead || When a member gets ahead of its group, it will slow down to at most this factor of its speed.
| [[Data types#double|double]] || || max_member_slowdown_when_ahead || When a member gets ahead of its group, it will slow down to at most this factor of its speed.
|-
|-
| double || || max_group_slowdown_factor || When members of a group are behind, the entire group will slow down to at most this factor of its max speed.
| [[Data types#double|double]] || || max_group_slowdown_factor || When members of a group are behind, the entire group will slow down to at most this factor of its max speed.
|-
|-
| double || || max_group_member_fallback_factor || If a member falls behind more than this times the group radius, the group will slow down to max_group_slowdown_factor.
| [[Data types#double|double]] || || max_group_member_fallback_factor || If a member falls behind more than this times the group radius, the group will slow down to max_group_slowdown_factor.
|-
|-
| double || || member_disown_distance || If a member falls behind more than this time the group radius, it will be removed from the group.
| [[Data types#double|double]] || || member_disown_distance || If a member falls behind more than this time the group radius, it will be removed from the group.
|-
|-
| int || || tick_tolerance_when_member_arrives || ???
| [[Data types#int|int]] || || tick_tolerance_when_member_arrives || ???
|-
|-
| int || || max_gathering_unit_groups || Maximum number of automatically created unit groups gathering for attack at any time.
| [[Data types#int|int]] || || max_gathering_unit_groups || Maximum number of automatically created unit groups gathering for attack at any time.
|-
|-
| int || || max_unit_group_size || Maximum size of an attack unit group. This only affects automatically-created unit groups.
| [[Data types#int|int]] || || max_unit_group_size || Maximum size of an attack unit group. This only affects automatically-created unit groups.
|-  
|-  
! * !! !! path_finder !! Path Finder
! * !! !! path_finder !! Path Finder
|-
|-
| int || || fwd2bwd_ratio || Defines whether we prefer forward (>1) or backward (<-1) or symmetrical (1) search.
| [[Data types#uint|uint]] || || fwd2bwd_ratio || The pathfinder performs a step of the backward search every fwd2bwd_ratio'th step. The minimum allowed value is 2, which means symmetric search.
|-
|-
| double || || goal_pressure_ratio || When comparing nodes in open which one to check next, heuristic value is multiplied by this ratio. The higher the number the more is the search directed directly towards the goal.
| [[Data types#double|double]] || || goal_pressure_ratio || When comparing nodes in open which one to check next, heuristic value is multiplied by this ratio. The higher the number the more is the search directed directly towards the goal.
|-
|-
| bool || || use_path_cache || ???
| [[Data types#bool|boolean]] || || use_path_cache || ???
|-
|-
| double || || max_steps_worked_per_tick || When this is exhausted no more requests are allowed. At the moment the first path to exhaust this will be finished (even if it is hundreds of steps).
| [[Data types#double|double]] || || max_steps_worked_per_tick || When this is exhausted no more requests are allowed. At the moment the first path to exhaust this will be finished (even if it is hundreds of steps).
|-
|-
| int || || short_cache_size ||+ rowspan=2 | Number of elements in the cache.
| [[Data types#int|int]] || || short_cache_size ||+ rowspan=2 | Number of elements in the cache.
|-
|-
| int || || long_cache_size
| [[Data types#int|int]] || || long_cache_size
|-
|-
| double || || short_cache_min_cacheable_distance || Minimal distance to goal for path to be searched in short path cache.
| [[Data types#double|double]] || || short_cache_min_cacheable_distance || Minimal distance to goal for path to be searched in short path cache.
|-
|-
| int || || short_cache_min_algo_steps_to_cache || Minimal number of algorithm steps for path to be inserted into the short path cache.
| [[Data types#int|int]] || || short_cache_min_algo_steps_to_cache || Minimal number of algorithm steps for path to be inserted into the short path cache.
|-
|-
| double || || long_cache_min_cacheable_distance || Minimal distance to goal for path to be searched in long path cache.
| [[Data types#double|double]] || || long_cache_min_cacheable_distance || Minimal distance to goal for path to be searched in long path cache.
|-
|-
| int || || cache_max_connect_to_cache_steps_multiplier || When searching for connection to path cache path, search at most for this number of steps times the initial estimate.
| [[Data types#int|int]] || || cache_max_connect_to_cache_steps_multiplier || When searching for connection to path cache path, search at most for this number of steps times the initial estimate.
|-
|-
| double || || cache_accept_path_start_distance_ratio || When looking for path from cache make sure it doesn't start too far from requested start in relative distance terms.
| [[Data types#double|double]] || || cache_accept_path_start_distance_ratio || When looking for path from cache make sure it doesn't start too far from requested start in relative distance terms.
|-
|-
| double || || cache_accept_path_end_distance_ratio || When looking for path from cache make sure it doesn't end too far from requested end. This is typically higher than accept value for the start because the end target can be moving.
| [[Data types#double|double]] || || cache_accept_path_end_distance_ratio || When looking for path from cache make sure it doesn't end too far from requested end. This is typically higher than accept value for the start because the end target can be moving.
|-
|-
| double || || negative_cache_accept_path_start_distance_ratio || Same as cache_accept_path_start_distance_ratio, but used for negative cache queries.
| [[Data types#double|double]] || || negative_cache_accept_path_start_distance_ratio || Same as cache_accept_path_start_distance_ratio, but used for negative cache queries.
|-
|-
| double || || negative_cache_accept_path_end_distance_ratio || Same as cache_accept_path_end_distance_ratio, but used for negative cache queries.
| [[Data types#double|double]] || || negative_cache_accept_path_end_distance_ratio || Same as cache_accept_path_end_distance_ratio, but used for negative cache queries.
|-
|-
| double || || cache_path_start_distance_rating_multiplier || When assigning rating to the best path this * start distances is considered.
| [[Data types#double|double]] || || cache_path_start_distance_rating_multiplier || When assigning rating to the best path this * start distances is considered.
|-
|-
| double || || cache_path_end_distance_rating_multiplier || When assigning rating to the best path this * end distances is considered. This is typically higher than value for the start to achieve better path end quality.
| [[Data types#double|double]] || || cache_path_end_distance_rating_multiplier || When assigning rating to the best path this * end distances is considered. This is typically higher than value for the start to achieve better path end quality.
|-
|-
| double || || stale_enemy_with_same_destination_collision_penalty || Somewhere along the path is stuck enemy we need to avoid. This is mainly to handle situations when units have arrived and are attacking the target, then units further in the back will use this and run around the target.
| [[Data types#double|double]] || || stale_enemy_with_same_destination_collision_penalty || Somewhere along the path is stuck enemy we need to avoid. This is mainly to handle situations when units have arrived and are attacking the target, then units further in the back will use this and run around the target.
|-
|-
| double || || ignore_moving_enemy_collision_distance || If there is a moving unit further than this we don't really care.
| [[Data types#double|double]] || || ignore_moving_enemy_collision_distance || If there is a moving unit further than this we don't really care.
|-
|-
| double || || enemy_with_different_destination_collision_penalty || Enemy is not moving/or is too close and has different destination.
| [[Data types#double|double]] || || enemy_with_different_destination_collision_penalty || Enemy is not moving/or is too close and has different destination.
|-
|-
| double || || general_entity_collision_penalty || Simplification for now - collision with everything else is this.
| [[Data types#double|double]] || || general_entity_collision_penalty || Simplification for now - collision with everything else is this.
|-
|-
| double || || general_entity_subsequent_collision_penalty || Collision penalty for successors of positions that require destroy to reach.
| [[Data types#double|double]] || || general_entity_subsequent_collision_penalty || Collision penalty for successors of positions that require destroy to reach.
|-
|-
| int || || max_clients_to_accept_any_new_request || Uptil this amount any client will be served by the path finder (no estimate on the path length).
| [[Data types#int|int]] || || max_clients_to_accept_any_new_request || Uptil this amount any client will be served by the path finder (no estimate on the path length).
|-
|-
| int || || max_clients_to_accept_short_new_request || From max_clients_to_accept_any_new_request till this one only those that have a short estimate will be served.
| [[Data types#int|int]] || || max_clients_to_accept_short_new_request || From max_clients_to_accept_any_new_request till this one only those that have a short estimate will be served.
|-
|-
| int || || direct_distance_to_consider_short_request || This is the "threshold" to decide what is short and what is not.
| [[Data types#int|int]] || || direct_distance_to_consider_short_request || This is the "threshold" to decide what is short and what is not.
|-
|-
| int || || short_request_max_steps || If a short request takes more than this many steps, it will be rescheduled as a long request.
| [[Data types#int|int]] || || short_request_max_steps || If a short request takes more than this many steps, it will be rescheduled as a long request.
|-
|-
| double || || short_request_ratio || How many steps will be allocated to short requests each tick, as a ratio of all available steps per tick.
| [[Data types#double|double]] || || short_request_ratio || How many steps will be allocated to short requests each tick, as a ratio of all available steps per tick.
|-
|-
| int || || min_steps_to_check_path_find_termination || Absolute minimum of steps that will be performed for every path find request no matter what.
| [[Data types#int|int]] || || min_steps_to_check_path_find_termination || Absolute minimum of steps that will be performed for every path find request no matter what.
|-
|-
| double || || start_to_goal_cost_multiplier_to_terminate_path_find || If the amount of steps is higher than this times estimate of start to goal then path finding is terminated.
| [[Data types#double|double]] || || start_to_goal_cost_multiplier_to_terminate_path_find || If the amount of steps is higher than this times estimate of start to goal then path finding is terminated.
|-
|-
| colspan = 4 | '''Note:''' The following fields do not use the special encapsulation method.
| colspan = 4 | '''Note:''' The following fields do not use the special encapsulation method.
Line 252: Line 278:
! byte[4] !! !! . (root) !! Other
! byte[4] !! !! . (root) !! Other
|-
|-
| int || || max_failed_behavior_count || If a behavior fails this many times, the enemy (or enemy group) is destroyed. This solves biters stuck within their own base.
| [[Data types#int|int]] || || max_failed_behavior_count || If a behavior fails this many times, the enemy (or enemy group) is destroyed. This solves biters stuck within their own base.
|-
|-
! Type !!+ style='writing-mode:vertical-lr;vertical-align:bottom;font-size:90%' | GUI !! LUA key !! Description
! Type !!+ style='writing-mode:vertical-lr;vertical-align:bottom;font-size:90%' | GUI !! LUA key !! Description
Line 266: Line 292:
! byte[10] !! ✓ !! difficulty_settings !! Difficulty Settings
! byte[10] !! ✓ !! difficulty_settings !! Difficulty Settings
|-
|-
| byte || ✓ || recipe_difficulty || Recipe difficulty. 0 for Normal, 1 for Expensive.
| [[Data types#byte|byte]] || ✓ || recipe_difficulty || Recipe difficulty. 0 for Normal, 1 for Expensive.
|-
|-
| byte || ✓ || technology_difficulty || Technology difficulty. 0 for Normal, 1 for Expensive.
| [[Data types#byte|byte]] || ✓ || technology_difficulty || Technology difficulty. 0 for Normal, 1 for Expensive.
|-
|-
| double || ✓ || technology_price_multiplier || Technology price multiplier.
| [[Data types#double|double]] || ✓ || technology_price_multiplier || Technology price multiplier.
|-
|-
|}
|}
Line 277: Line 303:


== Autoplace Control ==
== Autoplace Control ==
See the page on [[World generator#Settings on the top row|world generation]] for more information on frequency, size, and richness.
See the page on [[Map generator#Resources|map generation]] for more information on frequency, size, and richness.
{| class="wikitable"
{| class="wikitable"
| byte
! Type !! LUA key !! Description
|-
| [[Data types#byte|byte]]
| frequency
| Ore [[#Map_Gen_Size|frequency]].
| Ore [[#Map_Gen_Size|frequency]].
|-
|-
| byte
| [[Data types#byte|byte]]
| size
| Ore [[#Map_Gen_Size|size]].
| Ore [[#Map_Gen_Size|size]].
|-
|-
| byte
| [[Data types#byte|byte]]
| richness
| Ore [[#Map_Gen_Size|richness]].
| Ore [[#Map_Gen_Size|richness]].
|}
|}
Line 311: Line 342:
|}
|}


Each of the values in a triplet (such as "low", "small", and "poor") are synonymous.  
Each of the values in a triplet (such as "low", "small", and "poor") are synonymous.


[[Category:Technical]]
[[Category:Technical]]

Latest revision as of 09:06, 12 November 2023

This is a technical description of the map exchange string format, used to share map generating configurations with other users. This format is also used to store these settings inside save files for future chunk generation.

Factorio line wraps the entire map exchange string after 57 characters during export (55 code characters + '\r\n', which is fairly standard), but ignores all whitespace during import. The outer layer of the map exchange string format includes three angle brackets on either side: ">>>" and "<<<", which must be present for Factorio to accept the string. Between those two tokens is the map exchange data, encoded using base 64 as defined by RFC 4648 (or 3548, 2535, 2045, 1421, et al).

See the page on data types for an explanation of the different types of data used in this document.

Factorio 0.16 and Beyond

Beginning with Factorio 0.16.0, two important changes are made to the encoding of the map exchange string data:

  1. The map exchange data inside the Base 64 encoding is further encoded using the zlib compression algorithm. The best way to determine the encoding is to first attempt to parse the map exchange string using zlib, and if that fails, try again using the 0.14+ rules.
  2. All numeric data fields longer than 1 byte are encoding using a custom-built variable length integer format described by Factorio developer Rseding at Data_types#Space_Optimized. For appropriate Factorio versions, all such data types (int, short, dict, etc) used in this document represent values encoded using this approach, unless otherwise specifically noted.

After taking these considerations into your codec, proceed using the 0.14+ rules below.

Factorio 0.14 and Beyond

This is the base map exchange string format for all Factorio versions 0.14.x and greater.

Type Description
short[4] The version string of Factorio that generated this string, used to determine encoding format. This field is never space optimized.
byte[*] Map Gen Settings. Variable length. See linked section for information on how to parse.
byte[*] 0.15.x Map Settings. If present, this chunk consists of the remainder of the data (minus the checksum).
uint CRC32 checksum of all preceding data, as defined by ANSI X3.66 / FIPS 71 / ITU-T V.42 (the same one used by zlib, ethernet, etc.)

Map Gen Settings

This format matches MapGenSettings.

The "From" column denotes the earliest Factorio version in which that field is present. Most of them are currently labeled as "≤0.14", which means the field was present from at least 0.14. If you have more specific information, please edit this page!

Type LUA key From Description
byte terrain_segmentation ≤0.14 Water frequency.
byte water ≤0.14 Water size.
dict<string, byte[3]> autoplace_controls ≤0.14 An dictionary of Autoplace Controls, with string keys, where the key represents the resource name. Factorio doesn’t care what order this dictionary is in, but it always alphabetizes during export. Vanilla has seven resources: coal, copper-ore, crude-oil, enemy-base, iron-ore, stone, and uranium-ore. Unknown ores are ignored and missing ores are set to their defaults.

Factorio 0.16.x adds addition terrain related autoplace features: desert, dirt, grass, sand, trees. With the exception of trees, these resources ignore their richness and as such are not configuration using the map gen GUI, and always have a richness value of 3 ("Regular").

byte[2] TODO 0.16.0 TODO...
uint seed ≤0.14 Map seed. This field is never space optimized.
none shift ≤0.14 This field isn't present in the binary format! But it is part of the Lua structure - by default it's derived from the map seed. I'll slap the algorithm here soon(tm).
uint width ≤0.14 Map width. This field is never space optimized.
uint height ≤0.14 Map height. This field is never space optimized.
byte starting_area ≤0.14 Starting area size.
boolean peaceful_mode ≤0.14 Peaceful mode. Enabled if set to 1, disabled otherwise.

0.15 Map Settings

All of the following data fields (until noted at the end) have a special encapsulation format. Preceding each value is a single byte that states whether or not the value is present. If the byte is equal to zero, then the field value is not present. Otherwise, then the field's value follows.

In the LUA structure, this information is stored in the "game.map_settings" table, which is created by the "MapSettings" prototype. Each section in the table below represents a nested sub-table in "map-settings", where the LUA key listed is the key of the table, and all subsequent fields are part of the sub-table. See data/base/prototypes/map-settings.lua for a description of all attributes (some of that information has now been copied to this page).

Fields marked with a check (✓) in the "GUI" column are configurable in the new game map generator GUI.

Type GUI LUA key Description
* pollution Pollution
boolean enabled Pollution enabled.
double diffusion_ratio The amount of pollution that is diffused into neighboring chunk per second.
double min_to_diffuse This many PUs must be on the chunk to start diffusing.
double ageing [Modifier of] the pollution eaten by a chunks tiles.
double expected_max_per_chunk Anything bigger than this is visualised as this value.
double min_to_show_per_chunk Anything lower than this (but > 0) is visualised as this value.
double min_pollution_to_damage_trees Any pollution above this amount starts to damage trees.
double pollution_with_max_forest_damage ???
double pollution_per_tree_damage ???
double pollution_restored_per_tree_damage The amount of pollution absorbed by a tree when it is damaged by pollution.
double max_pollution_to_restore_trees ???
* steering.default Steering (Default)
double ??? ???
double ??? ???
double separation_force ???
boolean force_unit_fuzzy_goto_behavior ???
* steering.moving Steering (Moving)
double ??? ???
double ??? ???
double separation_force ???
boolean force_unit_fuzzy_goto_behavior ???
* enemy_evolution Evolution
boolean enabled Evolution enabled.
double time_factor Percent increase in the evolve factor for every second.
double destroy_factor Percent increase in the evolve factor for every destroyed spawner.
double pollution_factor Percent increase in the evolve factor for every 1000 PU [produced].
* enemy_expansion Enemy Expansion
boolean enabled Enemy expansion enabled.
int max_expansion_distance Distance in chunks from the furthest base around.
int friendly_base_influence_radius ???
int enemy_building_influence_radius ???
double building_coefficient Expansion algorithm. See LUA file for details.
double other_base_coefficient
double neighbouring_chunk_coefficient
double neighbouring_base_chunk_coefficient
double max_colliding_tiles_coefficient A chunk has to have at most this much percent unbuildable tiles for it to be considered a candidate.
int settler_group_min_size Size of the group that goes to build new base (in game this is multiplied by the evolution factor).
int settler_group_max_size
int min_expansion_cooldown Minimum cooldown.
int max_expansion_cooldown Maximum cooldown.
* unit_group Unit Group
int min_group_gathering_time A pollution triggered group's waiting time is a random time between min and max gathering time.
int max_group_gathering_time
int max_wait_time_for_late_members After the gathering is finished the group can still wait for late members, but it doesn't accept new ones anymore.
double max_group_radius Limits for group radius.
double min_group_radius
double max_member_speedup_when_behind When a member falls behind the group he can speedup up till this much of his regular speed.
double max_member_slowdown_when_ahead When a member gets ahead of its group, it will slow down to at most this factor of its speed.
double max_group_slowdown_factor When members of a group are behind, the entire group will slow down to at most this factor of its max speed.
double max_group_member_fallback_factor If a member falls behind more than this times the group radius, the group will slow down to max_group_slowdown_factor.
double member_disown_distance If a member falls behind more than this time the group radius, it will be removed from the group.
int tick_tolerance_when_member_arrives ???
int max_gathering_unit_groups Maximum number of automatically created unit groups gathering for attack at any time.
int max_unit_group_size Maximum size of an attack unit group. This only affects automatically-created unit groups.
* path_finder Path Finder
uint fwd2bwd_ratio The pathfinder performs a step of the backward search every fwd2bwd_ratio'th step. The minimum allowed value is 2, which means symmetric search.
double goal_pressure_ratio When comparing nodes in open which one to check next, heuristic value is multiplied by this ratio. The higher the number the more is the search directed directly towards the goal.
boolean use_path_cache ???
double max_steps_worked_per_tick When this is exhausted no more requests are allowed. At the moment the first path to exhaust this will be finished (even if it is hundreds of steps).
int short_cache_size Number of elements in the cache.
int long_cache_size
double short_cache_min_cacheable_distance Minimal distance to goal for path to be searched in short path cache.
int short_cache_min_algo_steps_to_cache Minimal number of algorithm steps for path to be inserted into the short path cache.
double long_cache_min_cacheable_distance Minimal distance to goal for path to be searched in long path cache.
int cache_max_connect_to_cache_steps_multiplier When searching for connection to path cache path, search at most for this number of steps times the initial estimate.
double cache_accept_path_start_distance_ratio When looking for path from cache make sure it doesn't start too far from requested start in relative distance terms.
double cache_accept_path_end_distance_ratio When looking for path from cache make sure it doesn't end too far from requested end. This is typically higher than accept value for the start because the end target can be moving.
double negative_cache_accept_path_start_distance_ratio Same as cache_accept_path_start_distance_ratio, but used for negative cache queries.
double negative_cache_accept_path_end_distance_ratio Same as cache_accept_path_end_distance_ratio, but used for negative cache queries.
double cache_path_start_distance_rating_multiplier When assigning rating to the best path this * start distances is considered.
double cache_path_end_distance_rating_multiplier When assigning rating to the best path this * end distances is considered. This is typically higher than value for the start to achieve better path end quality.
double stale_enemy_with_same_destination_collision_penalty Somewhere along the path is stuck enemy we need to avoid. This is mainly to handle situations when units have arrived and are attacking the target, then units further in the back will use this and run around the target.
double ignore_moving_enemy_collision_distance If there is a moving unit further than this we don't really care.
double enemy_with_different_destination_collision_penalty Enemy is not moving/or is too close and has different destination.
double general_entity_collision_penalty Simplification for now - collision with everything else is this.
double general_entity_subsequent_collision_penalty Collision penalty for successors of positions that require destroy to reach.
int max_clients_to_accept_any_new_request Uptil this amount any client will be served by the path finder (no estimate on the path length).
int max_clients_to_accept_short_new_request From max_clients_to_accept_any_new_request till this one only those that have a short estimate will be served.
int direct_distance_to_consider_short_request This is the "threshold" to decide what is short and what is not.
int short_request_max_steps If a short request takes more than this many steps, it will be rescheduled as a long request.
double short_request_ratio How many steps will be allocated to short requests each tick, as a ratio of all available steps per tick.
int min_steps_to_check_path_find_termination Absolute minimum of steps that will be performed for every path find request no matter what.
double start_to_goal_cost_multiplier_to_terminate_path_find If the amount of steps is higher than this times estimate of start to goal then path finding is terminated.
Note: The following fields do not use the special encapsulation method.
byte[4] . (root) Other
int max_failed_behavior_count If a behavior fails this many times, the enemy (or enemy group) is destroyed. This solves biters stuck within their own base.
Type GUI LUA key Description

Difficulty Settings

This information is instead stored in the LUA structure at game.difficulty_settings, which is prototyped by DifficultySettings. These fields do not use the special encapsulation method noted above.

Type GUI LUA key Description
byte[10] difficulty_settings Difficulty Settings
byte recipe_difficulty Recipe difficulty. 0 for Normal, 1 for Expensive.
byte technology_difficulty Technology difficulty. 0 for Normal, 1 for Expensive.
double technology_price_multiplier Technology price multiplier.

Note: these values are typically defined using the constants at defines.difficulty_settings.

Autoplace Control

See the page on map generation for more information on frequency, size, and richness.

Type LUA key Description
byte frequency Ore frequency.
byte size Ore size.
byte richness Ore richness.

Map Gen Size

These are the values used for the frequencies, sizes, and richnesses of ores, water, and the starting area size. None is a valid value for all three options.

0 None / None /None
1 Very Low / Small / Poor
2 Low / Small / Poor
3 Normal / Medium / Regular
4 High / Big / Good
5 Very High / Big / Good

Each of the values in a triplet (such as "low", "small", and "poor") are synonymous.