<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.factorio.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Osmo</id>
	<title>Official Factorio Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.factorio.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Osmo"/>
	<link rel="alternate" type="text/html" href="https://wiki.factorio.com/Special:Contributions/Osmo"/>
	<updated>2026-10-23T01:20:01Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.11</generator>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial/Gangsir&amp;diff=219970</id>
		<title>Tutorial:Modding tutorial/Gangsir</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial/Gangsir&amp;diff=219970"/>
		<updated>2026-09-12T09:56:17Z</updated>

		<summary type="html">&lt;p&gt;Osmo: Change the very outdated Load order section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
This is a modding tutorial for Factorio version 2.0. In this tutorial, the author will explain how Factorio works behind the scenes, how to modify Factorio, where to find documentation, and explain concepts.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Before we start the tutorial, a few things to note:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#AAFFAA!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
Code tinted green like this should be included into the mod this tutorial is going to create; If the reader follows along with it. The best way to do this is to copy and paste, to ensure faithful reproduction.&lt;br /&gt;
Whenever code is added to the mod, a Lua comment with the file name will be at the beginning of the green box. Place the code in the box into that file. Eg:&lt;br /&gt;
--control.lua&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
Code tinted purple like this should not be included into the mod, it&#039;s just for educational/example purposes, and to boost understanding.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This tutorial was updated to version 2.0, so any &#039;&#039;viewers in the future should take note that some minor changes may have been made&#039;&#039;, and should look at the changelogs up to the current version.&lt;br /&gt;
&lt;br /&gt;
== Terminology used in modding ==&lt;br /&gt;
&lt;br /&gt;
Before we start the tutorial, a few terms and definitions should be laid out, to ensure the reader understands.&lt;br /&gt;
&lt;br /&gt;
; Mod : A script or series of scripts that allow modifications to the game through the API.&lt;br /&gt;
; Entity : An entity in Factorio is anything in the game that is not a concept, event, or tile. Examples of entities include the character, an assembling machine, a biter, etc. This can be &#039;machines&#039; or free-moving objects like the character.&lt;br /&gt;
; Character : The actual entity that the player manipulates the world through.&lt;br /&gt;
; Player : All the data that defines a player, such as username, online time or the current zoom level.&lt;br /&gt;
; Prototype : A prototype describes an instance of an entity, item or recipe etc, a bit like a template. It defines stats, like what an entity actually is, an item&#039;s stack size, a recipe&#039;s ingredients etc. A prototype is used to create an instance of an entity/item/etc, and many functionally identical entities/items/etc will use the same prototype.&lt;br /&gt;
; Surface : A surface is a bit like a dimension. It is composed of terrain, such as grass, sand, and water, and all the entities on the surface. By default, there is only one surface in Factorio, referred to internally as &amp;quot;nauvis&amp;quot;, or &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces[1]&amp;lt;/code&amp;gt;, but mods may create additional surfaces through the API.&lt;br /&gt;
; Event : An event is a recurring...event, that is triggered internally by the game. There are several events that mods may connect functions to, such as &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, etc. More on this in the control scripting section.&lt;br /&gt;
; Item : Items are what is moved around in inventories, by inserters and on belts, etc. Each item in-game is an instance of the respective item prototype.&lt;br /&gt;
&lt;br /&gt;
More terminology may be declared and defined later in this tutorial.&lt;br /&gt;
&lt;br /&gt;
== Before beginning to mod ==&lt;br /&gt;
&lt;br /&gt;
Before we can start modding Factorio, we must understand what Factorio is. You may be tempted to answer in lieu of the [[Factorio:About|about page]], but that is what a player would say. Since we are trying to become a modder, we need a more detailed explanation. Factorio is a game that is coded in the language C++, with an API provided by Wube (the developers of Factorio) to mod Factorio in the programming language Lua (version 5.2.1). This API allows adding scripts to the Factorio init process, to modify it without the source code of the base game being exposed, or modifying memory. This may be different than other games that offer modding, but this is a more professional and proper way of supporting modding.&lt;br /&gt;
&lt;br /&gt;
To aid in the use of this API, the devs have kindly provided fairly comprehensive documentation of mods on at their [https://lua-api.factorio.com/latest/ API doc site]. Get used to using this site, as you will be frequently visiting it while you develop mods. The scripting API site contains information on [https://lua-api.factorio.com/latest/classes.html Factorio&#039;s classes] and information on [https://lua-api.factorio.com/latest/events.html events] that you can hook into. The [https://lua-api.factorio.com/latest/index-prototype.html prototype documentation] contains and links to information all around prototypes, listing their inheritance structure and their properties. You will need to check this site often, so the author recommends bookmarking it. In addition to this site, there are also many resources to be found created by the community, such as this tutorial.&lt;br /&gt;
&lt;br /&gt;
=== Setup ===&lt;br /&gt;
&lt;br /&gt;
The best way to develop a mod is to develop it in a place where it can be easily tested. When the tutorial gets to making the mod, this will be explained further. Additionally, using an editor that allows ease of typing and Lua language support is recommended. Emacs, Vim, Sublime Text, VSCode, and Notepad++ are all viable candidates.&lt;br /&gt;
&lt;br /&gt;
== How Factorio loads mods ==&lt;br /&gt;
&lt;br /&gt;
=== Load order ===&lt;br /&gt;
Within stages, mods are loaded by dependency, then by alphabetical order. This is &#039;&#039;very important&#039;&#039; to understand, as it can cause you problems if you neglect it and try to add inter-mod support to your mod.&lt;br /&gt;
&lt;br /&gt;
Factorio has multiple kinds of dependencies, all of them documented [https://lua-api.factorio.com/latest/auxiliary/mod-structure.html#dependencies here].&lt;br /&gt;
If your mod depends on another mod, the other mod will always be loaded first, unless you specified a load order unaffecting dependancy (&amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt;).&lt;br /&gt;
Required dependencies can be used if your mod will not work without the other mod present.&lt;br /&gt;
Incompatible dependencies will make the game error on startup if a mod marked incompatible by another mod is present.&lt;br /&gt;
Optional and recommended dependencies can be used to change stuff in your mod, such as adding or removing certain recipes, when the other mod is present.&lt;br /&gt;
&lt;br /&gt;
=== The settings stage ===&lt;br /&gt;
The very first mod stage that is loaded when Factorio initializes is the settings stage. This stage is used to define all mod settings that are later shown in the in-game mod settings GUI, and has no other functions or possibilities. When running through this stage, the game looks through all mods for a file called &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. After settings.lua has been executed for all mods, each mod&#039;s &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; is executed, and finally each mod&#039;s &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt; is called. These 3 different phases of the settings stage allow to change settings of other mods without needing to rely on dependencies to load last. All other files to be loaded will need to be required. All the files run here should contain nothing but setting definitions and code to produce setting definitions.&lt;br /&gt;
&lt;br /&gt;
The settings stage does not have access to prototype or runtime data because it is loaded before those stages. The settings are expected to have a certain format, and all additional code will be discarded once the stage is over.&lt;br /&gt;
&lt;br /&gt;
Mod settings are not covered in this tutorial, see [[Tutorial:Mod settings]] for further info on them.&lt;br /&gt;
&lt;br /&gt;
=== The data stage ===&lt;br /&gt;
&lt;br /&gt;
This is the most restricted part of the Factorio init, there&#039;s not much you can do here other than declare prototypes for technologies, entities, items and more. Things like manipulating files, affecting the world, etc, are blocked/unavailable. In fact, any functions or changes made will be discarded, as the lua session is terminated. You also cannot mess with the data table, it will error or be ignored. When using &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, it expects a specific format, more on this later.&lt;br /&gt;
&lt;br /&gt;
When running through this stage, the game looks through all mods for a file called &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. After data.lua has been executed for all mods, each mod&#039;s &amp;lt;code&amp;gt;data-updates.lua&amp;lt;/code&amp;gt; is executed, and finally each mod&#039;s &amp;lt;code&amp;gt;data-final-fixes.lua&amp;lt;/code&amp;gt; is called. These 3 different phases of the data stage allow to change data of other mods without needing to rely on dependencies to load last. For example, the base mod creates barrelling recipes for all (then present) fluids in data-updates.lua. This means that if you add a fluid in data.lua, the base mod&#039;s data-updates.lua will add barreling recipes for it, regardless of whether your mod depends on base. Of course this also means that if you add a fluid in data-final-fixes.lua, it is created after the barrelling code runs in data-updates.lua, so no barrelling recipe gets created, even when desired. Because of this and similar mod interactions, it is recommended to create prototypes as early as possible. So, don&#039;t use data-final-fixes.lua to exclude a fluid from barreling, instead create it in data.lua and utilize &amp;quot;auto_barrel = false&amp;quot; on the fluid.&lt;br /&gt;
&lt;br /&gt;
All other files to be loaded will need to be required. All the files run here should contain nothing but prototype definitions and code to produce prototype definitions. More on requiring files later.&lt;br /&gt;
&lt;br /&gt;
All prototypes are documented on the modding API documentation website: [https://lua-api.factorio.com/latest/index-prototype.html Prototype documentation].&lt;br /&gt;
&lt;br /&gt;
=== Migrations ===&lt;br /&gt;
&lt;br /&gt;
[https://lua-api.factorio.com/latest/auxiliary/migrations.html Migrations] are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototype names change within a mod, migrations must be setup to replace all the old instances of the prototyped entity in the world. This must be done for all updated entities, or the old entities will be removed from the world, which is an unprofessional fallback that makes users dislike you. While this tutorial will not discuss migrations, there are many resources on migrations to be found around the community, and the API site.&lt;br /&gt;
&lt;br /&gt;
To avoid having to write migrations, avoid changing prototype names and technology unlocks after shipping the mod out to the public. Additionally, prototype names cannot be dynamically migrated because migrations are just a static list of names. Try to come up with a finalized version of prototype names that you can base the mod around. Of course, migrations are unnecessary if the user simply starts a new world with each mod update, but do not expect the community to do this.&lt;br /&gt;
&lt;br /&gt;
=== Runtime stage ===&lt;br /&gt;
&lt;br /&gt;
Within most mods is a file called &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. This file contains scripting that makes the mod do things during the game, rather than just adding entities to the game. During this stage, each mod&#039;s control.lua is run, in it&#039;s own lua instance (this means no inter-communication without special setup) which it will own for the rest of the play session. During the play session, access to all tables provided by the game can be done inside of event handlers. (More on those below.) Because the control.lua is run every time a save file is created or loaded you don&#039;t need to restart the game to see changes made to the control.lua file. Simply restarting or reloading a save will re-run this stage. &#039;&#039;&#039;There are a few other caveats to this stage, reading the [https://lua-api.factorio.com/latest/auxiliary/data-lifecycle.html data life cycle] page on the API site provides the best overview.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The control stage documented is documented on [https://lua-api.factorio.com/latest/index-runtime.html lua-api.factorio.com].&lt;br /&gt;
&lt;br /&gt;
== The major components to any Factorio mod ==&lt;br /&gt;
&lt;br /&gt;
Within the average mod, there are several components that make the mod function.&lt;br /&gt;
&lt;br /&gt;
Mods that define new entities will need to declare these entities in &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;data-updates.lua&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;data-final-fixes.lua&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Mods with in-game effects will also need a &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt; file, to add scripting.&lt;br /&gt;
&lt;br /&gt;
Mods with configurable user settings will use &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt; to describe those settings.&lt;br /&gt;
&lt;br /&gt;
Mods that define any game element with a readable name may also provide a &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; directory and subdirectories with names/descriptions in one or more languages.&lt;br /&gt;
&lt;br /&gt;
The mod that we&#039;ll make in this tutorial will include both data.lua prototypes and control.lua scripting, to give you a feel for both.&lt;br /&gt;
&lt;br /&gt;
== The tutorial mod ==&lt;br /&gt;
&lt;br /&gt;
And now for the moment you&#039;ve been waiting for. Let&#039;s start making your first mod. You&#039;ll need:&lt;br /&gt;
&lt;br /&gt;
* A recent install of Factorio&lt;br /&gt;
* A text editor, such as Emacs, Vim, Sublime Text, VSCode, or Notepad++.&lt;br /&gt;
* An understanding of the tutorial above&lt;br /&gt;
* An understanding of Lua as a programming language. Enough to know the syntax and how it works. If you have prior programming experience, it should not be difficult to pick up.&lt;br /&gt;
&lt;br /&gt;
Once you have all of these things, we can begin.&lt;br /&gt;
&lt;br /&gt;
For this mod, we&#039;re going to make a set of armor that leaves behind damaging fire behind you as you walk. It will be fully resistant to fire, but weaker towards physical damage than heavy armor, making it an armor for hit and run attacks.&lt;br /&gt;
&lt;br /&gt;
=== Creation of the directory structure ===&lt;br /&gt;
&lt;br /&gt;
The game expects mod to be laid out [https://lua-api.factorio.com/latest/auxiliary/mod-structure.html in a certain way]. To start out, create a folder in your [[Application directory|user data directory]]/mods folder. This folder must have a specific name, &amp;lt;code&amp;gt;fire-armor&amp;lt;/code&amp;gt;. You don&#039;t need to zip anything for now, that will come later when you&#039;re done working on the mod. When you&#039;re finished, the mod directory should look like this:&lt;br /&gt;
&lt;br /&gt;
* (user data directory, sometimes called .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** fire-armor&lt;br /&gt;
&lt;br /&gt;
Then, inside fire-armor, create two files, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. The directory should now look like:&lt;br /&gt;
&lt;br /&gt;
* (user data directory, sometimes called .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** fire-armor&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== The info.json file ===&lt;br /&gt;
&lt;br /&gt;
Then, inside [https://lua-api.factorio.com/latest/auxiliary/mod-structure.html#info.json info.json], copy and paste the following into it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#AAFFAA!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;fire-armor&amp;quot;,&lt;br /&gt;
  &amp;quot;version&amp;quot;: &amp;quot;0.1.0&amp;quot;,&lt;br /&gt;
  &amp;quot;title&amp;quot;: &amp;quot;Fire Armor&amp;quot;,&lt;br /&gt;
  &amp;quot;author&amp;quot;: &amp;quot;You&amp;quot;,&lt;br /&gt;
  &amp;quot;factorio_version&amp;quot;: &amp;quot;2.0&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 2.0&amp;quot;],&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;This mod adds in fire armor that leaves behind damaging fire as you walk around.&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To explain each field:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Item&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| This is the internal name of your mod, it is used to identify your mod in code.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| This is the version of your mod. This can be anything you want, provided it&#039;s a of the format &amp;quot;number.number.number&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| The pretty title of your mod, this will be displayed on the mods screen and when you submit it to the mod portal.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Your name! You can change this in the example above.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| This tells the game what version the mod is for, this must match the version you&#039;re developing the mod for, 2.0 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A short description of your mod, which appears in game. The mod portal is better for a long description.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! &lt;br /&gt;
&lt;br /&gt;
=== Prototype creation ===&lt;br /&gt;
&lt;br /&gt;
Now, there are two ways to create prototypes in Factorio. There&#039;s the short way, and the long way. One way requires to create a complete prototype definition based on [https://lua-api.factorio.com/latest/index-prototype.html the documentation]. Another way uses a Lua function to copy and modify an already existing definition. For the sake of this tutorial, we&#039;ll do it both ways.&lt;br /&gt;
&lt;br /&gt;
In the data.lua file, copy and paste the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#AAFFAA!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
--data.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw[&amp;quot;armor&amp;quot;][&amp;quot;heavy-armor&amp;quot;]) -- copy the table that defines the heavy armor item into the fireArmor variable&lt;br /&gt;
&lt;br /&gt;
fireArmor.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
fireArmor.icons = {&lt;br /&gt;
  {&lt;br /&gt;
    icon = fireArmor.icon,&lt;br /&gt;
    icon_size = fireArmor.icon_size,&lt;br /&gt;
    tint = {r=1,g=0,b=0,a=0.3}&lt;br /&gt;
  },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fireArmor.resistances = {&lt;br /&gt;
  {&lt;br /&gt;
    type = &amp;quot;physical&amp;quot;,&lt;br /&gt;
    decrease = 6,&lt;br /&gt;
    percent = 10&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    type = &amp;quot;explosion&amp;quot;,&lt;br /&gt;
    decrease = 10,&lt;br /&gt;
    percent = 30&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    type = &amp;quot;acid&amp;quot;,&lt;br /&gt;
    decrease = 5,&lt;br /&gt;
    percent = 30&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    type = &amp;quot;fire&amp;quot;,&lt;br /&gt;
    decrease = 0,&lt;br /&gt;
    percent = 100&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- create the recipe prototype from scratch&lt;br /&gt;
local recipe = {&lt;br /&gt;
  type = &amp;quot;recipe&amp;quot;,&lt;br /&gt;
  name = &amp;quot;fire-armor&amp;quot;,&lt;br /&gt;
  enabled = true,&lt;br /&gt;
  energy_required = 8, -- time to craft in seconds (at crafting speed 1)&lt;br /&gt;
  ingredients = {&lt;br /&gt;
    {type = &amp;quot;item&amp;quot;, name = &amp;quot;copper-plate&amp;quot;, amount = 200},&lt;br /&gt;
    {type = &amp;quot;item&amp;quot;, name = &amp;quot;steel-plate&amp;quot;, amount = 50}&lt;br /&gt;
  },&lt;br /&gt;
  results = {{type = &amp;quot;item&amp;quot;, name = &amp;quot;fire-armor&amp;quot;, amount = 1}}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
data:extend{fireArmor, recipe}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What we&#039;ve just done here is we&#039;ve copied the definition of the heavy armor item, then changed its properties, and injected it into the Factorio init with data:extend. The first line of code is probably the most interesting. &amp;lt;code&amp;gt;table.deepcopy&amp;lt;/code&amp;gt; copies a table fully into another table. We do this from data.raw. The &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; part is a table, which will be used by the game to setup the Factorio universe. In fact, it contains the function &amp;lt;code&amp;gt;extend(self, prototypes)&amp;lt;/code&amp;gt; and a table called &amp;lt;code&amp;gt;raw&amp;lt;/code&amp;gt;. The former is a customary way to add new stuff to the latter. It is actually data.raw that holds the prototypes for the game. (You can view the implementation in the file [https://github.com/wube/factorio-data/blob/master/core/lualib/dataloader.lua /factorio/data/core/lualib/dataloader.lua]). It is important to note that data.raw only exists during the data loading stage of the game. During the control stage, when the game is running and being played, you cannot read this data; instead you read processed values through the API from the various types like LuaEntityPrototype.&lt;br /&gt;
&lt;br /&gt;
In addition to defining the item prototype, we also define a recipe for it. This is necessary if you want to be able to craft the thing. We also set it to enabled so it doesn&#039;t need a technology to unlock.&lt;br /&gt;
&lt;br /&gt;
=== More on data.raw ===&lt;br /&gt;
&lt;br /&gt;
When Factorio initializes, all prototypes are put into a table called data.raw. This table holds all prototype types, and within those types, individual prototypes identified by name: &amp;lt;code&amp;gt;local prototype = data.raw[&amp;quot;prototype-type&amp;quot;][&amp;quot;internal-name&amp;quot;]&amp;lt;/code&amp;gt;. You saw earlier how we deepcopied from the definition of heavy armor, and modified some fields. In fact, let&#039;s go over each part of the deepcopy line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw[&amp;quot;armor&amp;quot;][&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We assign a variable called fireArmor that holds our copy of the heavy armor definition. Notice how in data.raw, there is a type table that holds all armors, and the specific armor we&#039;re looking for is called heavy-armor. We can find [[heavy armor]]&#039;s prototype type and internal name in the infobox of its page on this wiki and just copy it from there.&amp;lt;br&amp;gt;&lt;br /&gt;
Alternatively, we can find the items prototype type and internal name by opening the game, inserting the item into our inventory and then pressing {{Keybinding|shift|ctrl|F}} while hovering over the item. This will open the prototype explorer GUI, which has rows showing the name and type of the item.&lt;br /&gt;
&lt;br /&gt;
As another example, the [[player|character]]&#039;s prototype would be, according to the infobox on the page:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
data.raw[&amp;quot;character&amp;quot;][&amp;quot;character&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the character is &#039;&#039;the&#039;&#039; character, his type matches his name. You could define a new character with a mod. You can see all the available prototype fields of the character in the documentation: [https://lua-api.factorio.com/latest/prototypes/CharacterPrototype.html CharacterPrototype].&lt;br /&gt;
&lt;br /&gt;
You may be thinking at this point, &amp;quot;Can I modify Factorio&#039;s existing prototypes without making new ones?&amp;quot; Well, the answer is yes! You would simply access the data.raw table during init, in data-final-fixes.lua if you want to run after all other mods, and change a property. For example, make the iron chest instead have 1000 health:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
data.raw[&amp;quot;container&amp;quot;][&amp;quot;iron-chest&amp;quot;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code is in data-final-fixes.lua is because that is the last file run, after all mod files have been run. This prevents (to a degree) your changes from being messed with by other mods. Of course, it is still possible to have incompatibilities. You should note any that you know of in your mod&#039;s description. Again, the [https://lua-api.factorio.com/latest/auxiliary/data-lifecycle.html dev&#039;s documentation] on this should be looked at.&lt;br /&gt;
&lt;br /&gt;
This can also be applied to other mods, not just Factorio&#039;s base. You could mod a mod, as long as you add the mod (that you modified with your mod) to your dependencies so it gets loaded first.&lt;br /&gt;
&lt;br /&gt;
=== The control scripting ===&lt;br /&gt;
&lt;br /&gt;
And now, to finalize the mod, we have to make it be more than just simple armor. Let&#039;s think about what we want the armor to do. We want the armor to create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called [https://lua-api.factorio.com/latest/events.html#on_player_changed_position on_player_changed_position], since we want the fire to be created when the player moves.&lt;br /&gt;
&lt;br /&gt;
In our mod folder, create a file called &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. The game will automatically execute this file, so requiring it is not necessary.&lt;br /&gt;
&lt;br /&gt;
Inside control.lua, copy and paste the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#AAFFAA!important; color:black;&amp;quot;&amp;gt;&lt;br /&gt;
--control.lua&lt;br /&gt;
&lt;br /&gt;
script.on_event(defines.events.on_player_changed_position,&lt;br /&gt;
  function(event)&lt;br /&gt;
    local player = game.get_player(event.player_index) -- get the player that moved            &lt;br /&gt;
    -- if they&#039;re currently controlling the character&lt;br /&gt;
    if player.controller_type == defines.controllers.character then&lt;br /&gt;
      -- and wearing our armor&lt;br /&gt;
      if player.get_inventory(defines.inventory.character_armor).get_item_count(&amp;quot;fire-armor&amp;quot;) &amp;gt;= 1 then&lt;br /&gt;
        -- create the fire where they&#039;re standing&lt;br /&gt;
        player.surface.create_entity{name=&amp;quot;fire-flame&amp;quot;, position=player.position, force=&amp;quot;neutral&amp;quot;}&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&#039;ve used lua comments in the code above to explain each step. It&#039;s fairly easy to understand, and it shows how you would get the current armor that the player character is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [https://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
=== Locale ===&lt;br /&gt;
&lt;br /&gt;
If you&#039;ve already tried loading up Factorio and trying the mod so far (which you can at this point without it crashing), you may have noticed that the item name of the armor says &amp;quot;Unknown key&amp;quot;. This means that Factorio has the internal name, but it doesn&#039;t know what it should look like to the user. So, we need to create a locale for our mod.&lt;br /&gt;
&lt;br /&gt;
In the mod folder, create a folder called &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt;, then create another folder inside that called &amp;lt;code&amp;gt;en&amp;lt;/code&amp;gt;, then a file called &amp;lt;code&amp;gt;any_name_can_be_here.cfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you know another language, you can also translate your mod by making other language code files inside locale, such as de for German.&lt;br /&gt;
&lt;br /&gt;
Inside the .cfg file, paste the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#AAFFAA!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[item-name]&lt;br /&gt;
fire-armor=Fire armor&lt;br /&gt;
&lt;br /&gt;
[item-description]&lt;br /&gt;
fire-armor=An armor that seems to catch the ground itself on fire when you take a step. It&#039;s warm to the touch.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice how this is not a lua file. Locale is handled with C config files, so the format is different.&lt;br /&gt;
&lt;br /&gt;
== The finished tutorial mod ==&lt;br /&gt;
&lt;br /&gt;
Well, the mod is finished. Since this mod is only a tutorial, there isn&#039;t much balance to it.&lt;br /&gt;
&lt;br /&gt;
If you want to share a mod with other users, it needs to be a zip file. For that, simply zip the &amp;lt;code&amp;gt;fire-armor&amp;lt;/code&amp;gt; folder and then rename the archive to &amp;lt;code&amp;gt;fire-armor_0.1.0&amp;lt;/code&amp;gt; so that it follows the expected mod zip name pattern of &amp;lt;code&amp;gt;mod-name_version&amp;lt;/code&amp;gt;. Keep in mind to not submit this tutorial mod to the mod portal as your own, since it&#039;s from the Wiki.&lt;br /&gt;
&lt;br /&gt;
However, you&#039;re free to take this mod and modify it for your own use, changing recipes, adding technologies, whatever.&lt;br /&gt;
&lt;br /&gt;
== Extended learning ==&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. The [[Tutorial:Inspecting a live mod]] is a good starting point for touring a particularly well-commented mod. As all mods can be opened and inspected, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
Something you&#039;ll see a lot in other mods or the base game are &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt; statements. These load other files, so you can split up long code files and organize your mod however you like.&lt;br /&gt;
&lt;br /&gt;
For example, if you wanted to put some of your data stage code into a file called &amp;quot;foo.lua&amp;quot; in a folder called &amp;quot;bar&amp;quot;, your mod folder would look like this:&lt;br /&gt;
&lt;br /&gt;
* fire-armor&lt;br /&gt;
** bar&lt;br /&gt;
*** foo.lua&lt;br /&gt;
** data.lua&lt;br /&gt;
** control.lua&lt;br /&gt;
** info.json&lt;br /&gt;
&lt;br /&gt;
And you would need to add this to data.lua:&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
require(&amp;quot;bar.foo&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
As Factorio evolves, things will change. Previously, you probably ignored the modding part of the changelog, you now need to read it and see if any changes affect your mod(s). If so, you&#039;ll need to fix them. If there&#039;s something wrong with your mod, the game will fail to init and explain why.&lt;br /&gt;
&lt;br /&gt;
== Resolving common errors in modding ==&lt;br /&gt;
&lt;br /&gt;
As you continue to write mods from scratch instead of from a tutorial, you may encounter the infamous error. There are several types of errors that you can encounter in modding Factorio, and knowing how to deal with these errors will allow you to continue working.&lt;br /&gt;
&lt;br /&gt;
=== Syntax errors ===&lt;br /&gt;
&lt;br /&gt;
The Lua programming language expects things to be laid out a certain way. If you miss a bracket, = sign, or dot, you will encounter a syntax error. As an example, see the error below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
Failed to load mod &amp;quot;fire-armor&amp;quot;: __fire-armor__/data.lua:39: unfinished string near &#039;&amp;quot;fire-armor,&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll see an error like the one above whenever you make a syntax error within the prototype definitions. The game will offer to restart, disable the troubling mod, disable all mods, or exit. Let&#039;s dissect the error, shall we?&lt;br /&gt;
&lt;br /&gt;
Right away, we see the reason why Factorio didn&#039;t start normally. &amp;quot;Failed to load mod &amp;quot;fire-armor&amp;quot;:&amp;quot;. So, we know that it&#039;s our mod that messed up. Whenever the Lua engine of Factorio has a syntax error, it will print a mini stack-trace that follows through all requires, listing the call order. First, we see that the problem was caused by line 39 of data.lua. After stating where it is line-wise, it will attempt to give you an estimate of where in the line the problem is. Don&#039;t trust this estimate, only roughly trust the line number, plus or minus a few lines.&lt;br /&gt;
&lt;br /&gt;
Going to line 39 of data.lua, we find:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
  name = &amp;quot;fire-armor,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hmm, that doesn&#039;t look right. Can you see what&#039;s missing? We left off an &amp;quot; after armor before the comma. Thus, syntax error. Fixing these can be difficult for new programmers, who don&#039;t know what to look for.&lt;br /&gt;
&lt;br /&gt;
=== Illogical actions, indexing nil ===&lt;br /&gt;
&lt;br /&gt;
In lua, &amp;quot;nothing&amp;quot; is defined as the keyword nil. This is similar to null in other programming languages. Whenever the programmer tries to access something in a table that is nil, they will get an error like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
Error while running event fire-armor::on_player_changed_position (ID 82)&lt;br /&gt;
__fire-armor__/control.lua:3: attempt to index field &#039;?&#039; (a nil value)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;attempt to index field ...&amp;quot; error is often caused by the modder making an assumption that didn&#039;t work out. These types of errors will always be identifiable by their signature line, &amp;quot;attempt to index field&amp;quot;. If we look at line 3 of control.lua (where the error is), we see:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
game.print(game.players[23])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What assumption has the modder made here? Well, there&#039;s actually two problems with this line. The first thing is that the modder has assumed that &amp;lt;code&amp;gt;game.players[23]&amp;lt;/code&amp;gt; is a valid player, which isn&#039;t the case; this is why we get the &amp;quot;index field &#039;?&#039;&amp;quot; bit. The game doesn&#039;t know what the field is that we tried to index, because it hasn&#039;t been created yet. These errors are difficult to debug unless you know the ins and outs of the modding API well.&lt;br /&gt;
&lt;br /&gt;
The second issue is a lot more subtle, and won&#039;t work. The modder is attempting to print a userdata table. [https://lua-api.factorio.com/latest/LuaPlayer.html A player] is a table of several values. Trying to print it simply print &amp;quot;LuaPlayer&amp;quot; instead of providing useful data.&lt;br /&gt;
&lt;br /&gt;
=== Error while running event ===&lt;br /&gt;
&lt;br /&gt;
Another common type of error in Factorio is the &amp;quot;Error while running event&amp;quot; error. This type of error only happens in control.lua scripting, and it happens when something goes wrong in an event function, such as a syntax error. &#039;&#039;&#039;Note that syntax errors in control.lua do not stop the game from starting, but may trigger after a save is loaded&#039;&#039;&#039;. There are a great deal of errors under this broad category, here&#039;s an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
Error while running event fire-armor::on_player_changed_position (ID 82)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__fire-armor__/control.lua:7: in function &amp;lt;__fire-armor__/control.lua:2&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you saw with the prototypes syntax error, Factorio gives a small traceback and the error name itself. In this case, we&#039;ve attempted to spawn an entity called &amp;quot;fire-flam&amp;quot; on line 7 of control.lua, inside of an on_player_changed_position event hook. Fire-flam isn&#039;t a real entity type, so we crashed.&lt;br /&gt;
&lt;br /&gt;
These types of errors can range from being a simple fix (like the one above, add the missing e), or can be very difficult.&lt;br /&gt;
&lt;br /&gt;
=== Internal errors ===&lt;br /&gt;
&lt;br /&gt;
The most rare form of error and the worst form is the internal error. This is an error with the C++ code of the game, and there&#039;s nothing you can do but report it to the devs. Mods occasionally cause these, and almost all of them are considered bugs, as mods &#039;&#039;should not&#039;&#039; be able to cause these, if that makes sense. They often get thrown into the logs.&lt;br /&gt;
&lt;br /&gt;
An example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
696.148 Error FlowStatistics.cpp:236: FlowStatistics attempted to save value larger than uint16 as uint16. Exiting to prevent save corruption.&lt;br /&gt;
Logger::writeStacktrace skipped.&lt;br /&gt;
696.148 Error CrashHandler.cpp:190: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:97: Unexpected error occurred. If you&#039;re running the latest version of the game you can help us solve the problem by posting the contents of the log file on the Factorio forums.&lt;br /&gt;
Please also include the save file(s), any mods you may be using, and any steps you know of to reproduce the crash.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Multiplayer and desyncs ==&lt;br /&gt;
&lt;br /&gt;
The reader may be wondering at this point how Factorio handles multiplayer with mods. It&#039;s fairly simple, but is still worth considering.&lt;br /&gt;
&lt;br /&gt;
Factorio is [https://en.wikipedia.org/wiki/Deterministic_algorithm deterministic], which means that when you provide a constant input, you get a constant output, with no variance. Every client and the server all reach the same points at the same time in simulation, so they all agree on what happened. When this differs, the players experience a &#039;&#039;desync&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
; Desync : Misalignment with server and clients. Client 1 expected A, but got B. All other clients got A. Thus, Client 1 will desync. Desync can also happen when all clients have information (for example a variable) but a client that recently joined the game doesn&#039;t. That client will be desynced.&lt;br /&gt;
: &#039;&#039;See also: [[Desynchronization]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Desyncs happen a lot to new devs of Factorio mods, because they are unaware that a particular piece of code they used causes desyncs. As a general rule, there are a few things that should never be done.&lt;br /&gt;
&lt;br /&gt;
=== Use local variables that are not final outside of event hooks ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
local globalLocal = 1&lt;br /&gt;
script.on_event(defines.events.on_player_built_item, function()&lt;br /&gt;
    globalLocal = math.random()&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the modder places a local variable outside of an event hook that gets changed during runtime, desyncs will happen when that variable is utilised to modify the game state (i.e. manipulate an entity, print text to players). If making a &amp;quot;global&amp;quot; variable is necessary, place the variable in the [https://lua-api.factorio.com/latest/auxiliary/storage.html storage] table instead. The game syncs this table between all clients, so they can all be aware of and reach the same conclusion as each other.&lt;br /&gt;
&lt;br /&gt;
=== Conditional event subscribing ===&lt;br /&gt;
&lt;br /&gt;
Mods in factorio may subscribe to events in order to be notified when they happen. This allows mods to react to events when they occur. Typically, event subscription is done at the top level of a lua file. &lt;br /&gt;
&lt;br /&gt;
Doing event subscription inside of a conditional, function, or other event is dangerous, as doing it incorrectly will lead to desyncs. Basically, since both the server and client need to reach the same conclusion after running code, conditional subscription can lead to certain clients or the server being subscribed to an event when the others are not, causing desyncs. &lt;br /&gt;
&lt;br /&gt;
=== Improper use of on_load ===&lt;br /&gt;
&lt;br /&gt;
Another way to cause desyncs is to make improper actions inside of an on_load call, which some players new to modding might try to do. According to the [https://lua-api.factorio.com/latest/LuaBootstrap.html#LuaBootstrap.on_load documentation], the on_load functionality is meant for 3 purposes &#039;&#039;&#039;only&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* Re-register conditional event handlers&lt;br /&gt;
* Re-setup meta tables&lt;br /&gt;
* Create local references to tables stored in the storage table&lt;br /&gt;
&lt;br /&gt;
Doing anything else will cause desyncs. The game will catch most attempts, crashing instead and terminating the mod.&lt;br /&gt;
&lt;br /&gt;
=== Comparison by reference ===&lt;br /&gt;
&lt;br /&gt;
Be cautious of comparing tables by reference. In multiplayer syncing, tables deserialized from the server state will be new objects, not equal by reference to any table initialized by client code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
if a == b then&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
if a ~= b then&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
If &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; are tables in the above conditionals, there will for example be different results between server and client if &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; is created locally and &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; is downloaded from the server.&lt;br /&gt;
&lt;br /&gt;
Note that LuaObjects provided by the game have their equality operator overwritten to prevent this behaviour, so code such as &amp;lt;code&amp;gt;LuaEntityA ~= LuaEntityB&amp;lt;/code&amp;gt; will not desync.&lt;br /&gt;
However, this does not apply when LuaObjects are used as keys in tables:&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#DDA0DD!important; color:black&amp;quot;&amp;gt;&lt;br /&gt;
if table[LuaObject] then&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will desync in the same way as described for the plain tables &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;b&amp;lt;/code&amp;gt; above. For entities it is recommended to use [https://lua-api.factorio.com/latest/LuaEntity.html#LuaEntity.unit_number LuaEntity.unit_number] as the table key instead of the whole entity.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Tutorial:Modding tutorial|Modding tutorial overview]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;/div&gt;</summary>
		<author><name>Osmo</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Localisation&amp;diff=218730</id>
		<title>Tutorial:Localisation</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Localisation&amp;diff=218730"/>
		<updated>2026-06-10T11:37:49Z</updated>

		<summary type="html">&lt;p&gt;Osmo: /* Default Behavior(s) for finding an Unspecified Localised String */ Improve this whole section, add rules for recipes and technologies. Remove &amp;quot;and is not an empty table&amp;quot; because empty tables are not valid localised strings (at least anymore).&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}Mods should define human readable names for prototypes that they add. They can also define descriptions for items or custom strings for usage in GUIs etc. This is called &#039;&#039;&#039;localisation&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== File format ==&lt;br /&gt;
Translations are stored as .cfg files, with the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;welcome-message=Hello world&lt;br /&gt;
[category]&lt;br /&gt;
title=Category related title&lt;br /&gt;
# Comment&lt;br /&gt;
; Another comment&amp;lt;/pre&amp;gt;&lt;br /&gt;
Any whitespace after or before &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt; is included in the key or string, so &amp;lt;code&amp;gt;title =Category related title&amp;lt;/code&amp;gt; will give an unknown key error if you are looking for the &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; key, since it is the &amp;lt;code&amp;gt;title&amp;amp;nbsp;&amp;lt;/code&amp;gt; key.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt; can be one of the existing locale categories, which permits implicit search mechanisms to find translations, but may also be another key, such as &amp;lt;code&amp;gt;[my-mod-messages]&amp;lt;/code&amp;gt;. These are accessible the same as other translations, e.g. &amp;lt;code&amp;gt;{&amp;quot;my-mod-messages.hello&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are located within the language code of the language in the locale folder of the mod, so as an English example &amp;lt;code&amp;gt;__mod__/locale/en/any_name_here.cfg&amp;lt;/code&amp;gt;. There can be more than 1 file per language, all of them will be read.&lt;br /&gt;
&lt;br /&gt;
== Localising simple strings ==&lt;br /&gt;
The simplest localisation is of items, entities etc. If we say the item is &amp;lt;code&amp;gt;iron-plate&amp;lt;/code&amp;gt;, the game will then search all loaded locale files for &amp;lt;code&amp;gt;item-name.iron-plate&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;item-description.iron-plate&amp;lt;/code&amp;gt;, which in the locale file looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;[item-name]&lt;br /&gt;
iron-plate=Iron plate&lt;br /&gt;
[item-description]&lt;br /&gt;
iron-plate=A plate made of iron.&amp;lt;/pre&amp;gt;&lt;br /&gt;
If found in the locale, the label is set to this string. If not found, the game will instead show: &amp;lt;code&amp;gt;Unknown key: &amp;amp;quot;item-name.iron-plate&amp;amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In script, the localised string is formatted as &amp;lt;code&amp;gt;{&amp;amp;quot;category.name&amp;amp;quot;}&amp;lt;/code&amp;gt;, so &amp;lt;code&amp;gt;game.print({&amp;amp;quot;item-name.iron-plate&amp;amp;quot;})&amp;lt;/code&amp;gt; prints &#039;&#039;Iron plate&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It is possible to use [[rich text]] features in the localised text if the location where the text is shown supports it, e.g. in the chat, prototype names and prototype tooltips.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt; can be used for line breaks if the location where the text is shown supports multiline text.&lt;br /&gt;
&lt;br /&gt;
The list of all localization categories used by the base game is:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Localization categories &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[achievement-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[achievement-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[ammo-category-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[autoplace-control-names]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[controls]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[damage-type-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[decorative-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[entity-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[entity-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[equipment-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[fluid-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[fuel-category-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-group-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-limitation]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[map-gen-preset-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[map-gen-preset-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[mod-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[mod-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[modifier-description]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[programmable-speaker-instrument]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[programmable-speaker-note]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[recipe-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[shortcut-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[story]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[string-mod-setting]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[technology-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[technology-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tile-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tips-and-tricks-item-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tips-and-tricks-item-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[virtual-signal-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[virtual-signal-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Localising with parameters ==&lt;br /&gt;
For more complex strings, localisation parameters can be used. For instance we want to show &#039;&#039;Time left: 10 minutes.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
So a key with a placeholder is defined, which is replaced by the first parameter after the locale key.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;time-left=Time left: __1__ minutes.&amp;lt;/pre&amp;gt;&lt;br /&gt;
So it is used like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;time-left&amp;quot;, 10})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
It also works with multiple parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;time-left&amp;quot;, 10, 45})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;time-left=Time left: __1__ minutes and __2__ seconds.&amp;lt;/pre&amp;gt;&lt;br /&gt;
Which results in &#039;&#039;Time left: 10 minutes and 45 seconds.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Built-in parameters ===&lt;br /&gt;
For some situations, we use localisation to show control schemes. For instance we want to say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;technology-prompt=Use T to open the technology screen&amp;lt;/pre&amp;gt;&lt;br /&gt;
However the player may have rebound the key, but we can’t figure out which key as it would not be deterministic. So instead we use the built-in replacement functionality&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;technology-prompt=Use __CONTROL__open-technology-gui__ to open the technology screen.&amp;lt;/pre&amp;gt;&lt;br /&gt;
We can also use this for items and entities:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;big-iron-plate=Big __ITEM__iron-plate__&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;tiny-gun-turret=Tiny __ENTITY__gun-turret__&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== List of built-in parameters ====&lt;br /&gt;
&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; is the name of an internal game control or a prototype name, depending on context. &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; can be 1 or 2, it&#039;s used in parameters that control [[#Localising_alternate_input_names|alternate input names]]. For a list of internal game control names, see [https://lua-api.factorio.com/latest/types/LinkedGameControl.html CustomInputPrototype::linked_game_control].&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL__name__&amp;lt;/code&amp;gt; - The combination of modifiers and input, such as &amp;quot;Control + Alt + Left-click&amp;quot;, or &amp;quot;Not set&amp;quot;.&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_MODIFIER__name__&amp;lt;/code&amp;gt; - The modifiers, such as &amp;quot;ControlShift&amp;quot;, or, &amp;quot;No modifier selected.&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_STYLE_BEGIN__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_STYLE_END__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_LEFT_CLICK__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-1&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-b&amp;lt;/code&amp;gt;[https://crowdin.com/project/factorio/discussions/214]&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_RIGHT_CLICK__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-2&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-x&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_KEY_SHIFT__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.shift&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-leftshoulder&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_KEY_CTRL__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.control&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-rightshoulder&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL_LEFT_CLICK__n__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-1-alt-n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-button-alt-n&amp;lt;/code&amp;gt; (with parameter &amp;lt;code&amp;gt;control-keys.controller-b&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL_RIGHT_CLICK__n__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-2-alt-n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-button-alt-n&amp;lt;/code&amp;gt; (with parameter &amp;lt;code&amp;gt;control-keys.controller-x&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL__n__name__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_MOVE__&amp;lt;/code&amp;gt; - The Movement keys, squished together. Example: &amp;quot;WASD&amp;quot;, from a conventional QWERTY English keyboard.&lt;br /&gt;
* &amp;lt;code&amp;gt;__REMARK_COLOR_BEGIN__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__REMARK_COLOR_END__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__ENTITY__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/EntityPrototype.html EntityPrototype] subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__FLUID__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/FluidPrototype.html FluidPrototype].&lt;br /&gt;
* &amp;lt;code&amp;gt;__ITEM__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/ItemPrototype.html ItemPrototype] or subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__PLANET__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/SpaceLocationPrototype.html SpaceLocationPrototype] or subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__TILE__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/TilePrototype.html TilePrototype].&lt;br /&gt;
&lt;br /&gt;
=== Plurals ===&lt;br /&gt;
Pluralization can be used in any string that uses a parameter (e.g. __1__) that is numeric, so something like an amount of minutes. It can be used multiple times per string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;format-days=__1__ __plural_for_parameter__1__{1=day|rest=days}__&amp;lt;/pre&amp;gt;&lt;br /&gt;
This results in &amp;quot;1 day&amp;quot; and &amp;quot;2 days&amp;quot; / &amp;quot;500 days&amp;quot; etc.&lt;br /&gt;
&lt;br /&gt;
The number after &amp;lt;code&amp;gt;__plural_for_parameter__&amp;lt;/code&amp;gt; denotes which parameter is used to determine the plural. This is the parameter 1 in the above example. Anything inside the {} is used to make the plural. Each plural form is separated by a |.&lt;br /&gt;
The text in front of the = determines for what the plural form is used. Options for this are:&lt;br /&gt;
* A simple number, e.g. &amp;quot;1&amp;quot;. &lt;br /&gt;
* Multiple numbers, e.g. &amp;quot;2,3,4&amp;quot;.&lt;br /&gt;
* What the number ends with, e.g. &amp;quot;ends in 11&amp;quot; or &amp;quot;ends in 1&amp;quot;&lt;br /&gt;
* Multiple ends with, e.g. &amp;quot;ends in 1,ends in 2,ends in 12&amp;quot;.&lt;br /&gt;
* &amp;quot;decimal&amp;quot; for any number with a fractional part. &lt;br /&gt;
* &amp;quot;rest&amp;quot; to give the default plural.&lt;br /&gt;
&lt;br /&gt;
For negative numbers the plural is picked as if the number was positive, so a plural like &amp;lt;code&amp;gt;__plural_for_parameter__1__{1=day|rest=days}__&amp;lt;/code&amp;gt; will result in &amp;quot;-1 day&amp;quot; for -1.&amp;lt;br&amp;gt;&lt;br /&gt;
For numbers with a SI prefix the plural is picked as if the number was fully written out, so a plural like &amp;lt;code&amp;gt;__plural_for_parameter__1__{1=day|1000=eons|rest=days}__&amp;lt;/code&amp;gt; will result in &amp;quot;1k eons&amp;quot; for 1k.&lt;br /&gt;
&lt;br /&gt;
Plural forms may be empty or contain other keys such as __1__ or spaces. This allows rather large plural forms:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;__plural_for_parameter__1__{1=__1__ player is|rest=__1__ players are}__ connecting&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system picks the first fitting plural that it encounters when multiple would fit:&lt;br /&gt;
&amp;lt;pre&amp;gt;__plural_for_parameter__1__{ends in 12=option 1|ends in 2=option 2|rest=option 3}__&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will result in &amp;quot;option 1&amp;quot; for 12 and in &amp;quot;option 2&amp;quot; for 22 and in &amp;quot;option 3&amp;quot; for numbers not ending with 2.&lt;br /&gt;
&lt;br /&gt;
The parameter used for pluralisation does not need to be present in the string. For example, a parameter could represent the number of list items present in another parameter:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I like __plural_for_parameter__1__{1=only one thing:|rest=these things:} __2__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Can result in &amp;quot;I like only one thing: trains&amp;quot;, or in &amp;quot;I like these things: trains and turtles&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Concatenating localised strings ===&lt;br /&gt;
The special locale key: &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; is used to concatenate, as the table format does not support concatenation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;&amp;quot;, {&amp;quot;item-name.iron-plate&amp;quot;}, &amp;quot;: &amp;quot;, 60})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Will result in: &#039;&#039;Iron plate: 60&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Advanced concatenation and modification existing localised strings ===&lt;br /&gt;
&lt;br /&gt;
When working with LocalisedString tables in prototype definitions (e.g., in data.lua, data-updates.lua, or data-final-fixes.lua), there are several important rules and practical patterns:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;All parameters must be strings&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
At the prototype data stage, every parameter passed to a localised string must be a string. Numbers, booleans, or other types will cause a Value must be a string error.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;-- This will cause an error:&lt;br /&gt;
localised_description = {&amp;quot;description.example&amp;quot;, 42}&lt;br /&gt;
&lt;br /&gt;
-- Correct:&lt;br /&gt;
localised_description = {&amp;quot;description.example&amp;quot;, &amp;quot;42&amp;quot;}&lt;br /&gt;
-- or using tostring():&lt;br /&gt;
localised_description = {&amp;quot;description.example&amp;quot;, tostring(42)}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This applies to numeric values from prototype properties as well:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;-- Wrong:&lt;br /&gt;
localised_description = {&amp;quot;description.radar-range&amp;quot;, prototype.max_distance}&lt;br /&gt;
&lt;br /&gt;
-- Correct:&lt;br /&gt;
localised_description = {&amp;quot;description.radar-range&amp;quot;, tostring(prototype.max_distance)}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Appending lines to existing descriptions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When modifying a prototype that already has a localised_description (e.g., from another mod), use the &amp;lt;code&amp;gt;&amp;quot;&amp;quot;&amp;lt;/code&amp;gt; (empty string) key for concatenation with newline separators. Here is a practical function that safely appends a new line while preserving existing content:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function append_localised_line(target, new_line)&lt;br /&gt;
    if not target.localised_description then&lt;br /&gt;
        target.localised_description = new_line&lt;br /&gt;
        return&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    local result = {&amp;quot;&amp;quot;}  -- concatenation key&lt;br /&gt;
    local idx = 2&lt;br /&gt;
    &lt;br /&gt;
    local function flatten(desc)&lt;br /&gt;
        if type(desc) == &amp;quot;string&amp;quot; then&lt;br /&gt;
            result[idx] = desc&lt;br /&gt;
            idx = idx + 1&lt;br /&gt;
        elseif type(desc) == &amp;quot;table&amp;quot; then&lt;br /&gt;
            -- Skip the key if present&lt;br /&gt;
            if desc[1] == &amp;quot;&amp;quot; or desc[1] == &amp;quot;?&amp;quot; then&lt;br /&gt;
                for i = 2, #desc do&lt;br /&gt;
                    flatten(desc[i])&lt;br /&gt;
                end&lt;br /&gt;
            else&lt;br /&gt;
                result[idx] = desc&lt;br /&gt;
                idx = idx + 1&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    flatten(target.localised_description)&lt;br /&gt;
    result[idx] = &amp;quot;\n&amp;quot;&lt;br /&gt;
    idx = idx + 1&lt;br /&gt;
    result[idx] = new_line&lt;br /&gt;
    &lt;br /&gt;
    target.localised_description = result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Usage:&lt;br /&gt;
append_localised_line(radar_prototype, {&amp;quot;description.radar-range&amp;quot;, tostring(range)})&lt;br /&gt;
&lt;br /&gt;
--Examples of modifying existing localised strings&lt;br /&gt;
&lt;br /&gt;
--Example 1: Adding line if localised_description == nil&lt;br /&gt;
local entity = data.raw[&amp;quot;assembling-machine&amp;quot;][&amp;quot;assembling-machine-3&amp;quot;]&lt;br /&gt;
append_localised_line(entity, {&amp;quot;description.building-size&amp;quot;, &amp;quot;3.0&amp;quot;, &amp;quot;3.0&amp;quot;})&lt;br /&gt;
--Result:&lt;br /&gt;
-- entity.localised_description = {&amp;quot;description.building-size&amp;quot;, &amp;quot;3.0&amp;quot;, &amp;quot;3.0&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
--Example 2: Adding a second line&lt;br /&gt;
append_localised_line(entity, {&amp;quot;description.max-health&amp;quot;, &amp;quot;500&amp;quot;})&lt;br /&gt;
--Result:&lt;br /&gt;
-- entity.localised_description = {&lt;br /&gt;
--     &amp;quot;&amp;quot;,&lt;br /&gt;
--     {&amp;quot;description.building-size&amp;quot;, &amp;quot;3.0&amp;quot;, &amp;quot;3.0&amp;quot;},&lt;br /&gt;
--     &amp;quot;\n&amp;quot;,&lt;br /&gt;
--     {&amp;quot;description.max-health&amp;quot;, &amp;quot;500&amp;quot;}&lt;br /&gt;
-- }&lt;br /&gt;
&lt;br /&gt;
--Final in-game display (with localization):&lt;br /&gt;
--Size: 3.0x3.0&lt;br /&gt;
--Max health: 500&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Error interpretation&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
When a LocalisedString error occurs, note that the property tree error messages use 0-based indexing, while Lua tables use 1-based indexing. An error pointing to &#039;&#039;&#039;[2][1]&#039;&#039;&#039; refers to the element at index &#039;&#039;&#039;3&#039;&#039;&#039; in your Lua table, then its element at index &#039;&#039;&#039;2&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== Localising alternate input names ===&lt;br /&gt;
&lt;br /&gt;
In the introduction campaign, a special locale system is used for informing players how to do certain actions with their mouse.&lt;br /&gt;
The normal form is to use eg:&lt;br /&gt;
&amp;lt;pre&amp;gt;how-to-build=Use __CONTROL__build__ to place a building&amp;lt;/pre&amp;gt;&lt;br /&gt;
which results in &amp;quot;Use Left mouse button to place a building&amp;quot;. A more natural phrasing would be &amp;quot;Left-click to place a building&amp;quot;, which can be achieved by using the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;how-to-build=__ALT_CONTROL__1__build__ to place a building&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These &amp;quot;alt&amp;quot; versions are controlled by a few special locale keys, mouse-button-X-alt-1 and mouse-button-X-alt-2. In English, form 1 produces eg &amp;quot;Left-click&amp;quot;, and form 2 produces eg &amp;quot;Left-clicking&amp;quot;.  Only two alt forms (&amp;quot;1&amp;quot; and &amp;quot;2&amp;quot;) are available at the moment, but if this a problem for some languages, more forms may be added in the future.&lt;br /&gt;
Extra mouse buttons, mouse scroll and keyboard keys are handled through the mouse-button-n-alt-1/2, mouse-wheel-alt-1/2 and keyboard-alt-1/2 keys, which just take the normal name and prepend something like &amp;quot;Press/Pressing&amp;quot;, or &amp;quot;Scroll/Scrolling&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
When translating to another language, you can use whatever forms you want here, but the important part is that you are consistent when you use the alt-forms everywhere else. It does not necessarily make sense to just copy the usages of alt forms from the English locale, and for some languages it may be more natural to simply not use this system at all.&lt;br /&gt;
&lt;br /&gt;
== Accessing the localised result in code ==&lt;br /&gt;
While usually unneeded, it is possible to read the resulting localised text in code, for example to search in localised names.&lt;br /&gt;
&lt;br /&gt;
See&lt;br /&gt;
[https://lua-api.factorio.com/latest/classes/LuaPlayer.html#request_translation LuaPlayer::request_translation],&lt;br /&gt;
[https://lua-api.factorio.com/latest/classes/LuaPlayer.html#request_translations LuaPlayer::request_translations] and&lt;br /&gt;
[https://lua-api.factorio.com/latest/events.html#on_string_translated on_string_translated event].&lt;br /&gt;
&lt;br /&gt;
== Default Behavior(s) for finding an Unspecified Localised String ==&lt;br /&gt;
If a localised_name or localised_description is not defined in the prototype, Factorio may have a default search behavior.&lt;br /&gt;
&lt;br /&gt;
Note: the angle brackets are meant to mean a generic term, they are not part of the actual string.&lt;br /&gt;
&lt;br /&gt;
For most types, the name defaults to {&amp;quot;&amp;lt;base type&amp;gt;-name.&amp;lt;prototype name&amp;gt;&amp;quot;}, for example {&amp;quot;entity-name.underground-belt&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Similarly, the description defaults to {&amp;quot;&amp;lt;base type&amp;gt;-description.&amp;lt;prototype name&amp;gt;&amp;quot;}, for example {&amp;quot;entity-description.underground-belt&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Base types are represented by [https://lua-api.factorio.com/latest/concepts/IDType.html IDType].&lt;br /&gt;
&lt;br /&gt;
=== Items ===&lt;br /&gt;
For items, the process is more complicated.&lt;br /&gt;
&lt;br /&gt;
Note: place_result and placed_as_equipment_result are strings, and and Factorio fetches the matching prototype to examine.&lt;br /&gt;
&lt;br /&gt;
# if localised_name is provided in the item prototype, use the provided value&lt;br /&gt;
# else if there is a place_result and it has a localised_name, use the localised_name of place_result&lt;br /&gt;
# else if there is a place_result, use {&amp;quot;entity-name.&amp;lt;place_result name&amp;gt;&amp;quot;}&lt;br /&gt;
# else if there is placed_as_equipment_result and it has a localised_name, use the localised_name of placed_as_equipment_result&lt;br /&gt;
# else if there is placed_as_equipment_result, use {&amp;quot;equipment-name.&amp;lt;place_as_equipment_result name&amp;gt;&amp;quot;}&lt;br /&gt;
# else use {&amp;quot;item-name.&amp;lt;item name&amp;gt;&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Descriptions of items are found in the same way, except localised_description is used instead of localised_name and &amp;lt;base type&amp;gt;-description is used instead of &amp;lt;base type&amp;gt;-name.&lt;br /&gt;
&lt;br /&gt;
Example: The transport-belt item does not have a localised_name, so 1-&amp;gt;2.&lt;br /&gt;
There is a place result, but the entity prototype does not have localised_name set, 2-&amp;gt;3.&lt;br /&gt;
There is a place result, so use the localised string {&amp;quot;entity-name.transport-belt&amp;quot;}.&lt;br /&gt;
&lt;br /&gt;
Reference: [https://forums.factorio.com/viewtopic.php?p=494243#p494243]&lt;br /&gt;
&lt;br /&gt;
=== Recipes ===&lt;br /&gt;
# if localised_name is provided in the recipe prototype, use the provided value&lt;br /&gt;
# else if main_product is set to an empty string: &amp;quot;&amp;quot;, use {&amp;quot;recipe-name.&amp;lt;recipe name&amp;gt;&amp;quot;}&lt;br /&gt;
# else if main_product is set or recipe only has a single product:&lt;br /&gt;
#:# if the main product or only product has the same name as the recipe, use the localised name of the product. For item products, this uses the rules described in [[#Items]].&lt;br /&gt;
#:# else use {&amp;quot;recipe-name.&amp;lt;recipe name&amp;gt;&amp;quot;}&lt;br /&gt;
# else use {&amp;quot;recipe-name.&amp;lt;recipe name&amp;gt;&amp;quot;}&lt;br /&gt;
Descriptions of recipes have no special rules.&lt;br /&gt;
&lt;br /&gt;
Reference: [https://lua-api.factorio.com/latest/prototypes/RecipePrototype.html#main_product]&lt;br /&gt;
&lt;br /&gt;
=== Technologies ===&lt;br /&gt;
If localised_name is provided in the technology prototype, the provided value is used.&lt;br /&gt;
Otherwise, if the name of a technology ends with -&amp;lt;number&amp;gt;, that number is ignored for localisation purposes.&lt;br /&gt;
E.g. if the name is technology-3, the localised name defaults to {&amp;quot;technology-name.technology&amp;quot;} and the localised description defaults to {&amp;quot;technology-description.technology&amp;quot;}.&lt;br /&gt;
&lt;br /&gt;
Reference: [https://lua-api.factorio.com/latest/prototypes/TechnologyPrototype.html#name]&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://lua-api.factorio.com/latest/types/LocalisedString.html LocalisedString data stage doc]&lt;br /&gt;
* [https://lua-api.factorio.com/latest/concepts/LocalisedString.html LocalisedString control stage doc]&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;/div&gt;</summary>
		<author><name>Osmo</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Localisation&amp;diff=218719</id>
		<title>Tutorial:Localisation</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Localisation&amp;diff=218719"/>
		<updated>2026-06-08T12:35:37Z</updated>

		<summary type="html">&lt;p&gt;Osmo: Undo revision 218718 by Osmo (talk) since it was prematurely saved&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}Mods should define human readable names for prototypes that they add. They can also define descriptions for items or custom strings for usage in GUIs etc. This is called &#039;&#039;&#039;localisation&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== File format ==&lt;br /&gt;
Translations are stored as .cfg files, with the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;welcome-message=Hello world&lt;br /&gt;
[category]&lt;br /&gt;
title=Category related title&lt;br /&gt;
# Comment&lt;br /&gt;
; Another comment&amp;lt;/pre&amp;gt;&lt;br /&gt;
Any whitespace after or before &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt; is included in the key or string, so &amp;lt;code&amp;gt;title =Category related title&amp;lt;/code&amp;gt; will give an unknown key error if you are looking for the &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; key, since it is the &amp;lt;code&amp;gt;title&amp;amp;nbsp;&amp;lt;/code&amp;gt; key.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt; can be one of the existing locale categories, which permits implicit search mechanisms to find translations, but may also be another key, such as &amp;lt;code&amp;gt;[my-mod-messages]&amp;lt;/code&amp;gt;. These are accessible the same as other translations, e.g. &amp;lt;code&amp;gt;{&amp;quot;my-mod-messages.hello&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are located within the language code of the language in the locale folder of the mod, so as an English example &amp;lt;code&amp;gt;__mod__/locale/en/any_name_here.cfg&amp;lt;/code&amp;gt;. There can be more than 1 file per language, all of them will be read.&lt;br /&gt;
&lt;br /&gt;
== Localising simple strings ==&lt;br /&gt;
The simplest localisation is of items, entities etc. If we say the item is &amp;lt;code&amp;gt;iron-plate&amp;lt;/code&amp;gt;, the game will then search all loaded locale files for &amp;lt;code&amp;gt;item-name.iron-plate&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;item-description.iron-plate&amp;lt;/code&amp;gt;, which in the locale file looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;[item-name]&lt;br /&gt;
iron-plate=Iron plate&lt;br /&gt;
[item-description]&lt;br /&gt;
iron-plate=A plate made of iron.&amp;lt;/pre&amp;gt;&lt;br /&gt;
If found in the locale, the label is set to this string. If not found, the game will instead show: &amp;lt;code&amp;gt;Unknown key: &amp;amp;quot;item-name.iron-plate&amp;amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In script, the localised string is formatted as &amp;lt;code&amp;gt;{&amp;amp;quot;category.name&amp;amp;quot;}&amp;lt;/code&amp;gt;, so &amp;lt;code&amp;gt;game.print({&amp;amp;quot;item-name.iron-plate&amp;amp;quot;})&amp;lt;/code&amp;gt; prints &#039;&#039;Iron plate&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It is possible to use [[rich text]] features in the localised text if the location where the text is shown supports it, e.g. in the chat, prototype names and prototype tooltips.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt; can be used for line breaks if the location where the text is shown supports multiline text.&lt;br /&gt;
&lt;br /&gt;
The list of all localization categories used by the base game is:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Localization categories &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[achievement-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[achievement-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[ammo-category-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[autoplace-control-names]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[controls]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[damage-type-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[decorative-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[entity-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[entity-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[equipment-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[fluid-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[fuel-category-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-group-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-limitation]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[map-gen-preset-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[map-gen-preset-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[mod-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[mod-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[modifier-description]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[programmable-speaker-instrument]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[programmable-speaker-note]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[recipe-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[shortcut-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[story]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[string-mod-setting]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[technology-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[technology-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tile-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tips-and-tricks-item-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tips-and-tricks-item-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[virtual-signal-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[virtual-signal-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Localising with parameters ==&lt;br /&gt;
For more complex strings, localisation parameters can be used. For instance we want to show &#039;&#039;Time left: 10 minutes.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
So a key with a placeholder is defined, which is replaced by the first parameter after the locale key.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;time-left=Time left: __1__ minutes.&amp;lt;/pre&amp;gt;&lt;br /&gt;
So it is used like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;time-left&amp;quot;, 10})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
It also works with multiple parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;time-left&amp;quot;, 10, 45})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;time-left=Time left: __1__ minutes and __2__ seconds.&amp;lt;/pre&amp;gt;&lt;br /&gt;
Which results in &#039;&#039;Time left: 10 minutes and 45 seconds.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Built-in parameters ===&lt;br /&gt;
For some situations, we use localisation to show control schemes. For instance we want to say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;technology-prompt=Use T to open the technology screen&amp;lt;/pre&amp;gt;&lt;br /&gt;
However the player may have rebound the key, but we can’t figure out which key as it would not be deterministic. So instead we use the built-in replacement functionality&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;technology-prompt=Use __CONTROL__open-technology-gui__ to open the technology screen.&amp;lt;/pre&amp;gt;&lt;br /&gt;
We can also use this for items and entities:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;big-iron-plate=Big __ITEM__iron-plate__&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;tiny-gun-turret=Tiny __ENTITY__gun-turret__&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== List of built-in parameters ====&lt;br /&gt;
&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; is the name of an internal game control or a prototype name, depending on context. &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; can be 1 or 2, it&#039;s used in parameters that control [[#Localising_alternate_input_names|alternate input names]]. For a list of internal game control names, see [https://lua-api.factorio.com/latest/types/LinkedGameControl.html CustomInputPrototype::linked_game_control].&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL__name__&amp;lt;/code&amp;gt; - The combination of modifiers and input, such as &amp;quot;Control + Alt + Left-click&amp;quot;, or &amp;quot;Not set&amp;quot;.&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_MODIFIER__name__&amp;lt;/code&amp;gt; - The modifiers, such as &amp;quot;ControlShift&amp;quot;, or, &amp;quot;No modifier selected.&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_STYLE_BEGIN__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_STYLE_END__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_LEFT_CLICK__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-1&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-b&amp;lt;/code&amp;gt;[https://crowdin.com/project/factorio/discussions/214]&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_RIGHT_CLICK__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-2&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-x&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_KEY_SHIFT__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.shift&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-leftshoulder&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_KEY_CTRL__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.control&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-rightshoulder&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL_LEFT_CLICK__n__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-1-alt-n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-button-alt-n&amp;lt;/code&amp;gt; (with parameter &amp;lt;code&amp;gt;control-keys.controller-b&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL_RIGHT_CLICK__n__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-2-alt-n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-button-alt-n&amp;lt;/code&amp;gt; (with parameter &amp;lt;code&amp;gt;control-keys.controller-x&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL__n__name__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_MOVE__&amp;lt;/code&amp;gt; - The Movement keys, squished together. Example: &amp;quot;WASD&amp;quot;, from a conventional QWERTY English keyboard.&lt;br /&gt;
* &amp;lt;code&amp;gt;__REMARK_COLOR_BEGIN__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__REMARK_COLOR_END__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__ENTITY__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/EntityPrototype.html EntityPrototype] subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__FLUID__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/FluidPrototype.html FluidPrototype].&lt;br /&gt;
* &amp;lt;code&amp;gt;__ITEM__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/ItemPrototype.html ItemPrototype] or subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__PLANET__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/SpaceLocationPrototype.html SpaceLocationPrototype] or subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__TILE__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/TilePrototype.html TilePrototype].&lt;br /&gt;
&lt;br /&gt;
=== Plurals ===&lt;br /&gt;
Pluralization can be used in any string that uses a parameter (e.g. __1__) that is numeric, so something like an amount of minutes. It can be used multiple times per string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;format-days=__1__ __plural_for_parameter__1__{1=day|rest=days}__&amp;lt;/pre&amp;gt;&lt;br /&gt;
This results in &amp;quot;1 day&amp;quot; and &amp;quot;2 days&amp;quot; / &amp;quot;500 days&amp;quot; etc.&lt;br /&gt;
&lt;br /&gt;
The number after &amp;lt;code&amp;gt;__plural_for_parameter__&amp;lt;/code&amp;gt; denotes which parameter is used to determine the plural. This is the parameter 1 in the above example. Anything inside the {} is used to make the plural. Each plural form is separated by a |.&lt;br /&gt;
The text in front of the = determines for what the plural form is used. Options for this are:&lt;br /&gt;
* A simple number, e.g. &amp;quot;1&amp;quot;. &lt;br /&gt;
* Multiple numbers, e.g. &amp;quot;2,3,4&amp;quot;.&lt;br /&gt;
* What the number ends with, e.g. &amp;quot;ends in 11&amp;quot; or &amp;quot;ends in 1&amp;quot;&lt;br /&gt;
* Multiple ends with, e.g. &amp;quot;ends in 1,ends in 2,ends in 12&amp;quot;.&lt;br /&gt;
* &amp;quot;decimal&amp;quot; for any number with a fractional part. &lt;br /&gt;
* &amp;quot;rest&amp;quot; to give the default plural.&lt;br /&gt;
&lt;br /&gt;
For negative numbers the plural is picked as if the number was positive, so a plural like &amp;lt;code&amp;gt;__plural_for_parameter__1__{1=day|rest=days}__&amp;lt;/code&amp;gt; will result in &amp;quot;-1 day&amp;quot; for -1.&amp;lt;br&amp;gt;&lt;br /&gt;
For numbers with a SI prefix the plural is picked as if the number was fully written out, so a plural like &amp;lt;code&amp;gt;__plural_for_parameter__1__{1=day|1000=eons|rest=days}__&amp;lt;/code&amp;gt; will result in &amp;quot;1k eons&amp;quot; for 1k.&lt;br /&gt;
&lt;br /&gt;
Plural forms may be empty or contain other keys such as __1__ or spaces. This allows rather large plural forms:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;__plural_for_parameter__1__{1=__1__ player is|rest=__1__ players are}__ connecting&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system picks the first fitting plural that it encounters when multiple would fit:&lt;br /&gt;
&amp;lt;pre&amp;gt;__plural_for_parameter__1__{ends in 12=option 1|ends in 2=option 2|rest=option 3}__&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will result in &amp;quot;option 1&amp;quot; for 12 and in &amp;quot;option 2&amp;quot; for 22 and in &amp;quot;option 3&amp;quot; for numbers not ending with 2.&lt;br /&gt;
&lt;br /&gt;
The parameter used for pluralisation does not need to be present in the string. For example, a parameter could represent the number of list items present in another parameter:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I like __plural_for_parameter__1__{1=only one thing:|rest=these things:} __2__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Can result in &amp;quot;I like only one thing: trains&amp;quot;, or in &amp;quot;I like these things: trains and turtles&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Concatenating localised strings ===&lt;br /&gt;
The special locale key: &amp;lt;code&amp;gt;&amp;amp;quot;&amp;amp;quot;&amp;lt;/code&amp;gt; is used to concatenate, as the table format does not support concatenation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;&amp;quot;, {&amp;quot;item-name.iron-plate&amp;quot;}, &amp;quot;: &amp;quot;, 60})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Will result in: &#039;&#039;Iron plate: 60&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Localising alternate input names ===&lt;br /&gt;
&lt;br /&gt;
In the introduction campaign, a special locale system is used for informing players how to do certain actions with their mouse.&lt;br /&gt;
The normal form is to use eg:&lt;br /&gt;
&amp;lt;pre&amp;gt;how-to-build=Use __CONTROL__build__ to place a building&amp;lt;/pre&amp;gt;&lt;br /&gt;
which results in &amp;quot;Use Left mouse button to place a building&amp;quot;. A more natural phrasing would be &amp;quot;Left-click to place a building&amp;quot;, which can be achieved by using the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;how-to-build=__ALT_CONTROL__1__build__ to place a building&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These &amp;quot;alt&amp;quot; versions are controlled by a few special locale keys, mouse-button-X-alt-1 and mouse-button-X-alt-2. In English, form 1 produces eg &amp;quot;Left-click&amp;quot;, and form 2 produces eg &amp;quot;Left-clicking&amp;quot;.  Only two alt forms (&amp;quot;1&amp;quot; and &amp;quot;2&amp;quot;) are available at the moment, but if this a problem for some languages, more forms may be added in the future.&lt;br /&gt;
Extra mouse buttons, mouse scroll and keyboard keys are handled through the mouse-button-n-alt-1/2, mouse-wheel-alt-1/2 and keyboard-alt-1/2 keys, which just take the normal name and prepend something like &amp;quot;Press/Pressing&amp;quot;, or &amp;quot;Scroll/Scrolling&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
When translating to another language, you can use whatever forms you want here, but the important part is that you are consistent when you use the alt-forms everywhere else. It does not necessarily make sense to just copy the usages of alt forms from the English locale, and for some languages it may be more natural to simply not use this system at all.&lt;br /&gt;
&lt;br /&gt;
== Accessing the localised result in code ==&lt;br /&gt;
While usually unneeded, it is possible to read the resulting localised text in code, for example to search in localised names.&lt;br /&gt;
&lt;br /&gt;
See&lt;br /&gt;
[https://lua-api.factorio.com/latest/classes/LuaPlayer.html#request_translation LuaPlayer::request_translation],&lt;br /&gt;
[https://lua-api.factorio.com/latest/classes/LuaPlayer.html#request_translations LuaPlayer::request_translations] and&lt;br /&gt;
[https://lua-api.factorio.com/latest/events.html#on_string_translated on_string_translated event].&lt;br /&gt;
&lt;br /&gt;
== Default Behavior(s) for finding an Unspecified Localised String ==&lt;br /&gt;
If a localised_string is not defined in the prototype for certain prototype classes, e.g. entity, item, Factorio may have a default search behavior.&lt;br /&gt;
&lt;br /&gt;
Determining an item&#039;s localised name:&lt;br /&gt;
Note: the angle brackets are meant to mean a generic term, they are not part of the actual string. Also, place_result and placed_as_equipment_result are strings, and Factorio fetches the matching prototype to examine.&lt;br /&gt;
&lt;br /&gt;
# if localised_name is provided in the item prototype and it is not empty {}, use the provided value&lt;br /&gt;
# else if there is place_result and it has localised_name that is not an empty table: {}, use the localised_name of place_result&lt;br /&gt;
# else if there is place_result with an empty localised_name, use {&amp;quot;entity-name.&amp;lt;entity prototype name&amp;gt;&amp;quot;}&lt;br /&gt;
# else if there is placed_as_equipment_result and it has a localised_name that is not an empty table: {}, use the localised_name of placed_as_equipment_result&lt;br /&gt;
# else if there is placed_as_equipment_result with empty localised_name, use {&amp;quot;equipment-name.&amp;lt;equipment name&amp;gt;&amp;quot;}&lt;br /&gt;
# else use default {&amp;quot;item-name.&amp;lt;item name&amp;gt;&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Reference: [https://forums.factorio.com/viewtopic.php?p=494243#p494243]&lt;br /&gt;
&lt;br /&gt;
Example: The transport-belt item does not have a localised_name, so 1-&amp;gt;2. There is a place result, but not localised_name in the entity prototype. 2-&amp;gt;3. The place result lacks a localised_name. Use the localised string {&amp;quot;entity-name.transport-belt&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Such defaults often include a &amp;quot;leading key&amp;quot; using [&amp;lt;group&amp;gt;-name] or [&amp;lt;group&amp;gt;-description] (such as [recipe-name], [mod-setting-description]). However, each prototype may have a distinct search behavior before using those, based on presence/absence of values in the prototype. [https://lua-api.factorio.com/latest/prototypes/RecipePrototype.html RecipePrototype] for example may use the first product&#039;s localised_name, or the main_product&#039;s localised_name, or the localised string found in {&amp;quot;recipe-name.&amp;lt;recipe name&amp;gt;&amp;quot;], depending on values provided (and lacking) in the prototype.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://lua-api.factorio.com/latest/types/LocalisedString.html LocalisedString data stage doc]&lt;br /&gt;
* [https://lua-api.factorio.com/latest/concepts/LocalisedString.html LocalisedString control stage doc]&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;/div&gt;</summary>
		<author><name>Osmo</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Localisation&amp;diff=218718</id>
		<title>Tutorial:Localisation</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Localisation&amp;diff=218718"/>
		<updated>2026-06-08T12:34:08Z</updated>

		<summary type="html">&lt;p&gt;Osmo: /* Default Behavior(s) for finding an Unspecified Localised String */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}Mods should define human readable names for prototypes that they add. They can also define descriptions for items or custom strings for usage in GUIs etc. This is called &#039;&#039;&#039;localisation&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== File format ==&lt;br /&gt;
Translations are stored as .cfg files, with the following format:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;welcome-message=Hello world&lt;br /&gt;
[category]&lt;br /&gt;
title=Category related title&lt;br /&gt;
# Comment&lt;br /&gt;
; Another comment&amp;lt;/pre&amp;gt;&lt;br /&gt;
Any whitespace after or before &amp;lt;code&amp;gt;=&amp;lt;/code&amp;gt; is included in the key or string, so &amp;lt;code&amp;gt;title =Category related title&amp;lt;/code&amp;gt; will give an unknown key error if you are looking for the &amp;lt;code&amp;gt;title&amp;lt;/code&amp;gt; key, since it is the &amp;lt;code&amp;gt;title&amp;amp;nbsp;&amp;lt;/code&amp;gt; key.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;category&amp;lt;/code&amp;gt; can be one of the existing locale categories, which permits implicit search mechanisms to find translations, but may also be another key, such as &amp;lt;code&amp;gt;[my-mod-messages]&amp;lt;/code&amp;gt;. These are accessible the same as other translations, e.g. &amp;lt;code&amp;gt;{&amp;quot;my-mod-messages.hello&amp;quot;}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are located within the language code of the language in the locale folder of the mod, so as an English example &amp;lt;code&amp;gt;__mod__/locale/en/any_name_here.cfg&amp;lt;/code&amp;gt;. There can be more than 1 file per language, all of them will be read.&lt;br /&gt;
&lt;br /&gt;
== Localising simple strings ==&lt;br /&gt;
The simplest localisation is of items, entities etc. If we say the item is &amp;lt;code&amp;gt;iron-plate&amp;lt;/code&amp;gt;, the game will then search all loaded locale files for &amp;lt;code&amp;gt;item-name.iron-plate&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;item-description.iron-plate&amp;lt;/code&amp;gt;, which in the locale file looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;[item-name]&lt;br /&gt;
iron-plate=Iron plate&lt;br /&gt;
[item-description]&lt;br /&gt;
iron-plate=A plate made of iron.&amp;lt;/pre&amp;gt;&lt;br /&gt;
If found in the locale, the label is set to this string. If not found, the game will instead show: &amp;lt;code&amp;gt;Unknown key: &amp;amp;quot;item-name.iron-plate&amp;amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In script, the localised string is formatted as &amp;lt;code&amp;gt;{&amp;amp;quot;category.name&amp;amp;quot;}&amp;lt;/code&amp;gt;, so &amp;lt;code&amp;gt;game.print({&amp;amp;quot;item-name.iron-plate&amp;amp;quot;})&amp;lt;/code&amp;gt; prints &#039;&#039;Iron plate&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
It is possible to use [[rich text]] features in the localised text if the location where the text is shown supports it, e.g. in the chat, prototype names and prototype tooltips.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;\n&amp;lt;/code&amp;gt; can be used for line breaks if the location where the text is shown supports multiline text.&lt;br /&gt;
&lt;br /&gt;
The list of all localization categories used by the base game is:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;mw-collapsible mw-collapsed wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Localization categories &lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[achievement-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[achievement-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[ammo-category-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[autoplace-control-names]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[controls]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[damage-type-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[decorative-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[entity-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[entity-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[equipment-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[fluid-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[fuel-category-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-group-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-limitation]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[item-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[map-gen-preset-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[map-gen-preset-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[mod-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[mod-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[modifier-description]&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[programmable-speaker-instrument]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[programmable-speaker-note]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[recipe-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[shortcut-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[story]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[string-mod-setting]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[technology-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[technology-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tile-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tips-and-tricks-item-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[tips-and-tricks-item-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[virtual-signal-description]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;[virtual-signal-name]&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Localising with parameters ==&lt;br /&gt;
For more complex strings, localisation parameters can be used. For instance we want to show &#039;&#039;Time left: 10 minutes.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
So a key with a placeholder is defined, which is replaced by the first parameter after the locale key.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;time-left=Time left: __1__ minutes.&amp;lt;/pre&amp;gt;&lt;br /&gt;
So it is used like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;time-left&amp;quot;, 10})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
It also works with multiple parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;time-left&amp;quot;, 10, 45})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;time-left=Time left: __1__ minutes and __2__ seconds.&amp;lt;/pre&amp;gt;&lt;br /&gt;
Which results in &#039;&#039;Time left: 10 minutes and 45 seconds.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Built-in parameters ===&lt;br /&gt;
For some situations, we use localisation to show control schemes. For instance we want to say:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;technology-prompt=Use T to open the technology screen&amp;lt;/pre&amp;gt;&lt;br /&gt;
However the player may have rebound the key, but we can’t figure out which key as it would not be deterministic. So instead we use the built-in replacement functionality&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;technology-prompt=Use __CONTROL__open-technology-gui__ to open the technology screen.&amp;lt;/pre&amp;gt;&lt;br /&gt;
We can also use this for items and entities:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;big-iron-plate=Big __ITEM__iron-plate__&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;tiny-gun-turret=Tiny __ENTITY__gun-turret__&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== List of built-in parameters ====&lt;br /&gt;
&amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; is the name of an internal game control or a prototype name, depending on context. &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; can be 1 or 2, it&#039;s used in parameters that control [[#Localising_alternate_input_names|alternate input names]]. For a list of internal game control names, see [https://lua-api.factorio.com/latest/types/LinkedGameControl.html CustomInputPrototype::linked_game_control].&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL__name__&amp;lt;/code&amp;gt; - The combination of modifiers and input, such as &amp;quot;Control + Alt + Left-click&amp;quot;, or &amp;quot;Not set&amp;quot;.&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_MODIFIER__name__&amp;lt;/code&amp;gt; - The modifiers, such as &amp;quot;ControlShift&amp;quot;, or, &amp;quot;No modifier selected.&amp;quot;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_STYLE_BEGIN__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_STYLE_END__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_LEFT_CLICK__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-1&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-b&amp;lt;/code&amp;gt;[https://crowdin.com/project/factorio/discussions/214]&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_RIGHT_CLICK__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-2&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-x&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_KEY_SHIFT__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.shift&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-leftshoulder&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_KEY_CTRL__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.control&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-rightshoulder&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL_LEFT_CLICK__n__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-1-alt-n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-button-alt-n&amp;lt;/code&amp;gt; (with parameter &amp;lt;code&amp;gt;control-keys.controller-b&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL_RIGHT_CLICK__n__&amp;lt;/code&amp;gt; is replaced with &amp;lt;code&amp;gt;control-keys.mouse-button-2-alt-n&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;control-keys.controller-button-alt-n&amp;lt;/code&amp;gt; (with parameter &amp;lt;code&amp;gt;control-keys.controller-x&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &amp;lt;code&amp;gt;__ALT_CONTROL__n__name__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__CONTROL_MOVE__&amp;lt;/code&amp;gt; - The Movement keys, squished together. Example: &amp;quot;WASD&amp;quot;, from a conventional QWERTY English keyboard.&lt;br /&gt;
* &amp;lt;code&amp;gt;__REMARK_COLOR_BEGIN__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__REMARK_COLOR_END__&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;__ENTITY__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/EntityPrototype.html EntityPrototype] subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__FLUID__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/FluidPrototype.html FluidPrototype].&lt;br /&gt;
* &amp;lt;code&amp;gt;__ITEM__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/ItemPrototype.html ItemPrototype] or subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__PLANET__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/SpaceLocationPrototype.html SpaceLocationPrototype] or subclass.&lt;br /&gt;
* &amp;lt;code&amp;gt;__TILE__name__&amp;lt;/code&amp;gt; - The localised name of the [https://lua-api.factorio.com/latest/prototypes/TilePrototype.html TilePrototype].&lt;br /&gt;
&lt;br /&gt;
=== Plurals ===&lt;br /&gt;
Pluralization can be used in any string that uses a parameter (e.g. __1__) that is numeric, so something like an amount of minutes. It can be used multiple times per string.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;format-days=__1__ __plural_for_parameter__1__{1=day|rest=days}__&amp;lt;/pre&amp;gt;&lt;br /&gt;
This results in &amp;quot;1 day&amp;quot; and &amp;quot;2 days&amp;quot; / &amp;quot;500 days&amp;quot; etc.&lt;br /&gt;
&lt;br /&gt;
The number after &amp;lt;code&amp;gt;__plural_for_parameter__&amp;lt;/code&amp;gt; denotes which parameter is used to determine the plural. This is the parameter 1 in the above example. Anything inside the {} is used to make the plural. Each plural form is separated by a |.&lt;br /&gt;
The text in front of the = determines for what the plural form is used. Options for this are:&lt;br /&gt;
* A simple number, e.g. &amp;quot;1&amp;quot;. &lt;br /&gt;
* Multiple numbers, e.g. &amp;quot;2,3,4&amp;quot;.&lt;br /&gt;
* What the number ends with, e.g. &amp;quot;ends in 11&amp;quot; or &amp;quot;ends in 1&amp;quot;&lt;br /&gt;
* Multiple ends with, e.g. &amp;quot;ends in 1,ends in 2,ends in 12&amp;quot;.&lt;br /&gt;
* &amp;quot;decimal&amp;quot; for any number with a fractional part. &lt;br /&gt;
* &amp;quot;rest&amp;quot; to give the default plural.&lt;br /&gt;
&lt;br /&gt;
For negative numbers the plural is picked as if the number was positive, so a plural like &amp;lt;code&amp;gt;__plural_for_parameter__1__{1=day|rest=days}__&amp;lt;/code&amp;gt; will result in &amp;quot;-1 day&amp;quot; for -1.&amp;lt;br&amp;gt;&lt;br /&gt;
For numbers with a SI prefix the plural is picked as if the number was fully written out, so a plural like &amp;lt;code&amp;gt;__plural_for_parameter__1__{1=day|1000=eons|rest=days}__&amp;lt;/code&amp;gt; will result in &amp;quot;1k eons&amp;quot; for 1k.&lt;br /&gt;
&lt;br /&gt;
Plural forms may be empty or contain other keys such as __1__ or spaces. This allows rather large plural forms:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;__plural_for_parameter__1__{1=__1__ player is|rest=__1__ players are}__ connecting&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system picks the first fitting plural that it encounters when multiple would fit:&lt;br /&gt;
&amp;lt;pre&amp;gt;__plural_for_parameter__1__{ends in 12=option 1|ends in 2=option 2|rest=option 3}__&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will result in &amp;quot;option 1&amp;quot; for 12 and in &amp;quot;option 2&amp;quot; for 22 and in &amp;quot;option 3&amp;quot; for numbers not ending with 2.&lt;br /&gt;
&lt;br /&gt;
The parameter used for pluralisation does not need to be present in the string. For example, a parameter could represent the number of list items present in another parameter:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
I like __plural_for_parameter__1__{1=only one thing:|rest=these things:} __2__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Can result in &amp;quot;I like only one thing: trains&amp;quot;, or in &amp;quot;I like these things: trains and turtles&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Concatenating localised strings ===&lt;br /&gt;
The special locale key: &amp;lt;code&amp;gt;&amp;amp;quot;&amp;amp;quot;&amp;lt;/code&amp;gt; is used to concatenate, as the table format does not support concatenation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;game.print({&amp;quot;&amp;quot;, {&amp;quot;item-name.iron-plate&amp;quot;}, &amp;quot;: &amp;quot;, 60})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Will result in: &#039;&#039;Iron plate: 60&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Localising alternate input names ===&lt;br /&gt;
&lt;br /&gt;
In the introduction campaign, a special locale system is used for informing players how to do certain actions with their mouse.&lt;br /&gt;
The normal form is to use eg:&lt;br /&gt;
&amp;lt;pre&amp;gt;how-to-build=Use __CONTROL__build__ to place a building&amp;lt;/pre&amp;gt;&lt;br /&gt;
which results in &amp;quot;Use Left mouse button to place a building&amp;quot;. A more natural phrasing would be &amp;quot;Left-click to place a building&amp;quot;, which can be achieved by using the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;how-to-build=__ALT_CONTROL__1__build__ to place a building&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These &amp;quot;alt&amp;quot; versions are controlled by a few special locale keys, mouse-button-X-alt-1 and mouse-button-X-alt-2. In English, form 1 produces eg &amp;quot;Left-click&amp;quot;, and form 2 produces eg &amp;quot;Left-clicking&amp;quot;.  Only two alt forms (&amp;quot;1&amp;quot; and &amp;quot;2&amp;quot;) are available at the moment, but if this a problem for some languages, more forms may be added in the future.&lt;br /&gt;
Extra mouse buttons, mouse scroll and keyboard keys are handled through the mouse-button-n-alt-1/2, mouse-wheel-alt-1/2 and keyboard-alt-1/2 keys, which just take the normal name and prepend something like &amp;quot;Press/Pressing&amp;quot;, or &amp;quot;Scroll/Scrolling&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
When translating to another language, you can use whatever forms you want here, but the important part is that you are consistent when you use the alt-forms everywhere else. It does not necessarily make sense to just copy the usages of alt forms from the English locale, and for some languages it may be more natural to simply not use this system at all.&lt;br /&gt;
&lt;br /&gt;
== Accessing the localised result in code ==&lt;br /&gt;
While usually unneeded, it is possible to read the resulting localised text in code, for example to search in localised names.&lt;br /&gt;
&lt;br /&gt;
See&lt;br /&gt;
[https://lua-api.factorio.com/latest/classes/LuaPlayer.html#request_translation LuaPlayer::request_translation],&lt;br /&gt;
[https://lua-api.factorio.com/latest/classes/LuaPlayer.html#request_translations LuaPlayer::request_translations] and&lt;br /&gt;
[https://lua-api.factorio.com/latest/events.html#on_string_translated on_string_translated event].&lt;br /&gt;
&lt;br /&gt;
== Default Behavior(s) for finding an Unspecified Localised String ==&lt;br /&gt;
If a localised_name or localised_description is not defined in the prototype or is an empty table: {}, Factorio may have a default search behavior.&lt;br /&gt;
&lt;br /&gt;
For most types, the name defaults to {&amp;quot;&amp;lt;base type&amp;gt;-name.&amp;lt;prototype name&amp;gt;&amp;quot;}, for example {&amp;quot;entity-name.underground-belt&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Similarly, the description defaults to {&amp;quot;&amp;lt;base type&amp;gt;-description.&amp;lt;prototype name&amp;gt;&amp;quot;}, for example {&amp;quot;entity-description.underground-belt&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Note: the angle brackets are meant to mean a generic term, they are not part of the actual string.&lt;br /&gt;
&lt;br /&gt;
For items, the process is more complicated:&lt;br /&gt;
# if localised_name is provided in the item prototype and it is not empty {}, use the provided value&lt;br /&gt;
# else if the item prototype has a place_result:&lt;br /&gt;
#:# if place_result has localised_name that is not an empty table: {}, use the localised_name of place_result&lt;br /&gt;
#:# else if {&amp;quot;entity-name.&amp;lt;place_result name&amp;gt;&amp;quot;} has a translation, use it&lt;br /&gt;
#:# else use {&amp;quot;item-name.&amp;lt;item name&amp;gt;&amp;quot;}&lt;br /&gt;
# else if the item prototype has a placed_as_equipment_result:&lt;br /&gt;
#:# if place_result has a localised_name that is not an empty table: {}, use the localised_name of placed_as_equipment_result&lt;br /&gt;
#:# else if {&amp;quot;equipment-name.&amp;lt;place_as_equipment_result name&amp;gt;&amp;quot;} has a translation, use it&lt;br /&gt;
#:# else use {&amp;quot;item-name.&amp;lt;item name&amp;gt;&amp;quot;}&lt;br /&gt;
# else if the item prototype has a placed_as_tile:&lt;br /&gt;
#:# if place_as_tile result has a localised_name that is not an empty table: {}, use the localised_name of placed_as_tile result&lt;br /&gt;
#:# else if {&amp;quot;tile-name.&amp;lt;place_as_tile result name&amp;gt;&amp;quot;} has a translation, use it&lt;br /&gt;
#:# else use {&amp;quot;item-name.&amp;lt;item name&amp;gt;&amp;quot;}&lt;br /&gt;
# else use {&amp;quot;item-name.&amp;lt;item name&amp;gt;&amp;quot;}&lt;br /&gt;
Descriptions of items are found in the same way, except localised_description is used instead of localised_name and &amp;lt;base type&amp;gt;-description is used instead of &amp;lt;base type&amp;gt;-name.&lt;br /&gt;
&lt;br /&gt;
Reference: [https://forums.factorio.com/viewtopic.php?p=494243#p494243] &amp;lt;!-- TODO: Keep it? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example: The transport-belt item does not have a localised_name, so 1-&amp;gt;2. There is a place result, but not localised_name in the entity prototype. 2-&amp;gt;3. The place result lacks a localised_name. Use the localised string {&amp;quot;entity-name.transport-belt&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
Such defaults often include a &amp;quot;leading key&amp;quot; using [&amp;lt;group&amp;gt;-name] or [&amp;lt;group&amp;gt;-description] (such as [recipe-name], [mod-setting-description]). However, each prototype may have a distinct search behavior before using those, based on presence/absence of values in the prototype. [https://lua-api.factorio.com/latest/prototypes/RecipePrototype.html RecipePrototype] for example may use the first product&#039;s localised_name, or the main_product&#039;s localised_name, or the localised string found in {&amp;quot;recipe-name.&amp;lt;recipe name&amp;gt;&amp;quot;], depending on values provided (and lacking) in the prototype.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://lua-api.factorio.com/latest/types/LocalisedString.html LocalisedString data stage doc]&lt;br /&gt;
* [https://lua-api.factorio.com/latest/concepts/LocalisedString.html LocalisedString control stage doc]&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;/div&gt;</summary>
		<author><name>Osmo</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Command_line_parameters&amp;diff=218191</id>
		<title>Command line parameters</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Command_line_parameters&amp;diff=218191"/>
		<updated>2026-04-24T03:41:35Z</updated>

		<summary type="html">&lt;p&gt;Osmo: Add --enable-lua-udp&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}__TOC__&lt;br /&gt;
&lt;br /&gt;
Command line parameters can be used to set settings in the command line before the game launches, this is useful mainly for advanced users or server hosts.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+General options&lt;br /&gt;
|-&lt;br /&gt;
| -h, --help&lt;br /&gt;
|&lt;br /&gt;
| display help&lt;br /&gt;
|-&lt;br /&gt;
| --version&lt;br /&gt;
|&lt;br /&gt;
| show version information&lt;br /&gt;
|-&lt;br /&gt;
| -v, --verbose&lt;br /&gt;
|&lt;br /&gt;
| enable verbose logging&lt;br /&gt;
|-&lt;br /&gt;
| -c, --config&lt;br /&gt;
| PATH&lt;br /&gt;
| config file to use&lt;br /&gt;
|-&lt;br /&gt;
| --no-log-rotation&lt;br /&gt;
|&lt;br /&gt;
| don&#039;t rotate log file&lt;br /&gt;
|-&lt;br /&gt;
| --mod-directory&lt;br /&gt;
| PATH&lt;br /&gt;
| Mod directory to use&lt;br /&gt;
|-&lt;br /&gt;
| --check-unused-prototype-data&lt;br /&gt;
|&lt;br /&gt;
| Print a warning for all prototype values that were not accessed. Note for mod authors: If an entry is unused and is a table that contains the key/value pair &#039;ignore&#039; with the value &#039;true&#039; then the entire entry is ignored.&lt;br /&gt;
|-&lt;br /&gt;
| --executable-path&lt;br /&gt;
| PATH&lt;br /&gt;
| Override autodetected __PATH__executable. Usually not needed except on very weird systems.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Running options&lt;br /&gt;
|-&lt;br /&gt;
| -s, --map2scenario&lt;br /&gt;
| arg&lt;br /&gt;
| map to scenario conversion&lt;br /&gt;
|-&lt;br /&gt;
| -m, --scenario2map&lt;br /&gt;
| arg&lt;br /&gt;
| scenario to map conversion&lt;br /&gt;
|-&lt;br /&gt;
| --apply-update&lt;br /&gt;
| arg&lt;br /&gt;
| immediately apply update package&lt;br /&gt;
|-&lt;br /&gt;
| --create&lt;br /&gt;
| FILE&lt;br /&gt;
| create a new map&lt;br /&gt;
|-&lt;br /&gt;
| --map-gen-settings&lt;br /&gt;
| FILE&lt;br /&gt;
| Map generation settings for use with &amp;lt;code&amp;gt;--create&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;--start-server-load-scenario&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;--generate-map-preview&amp;lt;/code&amp;gt;. See data/map-gen-settings.example.json&lt;br /&gt;
|-&lt;br /&gt;
| --map-gen-seed&lt;br /&gt;
| SEED&lt;br /&gt;
| Map generation seed for use with --create, --start-server-load-scenario or --generate-map-preview. Will override seed specified in map gen settings&lt;br /&gt;
|-&lt;br /&gt;
| --map-gen-seed-max&lt;br /&gt;
| SEED&lt;br /&gt;
| Map generation seed for use with --generate-map-preview to generate multiple previews using every second seed in the interval from map-gen-seed to map-gen-seed-max.&lt;br /&gt;
|-&lt;br /&gt;
| --map-settings&lt;br /&gt;
| FILE&lt;br /&gt;
| Map settings for use with --create or --start-server-load-scenario. See data/base/prototypes/map-settings.lua&lt;br /&gt;
|-&lt;br /&gt;
| --preset&lt;br /&gt;
| arg&lt;br /&gt;
| Name of the map generation preset to be used.&lt;br /&gt;
|-&lt;br /&gt;
| --generate-map-preview&lt;br /&gt;
| PATH&lt;br /&gt;
| Generate preview images of the map; PATH should name a PNG file or end with a &#039;/&#039; or &#039;\&#039; to indicate a directory.&lt;br /&gt;
|-&lt;br /&gt;
| --generate-map-preview-random&lt;br /&gt;
| COUNT&lt;br /&gt;
| Number of maps to generate with a random seed using --generate-map-preview.&lt;br /&gt;
|-&lt;br /&gt;
| --map-preview-size&lt;br /&gt;
| SIZE&lt;br /&gt;
| Size (in pixels) of map preview (default: 1024)&lt;br /&gt;
|-&lt;br /&gt;
| --map-preview-offset&lt;br /&gt;
| X,Y&lt;br /&gt;
| Offset of the center of the map, in meters (default: 0,0)&lt;br /&gt;
|-&lt;br /&gt;
| --map-preview-planet&lt;br /&gt;
| PLANET&lt;br /&gt;
| Planet to generate the preview for (default: nauvis)&lt;br /&gt;
|-&lt;br /&gt;
| --report-quantities&lt;br /&gt;
| PROTOTYPE,...&lt;br /&gt;
| When generating map preview, report approximate quantities of the named entity prototypes&lt;br /&gt;
|-&lt;br /&gt;
| --threads&lt;br /&gt;
| THREADCOUNT&lt;br /&gt;
| Number of threads to use when generating map previews&lt;br /&gt;
|-&lt;br /&gt;
| --disable-migration-window&lt;br /&gt;
|&lt;br /&gt;
| Disables the gui that is shown when opening a save with migrated content&lt;br /&gt;
|-&lt;br /&gt;
| --instrument-mod&lt;br /&gt;
| arg&lt;br /&gt;
| Name of a mod to enable [https://lua-api.factorio.com/latest/auxiliary/instrument.html Instrument Mode]&lt;br /&gt;
|-&lt;br /&gt;
| --sync-mods&lt;br /&gt;
| FILE&lt;br /&gt;
| Sync mods with save. Note for headless servers: requires &amp;lt;code&amp;gt;service-username&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;service-token&amp;lt;/code&amp;gt; to be set in the player-data.json file if any mods need to be downloaded.&lt;br /&gt;
|-&lt;br /&gt;
| --enable-unsafe-lua-debug-api&lt;br /&gt;
|&lt;br /&gt;
| Enables unsafe functions in the Lua debug library.&lt;br /&gt;
|-&lt;br /&gt;
| --enable-lua-udp&lt;br /&gt;
| arg&lt;br /&gt;
| Set local port and enable [https://lua-api.factorio.com/latest/classes/LuaHelpers.html#send_udp helpers.send_udp()] and and [https://lua-api.factorio.com/latest/classes/LuaHelpers.html#recv_udp helpers.recv_udp()]&lt;br /&gt;
|-&lt;br /&gt;
| --host&lt;br /&gt;
| FILE&lt;br /&gt;
| Start hosting a multiplayer game&lt;br /&gt;
|-&lt;br /&gt;
| --host-interactive&lt;br /&gt;
| FILE&lt;br /&gt;
| Open multiplayer server settings for hosting the selecting save&lt;br /&gt;
|-&lt;br /&gt;
| --start-server&lt;br /&gt;
| FILE&lt;br /&gt;
| start a multiplayer server&lt;br /&gt;
|-&lt;br /&gt;
| --start-server-load-scenario&lt;br /&gt;
| [MOD/]NAME&lt;br /&gt;
| start a multiplayer server and load the specified scenario. The scenario is looked for inside the given mod. If no mod is given, it is looked for in the top-level scenarios directory.&lt;br /&gt;
|-&lt;br /&gt;
| --start-server-load-latest&lt;br /&gt;
|&lt;br /&gt;
| start a multiplayer server and load the latest available save&lt;br /&gt;
|-&lt;br /&gt;
| --until-tick&lt;br /&gt;
| TICK&lt;br /&gt;
| run a save until given map tick&lt;br /&gt;
|-&lt;br /&gt;
| --benchmark&lt;br /&gt;
| FILE&lt;br /&gt;
| load save and run benchmark&lt;br /&gt;
|-&lt;br /&gt;
| --benchmark-ticks&lt;br /&gt;
| N&lt;br /&gt;
| number of ticks for benchmarking. Default is 1000&lt;br /&gt;
|-&lt;br /&gt;
| --benchmark-runs&lt;br /&gt;
| N&lt;br /&gt;
| how often the number of ticks will be run, map will reload after each run. Default is 1&lt;br /&gt;
|-&lt;br /&gt;
| --benchmark-verbose&lt;br /&gt;
| timings&lt;br /&gt;
| comma separated list of Update timings to output each tick. &amp;quot;all&amp;quot;, &amp;quot;timestamp&amp;quot; as well as all other values seen in the debug show-time-usage view&#039;s Update section are allowed here. An empty string disabled verbose benchmarking. Timings are returned in nanoseconds.&lt;br /&gt;
|-&lt;br /&gt;
| --benchmark-sanitize&lt;br /&gt;
|&lt;br /&gt;
| only output the final benchmark results&lt;br /&gt;
|-&lt;br /&gt;
| --benchmark-ignore-paused&lt;br /&gt;
|&lt;br /&gt;
| leaves the game paused if it was paused when saved. By default the game is unpaused when a benchmark starts.&lt;br /&gt;
|-&lt;br /&gt;
| --output-perf-stats&lt;br /&gt;
| FILE&lt;br /&gt;
| path of file to which rendering performance statistics measurements should be saved. Special tags {api}, {hw}, {time} and {tag} will be replaced.&lt;br /&gt;
|-&lt;br /&gt;
| --dump-data&lt;br /&gt;
|&lt;br /&gt;
| dumps data.raw as JSON to the script output folder and exits.&lt;br /&gt;
|-&lt;br /&gt;
| --dump-icon-sprites&lt;br /&gt;
|&lt;br /&gt;
| dumps all icon sprites as png files to the script output folder and exits.&lt;br /&gt;
|-&lt;br /&gt;
| --dump-prototype-locale&lt;br /&gt;
|&lt;br /&gt;
| dumps all prototypes name and description (if they have a valid value) to the script output folder and exits.&lt;br /&gt;
|-&lt;br /&gt;
| --report-autogenerated-icon-mipmaps&lt;br /&gt;
|&lt;br /&gt;
| Report which icons will have generated mipmaps.&lt;br /&gt;
|-&lt;br /&gt;
| --log-shared-tile-layers&lt;br /&gt;
|&lt;br /&gt;
| After loading prototypes logs which tile layers are shared by multiple prototypes and lists the prototypes that share them.&lt;br /&gt;
|-&lt;br /&gt;
| --log-spritesheets-to-optimize&lt;br /&gt;
| N&lt;br /&gt;
| Logs N spritesheets that seem to have some nearly transparent noise, and could be made much smaller if the noise was cleaned up.&lt;br /&gt;
|-&lt;br /&gt;
| --mp-connect&lt;br /&gt;
| ADDRESS&lt;br /&gt;
| start factorio and connect to address&lt;br /&gt;
|-&lt;br /&gt;
| --password&lt;br /&gt;
| PASSWORD&lt;br /&gt;
| the password to use when using mp-connect (if any)&lt;br /&gt;
|-&lt;br /&gt;
| --heavy&lt;br /&gt;
|&lt;br /&gt;
| run the game in heavy mode if singleplayer with graphics. (heavy mode is related to investigating desyncs, see [[Desynchronization#Using_heavy_mode_command]])&lt;br /&gt;
|-&lt;br /&gt;
| --load-game&lt;br /&gt;
| FILE&lt;br /&gt;
| start Factorio and load a game in singleplayer&lt;br /&gt;
|-&lt;br /&gt;
| --load-scenario&lt;br /&gt;
| [MOD/]NAME&lt;br /&gt;
| start Factorio and load the specified scenario in singleplayer. The scenario is looked for inside the given mod. If no mod is given, it is looked for in the top-level scenarios directory.&lt;br /&gt;
|-&lt;br /&gt;
| --benchmark-graphics&lt;br /&gt;
| FILE&lt;br /&gt;
| load save and run it with graphics for benchmark-ticks number of ticks as normal game would&lt;br /&gt;
|-&lt;br /&gt;
| --benchmark-frame&lt;br /&gt;
| FILE&lt;br /&gt;
| load save and benchmark graphics rendering of single frame (prepare + render) without updating the game&lt;br /&gt;
|-&lt;br /&gt;
| --force-opengl&lt;br /&gt;
|&lt;br /&gt;
|use OpenGL for rendering (windows, mac only)&lt;br /&gt;
|-&lt;br /&gt;
| --force-d3d&lt;br /&gt;
|&lt;br /&gt;
|use Direct3D for rendering (windows only)&lt;br /&gt;
|-&lt;br /&gt;
| --d3d-adapter&lt;br /&gt;
| ID&lt;br /&gt;
|adapter which should be used to initialized Direct3D (windows only)&lt;br /&gt;
|-&lt;br /&gt;
| --d3d-feature-level&lt;br /&gt;
|&lt;br /&gt;
|override feature level (11, 10.1, 10) (windows only)&lt;br /&gt;
|-&lt;br /&gt;
| --dxgi-blit-model&lt;br /&gt;
|&lt;br /&gt;
|force Blit presentation mode (windows only)&lt;br /&gt;
|-&lt;br /&gt;
| --force-metal&lt;br /&gt;
|&lt;br /&gt;
|use Metal for rendering (mac only)&lt;br /&gt;
|-&lt;br /&gt;
| --debug-graphics&lt;br /&gt;
|&lt;br /&gt;
| enables debugging layer for graphics API. If DirectX is used DirectX SDK needs to be installed for this to work.&lt;br /&gt;
|-&lt;br /&gt;
| --fullscreen&lt;br /&gt;
| BOOL&lt;br /&gt;
| start game in windowed mode (saved to configuration)&lt;br /&gt;
|-&lt;br /&gt;
| --max-texture-size&lt;br /&gt;
| N&lt;br /&gt;
| maximal size of texture that the game can use (saved to configuration). Should be power of two greater than 2048&lt;br /&gt;
|-&lt;br /&gt;
| --graphics-quality&lt;br /&gt;
| arg&lt;br /&gt;
| accepted values: high, medium&lt;br /&gt;
|-&lt;br /&gt;
| --video-memory-usage&lt;br /&gt;
| arg&lt;br /&gt;
| accepted values: all, high, medium, low&lt;br /&gt;
|-&lt;br /&gt;
| --force-graphics-preset&lt;br /&gt;
| arg&lt;br /&gt;
| accepted values: very-low, low, mac-with-low-ram, medium-with-low-vram, medium, high, very-high, extreme&lt;br /&gt;
|-&lt;br /&gt;
| --gfx-safe-mode&lt;br /&gt;
|&lt;br /&gt;
| resets some graphics settings to values that should work on most configurations&lt;br /&gt;
|-&lt;br /&gt;
| --low-vram&lt;br /&gt;
|&lt;br /&gt;
| sprites that are not put into sprite atlases won&#039;t be allocated as texture objects&lt;br /&gt;
|-&lt;br /&gt;
| --shader&lt;br /&gt;
| arg&lt;br /&gt;
| enable/disable shader postprocessing (saved to configuration)&lt;br /&gt;
|-&lt;br /&gt;
| --disable-audio&lt;br /&gt;
|&lt;br /&gt;
| Disable audio. Mainly for faster startup during development.&lt;br /&gt;
|-&lt;br /&gt;
| --window-size&lt;br /&gt;
| arg&lt;br /&gt;
| Desired window resolution. For example &amp;quot;1680x1050&amp;quot;. Or &amp;quot;maximized&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| --single-thread-loading&lt;br /&gt;
|&lt;br /&gt;
| Disables loading of sprites in multiple threads.&lt;br /&gt;
|-&lt;br /&gt;
| --cache-sprite-atlas&lt;br /&gt;
| BOOL&lt;br /&gt;
| Enable/disable sprite atlas cache.&lt;br /&gt;
|-&lt;br /&gt;
| --nogamepad&lt;br /&gt;
|&lt;br /&gt;
| Disable gamepad(controller) support&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Server options&lt;br /&gt;
|-&lt;br /&gt;
| --port&lt;br /&gt;
| N&lt;br /&gt;
| network port to use&lt;br /&gt;
|-&lt;br /&gt;
| --bind&lt;br /&gt;
| ADDRESS[:PORT]&lt;br /&gt;
| IP address (and optionally port) to bind to&lt;br /&gt;
|-&lt;br /&gt;
| --rcon-port&lt;br /&gt;
| N&lt;br /&gt;
| Port to use for RCON&lt;br /&gt;
|-&lt;br /&gt;
| --rcon-bind&lt;br /&gt;
| ADDRESS:PORT&lt;br /&gt;
| IP address and port to use for RCON&lt;br /&gt;
|-&lt;br /&gt;
| --rcon-password&lt;br /&gt;
| PASSWORD&lt;br /&gt;
| Password for RCON&lt;br /&gt;
|-&lt;br /&gt;
| --server-settings&lt;br /&gt;
| FILE&lt;br /&gt;
| Path to file with server settings. See data/server-settings.example.json&lt;br /&gt;
|-&lt;br /&gt;
| --use-server-whitelist&lt;br /&gt;
| BOOL&lt;br /&gt;
| If the whitelist should be used.&lt;br /&gt;
|-&lt;br /&gt;
| --use-authserver-bans&lt;br /&gt;
|&lt;br /&gt;
| Verify that connecting players are not banned from multiplayer and inform Factorio.com about ban/unban commands.&lt;br /&gt;
|-&lt;br /&gt;
| --server-whitelist&lt;br /&gt;
| FILE&lt;br /&gt;
| Path to file with server whitelist.&lt;br /&gt;
|-&lt;br /&gt;
| --server-banlist&lt;br /&gt;
| FILE&lt;br /&gt;
| Path to file with server banlist.&lt;br /&gt;
|-&lt;br /&gt;
| --server-adminlist&lt;br /&gt;
| FILE&lt;br /&gt;
| Path to file with server adminlist.&lt;br /&gt;
|-&lt;br /&gt;
| --console-log&lt;br /&gt;
| FILE&lt;br /&gt;
| Path to file where a copy of the server&#039;s log will be stored&lt;br /&gt;
|-&lt;br /&gt;
| --server-id&lt;br /&gt;
| FILE&lt;br /&gt;
| Path where server ID will be stored or read from&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Boolean options ===&lt;br /&gt;
&lt;br /&gt;
Parameters shown above with a BOOL option must be formatted as &amp;lt;code&amp;gt;[parameter]=true&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;[parameter]=false&amp;lt;/code&amp;gt;. For example,&lt;br /&gt;
&lt;br /&gt;
  --fullscreen=false&lt;br /&gt;
&lt;br /&gt;
will start the game in windowed (not fullscreen) mode.&lt;br /&gt;
&lt;br /&gt;
=== Multiplayer ===&lt;br /&gt;
&lt;br /&gt;
  --start-server SAVE&lt;br /&gt;
&lt;br /&gt;
Will start a Headless (Dedicated) server, with no GUI.&lt;br /&gt;
&lt;br /&gt;
  --mp-connect ADDRESS&lt;br /&gt;
ADDRESS is the IP:port of the remote host. Port is optional.&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
  ./factorio --mp-connect 192.168.1.101&lt;br /&gt;
  ./factorio --mp-connect 192.168.1.101:2345&lt;br /&gt;
&lt;br /&gt;
As above, port can be specified by placing the port number after a colon in the address.&lt;br /&gt;
&lt;br /&gt;
=== Creating a map from custom settings ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it&#039;s useful to create a new game with map and/or map generator settings stored in a JSON file rather than going through the in-game map settings screen.&lt;br /&gt;
One reason is that by editing the settings directly it is possible to set settings outside the range normally available from the GUI.&lt;br /&gt;
&lt;br /&gt;
To do this, Factorio is run from the command-line, and a JSON file containing the map generator settings and a JSON file containing map settings (if customizing them) are needed.&lt;br /&gt;
&lt;br /&gt;
Example for custom generator settings:&lt;br /&gt;
&amp;lt;pre&amp;gt;{&lt;br /&gt;
    &amp;quot;terrain_segmentation&amp;quot;: 0.5,&lt;br /&gt;
    &amp;quot;water&amp;quot;: &amp;quot;2&amp;quot;,&lt;br /&gt;
    &amp;quot;width&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;height&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;starting_area&amp;quot;: &amp;quot;normal&amp;quot;,&lt;br /&gt;
    &amp;quot;peaceful_mode&amp;quot;: false,&lt;br /&gt;
    &amp;quot;autoplace_controls&amp;quot;:&lt;br /&gt;
    {&lt;br /&gt;
        &amp;quot;coal&amp;quot;: {&amp;quot;frequency&amp;quot;: 1, &amp;quot;size&amp;quot;: 2, &amp;quot;richness&amp;quot;: 0.5},&lt;br /&gt;
        &amp;quot;copper-ore&amp;quot;: {&amp;quot;frequency&amp;quot;: &amp;quot;low&amp;quot;, &amp;quot;size&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;richness&amp;quot;: &amp;quot;high&amp;quot;},&lt;br /&gt;
        &amp;quot;crude-oil&amp;quot;: {&amp;quot;frequency&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;size&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;richness&amp;quot;: &amp;quot;normal&amp;quot;},&lt;br /&gt;
        &amp;quot;enemy-base&amp;quot;: {&amp;quot;frequency&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;size&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;richness&amp;quot;: &amp;quot;normal&amp;quot;},&lt;br /&gt;
        &amp;quot;iron-ore&amp;quot;: {&amp;quot;frequency&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;size&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;richness&amp;quot;: &amp;quot;normal&amp;quot;},&lt;br /&gt;
        &amp;quot;stone&amp;quot;: {&amp;quot;frequency&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;size&amp;quot;: 0, &amp;quot;richness&amp;quot;: &amp;quot;normal&amp;quot;},&lt;br /&gt;
        &amp;quot;uranium-ore&amp;quot;: {&amp;quot;frequency&amp;quot;: &amp;quot;normal&amp;quot;, &amp;quot;size&amp;quot;: &amp;quot;none&amp;quot;, &amp;quot;richness&amp;quot;: &amp;quot;normal&amp;quot;}&lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;cliff_settings&amp;quot;:&lt;br /&gt;
    {&lt;br /&gt;
        &amp;quot;name&amp;quot;: &amp;quot;cliff&amp;quot;,                &lt;br /&gt;
        &amp;quot;cliff_elevation_0&amp;quot;: 30,        &lt;br /&gt;
        &amp;quot;cliff_elevation_interval&amp;quot;: 20, &lt;br /&gt;
        &amp;quot;richness&amp;quot;: 1                   &lt;br /&gt;
    },&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;property_expression_names&amp;quot;:&lt;br /&gt;
    {&lt;br /&gt;
        &amp;quot;elevation&amp;quot;: &amp;quot;0_16-elevation&amp;quot;,&lt;br /&gt;
        &amp;quot;temperature&amp;quot;: &amp;quot;35&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &lt;br /&gt;
    &amp;quot;seed&amp;quot;: null&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this is the same format as [https://lua-api.factorio.com/latest/concepts/MapGenSettings.html MapGenSettings] that are modifiable from Lua. Everything in the file is optional.&lt;br /&gt;
&lt;br /&gt;
Creating a custom save:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files\Factorio\bin\x64\Factorio.exe&amp;quot; --create stuff-seed123.zip --map-gen-settings map-gen-settings.json --map-gen-seed 123&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generating a map preview:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;quot;C:\Program Files\Factorio\bin\x64\Factorio.exe&amp;quot; --generate-map-preview preview-seed123.png --map-gen-settings map-gen-settings.json --map-gen-seed 123&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Creating the JSON files from a map exchange string ====&lt;br /&gt;
&lt;br /&gt;
It can be useful to create the initial JSON files from a known map exchange string instead of creating them from scratch. To convert the map exchange string to JSON, open the game and run the following command with your map exchange string:&lt;br /&gt;
&lt;br /&gt;
 /c helpers.write_file(&#039;map.txt&#039;, helpers.table_to_json(helpers.parse_map_exchange_string(&amp;quot;&amp;lt;your exchange string here&amp;gt;&amp;quot;)))&lt;br /&gt;
&lt;br /&gt;
Then open the script_output folder in the [[user data directory]] and open map.txt - it will look like this:&lt;br /&gt;
&lt;br /&gt;
 {&amp;quot;map_settings&amp;quot;:{ ...&amp;lt;MAP_SETTINGS&amp;gt; ... },&amp;quot;map_gen_settings&amp;quot;:{ ...&amp;lt;MAP_GEN_SETTINGS&amp;gt;... }}&lt;br /&gt;
&lt;br /&gt;
Copy the { ...&amp;lt;MAP_SETTINGS&amp;gt; ... } section into a new file called &#039;map-settings.json&#039; in the desired location. Copy the { ...&amp;lt;MAP_GEN_SETTINGS&amp;gt; ... } section section into a new file called &#039;map-gen-settings.json&#039; in the desired location.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Console]]&lt;br /&gt;
&lt;br /&gt;
{{C|Modding}}&lt;/div&gt;</summary>
		<author><name>Osmo</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Settings&amp;diff=216886</id>
		<title>Settings</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Settings&amp;diff=216886"/>
		<updated>2026-01-06T06:49:56Z</updated>

		<summary type="html">&lt;p&gt;Osmo: typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
{{Stub}}&lt;br /&gt;
&lt;br /&gt;
Factorio has a number of &#039;&#039;&#039;settings&#039;&#039;&#039; in different places, this page covers the ones accessible through the Main menu and Game (pause) menu. These settings are also saved to and can be changed from the &amp;quot;config.ini&amp;quot; file in the Factorio [[Application_directory#User_data_directory|user data directory]]. The [[#See also]] section covers other places that allow configuring the game.&lt;br /&gt;
&lt;br /&gt;
== Controls ==&lt;br /&gt;
&lt;br /&gt;
See [[Controls]]&lt;br /&gt;
&lt;br /&gt;
== Mod settings ==&lt;br /&gt;
&lt;br /&gt;
Settings added by mods are placed here. There are 3 sections: Startup, Map and Per player. Each section contains a list of settings, grouped per mod that added them.&lt;br /&gt;
&lt;br /&gt;
Startup settings require the game to be restarted. This means closing and opening the game, not resetting progress in a save file. Map settings can be changed while the game is running. Per player settings can be changed while the game is running and allow each player to have different values in the settings.&lt;br /&gt;
&lt;br /&gt;
See also: [[Tutorial:Mod settings]]&lt;br /&gt;
&lt;br /&gt;
== Hidden settings ==&lt;br /&gt;
&lt;br /&gt;
Factorio supports a number of hidden configuration options that are not normally shown in the GUI. They can be accessed by holding CTRL + ALT when clicking the &amp;quot;Settings&amp;quot; button in the pause menu, which will cause a new button labeled &amp;quot;The rest&amp;quot; to appear.&lt;br /&gt;
&lt;br /&gt;
These settings may be experimental and may not be validated for safety, so change them at your own risk.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Notable hidden settings&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Default !! Description&lt;br /&gt;
|-&lt;br /&gt;
| autosave-slots || 3 || How many autosaves to keep on a rolling basis&lt;br /&gt;
|-&lt;br /&gt;
| non-blocking-saving || false || Only works on Mac and Linux. When set to true, saves do not cause the game to pause. [https://forums.factorio.com/viewtopic.php?t=57464]&lt;br /&gt;
|-&lt;br /&gt;
| technology-gui-pauses-game || true || By setting to false, the game will no longer pause in single player when opening the technology tree.&lt;br /&gt;
|-&lt;br /&gt;
| cache-prototype-data || false || When enabled, significantly speeds up the &amp;quot;Building prototypes...&amp;quot; step when starting the game at the cost of increased storage space, if prototypes haven&#039;t changed since last startup. The cache needs to be built first, so the loading time will increase when rebuilding it, such as when the setting is enabled for the first time.&lt;br /&gt;
|-&lt;br /&gt;
| cache-sprite-atlas || false || When enabled, significantly speeds up the &amp;quot;Loading sprites...&amp;quot; step when starting the game at the cost of increased storage space, if sprites haven&#039;t changed since last startup. The cache needs to be built first, so the loading time will increase when rebuilding it, such as when the setting is enabled for the first time.&lt;br /&gt;
|-&lt;br /&gt;
| main-menu-simulation-selector || false || Shows a dropdown on the main menu allowing to select a simulation to play in the background. Can be useful for modders when creating custom simulations.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Debug mode|Debug options]]&lt;br /&gt;
* [[Command line parameters]]&lt;br /&gt;
* [[Map generator]]&lt;/div&gt;</summary>
		<author><name>Osmo</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Settings&amp;diff=216160</id>
		<title>Settings</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Settings&amp;diff=216160"/>
		<updated>2025-10-23T04:32:45Z</updated>

		<summary type="html">&lt;p&gt;Osmo: Links to multiple relevant pages, added more information, covered settings other than hidden settings.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{{Stub}}&lt;br /&gt;
&lt;br /&gt;
Factorio has a number of &#039;&#039;&#039;settings&#039;&#039;&#039; in different places, this page covers the ones accessible through the Main menu and Game (pause) menu. These settings are also saved to and can be changed from the &amp;quot;config.ini&amp;quot; file in the Factorio [[Application_directory#User_data_directory|user data directory]]. The [[#See also]] section covers other places that allow configuring the game.&lt;br /&gt;
&lt;br /&gt;
== Controls ==&lt;br /&gt;
&lt;br /&gt;
See [[Controls]]&lt;br /&gt;
&lt;br /&gt;
== Mod settings ==&lt;br /&gt;
&lt;br /&gt;
Settings added by mods are placed here. There are 3 sections: Startup, Map and Per player. Each section contains a list of settings, grouped per mod that added them.&lt;br /&gt;
&lt;br /&gt;
Startup settings require the game to be restarted. This means closing and opening the game, not resetting progress in a save file. Map settings can be changed while the game is running. Per player settings can be changed while the game is running and allow each player to have different values in the settings.&lt;br /&gt;
&lt;br /&gt;
See also: [[Tutorial:Mod settings]]&lt;br /&gt;
&lt;br /&gt;
== Hidden settings ==&lt;br /&gt;
&lt;br /&gt;
Factorio supports a number of hidden configuration options that are not normally shown in the GUI. They can be accessed by holding CTRL + ALT when clicking the &amp;quot;Settings&amp;quot; button in the pause menu, which will cause a new button labeled &amp;quot;The rest&amp;quot; to appear.&lt;br /&gt;
&lt;br /&gt;
These settings may be experimental and may not be validated for safety, so change them at your own risk.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Notable hidden settings&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Default !! Description&lt;br /&gt;
|-&lt;br /&gt;
| autosave-slots || 3 || How many autosaves to keep on a rolling basis&lt;br /&gt;
|-&lt;br /&gt;
| non-blocking-saving || false || Only works on Mac and Linux. When set to true, saves do not cause to game to pause. [https://forums.factorio.com/viewtopic.php?t=57464]&lt;br /&gt;
|-&lt;br /&gt;
| technology-gui-pauses-game || true || By setting to false, the game will no longer pause in single player when opening the technology tree.&lt;br /&gt;
|-&lt;br /&gt;
| cache-prototype-data || false || When enabled, significantly speeds up the &amp;quot;Building prototypes...&amp;quot; step when starting the game at the cost of increased storage space, if prototypes haven&#039;t changed since last startup. The cache needs to be built first, so the loading time will increase when rebuilding it, such as when the setting is enabled for the first time.&lt;br /&gt;
|-&lt;br /&gt;
| cache-sprite-atlas || false || When enabled, significantly speeds up the &amp;quot;Loading sprites...&amp;quot; step when starting the game at the cost of increased storage space, if sprites haven&#039;t changed since last startup. The cache needs to be built first, so the loading time will increase when rebuilding it, such as when the setting is enabled for the first time.&lt;br /&gt;
|-&lt;br /&gt;
| main-menu-simulation-selector || false || Shows a dropdown on the main menu allowing to select a simulation to play in the background. Can be useful for modders when creating custom simulations.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Debug mode|Debug options]]&lt;br /&gt;
* [[Command line parameters]]&lt;br /&gt;
* [[Map generator]]&lt;/div&gt;</summary>
		<author><name>Osmo</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=215811</id>
		<title>Rich text</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=215811"/>
		<updated>2025-09-15T22:33:10Z</updated>

		<summary type="html">&lt;p&gt;Osmo: Fix syntactical error&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
Rich text formatting allows the use of tags within most of the game&#039;s textboxes to change the visual formatting of text or to embed interactable images/entities. Predefined text tags are employed for this purpose.&lt;br /&gt;
&lt;br /&gt;
== Tags ==&lt;br /&gt;
&lt;br /&gt;
Tags are useful for sharing blueprints, marking map locations in chat or adding icons to map markers and train stations.&lt;br /&gt;
Ctrl+alt clicking the map or ground will automatically insert a gps tag and post it into [[console|chat]].&lt;br /&gt;
&lt;br /&gt;
Shift clicking most things with the console open will insert a tag for that thing into chat. The chat and many other textboxes in the game have a button on the right edge that opens an icon selector. This can be used to easily insert rich text tags of recipes, items, fluids, virtual signals and entities into the textbox.&lt;br /&gt;
&lt;br /&gt;
When used in chat, the tag image will be followed by a text description, except for the img tag.&lt;br /&gt;
Used elsewhere only the image is shown.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%&amp;quot;| Syntax&lt;br /&gt;
! style=&amp;quot;width:15%&amp;quot;| Example Input&lt;br /&gt;
! style=&amp;quot;width:15%&amp;quot;| Example Result&lt;br /&gt;
! style=&amp;quot;width:50%&amp;quot;| Description&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [img=&amp;lt;i&amp;gt;class&amp;lt;/i&amp;gt;/&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&amp;lt;br&amp;gt;&lt;br /&gt;
[img=&amp;lt;i&amp;gt;class&amp;lt;/i&amp;gt;.&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&amp;lt;br&amp;gt;&lt;br /&gt;
[img=&amp;lt;i&amp;gt;sprite-prototype-name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [img=item.iron-plate]&amp;lt;br&amp;gt;&lt;br /&gt;
[img=quantity-time]&amp;lt;br&amp;gt;&lt;br /&gt;
[img=utility/played_green]&lt;br /&gt;
| [[File:Iron_plate.png|28px]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Time_icon.png|28px]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Played green.png|28px]]&lt;br /&gt;
| Embeds only a small inline game graphic. The period format must be used in game save names. This tag uses [https://lua-api.factorio.com/latest/concepts/SpritePath.html sprite paths]:&lt;br /&gt;
&amp;lt;i&amp;gt;class&amp;lt;/i&amp;gt; is any of: item, entity, technology, recipe, item-group, fluid, tile, virtual-signal, achievement, equipment, space-location or utility.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;: see below&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;sprite-prototype-name&amp;lt;/i&amp;gt; is the [[Data.raw#sprite|internal-name]] of a [[Prototype/Sprite|sprite prototype]].&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [item=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [item=iron-plate]&lt;br /&gt;
| [[File:Iron_plate.png|28px]] [Item: Iron plate]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal-name of the item&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [entity=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [entity=small-biter]&lt;br /&gt;
| [[File:Small_biter.png|28px]] [Entity: Small biter]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal-name of the entity&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [technology=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [technology=logistics]&lt;br /&gt;
| [[File:Logistics_(research).png|28px]] [Technology: Logistics]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal-name of the technology&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [recipe=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [recipe=basic-oil-processing]&lt;br /&gt;
| [[File:Basic_oil_processing.png|28px]] [Recipe: Basic oil processing]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal-name of the recipe, usually the item name&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [item-group=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [item-group=combat]&lt;br /&gt;
| [[File:Item-group_military.png|28px]] [Item Group: Combat]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is any of: logistics, production, intermediate-products, combat, fluids or signals&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [fluid=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [fluid=water]&lt;br /&gt;
| [[File:Water.png|28px]] [Fluid: Water]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal name of the fluid&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [tile=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [tile=grass-3]&lt;br /&gt;
| [[File:Grass_3.png|28px]] [Tile: Grass 3]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal name of the tile, usually the lowercase name with hyphens replacing spaces as written from the map editor&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [virtual-signal=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [virtual-signal=signal-A]&lt;br /&gt;
| [[File:Signal-A.png|28px]] [Virtual Signal: Signal A]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the word signal followed by either an uppercase letter, number, color, each, everything or anything&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [achievement=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [achievement=minions]&lt;br /&gt;
| [[File:Minions-achievement.png|28px]] [Achievement: Minions]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal-name of the achievement, usually the lowercase name with hyphens replacing spaces&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [gps=&amp;lt;i&amp;gt;x,y&amp;lt;/i&amp;gt;]&lt;br /&gt;
[gps=&amp;lt;i&amp;gt;x,y,surface&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [gps=0,0]&lt;br /&gt;
| [[File:Map.png|28px]] [Location: 0,0]&lt;br /&gt;
| Embeds a map location and marks the location on the map of other players.&lt;br /&gt;
&amp;lt;i&amp;gt;x&amp;lt;/i&amp;gt; is the x point coordinate&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;i&amp;gt;y&amp;lt;/i&amp;gt; is the y point coordinate&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;i&amp;gt;surface&amp;lt;/i&amp;gt; is the current surface. Is only added if the player Ctrl+alt clicks on a surface that is not the default surface. When the player is on another surface than &amp;lt;i&amp;gt;surface&amp;lt;/i&amp;gt;, clicking the tag does nothing. Mods must handle this case with [https://lua-api.factorio.com/latest/events.html#on_player_clicked_gps_tag on_player_clicked_gps_tag]&lt;br /&gt;
|-&lt;br /&gt;
| [special-item=&amp;lt;i&amp;gt;blueprint_string&amp;lt;/i&amp;gt;]&lt;br /&gt;
| &lt;br /&gt;
| [[File:Blueprint.png|28px]] [Blueprint]&lt;br /&gt;
| Embeds a blueprint. Players can get a blueprint item by clicking the icon.&lt;br /&gt;
&amp;lt;i&amp;gt;blueprint_string&amp;lt;/i&amp;gt; is the blueprint string of a blueprint, deconstruction planner or upgrade planners&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [armor=&amp;lt;i&amp;gt;player&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [armor=Player] &lt;br /&gt;
| [[File:Power_armor_MK2.png|28px]] [Armor: Player]&lt;br /&gt;
| Embeds the armor of a player. Allows other players to see the equipment installed.&lt;br /&gt;
&amp;lt;i&amp;gt;player&amp;lt;/i&amp;gt; is the name of the player&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [train=&amp;lt;i&amp;gt;number&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [train=93] &lt;br /&gt;
| [[File:Locomotive.png|28px]] [Train: 2]&lt;br /&gt;
| Embeds a reference to a train. Clicking the icon will open the train GUI for that train.&lt;br /&gt;
&amp;lt;i&amp;gt;number&amp;lt;/i&amp;gt; is the internal unit number of the train&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [train-stop=&amp;lt;i&amp;gt;number&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [train-stop=100]&lt;br /&gt;
| [[File:Train_stop.png|28px]] [Train Stop: Trangar]&lt;br /&gt;
| Embeds a reference to a train stop. Clicking the icon will open the GUI for that train stop.&lt;br /&gt;
&amp;lt;i&amp;gt;number&amp;lt;/i&amp;gt; is the internal unit number of the train stop&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [shortcut=&amp;lt;i&amp;gt;shortcut-name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [shortcut=give-spidertron-remote]&lt;br /&gt;
| [[File:Spidertron_remote.png|28px]] [Shortcut: Create spidertron remote]&lt;br /&gt;
| Embeds a reference to a shortcut from the [[Shortcut bar]]. Hovering over the rich text will show the shortcut&#039;s description. Clicking the rich text will act as if you clicked the shortcut.&lt;br /&gt;
&amp;lt;i&amp;gt;shortcut-name&amp;lt;/i&amp;gt; is the internal name of the shortcut.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [tip=&amp;lt;i&amp;gt;tip-name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [tip=spidertron-control]&lt;br /&gt;
| [[File:Tip.png|28px]] [Tip: Spidertron control]&lt;br /&gt;
| Embeds a reference to a tip from the &amp;quot;Tips and tricks&amp;quot; menu. Hovering over the icon will show the tip&#039;s text. Clicking the icon will open the &amp;quot;Tips and tricks&amp;quot; menu to that page.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [tooltip=&amp;lt;i&amp;gt;text,tooltip locale key&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [tooltip=Hover to see &amp;quot;Iron plate&amp;quot;,item-name.iron-plate]&lt;br /&gt;
| &amp;lt;span title=&amp;quot;Iron plate&amp;quot;&amp;gt; [[File:Custom-tag-icon.png|28px]] Hover to see &amp;quot;Iron plate&amp;quot;&amp;lt;/span&amp;gt;&lt;br /&gt;
| Shows the given &amp;lt;i&amp;gt;text&amp;lt;/i&amp;gt; with a &amp;lt;i&amp;gt;tooltip&amp;lt;/i&amp;gt; that is specified with a [[Tutorial:Localisation#Localising_simple_strings|locale key]].&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [quality=&amp;lt;i&amp;gt;tier&amp;lt;/i&amp;gt;]&amp;lt;br&amp;gt;&lt;br /&gt;
[item=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;,quality=&amp;lt;i&amp;gt;tier&amp;lt;/i&amp;gt;]&amp;lt;br&amp;gt;&lt;br /&gt;
[entity=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;,quality=&amp;lt;i&amp;gt;tier&amp;lt;/i&amp;gt;]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;!--[recipe=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;,quality=&amp;lt;i&amp;gt;tier&amp;lt;/i&amp;gt;]&amp;lt;br&amp;gt;&lt;br /&gt;
[fluid=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;,quality=&amp;lt;i&amp;gt;tier&amp;lt;/i&amp;gt;]&amp;lt;br&amp;gt;&lt;br /&gt;
[virtual-signal=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;,quality=&amp;lt;i&amp;gt;tier&amp;lt;/i&amp;gt;]--&amp;gt;&lt;br /&gt;
|[quality=normal]&amp;lt;br&amp;gt;&lt;br /&gt;
[item=iron-plate,quality=normal]&amp;lt;br&amp;gt;&lt;br /&gt;
[entity=small-biter,quality=uncommon]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;!--[recipe=basic-oil-processing,quality=rare]&amp;lt;br&amp;gt;&lt;br /&gt;
[fluid=water,quality=epic]&amp;lt;br&amp;gt;&lt;br /&gt;
[virtual-signal=signal-A,quality=legendary]--&amp;gt;&lt;br /&gt;
| [[File:Quality normal.png|28px]] [Quality: Normal]&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Iron_plate.png|28px]] [Item: Iron plate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Uncommon small biter.png|28px]] [Entity: Uncommon Small biter]&amp;lt;br&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
[[Quality]] can also be optionally specified on the following tags: item, entity, recipe, fluid, and virtual-signal&amp;lt;br&amp;gt;&lt;br /&gt;
It can also be added to the other tags that use &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;, but they ignore it.&lt;br /&gt;
&lt;br /&gt;
The normal quality is the default quality and won&#039;t modify tags. Any other quality won&#039;t exist without [[Space Age]] and Quality&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;tier&amp;lt;/i&amp;gt; is the internal-name of the quality&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [space-platform=&amp;lt;i&amp;gt;number&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [space-platform=3]&lt;br /&gt;
| [[File:Space_platform_hub.png|28px]] [Space platform: My cool space platform] &lt;br /&gt;
| &amp;lt;i&amp;gt;number&amp;lt;/i&amp;gt; is the internal id of a space-platform, starting with 1.&lt;br /&gt;
Hovering over the rich text will show a view of the space platform. Clicking the rich text will go to the platform in remote view.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [planet=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [planet=gleba]&lt;br /&gt;
| [[File:Gleba.png|28px]] [Planet: Gleba]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal name of a planet.&lt;br /&gt;
Available planets in Space Age are: nauvis, gleba, fulgora, vulcanus, and aquilo.&lt;br /&gt;
&lt;br /&gt;
[[Nauvis]] is part of the base game and will always be available.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [space-location=&amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt;]&lt;br /&gt;
| [space-location=shattered-planet]&lt;br /&gt;
[space-location=gleba]&lt;br /&gt;
| [[File:Shattered planet.png|28px]] [Space location: Shattered Planet] &lt;br /&gt;
[[File:Gleba.png|28px]] [Planet: Gleba]&lt;br /&gt;
| &amp;lt;i&amp;gt;name&amp;lt;/i&amp;gt; is the internal name of a space-location in Space Age.&lt;br /&gt;
Available locations in Space Age are: nauvis, gleba, fulgora, vulcanus, aquilo, solar-system-edge, and shattered-planet.&lt;br /&gt;
&lt;br /&gt;
For the planet&#039;s listed in the section above &#039;planet&#039; will be used as the text prefix instead of &#039;space-location&#039;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| [space-age]&lt;br /&gt;
| [space-age]&lt;br /&gt;
| [[File:Space_age_icon.png|28px]]&lt;br /&gt;
| Embeds the Space Age icon.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Text modifiers ==&lt;br /&gt;
[[File:Fonts.png|right|thumbnail|100px|Different fonts displayed in-game. (Click to enlarge.)]]&lt;br /&gt;
&lt;br /&gt;
The color and font of text can be changed&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:20%&amp;quot;| Syntax&lt;br /&gt;
! style=&amp;quot;width:15%&amp;quot;| Example Input&lt;br /&gt;
! style=&amp;quot;width:15%&amp;quot;| Example Result&lt;br /&gt;
! style=&amp;quot;width:50%&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
| [color=&amp;lt;i&amp;gt;rgb&amp;lt;/i&amp;gt;]...[/color]&amp;lt;br&amp;gt;&lt;br /&gt;
[color=&amp;lt;i&amp;gt;#rrggbb&amp;lt;/i&amp;gt;]...[/color]&amp;lt;br&amp;gt;&lt;br /&gt;
[color=&amp;lt;i&amp;gt;#aarrggbb&amp;lt;/i&amp;gt;]...[/color]&amp;lt;br&amp;gt;&lt;br /&gt;
[color=&amp;lt;i&amp;gt;rgb&amp;lt;/i&amp;gt;]...[.color]&amp;lt;br&amp;gt;&lt;br /&gt;
[color=&amp;lt;i&amp;gt;#rrggbb&amp;lt;/i&amp;gt;]...[.color]&amp;lt;br&amp;gt;&lt;br /&gt;
[color=&amp;lt;i&amp;gt;#aarrggbb&amp;lt;/i&amp;gt;]...[.color]&lt;br /&gt;
| [color=red]Red[/color] text&amp;lt;br&amp;gt;&lt;br /&gt;
[color=1,0,0]Red[/color] text&amp;lt;br&amp;gt;&lt;br /&gt;
[color=255,0,0]Red[/color] text&amp;lt;br&amp;gt;&lt;br /&gt;
[color=#ff0000]Red[/color] text&lt;br /&gt;
| &amp;lt;span style=&amp;quot;color: #ff0000&amp;quot;&amp;gt;Red&amp;lt;/span&amp;gt; text&lt;br /&gt;
| &amp;lt;i&amp;gt;rgb&amp;lt;/i&amp;gt; is a comma separated RGB color ranging from 0 to 1 or 0 to 255, or a color name&lt;br /&gt;
Available colors: default, red, green, blue, orange, yellow, pink, purple, white, black, gray, brown, cyan, acid.&lt;br /&gt;
|-&lt;br /&gt;
| [font=&amp;lt;i&amp;gt;font-name&amp;lt;/i&amp;gt;]...[/font]&amp;lt;br&amp;gt;&lt;br /&gt;
[font=&amp;lt;i&amp;gt;font-name&amp;lt;/i&amp;gt;]...[.font]&lt;br /&gt;
| [font=default-bold]Bold text[/font]&lt;br /&gt;
| &amp;lt;b&amp;gt;Bold text&amp;lt;/b&amp;gt;&lt;br /&gt;
| &amp;lt;i&amp;gt;font-name&amp;lt;/i&amp;gt; is the name of the [[Data.raw#font|Factorio font]] to render&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Console]]&lt;br /&gt;
* [[Data.raw]] for the list of internal names of recipes, technologies, fluids, etc.&lt;br /&gt;
&lt;br /&gt;
{{C|GUI}}&lt;/div&gt;</summary>
		<author><name>Osmo</name></author>
	</entry>
</feed>