<?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=PennyJim</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=PennyJim"/>
	<link rel="alternate" type="text/html" href="https://wiki.factorio.com/Special:Contributions/PennyJim"/>
	<updated>2026-04-22T01:32:10Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Console&amp;diff=217068</id>
		<title>Console</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Console&amp;diff=217068"/>
		<updated>2026-01-26T00:32:56Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Add evolution surface parameter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
The &#039;&#039;&#039;console&#039;&#039;&#039; is Factorio&#039;s in-game command-line interface. See [[command line parameters]] for the command line interface of the Factorio executable.&lt;br /&gt;
&lt;br /&gt;
The in-game console can be used for:&lt;br /&gt;
&lt;br /&gt;
* Chatting with other players&lt;br /&gt;
* Occasional status updates&lt;br /&gt;
* Running commands / scripts / cheats&lt;br /&gt;
&lt;br /&gt;
There are three types of commands:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;[[#Normal commands|Normal]]&#039;&#039;&#039; - Display information about the game and customize your experience.&lt;br /&gt;
* &#039;&#039;&#039;[[#Multiplayer commands|Multiplayer]]&#039;&#039;&#039; - Message filtering, banning users, etc.&lt;br /&gt;
* &#039;&#039;&#039;[[#Scripting and cheat commands|Scripting/Cheating]]&#039;&#039;&#039; - Run small Lua scripts (but they &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;disable achievements for the save game&amp;lt;/span&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=== Using the console ===&lt;br /&gt;
The console display can be toggled with the {{Keybinding|grave}} key (&amp;lt;code&amp;gt;`&amp;lt;/code&amp;gt;). This is the key located to the left of the &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; key, above &amp;lt;code&amp;gt;Tab&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can customize the keys via &#039;&#039;&#039;Settings menu → Controls → Toggle chat (and Lua console)&#039;&#039;&#039;.&lt;br /&gt;
When the console is open, you&#039;ll see a blinking cursor at the bottom of the screen; type your message or command and hit &#039;&#039;&#039;Return&#039;&#039;&#039; to send it (this will also close the console).&lt;br /&gt;
Documentation about message and command prefixes can be found further down this page.&lt;br /&gt;
&lt;br /&gt;
The console supports [[rich text]] tags. These tags are useful for sharing blueprints, marking map locations in chat or adding icons to map markers and train stations. Ctrl + Alt-clicking the map or ground will automatically insert a GPS tag and post it into the console. Shift-clicking most things with the console open will insert a tag for that thing into the console.&lt;br /&gt;
&lt;br /&gt;
When the console is closed, only the most recent messages/commands will be displayed, but they will gradually fade away (opening the console will immediately re-display all recent messages).&lt;br /&gt;
Note that by default, all executed commands are made visible to all users. The fade-out time can be changed via &#039;&#039;&#039;Settings menu → Interface → Chat message delay&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The console can be cleared with the &#039;&#039;&#039;/clear&#039;&#039;&#039; command.&lt;br /&gt;
&lt;br /&gt;
Use the {{keybinding|&amp;amp;uarr;}} and {{keybinding|&amp;amp;darr;}} keys to scroll through the console history. The {{keybinding|Tab}} key provides intelligent code completion on commands, options and player names.&lt;br /&gt;
&lt;br /&gt;
== Normal commands ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot;| Command&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot;| Example&lt;br /&gt;
! style=&amp;quot;width:46%&amp;quot;| Description&lt;br /&gt;
! style=&amp;quot;width:4%&amp;quot;| Admin only&lt;br /&gt;
|-&lt;br /&gt;
| /alerts &amp;lt;enable/disable/mute/unmute&amp;gt; &amp;lt;alert&amp;gt;&lt;br /&gt;
| /alerts disable turret_fire&lt;br /&gt;
| Enables, disables, mutes, or unmutes the given  [[alerts|alert]] type. Available alerts: entity_destroyed, entity_under_attack, not_enough_construction_robots, no_material_for_construction, not_enough_repair_packs, platform_tile_building_blocked, turret_out_of_ammo, turret_fire, custom, no_storage, train_out_of_fuel, train_no_path, no_platform_storage, collector_path_blocked, unclaimed_cargo, no_roboport_storage, pipeline_overextended.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /clear&lt;br /&gt;
| /clear&lt;br /&gt;
| Clears the console.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /color &amp;lt;color&amp;gt;&lt;br /&gt;
| /color 20 255 255&lt;br /&gt;
| Changes your color. Can either be one of the pre-defined colors or [[:Wikipedia:RGB_color_space|RGB value]] in the format of “# # #”. Available colors: default, red, green, blue, orange, yellow, pink, purple, white, black, gray, brown, cyan, acid.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /evolution [surface]&lt;br /&gt;
| /evolution nauvis&lt;br /&gt;
| Prints info about the alien evolution factor for all surfaces or optionally only the given one.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /help [command]&lt;br /&gt;
| /help&lt;br /&gt;
| Prints a list of available commands, the optional argument can specify the command that should be described.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /h [command]&lt;br /&gt;
| /h&lt;br /&gt;
| Same as /help.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /mute-programmable-speaker &amp;lt;mute/unmute&amp;gt; &amp;lt;local/everyone&amp;gt;&lt;br /&gt;
| /mute-programmable-speaker mute local&lt;br /&gt;
| Mutes or unmutes the global sounds created by the Programmable Speaker. Use “local” to mute just the local client. Admins can use “everyone” to mute the sounds for everyone on the server.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /perf-avg-frames &amp;lt;number&amp;gt;&lt;br /&gt;
| /perf-avg-frames 100&lt;br /&gt;
| Number of ticks/updates used to average performance counters. Default is 100. Value of 5-10 is recommended for fast convergence, but numbers will jitter more rapidly.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /permissions&lt;br /&gt;
| /permissions&lt;br /&gt;
| Opens the [[permissions]] GUI.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /permissions &amp;lt;action&amp;gt; &amp;lt;parameters&amp;gt;&lt;br /&gt;
| /permissions add-player DeveloperGroup kovarex&lt;br /&gt;
| Available actions are add-player &amp;lt;group&amp;gt; &amp;lt;player&amp;gt;, create-group &amp;lt;name&amp;gt;, delete-group &amp;lt;group&amp;gt;, edit-group &amp;lt;group&amp;gt; &amp;lt;input_action&amp;gt; &amp;lt;true/false&amp;gt;, get-player-group &amp;lt;player&amp;gt;, remove-player &amp;lt;group&amp;gt; &amp;lt;player&amp;gt;, rename-group &amp;lt;group&amp;gt; &amp;lt;new_name&amp;gt; and reset&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /reset-tips&lt;br /&gt;
| /reset-tips&lt;br /&gt;
| Resets the state of the tips and tricks as if the game was just started for the first time.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /screenshot [x resolution] [y resolution] [zoom]&lt;br /&gt;
| /screenshot&lt;br /&gt;
| Takes a screenshot with the GUI hidden, centered on the player. It is saved in the &amp;quot;script-output&amp;quot; subfolder of your [[User data directory]].  Resolution is optional and defaults to the current window size. Zoom is optional and defaults to 1.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /seed&lt;br /&gt;
| /seed&lt;br /&gt;
| Prints the starting map seed.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /time&lt;br /&gt;
| /time&lt;br /&gt;
| Prints info about how old the map is.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /toggle-action-logging&lt;br /&gt;
| /toggle-action-logging&lt;br /&gt;
| Toggles logging all input actions performed by the game. This value isn’t persisted between game restarts and only affects your local game in multiplayer sessions.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /toggle-heavy-mode&lt;br /&gt;
| /toggle-heavy-mode&lt;br /&gt;
| Used to investigate [[Desynchronization#Using_heavy_mode_command|desyncs]]. Will slow down the game and make multiplayer unplayable.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /unlock-shortcut-bar&lt;br /&gt;
| /unlock-shortcut-bar&lt;br /&gt;
| Unlocks all [[shortcut bar]] items, including blueprint string import, copy &amp;amp; paste, deconstruction and upgrade planner.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /unlock-tips&lt;br /&gt;
| /unlock-tips&lt;br /&gt;
| Unlocks all tips and tricks entries.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /version&lt;br /&gt;
| /version&lt;br /&gt;
| Prints the current game version.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Multiplayer commands ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot;| Command&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot;| Example&lt;br /&gt;
! style=&amp;quot;width:46%&amp;quot;| Description&lt;br /&gt;
! style=&amp;quot;width:4%&amp;quot;| Admin only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;message&amp;gt;&lt;br /&gt;
| Hello team!&lt;br /&gt;
| Console input that does not start with {{keybinding|/}} is shown as a chat message to your team.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /admin&lt;br /&gt;
| /admin&lt;br /&gt;
| Opens the player management GUI.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /admins&lt;br /&gt;
| /admins&lt;br /&gt;
| Prints a list of game admins.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /ban &amp;lt;player&amp;gt; &amp;lt;reason&amp;gt;&lt;br /&gt;
| /ban xTROLLx Throwing grenades in base&lt;br /&gt;
| Bans the specified player.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /bans&lt;br /&gt;
| /bans&lt;br /&gt;
| Prints a list of banned players.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /banlist &amp;lt;add/remove/get/clear&amp;gt; &amp;lt;player&amp;gt;&lt;br /&gt;
| /banlist get&lt;br /&gt;
| Adds or removes a player from the banlist. Same as /ban or /unban.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /config&lt;br /&gt;
| /config&lt;br /&gt;
| Opens the server configuration GUI.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /config &amp;lt;get/set&amp;gt; &amp;lt;option&amp;gt; &amp;lt;value&amp;gt;&lt;br /&gt;
| /config set password hunter2&lt;br /&gt;
| Gets or sets various multiplayer game settings. Available configs are: afk-auto-kick, allow-commands, allow-debug-settings, autosave-interval, autosave-only-on-server, ignore-player-limit-for-returning-players, max-players, max-upload-speed, only-admins-can-pause, password, require-user-verification, visibility-lan, visibility-public. The units for the options afk-auto-kick and autosave-interval are in minutes.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /delete-blueprint-library &amp;lt;player&amp;gt;&lt;br /&gt;
| /delete-blueprint-library everybody confirm&lt;br /&gt;
| Deletes the blueprint library storage for the given offline player from the save file. Enter “everybody confirm” to delete the storage of all offline players.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /demote &amp;lt;player&amp;gt;&lt;br /&gt;
| /demote AzureDiamond&lt;br /&gt;
| Demotes the player from admin.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /ignore &amp;lt;player&amp;gt;&lt;br /&gt;
| /ignore Cthon98&lt;br /&gt;
| Prevents the chat from showing messages from this player. Admin messages are still shown.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /ignores&lt;br /&gt;
| /ignores&lt;br /&gt;
| Prints a list of ignored players.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /kick &amp;lt;player&amp;gt; &amp;lt;reason&amp;gt;&lt;br /&gt;
| /kick xTROLLx Throwing grenades in base&lt;br /&gt;
| Kicks the specified player.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /mute &amp;lt;player&amp;gt;&lt;br /&gt;
| /mute Cthon98&lt;br /&gt;
| Prevents the player from saying anything in chat.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /mutes&lt;br /&gt;
| /mutes&lt;br /&gt;
| All players that are muted (can’t talk in chat).&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /open &amp;lt;player&amp;gt;&lt;br /&gt;
| /open AzureDiamond&lt;br /&gt;
| Opens another player’s inventory.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /o &amp;lt;player&amp;gt;&lt;br /&gt;
| /o AzureDiamond&lt;br /&gt;
| Same as /open.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /players [online/o/count/c]&lt;br /&gt;
| /players&lt;br /&gt;
| Prints a list of players in the game. (parameter online/o, it prints only players that are online, count/c prints only count)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /p [online/o/count/c]&lt;br /&gt;
| /p o c&lt;br /&gt;
| Same as /players.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /promote &amp;lt;player&amp;gt;&lt;br /&gt;
| /promote AzureDiamond&lt;br /&gt;
| Promotes the player to admin.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /purge &amp;lt;player&amp;gt;&lt;br /&gt;
| /purge Cthon98&lt;br /&gt;
| Clears all the messages from this player from the chat log.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /reply &amp;lt;message&amp;gt;&lt;br /&gt;
| /reply oh, really?&lt;br /&gt;
| Replies to the last player that whispered to you.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /r &amp;lt;message&amp;gt;&lt;br /&gt;
| /r oh, really?&lt;br /&gt;
| Same as /reply.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /server-save&lt;br /&gt;
| /server-save&lt;br /&gt;
| Saves the game on the server in a multiplayer game.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /shout &amp;lt;message&amp;gt;&lt;br /&gt;
| /shout Hello world!&lt;br /&gt;
| Sends a message to all players including other forces.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /s &amp;lt;message&amp;gt;&lt;br /&gt;
| /s Hello world!&lt;br /&gt;
| Same as /shout.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /swap-players &amp;lt;player&amp;gt; [player]&lt;br /&gt;
| /swap-players AzureDiamond&lt;br /&gt;
| Swaps your character with the given player’s character, or if two players are given swaps the two player characters.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /unban &amp;lt;player&amp;gt;&lt;br /&gt;
| /unban xTROLLx&lt;br /&gt;
| Unbans the specified player.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /unignore &amp;lt;player&amp;gt;&lt;br /&gt;
| /unignore Cthon98&lt;br /&gt;
| Allows the chat to show messages from this player.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /unmute &amp;lt;player&amp;gt;&lt;br /&gt;
| /unmute Cthon98&lt;br /&gt;
| Allows the player to talk in chat again.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /whisper &amp;lt;player&amp;gt; &amp;lt;message&amp;gt;&lt;br /&gt;
| /whisper AzureDiamond that&#039;s what I see&lt;br /&gt;
| Sends a message to the specified player.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /w &amp;lt;player&amp;gt; &amp;lt;message&amp;gt;&lt;br /&gt;
| /w AzureDiamond that&#039;s what I see&lt;br /&gt;
| Same as /whisper.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /whitelist &amp;lt;add/remove/get/clear&amp;gt; [player]&lt;br /&gt;
| /whitelist get&lt;br /&gt;
| Adds or removes a player from the whitelist, where only whitelisted players can join the game. Enter nothing for “player” when using “get” to print a list of all whitelisted players. An empty whitelist disables the whitelist functionality allowing anyone to join.&lt;br /&gt;
| No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Scripting and cheat commands ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| /cheat [all/&amp;lt;planet-name&amp;gt;/&amp;lt;platform-name&amp;gt;/off]&lt;br /&gt;
| Researches all technologies and enables cheat mode (allowing free crafting of any item). &lt;br /&gt;
* Using the &#039;&#039;&#039;all&#039;&#039;&#039; option also gives the player some additional items.&lt;br /&gt;
* Specifying a &#039;&#039;planet-name&#039;&#039; or &#039;&#039;platform-name&#039;&#039; also moves the player to the origin of the specified planet or platform.&lt;br /&gt;
* Using the &#039;&#039;&#039;off&#039;&#039;&#039; option turns cheat mode off.&lt;br /&gt;
|-&lt;br /&gt;
| /command &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed).&lt;br /&gt;
|-&lt;br /&gt;
| /c &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed).&lt;br /&gt;
|-&lt;br /&gt;
| /editor&lt;br /&gt;
| Toggles the map editor.&lt;br /&gt;
|-&lt;br /&gt;
| /measured-command &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed) and measures time it took.&lt;br /&gt;
|-&lt;br /&gt;
| /mc &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed) and measures time it took.&lt;br /&gt;
|-&lt;br /&gt;
| /silent-command &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed) without printing it to the console.&lt;br /&gt;
|-&lt;br /&gt;
| /sc &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed) without printing it to the console.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is a very powerful feature, which also allows cheating, and as such &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;achievements will be permanently disabled for the save&amp;lt;/span&amp;gt; as soon as you use a script command.&lt;br /&gt;
&lt;br /&gt;
== Basic example scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Use it as calculator ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.print(1234*5678)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zoom beyond normal bounds ===&lt;br /&gt;
Note that zooming too far out can cause performance hits. Be careful.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.zoom=0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In freeplay, the farthest you can zoom out is 0.3. In the map editor, it is 0.1. Smaller zoom values will be clamped.&lt;br /&gt;
&lt;br /&gt;
=== Mine faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.manual_mining_speed_modifier=1000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Craft faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.manual_crafting_speed_modifier=1000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unlock and research all technologies ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.research_all_technologies()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Undo this with the command in the next section.&lt;br /&gt;
&lt;br /&gt;
Note: Specific technologies can be researched using the [[map editor]] by shift clicking the &amp;quot;start research&amp;quot; button on the technology GUI.&lt;br /&gt;
&lt;br /&gt;
=== Unresearch all technologies ===&lt;br /&gt;
This does not reset manually applied bonuses&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for _, tech in pairs(game.player.force.technologies) do &lt;br /&gt;
	tech.researched=false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Specific technologies can be unresearched using the [[map editor]] by clicking the &amp;quot;un-research&amp;quot; button on the technology GUI.&lt;br /&gt;
&lt;br /&gt;
=== Reset your force ===&lt;br /&gt;
This resets all data for your force, including kill and production statistics, technologies, bonuses and charting status.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.reset()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Always show rail block visualization ===&lt;br /&gt;
Permanently show the rail block visualization instead of only when holding a rail signal. Disable by replacing true with false.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.game_view_settings.show_rail_block_visualisation = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set all trains to Automatic mode ===&lt;br /&gt;
Set all trains to automatic mode - for example after building them with a blueprint. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for key,ent in pairs (game.player.surface.find_entities_filtered{name=&amp;quot;locomotive&amp;quot;}) do &lt;br /&gt;
    ent.train.manual_mode = false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Inventory manipulation scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Cheat mode ===&lt;br /&gt;
Allows for infinite free crafting. Disable by replacing true with false.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.cheat_mode=true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refill resources (refill oil, iron etc.) ===&lt;br /&gt;
While holding the cursor over a resource tile in-game:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.selected.amount=7500&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively you can refill all resources in the map with the following command. Change ore.amount to the desired value.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c surface = game.player.surface&lt;br /&gt;
for _, ore in pairs(surface.find_entities_filtered({type=&amp;quot;resource&amp;quot;})) do&lt;br /&gt;
    ore.amount = 10000&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add items to the player&#039;s inventory ===&lt;br /&gt;
Replace iron-plate with the [[data.raw|internal name]] of the item desired.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.insert{name=&amp;quot;iron-plate&amp;quot;, count=100}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance, here&#039;s a stack of the god-mode energy system interface:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.insert{name=&amp;quot;electric-energy-interface&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several god-mode items available:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;infinity-chest&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;infinity-pipe&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;electric-energy-interface&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;heat-interface&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a powerful armor with equipment and some tools for construction:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c	local player = game.player&lt;br /&gt;
player.insert{name=&amp;quot;power-armor-mk2&amp;quot;, count = 1}&lt;br /&gt;
local p_armor = player.get_inventory(5)[1].grid&lt;br /&gt;
	p_armor.put({name = &amp;quot;fission-reactor-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;fission-reactor-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;fission-reactor-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;exoskeleton-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;exoskeleton-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;exoskeleton-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;exoskeleton-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;energy-shield-mk2-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;energy-shield-mk2-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;personal-roboport-mk2-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;night-vision-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;battery-mk2-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;battery-mk2-equipment&amp;quot;})&lt;br /&gt;
player.insert{name=&amp;quot;construction-robot&amp;quot;, count = 25}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Adding [[Quality|higher quality]] items looks like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.insert{name=&amp;quot;iron-plate&amp;quot;, quality=&amp;quot;legendary&amp;quot;, count=100}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Increase player inventory slots ===&lt;br /&gt;
Gives 100 additional bonus inventory slots to your entire force. Used by the [[Toolbelt (research)]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.character_inventory_slots_bonus=100&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== World manipulation scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Reveal the map around the player ===&lt;br /&gt;
&lt;br /&gt;
Reveals the map around the player, similar to a [[radar]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local radius=150&lt;br /&gt;
game.player.force.chart(game.player.surface, {{game.player.position.x-radius, game.player.position.y-radius}, {game.player.position.x+radius, game.player.position.y+radius}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or from start position&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local radius=150&lt;br /&gt;
game.player.force.chart(game.player.surface, {{x = -radius, y = -radius}, {x = radius, y = radius}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Change 150 to the desired radius, higher values take longer.&lt;br /&gt;
&lt;br /&gt;
=== Hide revealed map ===&lt;br /&gt;
&lt;br /&gt;
Hides all revealed chunks, inverted map revealing.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
local force = game.player.force&lt;br /&gt;
for chunk in surface.get_chunks() do&lt;br /&gt;
  force.unchart_chunk({x = chunk.x, y = chunk.y}, surface)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reveal all generated map ===&lt;br /&gt;
&lt;br /&gt;
Revels all of the generated map to the player&#039;s team.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.chart_all()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Delete chunks ===&lt;br /&gt;
If much of the map is revealed, it increases the size of the save file. The following command cancels the generation of all chunks that are currently queued for generation and removes chunks outside a 32 chunks radius around 0,0. Note that this will remove player entities if there are any on these chunks.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface;&lt;br /&gt;
game.player.force.cancel_charting(surface); &lt;br /&gt;
local chunk_radius = 32;&lt;br /&gt;
for chunk in surface.get_chunks() do&lt;br /&gt;
  if (chunk.x &amp;lt; -chunk_radius or chunk.x &amp;gt; chunk_radius or chunk.y &amp;lt; -chunk_radius or chunk.y &amp;gt; chunk_radius) then&lt;br /&gt;
    surface.delete_chunk(chunk)&lt;br /&gt;
  end&lt;br /&gt;
end &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Delete unrevealed chunks ===&lt;br /&gt;
This command deletes chunks that are not revealed by the player. Can be used after the command for [[#Hide revealed map|hiding revealed map]] to delete the chunks not covered by radar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;/c local surface = game.player.surface&lt;br /&gt;
local force = game.player.force&lt;br /&gt;
for chunk in surface.get_chunks() do&lt;br /&gt;
  if not force.is_chunk_charted(surface, chunk) then&lt;br /&gt;
    surface.delete_chunk(chunk)&lt;br /&gt;
  end&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Turn off night ===&lt;br /&gt;
Enables eternal day.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.always_day=true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Change game speed ===&lt;br /&gt;
0.5 is half speed, 1 is default, 2 is double speed, etc. Minimum is 0.01. This can be used for a lot of things like when you know you will have to wait for long periods of time for something to complete. Increasing will decrease performance, be careful.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.speed=X&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Freeze time ===&lt;br /&gt;
Stops the advancement of the time. Unfreezes it if you by replace &amp;quot;true&amp;quot; with &amp;quot;false&amp;quot;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.freeze_daytime=true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Remove all pollution ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.clear_pollution()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Completely turn off pollution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for _, surface in pairs(game.surfaces) do&lt;br /&gt;
  surface.clear_pollution()&lt;br /&gt;
end&lt;br /&gt;
game.map_settings.pollution.enabled = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add a lot of pollution ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.pollute(game.player.position, 1000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Where speakers are, who placed them ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local speakers = game.player.surface.find_entities_filtered{force = game.player.force, type=&amp;quot;programmable-speaker&amp;quot;}&lt;br /&gt;
for key, speaker in pairs(speakers) do&lt;br /&gt;
    game.player.print(speaker.last_user.name .. &amp;quot; placed a speaker at &amp;quot; .. speaker.gps_tag)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disable friendly fire for your force ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.friendly_fire = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add new resource patch ===&lt;br /&gt;
This creates a new 11×11 patch of resources, centered on the player character, where the ground is not water.&lt;br /&gt;
The patch it creates is perfectly square but it randomizes the amount similar to natural generation, with fewer ore at the edges and more ore in the center.&lt;br /&gt;
The default numbers result in a patch with 2500-3000 ore.&lt;br /&gt;
&lt;br /&gt;
If you want a larger patch, change &amp;quot;local size = 5&amp;quot; to a larger number.&lt;br /&gt;
A larger patch will have exponentially more ore.&lt;br /&gt;
Entering a number above 30 is not recommended.&lt;br /&gt;
&lt;br /&gt;
If you want a richer patch, change &amp;quot;local density = 10&amp;quot; to a larger number.&lt;br /&gt;
Entering a very large number shouldn&#039;t hurt anything but you probably don&#039;t need to go above 100.&lt;br /&gt;
&lt;br /&gt;
To choose which resource is spawned, change &amp;quot;stone&amp;quot; near the bottom to &amp;quot;iron-ore&amp;quot;, &amp;quot;copper-ore&amp;quot;, &amp;quot;coal&amp;quot;, or &amp;quot;uranium-ore&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface=game.player.surface&lt;br /&gt;
local ore=nil&lt;br /&gt;
local size=5&lt;br /&gt;
local density=10&lt;br /&gt;
for y=-size, size do&lt;br /&gt;
	for x=-size, size do&lt;br /&gt;
		a=(size+1-math.abs(x))*10&lt;br /&gt;
		b=(size+1-math.abs(y))*10&lt;br /&gt;
		if a&amp;lt;b then&lt;br /&gt;
			ore=math.random(a*density-a*(density-8), a*density+a*(density-8))&lt;br /&gt;
		end&lt;br /&gt;
		if b&amp;lt;a then&lt;br /&gt;
			ore=math.random(b*density-b*(density-8), b*density+b*(density-8))&lt;br /&gt;
		end&lt;br /&gt;
		if surface.get_tile(game.player.position.x+x, game.player.position.y+y).collides_with(&amp;quot;ground_tile&amp;quot;) then&lt;br /&gt;
			surface.create_entity({name=&amp;quot;stone&amp;quot;, amount=ore, position={game.player.position.x+x, game.player.position.y+y}})&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more flexibility, the [[map editor]] can also be used to create/alter/remove resource patches.&lt;br /&gt;
&lt;br /&gt;
=== Remove resources around the player ===&lt;br /&gt;
Removes all resource patches from the ground in a 50 x 50 area around the player.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface=game.player.surface&lt;br /&gt;
local size=50&lt;br /&gt;
local pos=game.player.position&lt;br /&gt;
&lt;br /&gt;
for _, e in pairs(surface.find_entities_filtered{area={{pos.x-size, pos.y-size},{pos.x+size, pos.y+size}}, type=&amp;quot;resource&amp;quot;}) &lt;br /&gt;
	do e.destroy() &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add new oil patch ===&lt;br /&gt;
This creates 9 crude oil patches in a 3×3 square.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for y=0,2 do&lt;br /&gt;
	for x=0,2 do&lt;br /&gt;
		game.player.surface.create_entity({name=&amp;quot;crude-oil&amp;quot;, amount=100000, position={game.player.position.x+x*7-7, game.player.position.y+y*7-7}})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or randomly without any collision:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local position=nil&lt;br /&gt;
for i=1,9 do&lt;br /&gt;
	position=game.player.surface.find_non_colliding_position(&amp;quot;crude-oil&amp;quot;, game.player.position, 0, i/2+1.5)&lt;br /&gt;
	if position then &lt;br /&gt;
		game.player.surface.create_entity({name=&amp;quot;crude-oil&amp;quot;, amount=100000, position=position})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add new water patch ===&lt;br /&gt;
&lt;br /&gt;
This creates a small pond in a 4x2 square.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c&lt;br /&gt;
local waterTiles = {}&lt;br /&gt;
for y=2,4 do&lt;br /&gt;
 for x=-2,2 do&lt;br /&gt;
  table.insert(waterTiles, {name=&amp;quot;water&amp;quot;, position={game.player.position.x+x, game.player.position.y+y}})&lt;br /&gt;
 end&lt;br /&gt;
 game.player.surface.set_tiles(waterTiles)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Regenerate resources ===&lt;br /&gt;
For solid resources like iron, destroys all resource entities and creates resource entities as in the original map generation. For fluid resources like oil, sets the yield of all existing resource entities to the original amount. Regenerates resources on the entire surface.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
for _, e in pairs(surface.find_entities_filtered{type=&amp;quot;resource&amp;quot;}) do&lt;br /&gt;
  if e.prototype.infinite_resource then&lt;br /&gt;
    e.amount = e.initial_amount&lt;br /&gt;
  else&lt;br /&gt;
    e.destroy()&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
local non_infinites = {}&lt;br /&gt;
for resource, prototype in pairs(prototypes.get_entity_filtered{{filter=&amp;quot;type&amp;quot;, type=&amp;quot;resource&amp;quot;}}) do&lt;br /&gt;
  if not prototype.infinite_resource then&lt;br /&gt;
    table.insert(non_infinites, resource)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
surface.regenerate_entity(non_infinites)&lt;br /&gt;
for _, e in pairs(surface.find_entities_filtered{type=&amp;quot;mining-drill&amp;quot;}) do&lt;br /&gt;
    e.update_connections()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Count entities ===&lt;br /&gt;
Counts all entities whose name includes the string in local entity.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local entity=&amp;quot;belt&amp;quot;&lt;br /&gt;
local surface=game.player.surface&lt;br /&gt;
local count=0&lt;br /&gt;
for key, ent in pairs(surface.find_entities_filtered({force=game.player.force})) do&lt;br /&gt;
	if string.find(ent.name,entity) then&lt;br /&gt;
		count=count+1&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
game.player.print(count)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Turn off cliff generation ===&lt;br /&gt;
Sets size to &amp;quot;none&amp;quot;. Only effective on chunks that are generated after using this command. Use [[#Remove all cliffs]] to delete existing cliffs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local mgs = game.player.surface.map_gen_settings&lt;br /&gt;
mgs.cliff_settings.cliff_elevation_0 = 1024&lt;br /&gt;
game.player.surface.map_gen_settings = mgs&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Remove all cliffs ===&lt;br /&gt;
Removes all cliffs existing cliffs from the world. Use [[#Turn off cliff generation]] to turn off cliff generation in new chunks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for _, v in pairs(game.player.surface.find_entities_filtered{type=&amp;quot;cliff&amp;quot;}) do&lt;br /&gt;
  v.destroy()&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Delete all decoratives ===&lt;br /&gt;
Delete the decoratives that can be found in the world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.destroy_decoratives({})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Change map generation settings ===&lt;br /&gt;
This allows to change the map generation settings for new chunks; it does not alter already generated chunks. [[#Delete chunks|Deleted chunks]] are affected by the setting change because they are newly generated when they get explored again.&lt;br /&gt;
&lt;br /&gt;
To change resource generation settings, replace &amp;quot;iron-ore&amp;quot; with the [[Data.raw#resource|resource]] that should be changed and replace &amp;quot;very-high&amp;quot; with the desired [https://lua-api.factorio.com/latest/concepts/MapGenSize.html MapGenSize] in the following command. Replace &amp;quot;iron-ore&amp;quot; with &amp;quot;enemy-base&amp;quot; to change the enemy base generation settings. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
local resource = &amp;quot;iron-ore&amp;quot;&lt;br /&gt;
local mgs = surface.map_gen_settings&lt;br /&gt;
mgs.autoplace_controls[resource].size = &amp;quot;very-high&amp;quot;&lt;br /&gt;
mgs.autoplace_controls[resource].frequency = &amp;quot;very-high&amp;quot;&lt;br /&gt;
mgs.autoplace_controls[resource].richness = &amp;quot;very-high&amp;quot;&lt;br /&gt;
surface.map_gen_settings = mgs&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To change water generation settings, replace &amp;quot;very-high&amp;quot; with the desired [https://lua-api.factorio.com/latest/concepts/MapGenSize.html MapGenSize] in the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
local mgs = surface.map_gen_settings&lt;br /&gt;
mgs.water = &amp;quot;very-high&amp;quot; --[[ size]]&lt;br /&gt;
mgs.terrain_segmentation  = &amp;quot;very-high&amp;quot; --[[ frequency]]&lt;br /&gt;
surface.map_gen_settings = mgs &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Making a structure indestructible ===&lt;br /&gt;
This makes it impossible for an entity to be damaged or killed, e.g. by biters. Hover over the entity and then run:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.selected.destructible = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Connect linked belts ===&lt;br /&gt;
If there exist at least two [https://lua-api.factorio.com/latest/prototypes/LinkedBeltPrototype.html linked belts], and one of them has the &amp;quot;Entity tag&amp;quot; &amp;lt;code&amp;gt;in&amp;lt;/code&amp;gt;, and another linked belt has the &amp;quot;Entity tag&amp;quot; &amp;lt;code&amp;gt;out&amp;lt;/code&amp;gt;, then the following command should link these two linked belts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local i = game.get_entity_by_tag(&#039;in&#039;)&lt;br /&gt;
local o = game.get_entity_by_tag(&#039;out&#039;)&lt;br /&gt;
i.linked_belt_type = &#039;input&#039;&lt;br /&gt;
o.linked_belt_type = &#039;output&#039;&lt;br /&gt;
i.connect_linked_belts(o)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Deactivate cars and tanks ===&lt;br /&gt;
The [[car]] and [[tank]] can be used like larger, 2x3 chests, but doing this at a large scale can have a negative performance impact. Deactivating them reduces their performance impact, though it also prevents them from being driven or moved by belts.&lt;br /&gt;
&lt;br /&gt;
Deactivate selected car or tank (hover with mouse then enter command):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.selected.active = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Deactivate all cars and tanks on surface:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for _, v in pairs(game.player.surface.find_entities_filtered{type=&amp;quot;car&amp;quot;}) do&lt;br /&gt;
  v.active = false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Enemy/evolution scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Set evolution factor ===&lt;br /&gt;
Ranges from 0 (new game) to 1.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.forces[&amp;quot;enemy&amp;quot;].set_evolution_factor(X, game.player.surface)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disable time-based evolution &amp;amp; increases pollution-based evolution ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.map_settings.enemy_evolution.time_factor=0&lt;br /&gt;
/c game.map_settings.enemy_evolution.pollution_factor=game.map_settings.enemy_evolution.pollution_factor*2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;2&amp;quot; at the end of the last command will double the default pollution factor. You can substitute another number to increase (or decrease) the pollution factor further.&lt;br /&gt;
&lt;br /&gt;
=== Kill all biters on the &amp;quot;enemy&amp;quot; force ===&lt;br /&gt;
Note that this will kill only mobile units, spawners will not be killed.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.forces[&amp;quot;enemy&amp;quot;].kill_all_units()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kill all enemies ===&lt;br /&gt;
This will kill all biters, bases and worms. Anything that is an enemy will be completely destroyed. This only affects enemies in the generated world, so any unexplored parts of the map which still need to be generated will still have enemies. You can [[#Prevent biters being on newly generated chunks|prevent biters being on newly generated chunks]] if desired.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface=game.player.surface&lt;br /&gt;
for key, entity in pairs(surface.find_entities_filtered({force=&amp;quot;enemy&amp;quot;})) do&lt;br /&gt;
	entity.destroy()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kill all nearby enemies ===&lt;br /&gt;
&lt;br /&gt;
This will kill all biters, bases and worms in a configurable radius. The default, 250 tiles, is about two zoomed-out screen widths on full HD. After destruction, it shows how many objects were destroyed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface=game.player.surface&lt;br /&gt;
local pp = game.player.position&lt;br /&gt;
local cnt = 0&lt;br /&gt;
for key, entity in pairs(surface.find_entities_filtered({force=&amp;quot;enemy&amp;quot;, radius=250, position=pp })) do&lt;br /&gt;
	cnt = cnt+1&lt;br /&gt;
	entity.destroy()&lt;br /&gt;
 end	&lt;br /&gt;
game.player.print(cnt)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable/Disable peaceful mode ===&lt;br /&gt;
Enabling peaceful mode prevents biter attacks until provoked. Substitute true for false to disable. Already existing biters are not affected by this command so attacks could continue for a while after activating peaceful mode.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.peaceful_mode = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable/Disable biter expansion ===&lt;br /&gt;
Biter expansion allows biters to create new nests, it is enabled by default. Substitute true for false to disable.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.map_settings.enemy_expansion.enabled = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Prevent biters being on newly generated chunks ===&lt;br /&gt;
On newly generated chunks no biters will be present, however all current biters will remain unaffected. Equivalent of setting the Enemy Base Size to None under the Terrain settings during map generation but achieved mid game by [[#Change map generation settings|changing map generation settings]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
local mgs = surface.map_gen_settings&lt;br /&gt;
mgs.autoplace_controls[&amp;quot;enemy-base&amp;quot;].size = &amp;quot;none&amp;quot;&lt;br /&gt;
surface.map_gen_settings = mgs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of the command, it is also possible to use a GUI in the [[map editor]] to changing map generation settings mid game. Access the map editor with &amp;lt;code&amp;gt;/editor&amp;lt;/code&amp;gt;, go to the &amp;quot;Surfaces&amp;quot; tab and click &amp;quot;Edit map gen settings&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Player character scripts ==&lt;br /&gt;
Commands concerning the player directly.&lt;br /&gt;
=== Get player position ===&lt;br /&gt;
Prints coordinates of your current position.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.print(game.player.position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Teleport player ===&lt;br /&gt;
Moves the player to the specified location. You should be able to teleport to a specific player if you obtain their coordinates via them executing the previous command and giving them to you.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.teleport({X, Y})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To teleport to the world&#039;s origin, use 0,0.&lt;br /&gt;
&lt;br /&gt;
To teleport to a different planet / surface, use:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.teleport({X, Y}, &#039;surface_name&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable god mode ===&lt;br /&gt;
God mode removes your player character allowing you to fly over obstacles and take no damage.&lt;br /&gt;
&lt;br /&gt;
Disassociate your controls from the character and destroy it:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.character.destroy()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To undo, spawn a player character. This will spawn a new character at the spawn point of the world, and connect your controls to it.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.create_character()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable long reach ===&lt;br /&gt;
Enables long reach, which allows the player to build and interact with entities at a greater distance. The default reach is 10.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local reach = 10000&lt;br /&gt;
game.player.force.character_build_distance_bonus = reach&lt;br /&gt;
game.player.force.character_reach_distance_bonus = reach&lt;br /&gt;
game.player.force.character_resource_reach_distance_bonus = reach&lt;br /&gt;
game.player.force.character_item_drop_distance_bonus = reach&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Find player corpses ===&lt;br /&gt;
Pings player corpses on the map.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local found_corpses = game.player.surface.find_entities_filtered{type=&amp;quot;character-corpse&amp;quot;}&lt;br /&gt;
for _,corpse in pairs(found_corpses) do&lt;br /&gt;
    local player = game.get_player(corpse.character_corpse_player_index)&lt;br /&gt;
    local name = player and player.name or &amp;quot;????&amp;quot;&lt;br /&gt;
    game.player.print(name .. &amp;quot; --&amp;gt; &amp;quot; .. corpse.gps_tag)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.character_running_speed_modifier=3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research scripts ==&lt;br /&gt;
=== Enable faster research ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.laboratory_speed_modifier=1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-0.5 is half speed, 0 is normal speed, 1 is double speed, 2 is triple etc.&lt;br /&gt;
&lt;br /&gt;
=== Research specific technologies ===&lt;br /&gt;
The internal technology names can be found in the infoboxes on their respective pages.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.technologies[&#039;electric-energy-distribution-1&#039;].researched=true&lt;br /&gt;
/c game.player.force.technologies[&#039;steel-processing&#039;].researched=true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To research a high level of an infinite technology, set its level:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.technologies[&#039;worker-robots-speed-7&#039;].level = 100&lt;br /&gt;
/c game.player.force.technologies[&#039;mining-productivity-3&#039;].level = 100&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unresearch specific technologies ===&lt;br /&gt;
The internal technology names can be found in the infoboxes on their respective pages.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.technologies[&#039;electric-energy-distribution-1&#039;].researched=false&lt;br /&gt;
/c game.player.force.technologies[&#039;steel-processing&#039;].researched=false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enabling specific recipes ===&lt;br /&gt;
The internal recipe/item names can be found in the infoboxes on their respective pages.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.recipes[&amp;quot;electric-energy-interface&amp;quot;].enabled=true&lt;br /&gt;
/c game.player.force.recipes[&amp;quot;rocket-silo&amp;quot;].enabled=true&lt;br /&gt;
/c game.player.force.recipes.loader.enabled=true&lt;br /&gt;
/c game.player.force.recipes[&amp;quot;fast-loader&amp;quot;].enabled = true&lt;br /&gt;
/c game.player.force.recipes[&amp;quot;express-loader&amp;quot;].enabled = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable all recipes ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for name, recipe in pairs(game.player.force.recipes) do recipe.enabled = true end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resetting technology effects to default ===&lt;br /&gt;
This will reset the enabled/unlocked state of all recipes to what they would be purely based on the currently researched technologies, as well as resetting other technology effects like mining speed, etc. Any manual modifications to these effects and recipe unlocks will be undone.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.reset_technology_effects()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note: Can be used as a quick workaround when recipes are unavailable after adding or changing mods even though the technology unlocking them has already been researched.&lt;br /&gt;
&lt;br /&gt;
=== Enable ghosts for destroyed entities ===&lt;br /&gt;
This is normally unlocked through researching [[construction robotics (research)]], but this command unlocks it independent of the research.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.create_ghost_on_entity_death = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modding tools ==&lt;br /&gt;
A list of the internal names of most things in the vanilla game can also be found on [[data.raw]].&lt;br /&gt;
&lt;br /&gt;
=== Access a mod&#039;s data ===&lt;br /&gt;
If the first word of the command is __mod-name__ it will run in the context of the mod with the same name. For instance, this command prints the data from the Even Distribution mod:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c __even-distribution__ game.player.print(serpent.dump(storage))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Print to console the tile under the player ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.print(game.player.surface.get_tile(game.player.position).name)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Write all researched technologies to file ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local list = {}&lt;br /&gt;
for _, tech in pairs(game.player.force.technologies) do &lt;br /&gt;
	if tech.researched then&lt;br /&gt;
    list[#list+1] = tech.name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
game.write_file(&amp;quot;techs.lua&amp;quot;, serpent.block(list) .. &amp;quot;\n&amp;quot;, true)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Write all enabled recipes to file ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local list = {}&lt;br /&gt;
for _, recipe in pairs(game.player.force.recipes) do &lt;br /&gt;
	if recipe.enabled then&lt;br /&gt;
    list[#list+1] = recipe.name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
game.write_file(&amp;quot;recipes.lua&amp;quot;, serpent.block(list) .. &amp;quot;\n&amp;quot;, true)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Write mod list to file ===&lt;br /&gt;
Write all currently active mods and their version to the file script-output/mods.txt in the [[user data directory]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c helpers.write_file(&amp;quot;mods.txt&amp;quot;, serpent.block(script.active_mods))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exporting production statistics ===&lt;br /&gt;
Export production statistics out of the game into external JSON files.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;/c local timescales = {&lt;br /&gt;
  [defines.flow_precision_index.five_seconds] = &amp;quot;5s&amp;quot;,&lt;br /&gt;
  [defines.flow_precision_index.one_minute] = &amp;quot;1min&amp;quot;,&lt;br /&gt;
  [defines.flow_precision_index.ten_minutes] = &amp;quot;10min&amp;quot;,&lt;br /&gt;
  [defines.flow_precision_index.one_hour] = &amp;quot;1h&amp;quot;,&lt;br /&gt;
  [defines.flow_precision_index.ten_hours] = &amp;quot;10h&amp;quot;,&lt;br /&gt;
  [defines.flow_precision_index.fifty_hours] = &amp;quot;50h&amp;quot;,&lt;br /&gt;
  [defines.flow_precision_index.two_hundred_fifty_hours] = &amp;quot;250h&amp;quot;,&lt;br /&gt;
  [defines.flow_precision_index.one_thousand_hours] = &amp;quot;1000h&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
for surface_name, _ in pairs(game.surfaces) do&lt;br /&gt;
  local flowdata = game.player.force.get_item_production_statistics(surface_name)&lt;br /&gt;
  for timescale_index, timescale_name in pairs(timescales) do&lt;br /&gt;
    local tbl = {}&lt;br /&gt;
    local totals = flowdata.input_counts&lt;br /&gt;
    for item_name, _ in pairs(totals) do&lt;br /&gt;
      local row = {item_name}&lt;br /&gt;
      for i = 1, 300 do&lt;br /&gt;
        table.insert(row, flowdata.get_flow_count{name=item_name, category=&amp;quot;input&amp;quot;, precision_index=timescale_index, sample_index=i, count=true})&lt;br /&gt;
      end&lt;br /&gt;
      table.insert(tbl, row)&lt;br /&gt;
    end&lt;br /&gt;
    helpers.write_file(&amp;quot;stats-&amp;quot; .. surface_name .. &amp;quot;-&amp;quot; .. timescale_name .. &amp;quot;.json&amp;quot;, helpers.table_to_json(tbl), false)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
game.player.print(&amp;quot;Export done&amp;quot;)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
{{History|1.1.92|&lt;br /&gt;
* Added a notification when a technology is researched.&lt;br /&gt;
* Added /enable-research-queue console command to enable the research queue without disabling achievements.}}&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Command line parameters]]&lt;br /&gt;
* https://lua-api.factorio.com/latest/index-runtime.html - Factorio API reference for latest version&lt;br /&gt;
&lt;br /&gt;
{{C|Modding}}&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Mod_settings&amp;diff=214892</id>
		<title>Tutorial:Mod settings</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Mod_settings&amp;diff=214892"/>
		<updated>2025-07-06T19:59:31Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: /* The type property */ Went to kindergarten to learn to count :P&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
This tutorial aims to explain how to create and use mod settings. Basic knowledge of modding is assumed, so you should have at least understood [[Tutorial:Modding tutorial/Gangsir|Gangsir&#039;s modding tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Each mod can specify settings that users can change. The values of these settings can be accessed from inside the data stage or the control stage depending on their [[#The_setting_type_property|setting_type]] and allow to conditionally create or modify prototypes and to add configuration options to control scripts. They allow modders to easily create a graphical interface for their configuration options, instead of using on text files that have to be edited manually by users.&lt;br /&gt;
&lt;br /&gt;
== Location ==&lt;br /&gt;
&lt;br /&gt;
Mod settings are defined in the [https://lua-api.factorio.com/latest/Data-Lifecycle.html settings stage]. This stage is loaded before the data stage. There are three files in which settings can be defined:&lt;br /&gt;
* settings.lua&lt;br /&gt;
* settings-updates.lua&lt;br /&gt;
* settings-final-fixes.lua&lt;br /&gt;
&lt;br /&gt;
First the settings.lua file is called for each mod, in the order of their dependencies and then in the [[:Wikipedia:natural sort order|natural sort order]]. After settings.lua has been called for all mods, the settings-updates.lua file is called for each mod &amp;lt;sup&amp;gt;(in the same order)&amp;lt;/sup&amp;gt; and finally the settings-final-fixes.lua file is called for each mod &amp;lt;sup&amp;gt;(in the same order)&amp;lt;/sup&amp;gt;. These 3 different phases of the settings stage allow to change settings of other mods without needing to rely on dependencies to load last. The settings are all defined in the same stage and their user defined values are not available, therefore mods cannot conditionally create settings depending on the values of other mod settings. Since the settings stage gets loaded first, there is also no prototype data or [http://lua-api.factorio.com/latest/LuaRemote.html remote interface] available.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;mod-settings.dat&amp;quot; file stored in the [[Application_directory#User_Data_directory|mods folder]] for the game contains the local players settings between game sessions similar to the player-data.json file.&lt;br /&gt;
&lt;br /&gt;
== Creation ==&lt;br /&gt;
&lt;br /&gt;
Mod settings are defined and modified by using the data table during the settings stage. This works [[Tutorial:Modding_tutorial/Gangsir#Prototype_creation|the same way as other prototypes]]. An example would be:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
data:extend({&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;bool-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-test-setting&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;runtime-global&amp;quot;,&lt;br /&gt;
        default_value = true&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, the setting has multiple properties. Each setting supports the following standard prototype properties:&lt;br /&gt;
* name - [https://lua-api.factorio.com/latest/types/string.html string] - Mandatory.&lt;br /&gt;
* type - [https://lua-api.factorio.com/latest/types/string.html string] - Mandatory.&lt;br /&gt;
* localised_name - [https://lua-api.factorio.com/latest/types/LocalisedString.html LocalisedString] - Optional.&lt;br /&gt;
* localised_description - [https://lua-api.factorio.com/latest/types/LocalisedString.html LocalisedString] - Optional.&lt;br /&gt;
* [https://lua-api.factorio.com/latest/types/Order.html order] - [https://lua-api.factorio.com/latest/types/string.html string] - Optional.&lt;br /&gt;
&lt;br /&gt;
In addition to the standard properties, mod settings also contain:&lt;br /&gt;
&lt;br /&gt;
* hidden - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Optional.&lt;br /&gt;
* setting_type - [https://lua-api.factorio.com/latest/types/string.html string] - Mandatory.&lt;br /&gt;
&lt;br /&gt;
=== The name property ===&lt;br /&gt;
&lt;br /&gt;
The name of the settings prototype should be unique to avoid mod conflicts since the mod settings are global across all mods. Because of that it is recommened to prefix mod settings with your mod name, &amp;quot;my-mod&amp;quot; in this example.&lt;br /&gt;
&lt;br /&gt;
=== The type property ===&lt;br /&gt;
&lt;br /&gt;
There are five types of mod settings:&lt;br /&gt;
&lt;br /&gt;
* bool-setting - a true/false checkbox&lt;br /&gt;
* int-setting - a signed 64 bit integer textfield (or selection dropdown)&lt;br /&gt;
* double-setting - a double precision floating point textfield (or selection dropdown)&lt;br /&gt;
* string-setting - a string textfield (or selection dropdown)&lt;br /&gt;
* color-setting - a color picker (sliders), with whole number textfields. Includes alpha.&lt;br /&gt;
&lt;br /&gt;
Depending on the type, the prototype also allows or requires additional properties, these are listed below.&lt;br /&gt;
&lt;br /&gt;
==== bool-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting, in this case whether the checkbox is checked or not.&lt;br /&gt;
* forced_value - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Optional.&lt;br /&gt;
** Only loaded if &amp;lt;code&amp;gt;hidden = true&amp;lt;/code&amp;gt;. This forces the setting to be of this value. This can be useful for mod compatiblity.&amp;lt;sup&amp;gt;[https://forums.factorio.com/viewtopic.php?p=531322#p531322]&lt;br /&gt;
&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== int-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/int64.html int64] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting.&lt;br /&gt;
* minimum_value - [https://lua-api.factorio.com/latest/types/int64.html int64] - Optional.&lt;br /&gt;
** Defines the lowest possible number.&lt;br /&gt;
* maximum_value - [https://lua-api.factorio.com/latest/types/int64.html int64] - Optional.&lt;br /&gt;
** Defines the highest possible number.&lt;br /&gt;
* allowed_values - array of [https://lua-api.factorio.com/latest/types/int64.html int64] - Optional.&lt;br /&gt;
** Makes it possible to force the player to choose between the defined numbers, creates a dropdown instead of a texfield.&lt;br /&gt;
** If only one allowed value is given, the settings is forced to be of that value.&lt;br /&gt;
&lt;br /&gt;
==== double-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/double.html double] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting.&lt;br /&gt;
* minimum_value - [https://lua-api.factorio.com/latest/types/double.html double] - Optional.&lt;br /&gt;
** Defines the lowest possible number.&lt;br /&gt;
* maximum_value - [https://lua-api.factorio.com/latest/types/double.html double] - Optional.&lt;br /&gt;
** Defines the highest possible number.&lt;br /&gt;
* allowed_values - array of [https://lua-api.factorio.com/latest/types/double.html double] - Optional.&lt;br /&gt;
** Makes it possible to force the player to choose between the defined numbers, creates a dropdown instead of a textfield.&lt;br /&gt;
** If only one allowed value is given, the settings is forced to be of that value.&lt;br /&gt;
&lt;br /&gt;
==== string-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/string.html string] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting.&lt;br /&gt;
* allow_blank - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Optional. - Default: false&lt;br /&gt;
** Defines whether it&#039;s possible for the user to set the textfield to empty and apply the setting.&lt;br /&gt;
* auto_trim - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Optional. - Default: false&lt;br /&gt;
** Whether values that are input by the user should have whitespace removed from both ends of the string.&lt;br /&gt;
* allowed_values - array of [https://lua-api.factorio.com/latest/types/string.html string] - Optional.&lt;br /&gt;
** Makes it possible to force the player to choose between the defined strings, creates a dropdown instead of a textfield. The strings in the dropdown can be localized (translated) and can have a tooltip, see below.&lt;br /&gt;
** If only one allowed value is given, the settings is forced to be of that value.&lt;br /&gt;
&lt;br /&gt;
==== color-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/Color.html Color] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting.&lt;br /&gt;
&lt;br /&gt;
=== The order property ===&lt;br /&gt;
&lt;br /&gt;
The order property can be used to change how the mod settings are ordered in the settings gui. Mod settings are sorted&lt;br /&gt;
* first by mod&lt;br /&gt;
* then by the setting &amp;quot;order&amp;quot; string&lt;br /&gt;
* then finally by the setting name.&lt;br /&gt;
&lt;br /&gt;
For more info on how to use the order string, see [https://lua-api.factorio.com/latest/types/Order.html Order].&lt;br /&gt;
&lt;br /&gt;
=== The hidden property ===&lt;br /&gt;
&lt;br /&gt;
The hidden property can be used to hide mod settings from GUIs, so that they cannot be seen or changed by players. However, other mods can still access hidden settings.&amp;lt;sup&amp;gt;[https://forums.factorio.com/83316]&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The setting_type property ===&lt;br /&gt;
[[File:Mod_settings_gui.png|right|300px|thumb|The mod settings gui. Can be reached from the main menu → Settings → Mod settings.]]&lt;br /&gt;
There are the overall kinds of settings:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;startup&#039;&#039;&#039;: This kind of setting is available in the prototype stage, and can not be changed runtime. They have to be  set to the same values for all players on a server.&lt;br /&gt;
* &#039;&#039;&#039;runtime-global&#039;&#039;&#039;: This kind of setting is global to an entire save game and can be changed runtime. On servers, only admins can change these settings.&lt;br /&gt;
* &#039;&#039;&#039;runtime-per-user&#039;&#039;&#039;: This kind of setting is only available runtime in the control.lua stage and each player has their own instance of this setting. When a player joins a server their local setting of &amp;quot;keep mod settings per save&amp;quot; determines if the local settings they have set are synced to the loaded save or if the save&#039;s settings are used.&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;setting_type&amp;quot; also determines in which tab the setting is showed in the mod settings menu.&lt;br /&gt;
&lt;br /&gt;
=== Locale ===&lt;br /&gt;
The locale for mod settings works like any other locale in the game. The names of the groups for the setting name and description (tooltip) are &amp;quot;mod-setting-name&amp;quot; and &amp;quot;mod-setting-description&amp;quot;. The dropdown items of a string setting can be localized in the &amp;quot;string-mod-setting&amp;quot; group, but the game falls back to just showing the name of the dropdown item if no localization is found. An example for mod setting localization that would be set within &amp;quot;locale/en/locale.cfg&amp;quot;, is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mod-setting-name]&lt;br /&gt;
my-mod-string-test-setting=Localized test setting name&lt;br /&gt;
&lt;br /&gt;
[mod-setting-description]&lt;br /&gt;
my-mod-string-test-setting=Localized test setting description&lt;br /&gt;
&lt;br /&gt;
[string-mod-setting]&lt;br /&gt;
#&amp;lt;setting-name&amp;gt;-&amp;lt;dropdown-item-name&amp;gt;=&amp;lt;translated dropdown item&amp;gt;&lt;br /&gt;
my-mod-string-test-setting-item-1=Item 1 localized string&lt;br /&gt;
&lt;br /&gt;
[string-mod-setting-description]&lt;br /&gt;
#&amp;lt;setting-name&amp;gt;-&amp;lt;dropdown-item-name&amp;gt;=&amp;lt;tooltip of dropdown item&amp;gt;&lt;br /&gt;
my-mod-string-test-setting-item-1=Item 1 localized tooltip&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
=== Reading settings ===&lt;br /&gt;
When accessing any mod setting, you will have to specifically access the &#039;&#039;value&#039;&#039; of the setting. The data type of the value depends on the type of the setting. For string settings that use a selection of allowed values, the value of the setting is one of the original string values defined in the prototype, the localization is ignored. See also: [http://lua-api.factorio.com/latest/Concepts.html#ModSetting ModSetting concept].&lt;br /&gt;
&lt;br /&gt;
In the prototype stage you can access settings of the setting_type &amp;quot;startup&amp;quot; by indexing &amp;lt;code&amp;gt;settings.startup&amp;lt;/code&amp;gt; with the name of the setting. Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings.lua:&lt;br /&gt;
data:extend({&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;int-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-stone-wall-stack-size&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;startup&amp;quot;,&lt;br /&gt;
        minimum_value = 1,&lt;br /&gt;
        default_value = 100&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
--in data.lua:&lt;br /&gt;
data.raw.item[&amp;quot;stone-wall&amp;quot;].stack_size = settings.startup[&amp;quot;my-mod-stone-wall-stack-size&amp;quot;].value&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot;&amp;gt;&lt;br /&gt;
In the control stage, &amp;quot;runtime-global&amp;quot; and &amp;quot;runtime-per-user&amp;quot; are additonally available. They can be accessed as follows:&lt;br /&gt;
* &amp;quot;runtime-global&amp;quot; (the &#039;&#039;current&#039;&#039; settings, under the Map tab in Mod Settings) can be accessed using &amp;lt;code&amp;gt;settings.global[&amp;quot;setting-name&amp;quot;]&amp;lt;/code&amp;gt; (see [https://lua-api.factorio.com/latest/LuaSettings.html LuaSettings]).&lt;br /&gt;
* &amp;quot;runtime-per-user&amp;quot; are accessed using &amp;lt;code&amp;gt;settings.get_player_settings([https://lua-api.factorio.com/latest/Concepts.html#PlayerIdentification &amp;amp;lt;PlayerIdentification&amp;amp;gt;])[&amp;quot;setting-name&amp;quot;]&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;game.players[[https://lua-api.factorio.com/latest/Concepts.html#PlayerIdentification &amp;amp;lt;PlayerIdentification&amp;amp;gt;]].mod_settings[&amp;quot;setting-name&amp;quot;]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings.lua:&lt;br /&gt;
data:extend({&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;string-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-always-difficult&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;runtime-global&amp;quot;,&lt;br /&gt;
        default_value = &amp;quot;yes&amp;quot;,&lt;br /&gt;
        allowed_values = {&amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;}&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;bool-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-kill-player-on-entity-built&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;runtime-per-user&amp;quot;,&lt;br /&gt;
        default_value = false&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
--in control.lua:&lt;br /&gt;
script.on_init(function()&lt;br /&gt;
    if settings.global[&amp;quot;my-mod-always-difficult&amp;quot;].value == &amp;quot;yes&amp;quot; then&lt;br /&gt;
        game.difficulty_settings.recipe_difficulty = 1&lt;br /&gt;
        game.difficulty_settings.technology_difficulty = 1&lt;br /&gt;
        game.difficulty_settings.technology_price_multiplier = 4&lt;br /&gt;
    end&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
script.on_event(defines.events.on_built_entity, function(event)&lt;br /&gt;
    local setting_value = settings.get_player_settings(event.player_index)[&amp;quot;my-mod-kill-player-on-entity-built&amp;quot;].value&lt;br /&gt;
    if setting_value then&lt;br /&gt;
        game.get_player(event.player_index).die()&lt;br /&gt;
    end&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Writing to your own settings ===&lt;br /&gt;
It is possible for mods to write to their own runtime (global or per player) mod settings. This is done by writing a new [https://lua-api.factorio.com/latest/Concepts.html#ModSetting ModSetting] table to the setting.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings.lua:&lt;br /&gt;
data:extend({&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;string-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-always-difficult&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;runtime-global&amp;quot;,&lt;br /&gt;
        default_value = &amp;quot;yes&amp;quot;,&lt;br /&gt;
        allowed_values = {&amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;}&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
--in control.lua:&lt;br /&gt;
script.on_event(defines.events.on_rocket_launched, function()&lt;br /&gt;
    settings.global[&amp;quot;my-mod-always-difficult&amp;quot;] = {value = &amp;quot;yes&amp;quot;}&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Changing another mod&#039;s settings ===&lt;br /&gt;
After creating a setting in the settings stage, it is stored in data.raw until the end of the stage, so it can be altered from another mod.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings-updates.lua:&lt;br /&gt;
data.raw[&amp;quot;string-setting&amp;quot;][&amp;quot;my-mod-always-difficult&amp;quot;].order = &amp;quot;abc&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the intent is to force the setting to be of a certain value that cannot be modified by players, the properties [[#The_hidden_property|hidden]], allowed_values and forced_value can be used. Modifying existing settings of other mods can be useful for mod packs or other mod compatibility goals.[https://forums.factorio.com/viewtopic.php?p=531322#p531322]&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings-updates.lua:&lt;br /&gt;
data.raw[&amp;quot;string-setting&amp;quot;][&amp;quot;my-mod-always-difficult&amp;quot;].hidden = true&lt;br /&gt;
data.raw[&amp;quot;string-setting&amp;quot;][&amp;quot;my-mod-always-difficult&amp;quot;].allowed_values = {&amp;quot;no&amp;quot;}&lt;br /&gt;
data.raw[&amp;quot;string-setting&amp;quot;][&amp;quot;my-mod-always-difficult&amp;quot;].default_value = &amp;quot;no&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
* Do not conditionally &#039;require(...)&#039; things depending on mod settings: This breaks the CRC checks and people will get errors trying to use your mod in multiplayer. &#039;require(...)&#039; everything and then conditionally add the values to data.raw using the settings.&lt;br /&gt;
* You should cache the settings table inside the event you use it in. Accessing it is relatively expensive (about as expensive as accessing game.*prototypes[...]), so when accessing it mutliple times within the same event, you should set a local variable to it (within the event) to improve performance.&lt;br /&gt;
** If you want to cache startup/and runtime settings outside of events, you will have to makes sure that the local variable of settings of the setting_type &amp;quot;runtime-global&amp;quot; are updated in the &amp;lt;code&amp;gt;on_runtime_mod_setting_changed&amp;lt;/code&amp;gt; event.&lt;br /&gt;
* If you want to detect whether a certain mod is installed in the settings stage, you can use &amp;lt;code&amp;gt;if mods[&amp;quot;another-mods-name&amp;quot;] then&amp;lt;/code&amp;gt;, just like in the data stage.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://forums.factorio.com/viewtopic.php?p=207275 Forum post documenting mod settings]&lt;br /&gt;
* [https://forums.factorio.com/viewtopic.php?p=305644#p305644 per_user is not a valid property and has no effects!]&lt;br /&gt;
* [http://lua-api.factorio.com/latest/LuaSettings.html Lua api documentation on the settings table]&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Mod_settings&amp;diff=213963</id>
		<title>Tutorial:Mod settings</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Mod_settings&amp;diff=213963"/>
		<updated>2025-05-14T01:59:01Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: /* Reading settings */ Refine the wording of the clarification + Split the different types into more legibly different things&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
This tutorial aims to explain how to create and use mod settings. Basic knowledge of modding is assumed, so you should have at least understood [[Tutorial:Modding tutorial/Gangsir|Gangsir&#039;s modding tutorial]].&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
Each mod can specify settings that users can change. The values of these settings can be accessed from inside the data stage or the control stage depending on their [[#The_setting_type_property|setting_type]] and allow to conditionally create or modify prototypes and to add configuration options to control scripts. They allow modders to easily create a graphical interface for their configuration options, instead of using on text files that have to be edited manually by users.&lt;br /&gt;
&lt;br /&gt;
== Location ==&lt;br /&gt;
&lt;br /&gt;
Mod settings are defined in the [https://lua-api.factorio.com/latest/Data-Lifecycle.html settings stage]. This stage is loaded before the data stage. There are three files in which settings can be defined:&lt;br /&gt;
* settings.lua&lt;br /&gt;
* settings-updates.lua&lt;br /&gt;
* settings-final-fixes.lua&lt;br /&gt;
&lt;br /&gt;
First the settings.lua file is called for each mod, in the order of their dependencies and then in the [[:Wikipedia:natural sort order|natural sort order]]. After settings.lua has been called for all mods, the settings-updates.lua file is called for each mod &amp;lt;sup&amp;gt;(in the same order)&amp;lt;/sup&amp;gt; and finally the settings-final-fixes.lua file is called for each mod &amp;lt;sup&amp;gt;(in the same order)&amp;lt;/sup&amp;gt;. These 3 different phases of the settings stage allow to change settings of other mods without needing to rely on dependencies to load last. The settings are all defined in the same stage and their user defined values are not available, therefore mods cannot conditionally create settings depending on the values of other mod settings. Since the settings stage gets loaded first, there is also no prototype data or [http://lua-api.factorio.com/latest/LuaRemote.html remote interface] available.&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;mod-settings.dat&amp;quot; file stored in the [[Application_directory#User_Data_directory|mods folder]] for the game contains the local players settings between game sessions similar to the player-data.json file.&lt;br /&gt;
&lt;br /&gt;
== Creation ==&lt;br /&gt;
&lt;br /&gt;
Mod settings are defined and modified by using the data table during the settings stage. This works [[Tutorial:Modding_tutorial/Gangsir#Prototype_creation|the same way as other prototypes]]. An example would be:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
data:extend({&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;bool-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-test-setting&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;runtime-global&amp;quot;,&lt;br /&gt;
        default_value = true&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, the setting has multiple properties. Each setting supports the following standard prototype properties:&lt;br /&gt;
* name - [https://lua-api.factorio.com/latest/types/string.html string] - Mandatory.&lt;br /&gt;
* type - [https://lua-api.factorio.com/latest/types/string.html string] - Mandatory.&lt;br /&gt;
* localised_name - [https://lua-api.factorio.com/latest/types/LocalisedString.html LocalisedString] - Optional.&lt;br /&gt;
* localised_description - [https://lua-api.factorio.com/latest/types/LocalisedString.html LocalisedString] - Optional.&lt;br /&gt;
* [https://lua-api.factorio.com/latest/types/Order.html order] - [https://lua-api.factorio.com/latest/types/string.html string] - Optional.&lt;br /&gt;
&lt;br /&gt;
In addition to the standard properties, mod settings also contain:&lt;br /&gt;
&lt;br /&gt;
* hidden - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Optional.&lt;br /&gt;
* setting_type - [https://lua-api.factorio.com/latest/types/string.html string] - Mandatory.&lt;br /&gt;
&lt;br /&gt;
=== The name property ===&lt;br /&gt;
&lt;br /&gt;
The name of the settings prototype should be unique to avoid mod conflicts since the mod settings are global across all mods. Because of that it is recommened to prefix mod settings with your mod name, &amp;quot;my-mod&amp;quot; in this example.&lt;br /&gt;
&lt;br /&gt;
=== The type property ===&lt;br /&gt;
&lt;br /&gt;
There are four types of mod settings:&lt;br /&gt;
&lt;br /&gt;
* bool-setting - a true/false checkbox&lt;br /&gt;
* int-setting - a signed 64 bit integer textfield (or selection dropdown)&lt;br /&gt;
* double-setting - a double precision floating point textfield (or selection dropdown)&lt;br /&gt;
* string-setting - a string textfield (or selection dropdown)&lt;br /&gt;
* color-setting - a color picker (sliders), with whole number textfields. Includes alpha.&lt;br /&gt;
&lt;br /&gt;
Depending on the type, the prototype also allows or requires additional properties, these are listed below.&lt;br /&gt;
&lt;br /&gt;
==== bool-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting, in this case whether the checkbox is checked or not.&lt;br /&gt;
* forced_value - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Optional.&lt;br /&gt;
** Only loaded if &amp;lt;code&amp;gt;hidden = true&amp;lt;/code&amp;gt;. This forces the setting to be of this value. This can be useful for mod compatiblity.&amp;lt;sup&amp;gt;[https://forums.factorio.com/viewtopic.php?p=531322#p531322]&lt;br /&gt;
&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== int-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/int64.html int64] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting.&lt;br /&gt;
* minimum_value - [https://lua-api.factorio.com/latest/types/int64.html int64] - Optional.&lt;br /&gt;
** Defines the lowest possible number.&lt;br /&gt;
* maximum_value - [https://lua-api.factorio.com/latest/types/int64.html int64] - Optional.&lt;br /&gt;
** Defines the highest possible number.&lt;br /&gt;
* allowed_values - array of [https://lua-api.factorio.com/latest/types/int64.html int64] - Optional.&lt;br /&gt;
** Makes it possible to force the player to choose between the defined numbers, creates a dropdown instead of a texfield.&lt;br /&gt;
** If only one allowed value is given, the settings is forced to be of that value.&lt;br /&gt;
&lt;br /&gt;
==== double-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/double.html double] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting.&lt;br /&gt;
* minimum_value - [https://lua-api.factorio.com/latest/types/double.html double] - Optional.&lt;br /&gt;
** Defines the lowest possible number.&lt;br /&gt;
* maximum_value - [https://lua-api.factorio.com/latest/types/double.html double] - Optional.&lt;br /&gt;
** Defines the highest possible number.&lt;br /&gt;
* allowed_values - array of [https://lua-api.factorio.com/latest/types/double.html double] - Optional.&lt;br /&gt;
** Makes it possible to force the player to choose between the defined numbers, creates a dropdown instead of a textfield.&lt;br /&gt;
** If only one allowed value is given, the settings is forced to be of that value.&lt;br /&gt;
&lt;br /&gt;
==== string-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/string.html string] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting.&lt;br /&gt;
* allow_blank - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Optional. - Default: false&lt;br /&gt;
** Defines whether it&#039;s possible for the user to set the textfield to empty and apply the setting.&lt;br /&gt;
* auto_trim - [https://lua-api.factorio.com/latest/types/boolean.html boolean] - Optional. - Default: false&lt;br /&gt;
** Whether values that are input by the user should have whitespace removed from both ends of the string.&lt;br /&gt;
* allowed_values - array of [https://lua-api.factorio.com/latest/types/string.html string] - Optional.&lt;br /&gt;
** Makes it possible to force the player to choose between the defined strings, creates a dropdown instead of a textfield. The strings in the dropdown can be localized (translated) and can have a tooltip, see below.&lt;br /&gt;
** If only one allowed value is given, the settings is forced to be of that value.&lt;br /&gt;
&lt;br /&gt;
==== color-setting ====&lt;br /&gt;
* default_value - [https://lua-api.factorio.com/latest/types/Color.html Color] - Mandatory.&lt;br /&gt;
** Defines the default value of the setting.&lt;br /&gt;
&lt;br /&gt;
=== The order property ===&lt;br /&gt;
&lt;br /&gt;
The order property can be used to change how the mod settings are ordered in the settings gui. Mod settings are sorted&lt;br /&gt;
* first by mod&lt;br /&gt;
* then by the setting &amp;quot;order&amp;quot; string&lt;br /&gt;
* then finally by the setting name.&lt;br /&gt;
&lt;br /&gt;
For more info on how to use the order string, see [https://lua-api.factorio.com/latest/types/Order.html Order].&lt;br /&gt;
&lt;br /&gt;
=== The hidden property ===&lt;br /&gt;
&lt;br /&gt;
The hidden property can be used to hide mod settings from GUIs, so that they cannot be seen or changed by players. However, other mods can still access hidden settings.&amp;lt;sup&amp;gt;[https://forums.factorio.com/83316]&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The setting_type property ===&lt;br /&gt;
[[File:Mod_settings_gui.png|right|300px|thumb|The mod settings gui. Can be reached from the main menu → Settings → Mod settings.]]&lt;br /&gt;
There are the overall kinds of settings:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;startup&#039;&#039;&#039;: This kind of setting is available in the prototype stage, and can not be changed runtime. They have to be  set to the same values for all players on a server.&lt;br /&gt;
* &#039;&#039;&#039;runtime-global&#039;&#039;&#039;: This kind of setting is global to an entire save game and can be changed runtime. On servers, only admins can change these settings.&lt;br /&gt;
* &#039;&#039;&#039;runtime-per-user&#039;&#039;&#039;: This kind of setting is only available runtime in the control.lua stage and each player has their own instance of this setting. When a player joins a server their local setting of &amp;quot;keep mod settings per save&amp;quot; determines if the local settings they have set are synced to the loaded save or if the save&#039;s settings are used.&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;setting_type&amp;quot; also determines in which tab the setting is showed in the mod settings menu.&lt;br /&gt;
&lt;br /&gt;
=== Locale ===&lt;br /&gt;
The locale for mod settings works like any other locale in the game. The names of the groups for the setting name and description (tooltip) are &amp;quot;mod-setting-name&amp;quot; and &amp;quot;mod-setting-description&amp;quot;. The dropdown items of a string setting can be localized in the &amp;quot;string-mod-setting&amp;quot; group, but the game falls back to just showing the name of the dropdown item if no localization is found. An example for mod setting localization that would be set within &amp;quot;locale/en/locale.cfg&amp;quot;, is:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[mod-setting-name]&lt;br /&gt;
my-mod-string-test-setting=Localized test setting name&lt;br /&gt;
&lt;br /&gt;
[mod-setting-description]&lt;br /&gt;
my-mod-string-test-setting=Localized test setting description&lt;br /&gt;
&lt;br /&gt;
[string-mod-setting]&lt;br /&gt;
#&amp;lt;setting-name&amp;gt;-&amp;lt;dropdown-item-name&amp;gt;=&amp;lt;translated dropdown item&amp;gt;&lt;br /&gt;
my-mod-string-test-setting-item-1=Item 1 localized string&lt;br /&gt;
&lt;br /&gt;
[string-mod-setting-description]&lt;br /&gt;
#&amp;lt;setting-name&amp;gt;-&amp;lt;dropdown-item-name&amp;gt;=&amp;lt;tooltip of dropdown item&amp;gt;&lt;br /&gt;
my-mod-string-test-setting-item-1=Item 1 localized tooltip&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
=== Reading settings ===&lt;br /&gt;
When accessing any mod setting, you will have to specifically access the &#039;&#039;value&#039;&#039; of the setting. The data type of the value depends on the type of the setting. For string settings that use a selection of allowed values, the value of the setting is one of the original string values defined in the prototype, the localization is ignored. See also: [http://lua-api.factorio.com/latest/Concepts.html#ModSetting ModSetting concept].&lt;br /&gt;
&lt;br /&gt;
In the prototype stage you can access settings of the setting_type &amp;quot;startup&amp;quot; by indexing &amp;lt;code&amp;gt;settings.startup&amp;lt;/code&amp;gt; with the name of the setting. Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings.lua:&lt;br /&gt;
data:extend({&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;int-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-stone-wall-stack-size&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;startup&amp;quot;,&lt;br /&gt;
        minimum_value = 1,&lt;br /&gt;
        default_value = 100&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
--in data.lua:&lt;br /&gt;
data.raw.item[&amp;quot;stone-wall&amp;quot;].stack_size = settings.startup[&amp;quot;my-mod-stone-wall-stack-size&amp;quot;].value&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot;&amp;gt;&lt;br /&gt;
In the control stage, &amp;quot;runtime-global&amp;quot; and &amp;quot;runtime-per-user&amp;quot; are additonally available. They can be accessed as follows:&lt;br /&gt;
* &amp;quot;runtime-global&amp;quot; (the &#039;&#039;current&#039;&#039; settings, under the Map tab in Mod Settings) can be accessed using &amp;lt;code&amp;gt;settings.global[&amp;quot;setting-name&amp;quot;]&amp;lt;/code&amp;gt; (see [https://lua-api.factorio.com/latest/LuaSettings.html LuaSettings]).&lt;br /&gt;
* &amp;quot;runtime-per-user&amp;quot; are accessed using &amp;lt;code&amp;gt;settings.get_player_settings([https://lua-api.factorio.com/latest/Concepts.html#PlayerIdentification &amp;amp;lt;PlayerIdentification&amp;amp;gt;])[&amp;quot;setting-name&amp;quot;]&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;game.players[[https://lua-api.factorio.com/latest/Concepts.html#PlayerIdentification &amp;amp;lt;PlayerIdentification&amp;amp;gt;]].mod_settings[&amp;quot;setting-name&amp;quot;]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings.lua:&lt;br /&gt;
data:extend({&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;string-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-always-difficult&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;runtime-global&amp;quot;,&lt;br /&gt;
        default_value = &amp;quot;yes&amp;quot;,&lt;br /&gt;
        allowed_values = {&amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;}&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;bool-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-kill-player-on-entity-built&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;runtime-per-user&amp;quot;,&lt;br /&gt;
        default_value = false&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
--in control.lua:&lt;br /&gt;
script.on_init(function()&lt;br /&gt;
    if settings.global[&amp;quot;my-mod-always-difficult&amp;quot;].value == &amp;quot;yes&amp;quot; then&lt;br /&gt;
        game.difficulty_settings.recipe_difficulty = 1&lt;br /&gt;
        game.difficulty_settings.technology_difficulty = 1&lt;br /&gt;
        game.difficulty_settings.technology_price_multiplier = 4&lt;br /&gt;
    end&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
script.on_event(defines.events.on_built_entity, function(event)&lt;br /&gt;
    local setting_value = settings.get_player_settings(event.player_index)[&amp;quot;my-mod-kill-player-on-entity-built&amp;quot;].value&lt;br /&gt;
    if setting_value then&lt;br /&gt;
        game.get_player(event.player_index).die()&lt;br /&gt;
    end&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Writing to your own settings ===&lt;br /&gt;
It is possible for mods to write to their own runtime (global or per player) mod settings. This is done by writing a new [https://lua-api.factorio.com/latest/Concepts.html#ModSetting ModSetting] table to the setting.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings.lua:&lt;br /&gt;
data:extend({&lt;br /&gt;
    {&lt;br /&gt;
        type = &amp;quot;string-setting&amp;quot;,&lt;br /&gt;
        name = &amp;quot;my-mod-always-difficult&amp;quot;,&lt;br /&gt;
        setting_type = &amp;quot;runtime-global&amp;quot;,&lt;br /&gt;
        default_value = &amp;quot;yes&amp;quot;,&lt;br /&gt;
        allowed_values = {&amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;}&lt;br /&gt;
    }&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
--in control.lua:&lt;br /&gt;
script.on_event(defines.events.on_rocket_launched, function()&lt;br /&gt;
    settings.global[&amp;quot;my-mod-always-difficult&amp;quot;] = {value = &amp;quot;yes&amp;quot;}&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Changing another mod&#039;s settings ===&lt;br /&gt;
After creating a setting in the settings stage, it is stored in data.raw until the end of the stage, so it can be altered from another mod.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings-updates.lua:&lt;br /&gt;
data.raw[&amp;quot;string-setting&amp;quot;][&amp;quot;my-mod-always-difficult&amp;quot;].order = &amp;quot;abc&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the intent is to force the setting to be of a certain value that cannot be modified by players, the properties [[#The_hidden_property|hidden]], allowed_values and forced_value can be used. Modifying existing settings of other mods can be useful for mod packs or other mod compatibility goals.[https://forums.factorio.com/viewtopic.php?p=531322#p531322]&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--in settings-updates.lua:&lt;br /&gt;
data.raw[&amp;quot;string-setting&amp;quot;][&amp;quot;my-mod-always-difficult&amp;quot;].hidden = true&lt;br /&gt;
data.raw[&amp;quot;string-setting&amp;quot;][&amp;quot;my-mod-always-difficult&amp;quot;].allowed_values = {&amp;quot;no&amp;quot;}&lt;br /&gt;
data.raw[&amp;quot;string-setting&amp;quot;][&amp;quot;my-mod-always-difficult&amp;quot;].default_value = &amp;quot;no&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
* Do not conditionally &#039;require(...)&#039; things depending on mod settings: This breaks the CRC checks and people will get errors trying to use your mod in multiplayer. &#039;require(...)&#039; everything and then conditionally add the values to data.raw using the settings.&lt;br /&gt;
* You should cache the settings table inside the event you use it in. Accessing it is relatively expensive (about as expensive as accessing game.*prototypes[...]), so when accessing it mutliple times within the same event, you should set a local variable to it (within the event) to improve performance.&lt;br /&gt;
** If you want to cache startup/and runtime settings outside of events, you will have to makes sure that the local variable of settings of the setting_type &amp;quot;runtime-global&amp;quot; are updated in the &amp;lt;code&amp;gt;on_runtime_mod_setting_changed&amp;lt;/code&amp;gt; event.&lt;br /&gt;
* If you want to detect whether a certain mod is installed in the settings stage, you can use &amp;lt;code&amp;gt;if mods[&amp;quot;another-mods-name&amp;quot;] then&amp;lt;/code&amp;gt;, just like in the data stage.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://forums.factorio.com/viewtopic.php?p=207275 Forum post documenting mod settings]&lt;br /&gt;
* [https://forums.factorio.com/viewtopic.php?p=305644#p305644 per_user is not a valid property and has no effects!]&lt;br /&gt;
* [http://lua-api.factorio.com/latest/LuaSettings.html Lua api documentation on the settings table]&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Desynchronization&amp;diff=212001</id>
		<title>Desynchronization</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Desynchronization&amp;diff=212001"/>
		<updated>2025-03-03T02:41:27Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Repair API links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A desynchronization (desync) is a disagreement of the game state between the server and at least one client in a multiplayer game, this means the parties no longer run the simulation identically. &lt;br /&gt;
&lt;br /&gt;
== How desyncs happen ==&lt;br /&gt;
Desyncs are errors and should not occur during regular play, they can be caused by: &lt;br /&gt;
* a bug in Factorio code&lt;br /&gt;
* a bug in a mod/scenario&lt;br /&gt;
* a miscalculation on server or client hardware&lt;br /&gt;
Networking-, latency or performance problems do &#039;&#039;not&#039;&#039; cause desyncs.&lt;br /&gt;
&lt;br /&gt;
=== Factorio multiplayer architecture ===&lt;br /&gt;
Factorio multiplayer code uses deterministic lockstep to synchronize clients. This is a method of synchronizing a game from one computer to another by sending only the user inputs that control that game, rather than networking the state of the objects in the game itself. It means that all players&#039; games need to simulate every single tick of the game identically. If any computer does something ever-so-slightly different, a desynchronization (desync) occurs. The game includes processes to ensure any issues with network traffic do not cause desyncs.&lt;br /&gt;
&lt;br /&gt;
=== Player experience of desyncs ===&lt;br /&gt;
When a client detects a desync, it disconnects the player and starts to download files from the server (map and game state information) to include them in the [[#Desync_report|Desync report]], this will take longer than the normal map download. After the download is finished and the desync report has been generated the player is offered the options to view the report, quit or reconnect to continue playing. Depending on the cause of the desync, the client might immediately desync again when reconnecting.&lt;br /&gt;
&lt;br /&gt;
[[File:Desync report notification.jpg]]&lt;br /&gt;
&lt;br /&gt;
=== Desync report ===&lt;br /&gt;
The desync report will help mod/scenario makers or Factorio developers to fix the underlying bug, it contains both the player&#039;s and server&#039;s copy of the save game (map and game state). The player&#039;s copy is from when the desync occurred and titled &#039;&#039;desynced-level&#039;&#039;. With the server&#039;s copy being from when the automatic reconnection was made and titled &#039;&#039;reference-level.zip&#039;&#039;. A copy of the players Factorio log file is included titled &#039;&#039;log.txt&#039;&#039;. As the report contains two copies of the save game it may have a large file size. Furthermore, the save files that are made for the desync report contain more data than normal save files, further increasing their size.&lt;br /&gt;
&lt;br /&gt;
The desync report does not state the cause of the desync but rather is a record of the game state at the time of the desync.&lt;br /&gt;
&lt;br /&gt;
=== Next Steps ===&lt;br /&gt;
The next steps after a desync occurs is to start a desync investigation. In many situations restarting the server will work around the desync in the short term and allow all players to rejoin until the conditions for the bug to occur are re-created. However, a server restart isn&#039;t guaranteed success and may lead to no players being able to rejoin the server without desyncing.&lt;br /&gt;
&lt;br /&gt;
== Desync Investigations ==&lt;br /&gt;
In most cases when desyncs occur and mods or scenarios are being used they are the cause and need to be handled first. If they are found to not be the cause then it should be reported as a [[#Desync_reporting_of_core_Factorio_game|core Factorio desync]]. In both cases identifying the activity that triggers the desync is an important step. For example, whether it is tied to a player&#039;s action or activity that happens in the game (i.e. a train arriving at a station) or is a time-related event. In some cases, the desync may not be reproducible and so only a code investigation can work towards a fix.&lt;br /&gt;
&lt;br /&gt;
When desyncs occur and mods/scenarios are in the use there are 2 different approaches that can be taken to help get the issue fixed. The code investigation approach requires you to be familiar with Factorio modding and its coding rules. The less technical method is to identify the mod and activity that causes the desync through trial and error so it can be reported to the mod author.&lt;br /&gt;
&lt;br /&gt;
=== Identifying desync causing mod through trial and error ===&lt;br /&gt;
This is a less technical method aiming to identify the mod and its activity that seems to cause the desync so it can be reported to the mod/scenario author. The activity that causes the desync should be established prior to these activities being done to confirm if they are having an impact. These steps may affect the gameplay and should be done on a test save. &lt;br /&gt;
* Removing any newly added mods and rolling back (returning to the previous version) any updated mods to see if the issue still occurs.&lt;br /&gt;
* Removing mods from the game to rule them out as the cause.&lt;br /&gt;
Once the desync can no longer be reproduced the suspected mod can be re-added/updated and the desync recreated to confirm the mod and activity are the cause of the desync. As these steps require the server to be restarted this may in itself fix any desyncs in the short term until the conditions for the bug to occur are re-created.&lt;br /&gt;
&lt;br /&gt;
=== Code investigations with mods/scenarios involved ===&lt;br /&gt;
The desync report is a useful reference for investigating desyncs but it does not state the cause of the desync. Comparing the desync files and use of heavy mode can assist in identifying which mods and activities to review initially. Ideally, it is supplemented by an account of what was occurring and being done by players at the point of the desync occurring to assist with narrowing down the activities of code to review. However in many complicated scenarios this may not be known prior to the investigation.&lt;br /&gt;
&lt;br /&gt;
==== Code that causes desyncs ====&lt;br /&gt;
There are a number of ways mod and scenario code can cause desyncs, such as due to incorrect variable scoping, requiring or API event handling. Examples of these can be found in [[Tutorial:Modding tutorial/Gangsir#Multiplayer_and_desyncs|Gangsir&#039;s modding tutorial multiplayer and desyncs section]], with the full technical definition of usage constraints for API events in the [https://lua-api.factorio.com/latest/auxiliary/data-lifecycle.html Factorio API data lifecycle]. Not all instances of non-compliance will lead to desyncs or errors, but most will. For this reason, it is recommended to always maintain compliance to avoid risk and time-consuming testing. Instances of non-compliance found should be raised to the code author.&lt;br /&gt;
&lt;br /&gt;
==== Comparing game state &amp;amp; save files ====&lt;br /&gt;
The desync report files and heavy mode dumps contain a number of files that can be compared by any text comparison tool to look for differences. These files are generally sequelized dumps of Lua tables or c++ game objects and so are only partially human readable. The less human readable items can include floating point numbers serilaised (0x.HEXp+HEX) and &#039;&#039;magic&#039;&#039; unique identifier numbers for prototype instances in the c++ game state. These numbers and reference ids should generally be the same between files as the in-game entity they reference normally won&#039;t have changed between the 2 save game states being obtained. &lt;br /&gt;
When the data differs between files the source code of that mod/scenario must be examined for all interactions with that data item for any instances of non-compliance.&lt;br /&gt;
&lt;br /&gt;
==== Examining the desync files ====&lt;br /&gt;
Within each savegame&#039;s zip in the desync report are a number of files that when compared can show data changes. As the server copy of the save is obtained after the desync there may be genuine differences between the files. So differences aren&#039;t hard evidence of the cause of a desync, but only a pointer on where to investigate further.&lt;br /&gt;
&lt;br /&gt;
* script.dat - contains the scenario and mods [https://lua-api.factorio.com/latest/auxiliary/storage.html Factorio storage tables]. Generally, the save&#039;s persistent data should be the same between the 2 saves. On rare occasions, there can be a difference due to how the information is written out to the file. Should a mod causes a player&#039;s game to desync it can cause the player&#039;s game to stop processing other mod activity mid tick. This can lead those mod&#039;s global tables to have differences between the player and the server copies despite having no code defects themselves.&lt;br /&gt;
* level_with_tags_tick_XXXX.dat - contains the current game state together with additional saving tags to aid human readability. This can show if entity states or chat messages differ. &#039;&#039;level.dat&#039;&#039; is the same information, but without the descriptive tags for data values.&lt;br /&gt;
&lt;br /&gt;
==== Using heavy mode command ====&lt;br /&gt;
[[Console#Normal_commands|Heavy mode]] is an in-game option that can be enabled to make Factorio save and load the game every tick. This allows Factorio to highlight if there are any changes in the game state between the save and subsequent load. Should a state change occur, a message is shown in-game and the save and load game states recorded to a &#039;&#039;dumps&#039;&#039; folder in the players [[Application directory#User_data_directory|user data folder]].&lt;br /&gt;
Typically this process will trigger for incorrect changing of data as part of the on_load event or local/global variables being changed and not persisted. The recorded game state is a dump of the internal game state, including entities, but does not include the mod&#039;s global table. This allows the checking if an entity&#039;s state has become different between the load and save state.&lt;br /&gt;
&lt;br /&gt;
This process can be used to partially test a mod for multiplayer compliance without the need of multiple players or a server.&lt;br /&gt;
&lt;br /&gt;
=== Desync reporting of core Factorio game ===&lt;br /&gt;
If no mod or scenario were involved in the desync, the desync report and activity information should be posted to the [https://forums.factorio.com/53851 Factorio forums bug report section].&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [https://www.factorio.com/blog/post/fff-63 FFF 63] - How heavy mode works&lt;br /&gt;
&lt;br /&gt;
[[Category:Technical]]&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial&amp;diff=208731</id>
		<title>Tutorial:Modding tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial&amp;diff=208731"/>
		<updated>2025-01-04T19:37:13Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Update the broken API link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These tutorials range from teaching the first steps of modding to in-depth explanations of individual mechanics:&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial:Modding tutorial/Gangsir|Modding tutorial/Gangsir]] — A simple modding tutorial that suits beginners well.&lt;br /&gt;
* [[Tutorial:Mod structure|Mod structure]] — More details on how mods need to be structured in order to be loaded by the game.&lt;br /&gt;
* [[Tutorial:Scripting|Scripting]] — A small tutorial that focuses on run-time scripting and provides some info on how to use the story script.&lt;br /&gt;
* [[Tutorial:Mod settings|Mod settings]] — A comprehensive tutorial about how to create and use mod settings.&lt;br /&gt;
* [[Tutorial:Localisation|Localisation]] — A tutorial about how to format and use localisation, which is how mods are translated.&lt;br /&gt;
* [[Tutorial:Inspecting a live mod|Inspecting a live mod]] — An annotated tour of a mod that is live on the mod portal right now.&lt;br /&gt;
* [[Tutorial:Mod changelog format|Mod changelog format]] — The formatting requirements for the mod changelog.txt file.&lt;br /&gt;
* [[Tutorial:Script interfaces|Script interfaces]] — A small tutorial about script interfaces ([https://lua-api.factorio.com/latest/classes/LuaRemote.html LuaRemote]) and custom keyboard shortcuts.&lt;br /&gt;
* &amp;lt;s&amp;gt;[https://togos.github.io/togos-example-noise-programs/ Noise Expressions] — A tutorial about generating terrain, complete with [https://mods.factorio.com/mod/togos-example-noise-programs example mod].&amp;lt;/s&amp;gt; (Shows the 1.1 format which has significantly changed for 2.0)&lt;br /&gt;
* [https://github.com/ClaudeMetz/UntitledGuiGuide/wiki Untitled GUI Guide] — A tutorial about building custom interfaces that also expands into more advanced parts of GUI modding.&lt;br /&gt;
* [https://forums.factorio.com/106661 Controller modding guide / FAQ] — A guide about building your mod to support controllers (game pads).&lt;br /&gt;
&lt;br /&gt;
=== Additional info ===&lt;br /&gt;
* [https://lua-api.factorio.com/latest Modding API docs] - Overview page of the modding API documentation website&lt;br /&gt;
** [https://lua-api.factorio.com/latest/index-prototype.html Prototype documentation]&lt;br /&gt;
** [https://lua-api.factorio.com/latest/index-runtime.html Documentation of the runtime API]&lt;br /&gt;
* [[Scenario system]] — Save-based mods (&amp;quot;soft mods&amp;quot;) and their limitations&lt;br /&gt;
* [https://lua-api.factorio.com/latest/auxiliary/migrations.html Migrations guide] — All information about mod migrations&lt;br /&gt;
* [https://github.com/wube/factorio-data Factorio data github repository] — Tracks changes of the lua prototype definitions in Factorio in between releases&lt;br /&gt;
* [[Tutorial:Modding FAQ|Modding FAQ]]&lt;br /&gt;
&lt;br /&gt;
=== Third-Party Tools ===&lt;br /&gt;
There is a wide variety of tools contributed by community members to help in mod development, such as plugins for IDEs to provide auto-completion, debuggers, as well as scripts to automate common tasks regarding translations or packaging.&lt;br /&gt;
&lt;br /&gt;
* [https://forums.factorio.com/viewforum.php?f=135 Factorio sub-forum for mod development tools]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{Languages}}&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Tutorials]]&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[:Category:Technical]] — Documentation of technical formats and API&#039;s not related to modding&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial&amp;diff=208730</id>
		<title>Tutorial:Modding tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial&amp;diff=208730"/>
		<updated>2025-01-04T19:35:39Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Cross out the outdated NoiseExpression tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;These tutorials range from teaching the first steps of modding to in-depth explanations of individual mechanics:&lt;br /&gt;
&lt;br /&gt;
* [[Tutorial:Modding tutorial/Gangsir|Modding tutorial/Gangsir]] — A simple modding tutorial that suits beginners well.&lt;br /&gt;
* [[Tutorial:Mod structure|Mod structure]] — More details on how mods need to be structured in order to be loaded by the game.&lt;br /&gt;
* [[Tutorial:Scripting|Scripting]] — A small tutorial that focuses on run-time scripting and provides some info on how to use the story script.&lt;br /&gt;
* [[Tutorial:Mod settings|Mod settings]] — A comprehensive tutorial about how to create and use mod settings.&lt;br /&gt;
* [[Tutorial:Localisation|Localisation]] — A tutorial about how to format and use localisation, which is how mods are translated.&lt;br /&gt;
* [[Tutorial:Inspecting a live mod|Inspecting a live mod]] — An annotated tour of a mod that is live on the mod portal right now.&lt;br /&gt;
* [[Tutorial:Mod changelog format|Mod changelog format]] — The formatting requirements for the mod changelog.txt file.&lt;br /&gt;
* [[Tutorial:Script interfaces|Script interfaces]] — A small tutorial about script interfaces ([http://lua-api.factorio.com/latest/LuaRemote.html LuaRemote]) and custom keyboard shortcuts.&lt;br /&gt;
* &amp;lt;s&amp;gt;[https://togos.github.io/togos-example-noise-programs/ Noise Expressions] — A tutorial about generating terrain, complete with [https://mods.factorio.com/mod/togos-example-noise-programs example mod].&amp;lt;/s&amp;gt; (Shows the 1.1 format which has significantly changed for 2.0)&lt;br /&gt;
* [https://github.com/ClaudeMetz/UntitledGuiGuide/wiki Untitled GUI Guide] — A tutorial about building custom interfaces that also expands into more advanced parts of GUI modding.&lt;br /&gt;
* [https://forums.factorio.com/106661 Controller modding guide / FAQ] — A guide about building your mod to support controllers (game pads).&lt;br /&gt;
&lt;br /&gt;
=== Additional info ===&lt;br /&gt;
* [https://lua-api.factorio.com/latest Modding API docs] - Overview page of the modding API documentation website&lt;br /&gt;
** [https://lua-api.factorio.com/latest/index-prototype.html Prototype documentation]&lt;br /&gt;
** [https://lua-api.factorio.com/latest/index-runtime.html Documentation of the runtime API]&lt;br /&gt;
* [[Scenario system]] — Save-based mods (&amp;quot;soft mods&amp;quot;) and their limitations&lt;br /&gt;
* [https://lua-api.factorio.com/latest/auxiliary/migrations.html Migrations guide] — All information about mod migrations&lt;br /&gt;
* [https://github.com/wube/factorio-data Factorio data github repository] — Tracks changes of the lua prototype definitions in Factorio in between releases&lt;br /&gt;
* [[Tutorial:Modding FAQ|Modding FAQ]]&lt;br /&gt;
&lt;br /&gt;
=== Third-Party Tools ===&lt;br /&gt;
There is a wide variety of tools contributed by community members to help in mod development, such as plugins for IDEs to provide auto-completion, debuggers, as well as scripts to automate common tasks regarding translations or packaging.&lt;br /&gt;
&lt;br /&gt;
* [https://forums.factorio.com/viewforum.php?f=135 Factorio sub-forum for mod development tools]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{Languages}}&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Tutorials]]&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[:Category:Technical]] — Documentation of technical formats and API&#039;s not related to modding&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial/Gangsir&amp;diff=207926</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=207926"/>
		<updated>2024-12-13T23:12:36Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Update references of `global` to `storage` - Some rewording in places might be recommended&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 three kinds of dependencies. There are required dependencies, and optional dependencies. The third kind, restrictive dependencies, does not affect mod order and instead prevents the game from loading if the other mod is found. Required dependencies are loaded first, always. The game will fail to initialize if one of these is not present. Optional dependencies are loaded first if present, but do not have to be present. This is useful for enabling bonus features if mods are used together. Required dependencies should be used for mod libraries, and similar infrastructure.&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. Prototypes names cannot be dynamically changed and technology unlocks of already researched technologies do not apply automatically, making migrations necessary. Try to avoid these changes after shipping the mod out to the public. 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 [[Tutorial:Mod structure|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 [[Tutorial:Mod_structure#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>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Blueprint_string_format&amp;diff=206329</id>
		<title>Blueprint string format</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Blueprint_string_format&amp;diff=206329"/>
		<updated>2024-11-14T23:26:30Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Quick pass to fix invalid concept links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Cleanup|Needs to be updated for 2.0}}&lt;br /&gt;
[[File:blueprint_string_preview.png|thumb|340px|right|Preview of a blueprint string.]]This is a technical description of the blueprint string format, used to share blueprints with other users.&lt;br /&gt;
&lt;br /&gt;
A blueprint string is a JSON representation of the blueprint, compressed with zlib deflate using compression level 9 and then encoded using base64 with a version byte in front of the encoded string. The version byte is currently 0 (for all Factorio versions through 1.1).&lt;br /&gt;
So to get the JSON representation of a blueprint from a blueprint string, skip the first byte, base64 decode the string, and finally decompress using zlib inflate.&lt;br /&gt;
&lt;br /&gt;
== Json representation of a blueprint/blueprint book ==&lt;br /&gt;
&lt;br /&gt;
The json representation of a blueprint or blueprint book is one large object inside another &amp;quot;wrapping&amp;quot; object, its key inside that object is either blueprint or blueprint-book.&lt;br /&gt;
&lt;br /&gt;
=== Blueprint book object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| item&lt;br /&gt;
| String, the name of the item that was saved (&amp;quot;blueprint-book&amp;quot; in vanilla).&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| label&lt;br /&gt;
| String, the name of the blueprint set by the user.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| label_color&lt;br /&gt;
| The color of the label of this blueprint. Optional. [[#Color object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| blueprints&lt;br /&gt;
| The actual content of the blueprint book, array of objects containing an &amp;quot;index&amp;quot; key and 0-based value and a &amp;quot;blueprint&amp;quot; key with a [[#Blueprint object]] as the value.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| active_index&lt;br /&gt;
| Index of the currently selected blueprint, 0-based.&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| icons&lt;br /&gt;
| The icons of the blueprint book set by the user, array of [[#Icon object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| The description of the blueprint book. Optional.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| The map version of the map the blueprint was created in, see [[Version string format]].&lt;br /&gt;
| Integer (long)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Blueprint object ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| item&lt;br /&gt;
| String, the name of the item that was saved (&amp;quot;blueprint&amp;quot; in vanilla).&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| label&lt;br /&gt;
| String, the name of the blueprint set by the user.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| label_color&lt;br /&gt;
| The color of the label of this blueprint. Optional. [[#Color object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| entities&lt;br /&gt;
| The actual content of the blueprint, array of [[#Entity object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| tiles&lt;br /&gt;
| The tiles included in the blueprint, array of [[#Tile object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| icons&lt;br /&gt;
| The icons of the blueprint set by the user, array of [[#Icon object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| schedules&lt;br /&gt;
| The schedules for trains in this blueprint, array of [[#Schedule object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| The description of the blueprint. Optional.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| snap-to-grid&lt;br /&gt;
| The dimensions of the grid to use for snapping. Optional. [[#Position object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| absolute-snapping&lt;br /&gt;
| Whether the blueprint uses absolute or relative snapping. Optional.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| position-relative-to-grid&lt;br /&gt;
| Offset relative to the global absolute snapping grid. Optional. [[#Position object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| The map version of the map the blueprint was created in.&lt;br /&gt;
| Integer (long)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Icon object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
| Index of the icon, 1-based.&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| signal&lt;br /&gt;
| The icon that is displayed, [[#SignalID object]].&lt;br /&gt;
| Object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SignalID object ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Name of the signal prototype this signal is set to.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| Type of the signal. See [https://lua-api.factorio.com/stable/concepts/SignalIDType.html SignalIDType] for possible values. &amp;lt;br&amp;gt; &#039;&#039;&#039;Note for 2.x:&#039;&#039;&#039; property is optional and defaults to &amp;quot;item&amp;quot;.&lt;br /&gt;
| String&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Entity object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| entity_number&lt;br /&gt;
| Index of the entity, 1-based.&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Prototype name of the entity (e.g. &amp;quot;offshore-pump&amp;quot;).&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| position&lt;br /&gt;
| [[#Position object]], position of the entity within the blueprint.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| direction&lt;br /&gt;
| Direction of the entity, uint (optional).&amp;lt;br&amp;gt; &#039;&#039;&#039;Note for 2.x:&#039;&#039;&#039; Direction appears to be double the previous values&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| orientation&lt;br /&gt;
| Orientation of cargo wagon or locomotive, value 0 to 1 (optional).&lt;br /&gt;
| Floating Point&lt;br /&gt;
|-&lt;br /&gt;
| connections&lt;br /&gt;
| Circuit connection, object with keys starting from 1, values are [[#Connection object]]s (optional).&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| neighbours&lt;br /&gt;
| Copper wire connections, array of entity_numbers (optional).&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| control_behavior&lt;br /&gt;
| [[#Control behavior object]] of this entity (optional).&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| items&lt;br /&gt;
| Item requests by this entity, this is what defines the item-request-proxy when the blueprint is placed, optional. [[#Item request object]]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| recipe&lt;br /&gt;
| Name of the recipe prototype this assembling machine is set to, optional, string.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| bar&lt;br /&gt;
| Used by [[Prototype/Container]], optional. The index of the first inaccessible item slot due to limiting with the red &amp;quot;bar&amp;quot;. 0-based [[Types/ItemStackIndex]].&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| ammo_inventory&lt;br /&gt;
| Ammo inventory of an entity (e.g. [[Spidertron]]), optional. [[#Inventory object]]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| trunk_inventory&lt;br /&gt;
| Boot/Luggage inventory of an entity (e.g. storage inventory of a Spidertron), optional. [[#Inventory object]]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| inventory&lt;br /&gt;
| Cargo wagon inventory configuration, optional. [[#Inventory object]]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| infinity_settings&lt;br /&gt;
| Used by [[Prototype/InfinityContainer]], optional. [[#Infinity settings object]]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| Type of the underground belt or loader, optional. Either &amp;quot;input&amp;quot; or &amp;quot;output&amp;quot;.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| input_priority&lt;br /&gt;
| Input priority of the splitter, optional. Either &amp;quot;right&amp;quot; or &amp;quot;left&amp;quot;, &amp;quot;none&amp;quot; is omitted.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| output_priority&lt;br /&gt;
| Output priority of the splitter, optional. Either &amp;quot;right&amp;quot; or &amp;quot;left&amp;quot;, &amp;quot;none&amp;quot; is omitted.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| filter&lt;br /&gt;
| Filter of the splitter, optional. Name of the item prototype the filter is set to, string.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| filters&lt;br /&gt;
| Filters of the filter inserter or loader, optional. Array of [[#Item filter object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| filter_mode&lt;br /&gt;
| Filter mode of the filter inserter, optional. Either &amp;quot;whitelist&amp;quot; or &amp;quot;blacklist&amp;quot;.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| override_stack_size&lt;br /&gt;
| The stack size the inserter is set to, optional. [[Types/uint8]].&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| drop_position&lt;br /&gt;
| The drop position the inserter is set to, optional. [[#Position object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| pickup_position&lt;br /&gt;
| The pickup position the inserter is set to, optional. [[#Position object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| request_filters&lt;br /&gt;
| Used by [[Prototype/LogisticContainer]], optional. [[#Logistic filter object]].&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| request_from_buffers&lt;br /&gt;
| Boolean. Whether this requester chest can request from buffer chests.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| parameters&lt;br /&gt;
| Used by [[Programmable speaker]], optional. [[#Speaker parameter object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| alert_parameters&lt;br /&gt;
| Used by [[Programmable speaker]], optional. [[#Speaker alert parameter object]]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| auto_launch&lt;br /&gt;
| Used by the rocket silo, optional. Boolean, whether auto launch is enabled.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| variation&lt;br /&gt;
| Used by [[Prototype/SimpleEntityWithForce]] or [[Prototype/SimpleEntityWithOwner]], optional. [[Types/GraphicsVariation]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| color&lt;br /&gt;
| Color of the [[Prototype/SimpleEntityWithForce]], [[Prototype/SimpleEntityWithOwner]], or train station, optional. [[#Color object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| station&lt;br /&gt;
| The name of the train station, optional.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| manual_trains_limit&lt;br /&gt;
| The manually set train limit of the train station, optional.&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| switch_state&lt;br /&gt;
| The current state of the power switch, optional.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| tags&lt;br /&gt;
| Dictionary of arbitrary data, optional. [https://lua-api.factorio.com/latest/concepts/Tags.html Tags].&lt;br /&gt;
| Object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Inventory object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| filters&lt;br /&gt;
| Array of [[#Item filter object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| bar&lt;br /&gt;
| The index of the first inaccessible item slot due to limiting with the red &amp;quot;bar&amp;quot;. 0-based, optional.  [[Types/ItemStackIndex]].&lt;br /&gt;
| Integer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Schedule object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| schedule&lt;br /&gt;
| Array of [[#Schedule Record object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| locomotives&lt;br /&gt;
| Array of entity numbers of locomotives using this schedule.&lt;br /&gt;
| Array&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Schedule Record object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| station&lt;br /&gt;
| The name of the stop for this schedule record.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| wait_conditions&lt;br /&gt;
| Array of [[#Wait Condition object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| temporary&lt;br /&gt;
| Whether this is a temporary schedule record. Optional.&lt;br /&gt;
| Boolean&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Wait Condition object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| type&lt;br /&gt;
| One of &amp;quot;time&amp;quot;, &amp;quot;inactivity&amp;quot;, &amp;quot;full&amp;quot;, &amp;quot;empty&amp;quot;, &amp;quot;item_count&amp;quot;, &amp;quot;circuit&amp;quot;, &amp;quot;robots_inactive&amp;quot;, &amp;quot;fluid_count&amp;quot;, &amp;quot;passenger_present&amp;quot;, &amp;quot;passenger_not_present&amp;quot;.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| compare_type&lt;br /&gt;
| Either &amp;quot;and&amp;quot;, or &amp;quot;or&amp;quot;. Tells how this condition is to be compared with the preceding conditions in the corresponding wait_conditions array.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| ticks&lt;br /&gt;
| Number of ticks to wait or of inactivity. Only present when type is &amp;quot;time&amp;quot; or &amp;quot;inactivity&amp;quot;. Optional.&lt;br /&gt;
| uint&lt;br /&gt;
|-&lt;br /&gt;
| condition&lt;br /&gt;
| [https://lua-api.factorio.com/latest/concepts/CircuitCondition.html CircuitCondition object], only present when type is &amp;quot;item_count&amp;quot;, &amp;quot;circuit&amp;quot; or &amp;quot;fluid_count&amp;quot;.&lt;br /&gt;
| Object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Tile object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Prototype name of the tile (e.g. &amp;quot;concrete&amp;quot;)&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| position&lt;br /&gt;
| [[#Position object]], position of the entity within the blueprint.&lt;br /&gt;
| Object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Position object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| x&lt;br /&gt;
| X position within the blueprint, 0 is the center.&lt;br /&gt;
| Floating point&lt;br /&gt;
|-&lt;br /&gt;
| y&lt;br /&gt;
| Y position within the blueprint, 0 is the center.&lt;br /&gt;
| Floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Connection object ===&lt;br /&gt;
Object containing information about the connections to other entities formed by red or green wires.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| First connection point. The default for everything that doesn&#039;t have multiple connection points.[[#Connection point object]]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Second connection point. For example, the &amp;quot;output&amp;quot; part of an arithmetic combinator.[[#Connection point object]]&lt;br /&gt;
| Object&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Connection point object ===&lt;br /&gt;
The actual point where a wire is connected to. Contains information about where it is connected to.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| red&lt;br /&gt;
| An array of [[#Connection data object]] containing all the connections from this point created by red wire.&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| green&lt;br /&gt;
| An array of [[#Connection data object]] containing all the connections from this point created by green wire.&lt;br /&gt;
| Array&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Connection data object ===&lt;br /&gt;
Information about a single connection between two connection points.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| entity_id&lt;br /&gt;
| ID of the entity this connection is connected with.&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| circuit_id&lt;br /&gt;
| The circuit connector id of the entity this connection is connected to, see [https://lua-api.factorio.com/latest/defines.html#defines.circuit_connector_id defines.circuit_connector_id].&lt;br /&gt;
| Integer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Item request object ===&lt;br /&gt;
1 or more instances of key/value pairs.&lt;br /&gt;
Key is the name of the item, string.&lt;br /&gt;
Value is the amount of items to be requested, [[Types/ItemCountType]].&lt;br /&gt;
&lt;br /&gt;
=== Item filter object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Name of the item prototype this filter is set to.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
| Index of the filter, 1-based. &lt;br /&gt;
| Integer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Infinity settings object ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| remove_unfiltered_items&lt;br /&gt;
| Boolean. Whether the &amp;quot;remove unfiltered items&amp;quot; checkbox is checked.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| filters&lt;br /&gt;
| Filters of the infinity container, optional. Array of [[#Infinity filter object]]s.&lt;br /&gt;
| Array&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Infinity filter object ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Name of the item prototype the filter is set to, string.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| count&lt;br /&gt;
| Number the filter is set to, [[Types/ItemCountType]].&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| mode&lt;br /&gt;
| Mode of the filter. Either &amp;quot;at-least&amp;quot;, &amp;quot;at-most&amp;quot;, or &amp;quot;exactly&amp;quot;.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
| Index of the filter, 1-based.&lt;br /&gt;
| Integer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Logistic filter object ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Name of the item prototype this filter is set to.&lt;br /&gt;
| String&lt;br /&gt;
|-&lt;br /&gt;
| index&lt;br /&gt;
| Index of the filter, 1-based.&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| count&lt;br /&gt;
| Number the filter is set to, [[Types/ItemCountType]]. Is 0 for storage chests.&lt;br /&gt;
| Integer&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Speaker parameter object ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| playback_volume&lt;br /&gt;
| [[Types/double]]. Volume of the speaker.&lt;br /&gt;
| Floating point&lt;br /&gt;
|-&lt;br /&gt;
| playback_globally&lt;br /&gt;
| Boolean, whether global playback is enabled.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| allow_polyphony&lt;br /&gt;
| Boolean, whether polyphony is allowed.&lt;br /&gt;
| Boolean&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Speaker alert parameter object ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| show_alert&lt;br /&gt;
| Boolean, whether an alert is shown.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| show_on_map&lt;br /&gt;
| Boolean, whether an alert icon is shown on the map.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| icon_signal_id&lt;br /&gt;
| The icon that is displayed with the alert, [[#SignalID object]].&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| alert_message&lt;br /&gt;
| String, message of the alert.&lt;br /&gt;
| String&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Color object ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Description !! Data type&lt;br /&gt;
|-&lt;br /&gt;
| r&lt;br /&gt;
| red, number from 0 to 1.&lt;br /&gt;
| Floating point&lt;br /&gt;
|-&lt;br /&gt;
| g&lt;br /&gt;
| green, number from 0 to 1.&lt;br /&gt;
| Floating point&lt;br /&gt;
|-&lt;br /&gt;
| b&lt;br /&gt;
| blue, number from 0 to 1.&lt;br /&gt;
| Floating point&lt;br /&gt;
|-&lt;br /&gt;
| a&lt;br /&gt;
| transparency, number from 0 to 1.&lt;br /&gt;
| Floating point&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Control behavior object ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ALL fields are optional&#039;&#039;&#039; and depend on the type of the entity.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Key !! Description !! Data type &lt;br /&gt;
|-&lt;br /&gt;
| logistic_condition&lt;br /&gt;
| [https://lua-api.factorio.com/latest/concepts/CircuitCondition.html CircuitCondition]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| connect_to_logistic_network&lt;br /&gt;
| Whether this entity is connected to the logistic network and enables/disables based on logistic_condition.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| circuit_close_signal&lt;br /&gt;
| Whether this rail signal can be closed by circuit_condition.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| circuit_read_signal&lt;br /&gt;
| Whether or not to read the state of this rail/chain signal.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| red_output_signal&lt;br /&gt;
| [[#SignalID]] to use if the rail/chain signal is currently red.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| orange_output_signal&lt;br /&gt;
| [[#SignalID]] to use if the rail/chain signal is currently orange.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| green_output_signal&lt;br /&gt;
| [[#SignalID]] to use if the rail/chain signal is currently green.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| blue_output_signal&lt;br /&gt;
| [[#SignalID]] to use if the chain signal is currently blue.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| circuit_condition&lt;br /&gt;
| [https://lua-api.factorio.com/latest/concepts/CircuitCondition.html CircuitCondition]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| circuit_enable_disable&lt;br /&gt;
| Enable or disable based on circuit_condition.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| send_to_train&lt;br /&gt;
| Send circuit values to the train to use in schedule conditions.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| read_from_train&lt;br /&gt;
| Get the currently stopped trains cargo.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| read_stopped_train&lt;br /&gt;
| Get the currently stopped trains ID.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| train_stopped_signal&lt;br /&gt;
| [[#SignalID]] to output the train ID on.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| set_trains_limit&lt;br /&gt;
| Whether this stations trains limit will be set through circuit values.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| trains_limit_signal&lt;br /&gt;
| [[#SignalID]] to use to set the trains limit.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| read_trains_count&lt;br /&gt;
| Whether to read this stations currently on route trains count.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| trains_count_signal&lt;br /&gt;
| [[#SignalID]] to output the on route trains count on.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| read_logistics&lt;br /&gt;
| Whether this roboport should output the contents of its network.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| read_robot_stats&lt;br /&gt;
| Whether this roboport should output the robot stats of its network.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| available_logistic_output_signal&lt;br /&gt;
| [[#SignalID]] to output available logistic robots on.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| total_logistic_output_signal&lt;br /&gt;
| [[#SignalID]] to output the total count of logistic robots on.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| available_construction_output_signal&lt;br /&gt;
| [[#SignalID]] to output available construction robots on.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| total_construction_output_signal&lt;br /&gt;
| [[#SignalID]] to output the total count of construction robots on.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| circuit_open_gate&lt;br /&gt;
| Whether to limit the gate opening with circuit_condition.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| circuit_read_sensor&lt;br /&gt;
| Whether to send the wall-gate proximity sensor to the circuit network.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| output_signal&lt;br /&gt;
| [[#SignalID]] to output the wall-gate sensor / accumulator charge on.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| circuit_read_hand_contents&lt;br /&gt;
| Whether to read this belts content or inserters hand.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| circuit_contents_read_mode&lt;br /&gt;
| [https://lua-api.factorio.com/latest/defines.html#defines.control_behavior.transport_belt.content_read_mode defines.control_behavior.transport_belt.content_read_mode]&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| circuit_mode_of_operation&lt;br /&gt;
| &lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| circuit_hand_read_mode&lt;br /&gt;
| [https://lua-api.factorio.com/latest/defines.html#defines.control_behavior.inserter.hand_read_mode defines.control_behavior.inserter.hand_read_mode]&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| circuit_set_stack_size&lt;br /&gt;
| Whether to set the inserters stack size from a circuit signal.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| stack_control_input_signal&lt;br /&gt;
| [[#SignalID]] to use to set the inserters stack size.&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| circuit_read_resources&lt;br /&gt;
| Whether this miner should output its remaining resource amounts to the circuit network.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| circuit_resource_read_mode&lt;br /&gt;
| [https://lua-api.factorio.com/latest/defines.html#defines.control_behavior.mining_drill.resource_read_mode defines.control_behavior.mining_drill.resource_read_mode]&lt;br /&gt;
| Integer&lt;br /&gt;
|-&lt;br /&gt;
| is_on&lt;br /&gt;
| Whether this constant combinator is currently on or off.&lt;br /&gt;
| Boolean&lt;br /&gt;
|-&lt;br /&gt;
| filters&lt;br /&gt;
| Array of &amp;lt;s&amp;gt;[https://lua-api.factorio.com/latest/concepts/BlueprintLogisticFilter.html ConstantCombinatorParameters].&amp;lt;/s&amp;gt; It&#039;s now a kind of [https://lua-api.factorio.com/latest/concepts/LogisticSections.html LogisticSections] instead.&lt;br /&gt;
&#039;&#039;We might be missing a type for it specifically.&#039;&#039;&lt;br /&gt;
| Array&lt;br /&gt;
|-&lt;br /&gt;
| arithmetic_conditions&lt;br /&gt;
| [https://lua-api.factorio.com/latest/concepts/ArithmeticCombinatorParameters.html ArithmeticCombinatorParameters]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| decider_conditions&lt;br /&gt;
| [https://lua-api.factorio.com/latest/concepts/DeciderCombinatorParameters.html DeciderCombinatorParameters]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| circuit_parameters&lt;br /&gt;
| [https://lua-api.factorio.com/latest/concepts/ProgrammableSpeakerCircuitParameters.html ProgrammableSpeakerCircuitParameters]&lt;br /&gt;
| Object&lt;br /&gt;
|-&lt;br /&gt;
| use_colors&lt;br /&gt;
| Whether this lamp should use colors or not.&lt;br /&gt;
| Boolean&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Technical]]&lt;br /&gt;
&lt;br /&gt;
== Example code ==&lt;br /&gt;
&lt;br /&gt;
On a typical Bash command line, the blueprint can be decoded like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;echo &amp;quot;$blueprint_string&amp;quot; | cut -c2- | base64 -d | pigz -d&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you don&#039;t have &amp;lt;code&amp;gt;pigz&amp;lt;/code&amp;gt; installed, you can use &amp;lt;code&amp;gt;zlib-flate -uncompress&amp;lt;/code&amp;gt; instead (part of &amp;quot;qpdf&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
How to decode a string to Lua table:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local str=&amp;quot;$blueprint_string&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
local bp_to_table=function(instr)&lt;br /&gt;
  &lt;br /&gt;
  --[[version and the body part]]&lt;br /&gt;
  local version=string.sub(instr,1,1);&lt;br /&gt;
  local body=string.sub(instr,2);&lt;br /&gt;
  --[[then decode it]]&lt;br /&gt;
  local json_str=game.decode_string(body);&lt;br /&gt;
  --[[then turn it into table]]&lt;br /&gt;
  local output=game.json_to_table(json_str);&lt;br /&gt;
  &lt;br /&gt;
  return output;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[and this could test if it print properly]]&lt;br /&gt;
game.print( serpent.block( bp_to_table(str) ) );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Localisation&amp;diff=205579</id>
		<title>Tutorial:Localisation</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Localisation&amp;diff=205579"/>
		<updated>2024-11-09T22:19:06Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Update plural_for_parameter&amp;#039;s 2.0 syntax&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]&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;__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;__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;__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;__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;__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;
* &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;
&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;rest&amp;quot; to give the default plural.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Starting with version 2.0&#039;&#039;&#039;, there have to be two underscores surrounding the number that denotes which parameter is used to determine the plural: &amp;lt;code&amp;gt;__plural_for_parameter__1__{1=day|rest=days}__&amp;lt;/code&amp;gt;&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 chooses 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;
=== 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. See [https://lua-api.factorio.com/latest/LuaPlayer.html#LuaPlayer.request_translation LuaPlayer::request_translation] and  [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. [[Prototype/Recipe]] 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;
* [[Types/LocalisedString|LocalisedString data stage doc]]&lt;br /&gt;
* [https://lua-api.factorio.com/latest/Concepts.html#LocalisedString LocalisedString control stage doc]&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Talk:Version_history/2.0.0&amp;diff=205460</id>
		<title>Talk:Version history/2.0.0</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Talk:Version_history/2.0.0&amp;diff=205460"/>
		<updated>2024-11-08T23:35:30Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Maybe we should replace [space-age] with {{SA}} ==&lt;br /&gt;
&lt;br /&gt;
[space-age] is a rich text tag that turns into the icon in game, it would be more accurate to replicate it. I don&#039;t feel confident enough to make that decision on my own. If anything, maybe we use a slightly different template that has `[space-age]` as the alt text? Regardless of what we choose to do, [[User:Bilka|Bilka]] will need to update their bot to do the conversion as well -- [[User:PennyJim|PennyJim]] ([[User talk:PennyJim|talk]]) 23:35, 8 November 2024 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Kovarex enrichment process is &#039;&#039;&#039;NOT&#039;&#039;&#039; unlocked by automation, logistic and chemical science packs only. ==&lt;br /&gt;
&lt;br /&gt;
According to patch notes &amp;quot;Kovarex enrichment process&amp;quot; should be unlocked by red, green and blue packs but need also space ones. ~~ [[User:Mefisto1029|Mefisto1029]] ([[User talk:Mefisto1029|talk]]) 10:29, 23 October 2024 (UTC)&lt;br /&gt;
: This is only changed when the space age mod is active. Without the mod active (so, without the expansion), the technology does not require space science packs. I adjusted the [[Infobox:Kovarex_enrichment_process_(research)]] accordingly, now that the template supports this. -- [[User:Bilka|Bilka]] ([[User talk:Bilka|talk]]) - &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;Admin&amp;lt;/span&amp;gt; 12:34, 24 October 2024 (UTC)&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=205304</id>
		<title>Rich text</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=205304"/>
		<updated>2024-11-07T20:04:51Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Add the [space-age] tag&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
Rich text formatting in 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.html#SpritePath 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;
| [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;
| [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>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=205302</id>
		<title>Rich text</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=205302"/>
		<updated>2024-11-07T19:55:25Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Clarify that Nauvis is always defined.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
Rich text formatting in 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.html#SpritePath 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;
| [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;
| [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;
&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>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=205300</id>
		<title>Rich text</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=205300"/>
		<updated>2024-11-07T19:26:01Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Add space-location as a class option for img tag&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
Rich text formatting in 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.html#SpritePath 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;
| [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;
| [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 in Space Age. Available planets are: nauvis, gleba, fulgora, vulcanus, and aquilo.&lt;br /&gt;
&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. Available locations are: nauvis, gleba, fulgora, vulcanus, aquilo, solar-system-edge, and shattered-planet.&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;
== 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>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Console&amp;diff=205239</id>
		<title>Console</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Console&amp;diff=205239"/>
		<updated>2024-11-07T02:40:32Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Remove enable-research-queue (The command no longer exists because it now can&amp;#039;t be disabled)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
The &#039;&#039;&#039;console&#039;&#039;&#039; is Factorio&#039;s in-game command-line interface. See [[command line parameters]] for the command line interface of the Factorio executable.&lt;br /&gt;
&lt;br /&gt;
The in-game console can be used for:&lt;br /&gt;
&lt;br /&gt;
* Chatting with other players&lt;br /&gt;
* Occasional status updates&lt;br /&gt;
* Running commands / scripts / cheats&lt;br /&gt;
&lt;br /&gt;
There are three types of commands:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;[[#Normal commands|Normal]]&#039;&#039;&#039; - Display information about the game and customize your experience.&lt;br /&gt;
* &#039;&#039;&#039;[[#Multiplayer commands|Multiplayer]]&#039;&#039;&#039; - Message filtering, banning users, etc.&lt;br /&gt;
* &#039;&#039;&#039;[[#Scripting and cheat commands|Scripting/Cheating]]&#039;&#039;&#039; - Run small Lua scripts (but they &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;disable achievements for the save game&amp;lt;/span&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
=== Using the console ===&lt;br /&gt;
The console display can be toggled with the {{Keybinding|grave}} key (&amp;lt;code&amp;gt;`&amp;lt;/code&amp;gt;). This is the key located to the left of the &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; key, above &amp;lt;code&amp;gt;Tab&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
You can customize the keys via &#039;&#039;&#039;Settings menu → Controls → Toggle chat (and Lua console)&#039;&#039;&#039;.&lt;br /&gt;
When the console is open, you&#039;ll see a blinking cursor at the bottom of the screen; type your message or command and hit &#039;&#039;&#039;Return&#039;&#039;&#039; to send it (this will also close the console).&lt;br /&gt;
Documentation about message and command prefixes can be found further down this page.&lt;br /&gt;
&lt;br /&gt;
The console supports [[rich text]] tags. These tags are useful for sharing blueprints, marking map locations in chat or adding icons to map markers and train stations. Ctrl + Alt-clicking the map or ground will automatically insert a GPS tag and post it into the console. Shift-clicking most things with the console open will insert a tag for that thing into the console.&lt;br /&gt;
&lt;br /&gt;
When the console is closed, only the most recent messages/commands will be displayed, but they will gradually fade away (opening the console will immediately re-display all recent messages).&lt;br /&gt;
Note that by default, all executed commands are made visible to all users. The fade-out time can be changed via &#039;&#039;&#039;Settings menu → Interface → Chat message delay&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The console can be cleared with the &#039;&#039;&#039;/clear&#039;&#039;&#039; command.&lt;br /&gt;
&lt;br /&gt;
Use the {{keybinding|&amp;amp;uarr;}} and {{keybinding|&amp;amp;darr;}} keys to scroll through the console history. The {{keybinding|Tab}} key provides intelligent code completion on commands, options and player names.&lt;br /&gt;
&lt;br /&gt;
== Normal commands ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot;| Command&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot;| Example&lt;br /&gt;
! style=&amp;quot;width:46%&amp;quot;| Description&lt;br /&gt;
! style=&amp;quot;width:4%&amp;quot;| Admin only&lt;br /&gt;
|-&lt;br /&gt;
| /alerts &amp;lt;enable/disable/mute/unmute&amp;gt; &amp;lt;alert&amp;gt;&lt;br /&gt;
| /alerts disable turret_fire&lt;br /&gt;
| Enables, disables, mutes, or unmutes the given  [[alerts|alert]] type. Available alerts: entity_destroyed, entity_under_attack, not_enough_construction_robots, no_material_for_construction, not_enough_repair packs, turret_fire, custom, no_storage, train_out_of_fuel, fluid_mixing.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /clear&lt;br /&gt;
| /clear&lt;br /&gt;
| Clears the console.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /color &amp;lt;color&amp;gt;&lt;br /&gt;
| /color 20 255 255&lt;br /&gt;
| Changes your color. Can either be one of the pre-defined colors or [[:Wikipedia:RGB_color_space|RGB value]] in the format of “# # #”. Available colors: default, red, green, blue, orange, yellow, pink, purple, white, black, gray, brown, cyan, acid.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /evolution&lt;br /&gt;
| /evolution&lt;br /&gt;
| Prints info about the alien evolution factor.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /help [command]&lt;br /&gt;
| /help&lt;br /&gt;
| Prints a list of available commands, the optional argument can specify the command that should be described.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /h [command]&lt;br /&gt;
| /h&lt;br /&gt;
| Same as /help.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /mute-programmable-speaker &amp;lt;mute/unmute&amp;gt; &amp;lt;local/everyone&amp;gt;&lt;br /&gt;
| /mute-programmable-speaker mute local&lt;br /&gt;
| Mutes or unmutes the global sounds created by the Programmable Speaker. Use “local” to mute just the local client. Admins can use “everyone” to mute the sounds for everyone on the server.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /perf-avg-frames &amp;lt;number&amp;gt;&lt;br /&gt;
| /perf-avg-frames 100&lt;br /&gt;
| Number of ticks/updates used to average performance counters. Default is 100. Value of 5-10 is recommended for fast convergence, but numbers will jitter more rapidly.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /permissions&lt;br /&gt;
| /permissions&lt;br /&gt;
| Opens the [[permissions]] GUI.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /permissions &amp;lt;action&amp;gt; &amp;lt;parameters&amp;gt;&lt;br /&gt;
| /permissions add-player DeveloperGroup kovarex&lt;br /&gt;
| Available actions are add-player &amp;lt;group&amp;gt; &amp;lt;player&amp;gt;, create-group &amp;lt;name&amp;gt;, delete-group &amp;lt;group&amp;gt;, edit-group &amp;lt;group&amp;gt; &amp;lt;input_action&amp;gt; &amp;lt;true/false&amp;gt;, get-player-group &amp;lt;player&amp;gt;, remove-player &amp;lt;group&amp;gt; &amp;lt;player&amp;gt;, rename-group &amp;lt;group&amp;gt; &amp;lt;new_name&amp;gt; and reset&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /reset-tips&lt;br /&gt;
| /reset-tips&lt;br /&gt;
| Resets the state of the tips and tricks as if the game was just started for the first time.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /screenshot [x resolution] [y resolution] [zoom]&lt;br /&gt;
| /screenshot&lt;br /&gt;
| Takes a screenshot with the GUI hidden, centered on the player. It is saved in the &amp;quot;script-output&amp;quot; subfolder of your [[User data directory]].  Resolution is optional and defaults to the current window size. Zoom is optional and defaults to 1.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /seed&lt;br /&gt;
| /seed&lt;br /&gt;
| Prints the starting map seed.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /time&lt;br /&gt;
| /time&lt;br /&gt;
| Prints info about how old the map is.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /toggle-action-logging&lt;br /&gt;
| /toggle-action-logging&lt;br /&gt;
| Toggles logging all input actions performed by the game. This value isn’t persisted between game restarts and only affects your local game in multiplayer sessions.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /toggle-heavy-mode&lt;br /&gt;
| /toggle-heavy-mode&lt;br /&gt;
| Used to investigate [[Desynchronization#Using_heavy_mode_command|desyncs]]. Will slow down the game and make multiplayer unplayable.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /unlock-shortcut-bar&lt;br /&gt;
| /unlock-shortcut-bar&lt;br /&gt;
| Unlocks all [[shortcut bar]] items, including blueprint string import, copy &amp;amp; paste, deconstruction and upgrade planner.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /unlock-tips&lt;br /&gt;
| /unlock-tips&lt;br /&gt;
| Unlocks all tips and tricks entries.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /version&lt;br /&gt;
| /version&lt;br /&gt;
| Prints the current game version.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Multiplayer commands ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot;| Command&lt;br /&gt;
! style=&amp;quot;width:25%&amp;quot;| Example&lt;br /&gt;
! style=&amp;quot;width:46%&amp;quot;| Description&lt;br /&gt;
! style=&amp;quot;width:4%&amp;quot;| Admin only&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;message&amp;gt;&lt;br /&gt;
| Hello team!&lt;br /&gt;
| Console input that does not start with {{keybinding|/}} is shown as a chat message to your team.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /admin&lt;br /&gt;
| /admin&lt;br /&gt;
| Opens the player management GUI.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /admins&lt;br /&gt;
| /admins&lt;br /&gt;
| Prints a list of game admins.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /ban &amp;lt;player&amp;gt; &amp;lt;reason&amp;gt;&lt;br /&gt;
| /ban xTROLLx Throwing grenades in base&lt;br /&gt;
| Bans the specified player.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /bans&lt;br /&gt;
| /bans&lt;br /&gt;
| Prints a list of banned players.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /banlist &amp;lt;add/remove/get/clear&amp;gt; &amp;lt;player&amp;gt;&lt;br /&gt;
| /banlist get&lt;br /&gt;
| Adds or removes a player from the banlist. Same as /ban or /unban.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /config&lt;br /&gt;
| /config&lt;br /&gt;
| Opens the server configuration GUI.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /config &amp;lt;get/set&amp;gt; &amp;lt;option&amp;gt; &amp;lt;value&amp;gt;&lt;br /&gt;
| /config set password hunter2&lt;br /&gt;
| Gets or sets various multiplayer game settings. Available configs are: afk-auto-kick, allow-commands, allow-debug-settings, autosave-interval, autosave-only-on-server, ignore-player-limit-for-returning-players, max-players, max-upload-speed, only-admins-can-pause, password, require-user-verification, visibility-lan, visibility-public. The units for the options afk-auto-kick and autosave-interval are in minutes.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /delete-blueprint-library &amp;lt;player&amp;gt;&lt;br /&gt;
| /delete-blueprint-library everybody confirm&lt;br /&gt;
| Deletes the blueprint library storage for the given offline player from the save file. Enter “everybody confirm” to delete the storage of all offline players.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /demote &amp;lt;player&amp;gt;&lt;br /&gt;
| /demote AzureDiamond&lt;br /&gt;
| Demotes the player from admin.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /ignore &amp;lt;player&amp;gt;&lt;br /&gt;
| /ignore Cthon98&lt;br /&gt;
| Prevents the chat from showing messages from this player. Admin messages are still shown.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /ignores&lt;br /&gt;
| /ignores&lt;br /&gt;
| Prints a list of ignored players.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /kick &amp;lt;player&amp;gt; &amp;lt;reason&amp;gt;&lt;br /&gt;
| /kick xTROLLx Throwing grenades in base&lt;br /&gt;
| Kicks the specified player.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /mute &amp;lt;player&amp;gt;&lt;br /&gt;
| /mute Cthon98&lt;br /&gt;
| Prevents the player from saying anything in chat.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /mutes&lt;br /&gt;
| /mutes&lt;br /&gt;
| All players that are muted (can’t talk in chat).&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /open &amp;lt;player&amp;gt;&lt;br /&gt;
| /open AzureDiamond&lt;br /&gt;
| Opens another player’s inventory.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /o &amp;lt;player&amp;gt;&lt;br /&gt;
| /o AzureDiamond&lt;br /&gt;
| Same as /open.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /players [online/o/count/c]&lt;br /&gt;
| /players&lt;br /&gt;
| Prints a list of players in the game. (parameter online/o, it prints only players that are online, count/c prints only count)&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /p [online/o/count/c]&lt;br /&gt;
| /p o c&lt;br /&gt;
| Same as /players.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /promote &amp;lt;player&amp;gt;&lt;br /&gt;
| /promote AzureDiamond&lt;br /&gt;
| Promotes the player to admin.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /purge &amp;lt;player&amp;gt;&lt;br /&gt;
| /purge Cthon98&lt;br /&gt;
| Clears all the messages from this player from the chat log.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /reply &amp;lt;message&amp;gt;&lt;br /&gt;
| /reply oh, really?&lt;br /&gt;
| Replies to the last player that whispered to you.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /r &amp;lt;message&amp;gt;&lt;br /&gt;
| /r oh, really?&lt;br /&gt;
| Same as /reply.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /server-save&lt;br /&gt;
| /server-save&lt;br /&gt;
| Saves the game on the server in a multiplayer game.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /shout &amp;lt;message&amp;gt;&lt;br /&gt;
| /shout Hello world!&lt;br /&gt;
| Sends a message to all players including other forces.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /s &amp;lt;message&amp;gt;&lt;br /&gt;
| /s Hello world!&lt;br /&gt;
| Same as /shout.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /swap-players &amp;lt;player&amp;gt; [player]&lt;br /&gt;
| /swap-players AzureDiamond&lt;br /&gt;
| Swaps your character with the given player’s character, or if two players are given swaps the two player characters.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /unban &amp;lt;player&amp;gt;&lt;br /&gt;
| /unban xTROLLx&lt;br /&gt;
| Unbans the specified player.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /unignore &amp;lt;player&amp;gt;&lt;br /&gt;
| /unignore Cthon98&lt;br /&gt;
| Allows the chat to show messages from this player.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /unmute &amp;lt;player&amp;gt;&lt;br /&gt;
| /unmute Cthon98&lt;br /&gt;
| Allows the player to talk in chat again.&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| /whisper &amp;lt;player&amp;gt; &amp;lt;message&amp;gt;&lt;br /&gt;
| /whisper AzureDiamond that&#039;s what I see&lt;br /&gt;
| Sends a message to the specified player.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /w &amp;lt;player&amp;gt; &amp;lt;message&amp;gt;&lt;br /&gt;
| /w AzureDiamond that&#039;s what I see&lt;br /&gt;
| Same as /whisper.&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| /whitelist &amp;lt;add/remove/get/clear&amp;gt; [player]&lt;br /&gt;
| /whitelist get&lt;br /&gt;
| Adds or removes a player from the whitelist, where only whitelisted players can join the game. Enter nothing for “player” when using “get” to print a list of all whitelisted players. An empty whitelist disables the whitelist functionality allowing anyone to join.&lt;br /&gt;
| No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Scripting and cheat commands ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Command&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| /cheat [all/&amp;lt;planet-name&amp;gt;/&amp;lt;platform-name&amp;gt;/off]&lt;br /&gt;
| Researches all technologies and enables cheat mode (allowing free crafting of any item). &lt;br /&gt;
* Using the &#039;&#039;&#039;all&#039;&#039;&#039; option also gives the player some additional items.&lt;br /&gt;
* Specifying a &#039;&#039;planet-name&#039;&#039; or &#039;&#039;platform-name&#039;&#039; also moves the player to the origin of the specified planet or platform.&lt;br /&gt;
* Using the &#039;&#039;&#039;off&#039;&#039;&#039; option turns cheat mode off.&lt;br /&gt;
|-&lt;br /&gt;
| /command &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed).&lt;br /&gt;
|-&lt;br /&gt;
| /c &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed).&lt;br /&gt;
|-&lt;br /&gt;
| /editor&lt;br /&gt;
| Toggles the map editor.&lt;br /&gt;
|-&lt;br /&gt;
| /measured-command &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed) and measures time it took.&lt;br /&gt;
|-&lt;br /&gt;
| /mc &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed) and measures time it took.&lt;br /&gt;
|-&lt;br /&gt;
| /silent-command &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed) without printing it to the console.&lt;br /&gt;
|-&lt;br /&gt;
| /sc &amp;lt;command&amp;gt;&lt;br /&gt;
| Executes a Lua command (if allowed) without printing it to the console.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is a very powerful feature, which also allows cheating, and as such &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;achievements will be permanently disabled for the save&amp;lt;/span&amp;gt; as soon as you use a script command.&lt;br /&gt;
&lt;br /&gt;
== Basic example scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Use it as calculator ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.print(1234*5678)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Zoom beyond normal bounds ===&lt;br /&gt;
Note that zooming too far out can cause performance hits. Be careful.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.zoom=0.1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mine faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.manual_mining_speed_modifier=1000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Craft faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.manual_crafting_speed_modifier=1000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unlock and research all technologies ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.research_all_technologies()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Undo this with the command in the next section.&lt;br /&gt;
&lt;br /&gt;
Note: Specific technologies can be researched using the [[map editor]] by shift clicking the &amp;quot;start research&amp;quot; button on the technology GUI.&lt;br /&gt;
&lt;br /&gt;
=== Unresearch all technologies ===&lt;br /&gt;
This does not reset manually applied bonuses&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for _, tech in pairs(game.player.force.technologies) do &lt;br /&gt;
	tech.researched=false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Specific technologies can be unresearched using the [[map editor]] by clicking the &amp;quot;un-research&amp;quot; button on the technology GUI.&lt;br /&gt;
&lt;br /&gt;
=== Reset your force ===&lt;br /&gt;
This resets all data for your force, including kill and production statistics, technologies, bonuses and charting status.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.reset()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Always show rail block visualization ===&lt;br /&gt;
Permanently show the rail block visualization instead of only when holding a rail signal. Disable by replacing true with false.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.game_view_settings.show_rail_block_visualisation = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Set all trains to Automatic mode ===&lt;br /&gt;
Set all trains to automatic mode - for example after building them with a blueprint. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for key,ent in pairs (game.player.surface.find_entities_filtered{name=&amp;quot;locomotive&amp;quot;}) do &lt;br /&gt;
    ent.train.manual_mode = false&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Inventory manipulation scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Cheat mode ===&lt;br /&gt;
Allows for infinite free crafting. Disable by replacing true with false.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.cheat_mode=true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Refill resources (refill oil, iron etc.) ===&lt;br /&gt;
While holding the cursor over a resource tile in-game:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.selected.amount=7500&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternatively you can refill all resources in the map with the following command. Change ore.amount to the desired value.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c surface = game.player.surface&lt;br /&gt;
for _, ore in pairs(surface.find_entities_filtered({type=&amp;quot;resource&amp;quot;})) do&lt;br /&gt;
    ore.amount = 10000&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add items to the player&#039;s inventory ===&lt;br /&gt;
Replace iron-plate with the [[data.raw|internal name]] of the item desired.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.insert{name=&amp;quot;iron-plate&amp;quot;, count=100}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For instance, here&#039;s a stack of the god-mode energy system interface:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.insert{name=&amp;quot;electric-energy-interface&amp;quot;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several god-mode items available:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;infinity-chest&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;infinity-pipe&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;electric-energy-interface&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;heat-interface&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add a powerful armor with equipment and some tools for construction:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c	local player = game.player&lt;br /&gt;
player.insert{name=&amp;quot;power-armor-mk2&amp;quot;, count = 1}&lt;br /&gt;
local p_armor = player.get_inventory(5)[1].grid&lt;br /&gt;
	p_armor.put({name = &amp;quot;fusion-reactor-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;fusion-reactor-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;fusion-reactor-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;exoskeleton-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;exoskeleton-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;exoskeleton-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;exoskeleton-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;energy-shield-mk2-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;energy-shield-mk2-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;personal-roboport-mk2-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;night-vision-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;battery-mk2-equipment&amp;quot;})&lt;br /&gt;
	p_armor.put({name = &amp;quot;battery-mk2-equipment&amp;quot;})&lt;br /&gt;
player.insert{name=&amp;quot;construction-robot&amp;quot;, count = 25}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Increase player inventory slots ===&lt;br /&gt;
Gives 100 additional bonus inventory slots to your entire force. Used by the [[Toolbelt (research)]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.character_inventory_slots_bonus=100&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== World manipulation scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Reveal the map around the player ===&lt;br /&gt;
&lt;br /&gt;
Reveals the map around the player, similar to a [[radar]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local radius=150&lt;br /&gt;
game.player.force.chart(game.player.surface, {{game.player.position.x-radius, game.player.position.y-radius}, {game.player.position.x+radius, game.player.position.y+radius}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or from start position&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local radius=150&lt;br /&gt;
game.player.force.chart(game.player.surface, {{x = -radius, y = -radius}, {x = radius, y = radius}})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Change 150 to the desired radius, higher values take longer.&lt;br /&gt;
&lt;br /&gt;
=== Hide revealed map ===&lt;br /&gt;
&lt;br /&gt;
Hides all revealed chunks, inverted map revealing.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
local force = game.player.force&lt;br /&gt;
for chunk in surface.get_chunks() do&lt;br /&gt;
  force.unchart_chunk({x = chunk.x, y = chunk.y}, surface)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Reveal all generated map ===&lt;br /&gt;
&lt;br /&gt;
Revels all of the generated map to the player&#039;s team.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.chart_all()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Delete chunks ===&lt;br /&gt;
If much of the map is revealed, it increases the size of the save file. The following command cancels the generation of all chunks that are currently queued for generation and removes chunks outside a 32 chunks radius around 0,0. Note that this will remove player entities if there are any on these chunks.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface;&lt;br /&gt;
game.player.force.cancel_charting(surface); &lt;br /&gt;
local chunk_radius = 32;&lt;br /&gt;
for chunk in surface.get_chunks() do&lt;br /&gt;
  if (chunk.x &amp;lt; -chunk_radius or chunk.x &amp;gt; chunk_radius or chunk.y &amp;lt; -chunk_radius or chunk.y &amp;gt; chunk_radius) then&lt;br /&gt;
    surface.delete_chunk(chunk)&lt;br /&gt;
  end&lt;br /&gt;
end &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Delete unrevealed chunks ===&lt;br /&gt;
This command deletes chunks that are not revealed by the player. Can be used after the command for [[#Hide revealed map|hiding revealed map]] to delete the chunks not covered by radar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;/c local surface = game.player.surface&lt;br /&gt;
local force = game.player.force&lt;br /&gt;
for chunk in surface.get_chunks() do&lt;br /&gt;
  if not force.is_chunk_charted(surface, chunk) then&lt;br /&gt;
    surface.delete_chunk(chunk)&lt;br /&gt;
  end&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Turn off night ===&lt;br /&gt;
Enables eternal day.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.always_day=true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Change game speed ===&lt;br /&gt;
0.5 is half speed, 1 is default, 2 is double speed, etc. Minimum is 0.01. This can be used for a lot of things like when you know you will have to wait for long periods of time for something to complete. Increasing will decrease performance, be careful.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.speed=X&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Freeze time ===&lt;br /&gt;
Stops the advancement of the time. Unfreezes it if you by replace &amp;quot;true&amp;quot; with &amp;quot;false&amp;quot;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.freeze_daytime=true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Remove all pollution ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.clear_pollution()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Completely turn off pollution ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for _, surface in pairs(game.surfaces) do&lt;br /&gt;
  surface.clear_pollution()&lt;br /&gt;
end&lt;br /&gt;
game.map_settings.pollution.enabled = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add a lot of pollution ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.pollute(game.player.position, 1000000)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Where speakers are, who placed them ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local speakers = game.player.surface.find_entities_filtered{force = game.player.force, type=&amp;quot;programmable-speaker&amp;quot;}&lt;br /&gt;
for key, speaker in pairs(speakers) do&lt;br /&gt;
    game.player.print(speaker.last_user.name .. &amp;quot; placed a speaker at &amp;quot; .. speaker.gps_tag)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disable friendly fire for your force ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.friendly_fire = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add new resource patch ===&lt;br /&gt;
This creates a new 11×11 patch of resources, centered on the player character, where the ground is not water.&lt;br /&gt;
The patch it creates is perfectly square but it randomizes the amount similar to natural generation, with fewer ore at the edges and more ore in the center.&lt;br /&gt;
The default numbers result in a patch with 2500-3000 ore.&lt;br /&gt;
&lt;br /&gt;
If you want a larger patch, change &amp;quot;local size = 5&amp;quot; to a larger number.&lt;br /&gt;
A larger patch will have exponentially more ore.&lt;br /&gt;
Entering a number above 30 is not recommended.&lt;br /&gt;
&lt;br /&gt;
If you want a richer patch, change &amp;quot;local density = 10&amp;quot; to a larger number.&lt;br /&gt;
Entering a very large number shouldn&#039;t hurt anything but you probably don&#039;t need to go above 100.&lt;br /&gt;
&lt;br /&gt;
To choose which resource is spawned, change &amp;quot;stone&amp;quot; near the bottom to &amp;quot;iron-ore&amp;quot;, &amp;quot;copper-ore&amp;quot;, &amp;quot;coal&amp;quot;, or &amp;quot;uranium-ore&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface=game.player.surface&lt;br /&gt;
local ore=nil&lt;br /&gt;
local size=5&lt;br /&gt;
local density=10&lt;br /&gt;
for y=-size, size do&lt;br /&gt;
	for x=-size, size do&lt;br /&gt;
		a=(size+1-math.abs(x))*10&lt;br /&gt;
		b=(size+1-math.abs(y))*10&lt;br /&gt;
		if a&amp;lt;b then&lt;br /&gt;
			ore=math.random(a*density-a*(density-8), a*density+a*(density-8))&lt;br /&gt;
		end&lt;br /&gt;
		if b&amp;lt;a then&lt;br /&gt;
			ore=math.random(b*density-b*(density-8), b*density+b*(density-8))&lt;br /&gt;
		end&lt;br /&gt;
		if surface.get_tile(game.player.position.x+x, game.player.position.y+y).collides_with(&amp;quot;ground-tile&amp;quot;) then&lt;br /&gt;
			surface.create_entity({name=&amp;quot;stone&amp;quot;, amount=ore, position={game.player.position.x+x, game.player.position.y+y}})&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more flexibility, the [[map editor]] can also be used to create/alter/remove resource patches.&lt;br /&gt;
&lt;br /&gt;
=== Remove resources around the player ===&lt;br /&gt;
Removes all resource patches from the ground in a 50 x 50 area around the player.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface=game.player.surface&lt;br /&gt;
local size=50&lt;br /&gt;
local pos=game.player.position&lt;br /&gt;
&lt;br /&gt;
for _, e in pairs(surface.find_entities_filtered{area={{pos.x-size, pos.y-size},{pos.x+size, pos.y+size}}, type=&amp;quot;resource&amp;quot;}) &lt;br /&gt;
	do e.destroy() &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Add new oil patch ===&lt;br /&gt;
This creates 9 crude oil patches in a 3×3 square.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for y=0,2 do&lt;br /&gt;
	for x=0,2 do&lt;br /&gt;
		game.player.surface.create_entity({name=&amp;quot;crude-oil&amp;quot;, amount=100000, position={game.player.position.x+x*7-7, game.player.position.y+y*7-7}})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or randomly without any collision:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local position=nil&lt;br /&gt;
for i=1,9 do&lt;br /&gt;
	position=game.player.surface.find_non_colliding_position(&amp;quot;crude-oil&amp;quot;, game.player.position, 0, i/2+1.5)&lt;br /&gt;
	if position then &lt;br /&gt;
		game.player.surface.create_entity({name=&amp;quot;crude-oil&amp;quot;, amount=100000, position=position})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Regenerate resources ===&lt;br /&gt;
For solid resources like iron, destroys all resource entities and creates resource entities as in the original map generation. For fluid resources like oil, sets the yield of all existing resource entities to the original amount. Regenerates resources on the entire surface.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
for _, e in pairs(surface.find_entities_filtered{type=&amp;quot;resource&amp;quot;}) do&lt;br /&gt;
  if e.prototype.infinite_resource then&lt;br /&gt;
    e.amount = e.initial_amount&lt;br /&gt;
  else&lt;br /&gt;
    e.destroy()&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
local non_infinites = {}&lt;br /&gt;
for resource, prototype in pairs(prototypes.get_entity_filtered{{filter=&amp;quot;type&amp;quot;, type=&amp;quot;resource&amp;quot;}}) do&lt;br /&gt;
  if not prototype.infinite_resource then&lt;br /&gt;
    table.insert(non_infinites, resource)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
surface.regenerate_entity(non_infinites)&lt;br /&gt;
for _, e in pairs(surface.find_entities_filtered{type=&amp;quot;mining-drill&amp;quot;}) do&lt;br /&gt;
    e.update_connections()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Count entities ===&lt;br /&gt;
Counts all entities whose name includes the string in local entity.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local entity=&amp;quot;belt&amp;quot;&lt;br /&gt;
local surface=game.player.surface&lt;br /&gt;
local count=0&lt;br /&gt;
for key, ent in pairs(surface.find_entities_filtered({force=game.player.force})) do&lt;br /&gt;
	if string.find(ent.name,entity) then&lt;br /&gt;
		count=count+1&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
game.player.print(count)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Turn off cliff generation ===&lt;br /&gt;
Sets size to &amp;quot;none&amp;quot;. Only effective on chunks that are generated after using this command. Use [[#Remove all cliffs]] to delete existing cliffs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local mgs = game.player.surface.map_gen_settings&lt;br /&gt;
mgs.cliff_settings.cliff_elevation_0 = 1024&lt;br /&gt;
game.player.surface.map_gen_settings = mgs&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Remove all cliffs ===&lt;br /&gt;
Removes all cliffs existing cliffs from the world. Use [[#Turn off cliff generation]] to turn off cliff generation in new chunks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for _, v in pairs(game.player.surface.find_entities_filtered{type=&amp;quot;cliff&amp;quot;}) do&lt;br /&gt;
  v.destroy()&lt;br /&gt;
end&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Delete all decoratives ===&lt;br /&gt;
Delete the decoratives that can be found in the world.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.destroy_decoratives({})&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Change map generation settings ===&lt;br /&gt;
This allows to change the map generation settings for new chunks; it does not alter already generated chunks. [[#Delete chunks|Deleted chunks]] are affected by the setting change because they are newly generated when they get explored again.&lt;br /&gt;
&lt;br /&gt;
To change resource generation settings, replace &amp;quot;iron-ore&amp;quot; with the [[Data.raw#resource|resource]] that should be changed and replace &amp;quot;very-high&amp;quot; with the desired [https://lua-api.factorio.com/latest/Concepts.html#MapGenSize MapGenSize] in the following command. Replace &amp;quot;iron-ore&amp;quot; with &amp;quot;enemy-base&amp;quot; to change the enemy base generation settings. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
local resource = &amp;quot;iron-ore&amp;quot;&lt;br /&gt;
local mgs = surface.map_gen_settings&lt;br /&gt;
mgs.autoplace_controls[resource].size = &amp;quot;very-high&amp;quot;&lt;br /&gt;
mgs.autoplace_controls[resource].frequency = &amp;quot;very-high&amp;quot;&lt;br /&gt;
mgs.autoplace_controls[resource].richness = &amp;quot;very-high&amp;quot;&lt;br /&gt;
surface.map_gen_settings = mgs&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To change water generation settings, replace &amp;quot;very-high&amp;quot; with the desired [https://lua-api.factorio.com/latest/Concepts.html#MapGenSize MapGenSize] in the following command.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
local mgs = surface.map_gen_settings&lt;br /&gt;
mgs.water = &amp;quot;very-high&amp;quot; --[[ size]]&lt;br /&gt;
mgs.terrain_segmentation  = &amp;quot;very-high&amp;quot; --[[ frequency]]&lt;br /&gt;
surface.map_gen_settings = mgs &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Making a structure indestructible ===&lt;br /&gt;
This makes it impossible for an entity to be damaged or killed, e.g. by biters. Hover over the entity and then run:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.selected.destructible = false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Connect linked belts ===&lt;br /&gt;
If there exist at least two [https://lua-api.factorio.com/latest/prototypes/LinkedBeltPrototype.html linked belts], and one of them has the &amp;quot;Entity tag&amp;quot; &amp;lt;code&amp;gt;in&amp;lt;/code&amp;gt;, and another linked belt has the &amp;quot;Entity tag&amp;quot; &amp;lt;code&amp;gt;out&amp;lt;/code&amp;gt;, then the following command should link these two linked belts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local i = game.get_entity_by_tag(&#039;in&#039;)&lt;br /&gt;
local o = game.get_entity_by_tag(&#039;out&#039;)&lt;br /&gt;
i.linked_belt_type = &#039;input&#039;&lt;br /&gt;
o.linked_belt_type = &#039;output&#039;&lt;br /&gt;
i.connect_linked_belts(o)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Enemy/evolution scripts ==&lt;br /&gt;
&lt;br /&gt;
=== Set evolution factor ===&lt;br /&gt;
Ranges from 0 (new game) to 1.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.forces[&amp;quot;enemy&amp;quot;].set_evolution_factor(X, game.player.surface)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Disable time-based evolution &amp;amp; increases pollution-based evolution ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.map_settings.enemy_evolution.time_factor=0&lt;br /&gt;
/c game.map_settings.enemy_evolution.pollution_factor=game.map_settings.enemy_evolution.pollution_factor*2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;2&amp;quot; at the end of the last command will double the default pollution factor. You can substitute another number to increase (or decrease) the pollution factor further.&lt;br /&gt;
&lt;br /&gt;
=== Kill all biters on the &amp;quot;enemy&amp;quot; force ===&lt;br /&gt;
Note that this will kill only mobile units, spawners will not be killed.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.forces[&amp;quot;enemy&amp;quot;].kill_all_units()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kill all enemies ===&lt;br /&gt;
This will kill all biters, bases and worms. Anything that is an enemy will be completely destroyed. This only affects enemies in the generated world, so any unexplored parts of the map which still need to be generated will still have enemies. You can [[#Prevent biters being on newly generated chunks|prevent biters being on newly generated chunks]] if desired.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface=game.player.surface&lt;br /&gt;
for key, entity in pairs(surface.find_entities_filtered({force=&amp;quot;enemy&amp;quot;})) do&lt;br /&gt;
	entity.destroy()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kill all nearby enemies ===&lt;br /&gt;
&lt;br /&gt;
This will kill all biters, bases and worms in a configurable radius. The default, 250 tiles, is about two zoomed-out screen widths on full HD. After destruction, it shows how many objects were destroyed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface=game.player.surface&lt;br /&gt;
local pp = game.player.position&lt;br /&gt;
local cnt = 0&lt;br /&gt;
for key, entity in pairs(surface.find_entities_filtered({force=&amp;quot;enemy&amp;quot;, radius=250, position=pp })) do&lt;br /&gt;
	cnt = cnt+1&lt;br /&gt;
	entity.destroy()&lt;br /&gt;
 end	&lt;br /&gt;
game.player.print(cnt)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable/Disable peaceful mode ===&lt;br /&gt;
Enabling peaceful mode prevents biter attacks until provoked. Substitute true for false to disable. Already existing biters are not affected by this command so attacks could continue for a while after activating peaceful mode.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.surface.peaceful_mode = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable/Disable biter expansion ===&lt;br /&gt;
Biter expansion allows biters to create new nests, it is enabled by default. Substitute true for false to disable.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.map_settings.enemy_expansion.enabled = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Prevent biters being on newly generated chunks ===&lt;br /&gt;
On newly generated chunks no biters will be present, however all current biters will remain unaffected. Equivalent of setting the Enemy Base Size to None under the Terrain settings during map generation but achieved mid game by [[#Change map generation settings|changing map generation settings]].&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local surface = game.player.surface&lt;br /&gt;
local mgs = surface.map_gen_settings&lt;br /&gt;
mgs.autoplace_controls[&amp;quot;enemy-base&amp;quot;].size = &amp;quot;none&amp;quot;&lt;br /&gt;
surface.map_gen_settings = mgs&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of the command, it is also possible to use a GUI in the [[map editor]] to changing map generation settings mid game. Access the map editor with &amp;lt;code&amp;gt;/editor&amp;lt;/code&amp;gt;, go to the &amp;quot;Surfaces&amp;quot; tab and click &amp;quot;Edit map gen settings&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Player character scripts ==&lt;br /&gt;
Commands concerning the player directly.&lt;br /&gt;
=== Get player position ===&lt;br /&gt;
Prints coordinates of your current position.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.print(game.player.position)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Teleport player ===&lt;br /&gt;
Moves the player to the specified location. You should be able to teleport to a specific player if you obtain their coordinates via them executing the previous command and giving them to you.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.teleport({X, Y})&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To teleport to the world&#039;s origin, use 0,0.&lt;br /&gt;
&lt;br /&gt;
To teleport to a different planet / surface, use:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.teleport({X, Y}, &#039;surface_name&#039;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable god mode ===&lt;br /&gt;
God mode removes your player character allowing you to fly over obstacles and take no damage.&lt;br /&gt;
&lt;br /&gt;
Disassociate your controls from the character and destroy it:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.character.destroy()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To undo, spawn a player character. This will spawn a new character at the spawn point of the world, and connect your controls to it.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.create_character()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable long reach ===&lt;br /&gt;
Enables long reach, which allows the player to build and interact with entities at a greater distance. The default reach is 10.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local reach = 10000&lt;br /&gt;
game.player.force.character_build_distance_bonus = reach&lt;br /&gt;
game.player.force.character_reach_distance_bonus = reach&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Find player corpses ===&lt;br /&gt;
Pings player corpses on the map.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local found_corpses = game.player.surface.find_entities_filtered{type=&amp;quot;character-corpse&amp;quot;}&lt;br /&gt;
for _,corpse in pairs(found_corpses) do&lt;br /&gt;
    local player = game.get_player(corpse.character_corpse_player_index)&lt;br /&gt;
    local name = player and player.name or &amp;quot;????&amp;quot;&lt;br /&gt;
    game.player.print(name .. &amp;quot; --&amp;gt; &amp;quot; .. corpse.gps_tag)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Run faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.character_running_speed_modifier=3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Research scripts ==&lt;br /&gt;
=== Enable faster research ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.laboratory_speed_modifier=1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
-0.5 is half speed, 0 is normal speed, 1 is double speed, 2 is triple etc.&lt;br /&gt;
&lt;br /&gt;
=== Research specific technologies ===&lt;br /&gt;
The internal technology names can be found in the infoboxes on their respective pages.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.technologies[&#039;electric-energy-distribution-1&#039;].researched=true&lt;br /&gt;
/c game.player.force.technologies[&#039;steel-processing&#039;].researched=true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To research a high level of an infinite technology, set its level:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.technologies[&#039;worker-robots-speed-6&#039;].level = 100&lt;br /&gt;
/c game.player.force.technologies[&#039;mining-productivity-4&#039;].level = 100&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Unresearch specific technologies ===&lt;br /&gt;
The internal technology names can be found in the infoboxes on their respective pages.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.technologies[&#039;electric-energy-distribution-1&#039;].researched=false&lt;br /&gt;
/c game.player.force.technologies[&#039;steel-processing&#039;].researched=false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enabling specific recipes ===&lt;br /&gt;
The internal recipe/item names can be found in the infoboxes on their respective pages.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.recipes[&amp;quot;electric-energy-interface&amp;quot;].enabled=true&lt;br /&gt;
/c game.player.force.recipes[&amp;quot;rocket-silo&amp;quot;].enabled=true&lt;br /&gt;
/c game.player.force.recipes.loader.enabled=true&lt;br /&gt;
/c game.player.force.recipes[&amp;quot;fast-loader&amp;quot;].enabled = true&lt;br /&gt;
/c game.player.force.recipes[&amp;quot;express-loader&amp;quot;].enabled = true&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Enable all recipes ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c for name, recipe in pairs(game.player.force.recipes) do recipe.enabled = true end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resetting technology effects to default ===&lt;br /&gt;
This will reset the enabled/unlocked state of all recipes to what they would be purely based on the currently researched technologies, as well as resetting other technology effects like mining speed, etc. Any manual modifications to these effects and recipe unlocks will be undone.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.force.reset_technology_effects()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note: Can be used as a quick workaround when recipes are unavailable after adding or changing mods even though the technology unlocking them has already been researched.&lt;br /&gt;
&lt;br /&gt;
== Modding tools ==&lt;br /&gt;
A list of the internal names of most things in the vanilla game can also be found on [[data.raw]].&lt;br /&gt;
&lt;br /&gt;
=== Access a mod&#039;s data ===&lt;br /&gt;
If the first word of the command is __mod-name__ it will run in the context of the mod with the same name. For instance, this command prints the data from the Even Distribution mod:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c __even-distribution__ game.player.print(serpent.dump(global))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Print to console the tile under the player ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.player.print(game.player.surface.get_tile(game.player.position).name)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Write all researched technologies to file ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local list = {}&lt;br /&gt;
for _, tech in pairs(game.player.force.technologies) do &lt;br /&gt;
	if tech.researched then&lt;br /&gt;
    list[#list+1] = tech.name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
game.write_file(&amp;quot;techs.lua&amp;quot;, serpent.block(list) .. &amp;quot;\n&amp;quot;, true)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Write all enabled recipes to file ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c local list = {}&lt;br /&gt;
for _, recipe in pairs(game.player.force.recipes) do &lt;br /&gt;
	if recipe.enabled then&lt;br /&gt;
    list[#list+1] = recipe.name&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
game.write_file(&amp;quot;recipes.lua&amp;quot;, serpent.block(list) .. &amp;quot;\n&amp;quot;, true)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Write mod list to file ===&lt;br /&gt;
Write all currently active mods and their version to the file script-output/mods.txt in the [[user data directory]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
/c game.write_file(&amp;quot;mods.txt&amp;quot;, serpent.block(game.active_mods))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;br /&gt;
{{History|1.1.92|&lt;br /&gt;
* Added a notification when a technology is researched.&lt;br /&gt;
* Added /enable-research-queue console command to enable the research queue without disabling achievements.}}&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
* [[Command line parameters]]&lt;br /&gt;
* https://lua-api.factorio.com/latest/index-runtime.html - Factorio API reference for latest version&lt;br /&gt;
&lt;br /&gt;
{{C|Modding}}&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial/Gangsir&amp;diff=204741</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=204741"/>
		<updated>2024-11-03T22:51:20Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Fix typo (controller the character :facepalm:)&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 three kinds of dependencies. There are required dependencies, and optional dependencies. The third kind, restrictive dependencies, does not affect mod order and instead prevents the game from loading if the other mod is found. Required dependencies are loaded first, always. The game will fail to initialize if one of these is not present. Optional dependencies are loaded first if present, but do not have to be present. This is useful for enabling bonus features if mods are used together. Required dependencies should be used for mod libraries, and similar infrastructure.&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. Prototypes names cannot be dynamically changed and technology unlocks of already researched technologies do not apply automatically, making migrations necessary. Try to avoid these changes after shipping the mod out to the public. 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 [[Tutorial:Mod structure|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 [[Tutorial:Mod_structure#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/global.html global] 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 global 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>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial/Gangsir&amp;diff=204739</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=204739"/>
		<updated>2024-11-03T22:49:37Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Tweak formatting&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 three kinds of dependencies. There are required dependencies, and optional dependencies. The third kind, restrictive dependencies, does not affect mod order and instead prevents the game from loading if the other mod is found. Required dependencies are loaded first, always. The game will fail to initialize if one of these is not present. Optional dependencies are loaded first if present, but do not have to be present. This is useful for enabling bonus features if mods are used together. Required dependencies should be used for mod libraries, and similar infrastructure.&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. Prototypes names cannot be dynamically changed and technology unlocks of already researched technologies do not apply automatically, making migrations necessary. Try to avoid these changes after shipping the mod out to the public. 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 [[Tutorial:Mod structure|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 [[Tutorial:Mod_structure#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 controller 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/global.html global] 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 global 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>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Modding_tutorial/Gangsir&amp;diff=204736</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=204736"/>
		<updated>2024-11-03T22:36:32Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Update references of 1.1 to 2.0, and fix a crash with map view&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 three kinds of dependencies. There are required dependencies, and optional dependencies. The third kind, restrictive dependencies, does not affect mod order and instead prevents the game from loading if the other mod is found. Required dependencies are loaded first, always. The game will fail to initialize if one of these is not present. Optional dependencies are loaded first if present, but do not have to be present. This is useful for enabling bonus features if mods are used together. Required dependencies should be used for mod libraries, and similar infrastructure.&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. Prototypes names cannot be dynamically changed and technology unlocks of already researched technologies do not apply automatically, making migrations necessary. Try to avoid these changes after shipping the mod out to the public. 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 [[Tutorial:Mod structure|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 [[Tutorial:Mod_structure#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 controller the character&lt;br /&gt;
    if player.controller_type == defines.controllers.character&lt;br /&gt;
    -- And wearing our armor&lt;br /&gt;
    and 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;
)&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/global.html global] 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 global 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>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=202119</id>
		<title>Rich text</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Rich_text&amp;diff=202119"/>
		<updated>2024-10-23T17:24:17Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: Make quality its own section, and use a baked image instead of trying to overlay images&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
Rich text formatting in 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.html#SpritePath 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 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;
| [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;
&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>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=File:Uncommon_small_biter.png&amp;diff=202105</id>
		<title>File:Uncommon small biter.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=File:Uncommon_small_biter.png&amp;diff=202105"/>
		<updated>2024-10-23T16:48:54Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The icon for a small biter with the uncommon quality tag on it. It doesn&#039;t perfectly match the base game, but it&#039;s visually almost identical.&lt;br /&gt;
&lt;br /&gt;
The quality icon was simply scaled down to 32x32 before overlaying it on top of the 64x64 icon&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=File:Quality_uncommon.png&amp;diff=202103</id>
		<title>File:Quality uncommon.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=File:Quality_uncommon.png&amp;diff=202103"/>
		<updated>2024-10-23T16:39:24Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The uncommon quality tier icon&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=File:Quality_normal.png&amp;diff=202102</id>
		<title>File:Quality normal.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=File:Quality_normal.png&amp;diff=202102"/>
		<updated>2024-10-23T16:32:19Z</updated>

		<summary type="html">&lt;p&gt;PennyJim: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The icon for the normal quality&lt;/div&gt;</summary>
		<author><name>PennyJim</name></author>
	</entry>
</feed>