<?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=Sunarch</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=Sunarch"/>
	<link rel="alternate" type="text/html" href="https://wiki.factorio.com/Special:Contributions/Sunarch"/>
	<updated>2026-04-22T07:52:21Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Factorio_talk:Terms_of_Service&amp;diff=188126</id>
		<title>Factorio talk:Terms of Service</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Factorio_talk:Terms_of_Service&amp;diff=188126"/>
		<updated>2022-02-02T20:09:44Z</updated>

		<summary type="html">&lt;p&gt;Sunarch: Response&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In the &amp;quot;Intellectual Property and Sharing&amp;quot;, in the second bullet point the example is given thus: &amp;quot;(for instance namely translations)&amp;quot; which is a doubling of the meaning. Preferably it should be one or the other: &amp;quot;for instance, translations&amp;quot; or &amp;quot;namely, translations&amp;quot; (the first one being better in this context, in my opinion). -- [[User:Sunarch|Sunarch]] ([[User talk:Sunarch|talk]]) 05:08, 9 January 2022 (UTC)&lt;br /&gt;
:Hey, as stated on the page, these Terms of Service are a copy of the Terms of Service of factorio.com. If you&#039;d like those amended, I&#039;d suggest sending an email to factorio@factorio.com. -- [[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; 17:54, 13 January 2022 (UTC)&lt;br /&gt;
::I just wanted to point it out. If you don&#039;t think any action should be taken on it, I don&#039;t think it&#039;s a major issue. -- [[User:Sunarch|Sunarch]] ([[User talk:Sunarch|talk]]) 20:09, 2 February 2022 (UTC)&lt;/div&gt;</summary>
		<author><name>Sunarch</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Factorio_talk:Terms_of_Service&amp;diff=187817</id>
		<title>Factorio talk:Terms of Service</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Factorio_talk:Terms_of_Service&amp;diff=187817"/>
		<updated>2022-01-09T05:08:12Z</updated>

		<summary type="html">&lt;p&gt;Sunarch: Add note on wording of an example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In the &amp;quot;Intellectual Property and Sharing&amp;quot;, in the second bullet point the example is given thus: &amp;quot;(for instance namely translations)&amp;quot; which is a doubling of the meaning. Preferably it should be one or the other: &amp;quot;for instance, translations&amp;quot; or &amp;quot;namely, translations&amp;quot; (the first one being better in this context, in my opinion). -- [[User:Sunarch|Sunarch]] ([[User talk:Sunarch|talk]]) 05:08, 9 January 2022 (UTC)&lt;/div&gt;</summary>
		<author><name>Sunarch</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=Tutorial:Scripting&amp;diff=187816</id>
		<title>Tutorial:Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=Tutorial:Scripting&amp;diff=187816"/>
		<updated>2022-01-09T04:55:51Z</updated>

		<summary type="html">&lt;p&gt;Sunarch: /* Saving data &amp;amp;amp; the global table */ Add missing verb&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is a script? ==&lt;br /&gt;
&lt;br /&gt;
In general, you can learn the definition of a script [https://en.wikipedia.org/wiki/Scripting_language here]. Within the context of Factorio, a script refers to a Lua script, packaged with a mod or scenario.&lt;br /&gt;
&lt;br /&gt;
There are 2 usages of scripts, loading of [[prototype definitions|prototype data]], and runtime scripting of the game and its entities.&lt;br /&gt;
&lt;br /&gt;
This guide only covers usages of runtime scripts. To be more specific, we call these runtime scripts &#039;control scripts&#039;, as they assert direct control on the game as it runs.&lt;br /&gt;
&lt;br /&gt;
== Loading a script ==&lt;br /&gt;
&lt;br /&gt;
When you load a game, scenario and mod scripts are loaded. The game looks for a file called &#039;control.lua&#039;, in the mod directory or the scenario directory. If found, the game will then load that script, and any other scripts required in the control script.&lt;br /&gt;
&lt;br /&gt;
== [https://lua-api.factorio.com/latest/Libraries.html Factorio specifics] ==&lt;br /&gt;
&lt;br /&gt;
Factorio uses Lua version 5.2.1.&lt;br /&gt;
&lt;br /&gt;
Factorio uses Serpent for serialization - This comes with some big drawbacks:&lt;br /&gt;
&lt;br /&gt;
* Serpent is relatively slow and inefficient&lt;br /&gt;
* Serpent cannot serialize a lot of Lua objects, such as functions, metatables and coroutines.&lt;br /&gt;
&lt;br /&gt;
The full scripting API is generated and updated each release, and is available [http://lua-api.factorio.com/latest/index.html here]. This is the number 1 resource for scripting in the game.&lt;br /&gt;
&lt;br /&gt;
== [http://lua-api.factorio.com/latest/LuaBootstrap.html Script events] ==&lt;br /&gt;
&lt;br /&gt;
The Lua script has some special functions it runs outside of events: &lt;br /&gt;
* &amp;lt;code&amp;gt;script.on_init()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;script.on_configuration_changed()&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;script.on_load()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;on_init()&amp;lt;/code&amp;gt; will run when the game starts (or in mod cases, when you add it to an existing save). It is used to initialize global variables you will need, changing game parameters, for instance:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;script.on_init(function()&lt;br /&gt;
  global.ticker = 0&lt;br /&gt;
  global.level = 1&lt;br /&gt;
  global.teams = {default_team = &amp;quot;johns-lads&amp;quot;}&lt;br /&gt;
  game.create_surface(&amp;quot;Scenario Surface&amp;quot;)&lt;br /&gt;
  game.map_settings.pollution.enabled = false&lt;br /&gt;
  --etc.&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/LuaGameScript.html &amp;lt;code&amp;gt;game&amp;lt;/code&amp;gt;] namespace is available during on_init&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;on_configuration_changed(data)&amp;lt;/code&amp;gt; will run when some configuration about this save game changes, such as a mod being added, changed or removed. This function is used to account for changes to game or prototype changes. &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; will contain information on what has changed.&lt;br /&gt;
&lt;br /&gt;
So if you are dependent on some prototype for your script to work, you should check here that it still exists:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;script.on_configuration_changed(function(data)&lt;br /&gt;
  local turret_name = &amp;quot;gun-turret&amp;quot;&lt;br /&gt;
  if not game.entity_prototypes[turret_name] then&lt;br /&gt;
    log(&amp;quot;Gun turret isn&#039;t here, some mod or something has changed it&amp;quot;)&lt;br /&gt;
    global.do_turret_logic = false&lt;br /&gt;
  end&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The contents of the &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; parameter is defined [http://lua-api.factorio.com/latest/Concepts.html#ConfigurationChangedData here].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;on_load()&amp;lt;/code&amp;gt; will run every time the script loads. &amp;lt;code&amp;gt;game&amp;lt;/code&amp;gt; will not be available during &amp;lt;code&amp;gt;on_load&amp;lt;/code&amp;gt;. This should only be used to handle resetting up metatables, making local references to variables in &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt;, and setting up conditional event handlers.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;local variable&lt;br /&gt;
script.on_load(function()&lt;br /&gt;
  --Resetting metatables&lt;br /&gt;
  for k, v in (global.objects_with_metatable) do&lt;br /&gt;
    setmetatable(v, object_metatable)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  --Setting local reference to global variable&lt;br /&gt;
  variable = global.variable&lt;br /&gt;
&lt;br /&gt;
  --Conditional event handler&lt;br /&gt;
  if global.trees then&lt;br /&gt;
    script.on_event(defines.events.on_tick, handle_tree_function)&lt;br /&gt;
  end&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
It is quite easy to generate desyncs doing overly complex things with on_load, so we recommend only doing things with it if absolutely nescessary.&lt;br /&gt;
&lt;br /&gt;
== [http://lua-api.factorio.com/latest/events.html Game events] ==&lt;br /&gt;
&lt;br /&gt;
The scripts all run based off events. These events are sent by the game after certain actions are performed. For instance &amp;lt;code&amp;gt;on_player_crafted_item&amp;lt;/code&amp;gt;. To &#039;&#039;do&#039;&#039; something with an event, you will need to assign an event handler:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;script.on_event(defines.events.on_player_crafted_item, player_crafted_function)&amp;lt;/source&amp;gt;&lt;br /&gt;
When the event is triggered, it will then call the function with &amp;lt;code&amp;gt;event&amp;lt;/code&amp;gt; as its parameter. &amp;lt;code&amp;gt;event&amp;lt;/code&amp;gt; is a table that contains varying information about the event. More specific info on them [http://lua-api.factorio.com/latest/events.html here]. You then process the event using your own function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;function player_crafted_function(event)&lt;br /&gt;
  game.print(&amp;quot;A player crafted an item on tick &amp;quot;..event.tick)&lt;br /&gt;
end&amp;lt;/source&amp;gt;&lt;br /&gt;
This also works with anonymous functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;script.on_event(defines.events.on_tick, function(event)&lt;br /&gt;
  game.print(&amp;quot;tick&amp;quot;)&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
Note that only one event handler can be assigned for each event, such that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;script.on_event(defines.events.on_tick, function(event)&lt;br /&gt;
  game.print(&amp;quot;tick&amp;quot;)&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
script.on_event(defines.events.on_tick, function(event)&lt;br /&gt;
  game.print(&amp;quot;tock&amp;quot;)&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
The second handler will overwrite the first.&lt;br /&gt;
&lt;br /&gt;
If you want to do multiple things on the same event, a simple way is as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;script.on_event(defines.events.on_tick, function(event)&lt;br /&gt;
  this_on_tick(event)&lt;br /&gt;
  that_on_tick(event)&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
== Saving data &amp;amp;amp; the &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; table ==&lt;br /&gt;
&lt;br /&gt;
Save/Load stability is very important to preserve the determinism of the game. In Lua, all values are global by default. This isn’t good news in Factorio, as it can make it seem as though things are working correctly, but will lead to desyncs in MP.&lt;br /&gt;
&lt;br /&gt;
To preserve data between load and save, we have the &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt; table. If there is some variable that you need to use between events, this is where it should live.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;script.on_event(defines.events.on_tick, function(event)&lt;br /&gt;
  global.ticker = (global.ticker or 0) + 1&lt;br /&gt;
end)&amp;lt;/source&amp;gt;&lt;br /&gt;
Now when the player saves the game, the value of &amp;lt;code&amp;gt;global.ticker&amp;lt;/code&amp;gt; will be saved. When it is loaded again, its value will be restored. This is important, because in MP, players joining the game will load the value from the save.&lt;br /&gt;
&lt;br /&gt;
The way this can cause desyncs is quite clear, if one player has their Lua state, with a ticker value of 100, and another has a value of 50, and you then create ticker number of biters, it would create 100 for player 1, and 50 for player 2.&lt;br /&gt;
&lt;br /&gt;
However it is not often this easy. The case is often as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;tick_to_print = 10 --So lets say this is a static variable. Just some config for how your script works.&lt;br /&gt;
&lt;br /&gt;
function on_tick()&lt;br /&gt;
  if game.tick == tick_to_print then&lt;br /&gt;
    game.print(&amp;quot;hello&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
script.on_event(defines.event.on_tick, on_tick)&amp;lt;/source&amp;gt;&lt;br /&gt;
This will be fine, we are using the variable, but not changing it. When a new player loads the game, &amp;lt;code&amp;gt;tick_to_print&amp;lt;/code&amp;gt; will be &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;, same as the other players.&lt;br /&gt;
&lt;br /&gt;
Problem comes if we adjust &amp;lt;code&amp;gt;tick_to_print&amp;lt;/code&amp;gt;, either by purpose or intentionally.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;tick_to_print = 10 --So lets say this is a static variable. Just some config for how your script works.&lt;br /&gt;
&lt;br /&gt;
function on_tick()&lt;br /&gt;
  if game.tick == tick_to_print then&lt;br /&gt;
    game.print(&amp;quot;hello&amp;quot;)&lt;br /&gt;
    tick_to_print = tick_to_print + 100 --Say we want it to print again in 100 ticks&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
script.on_event(defines.event.on_tick, on_tick)&amp;lt;/source&amp;gt;&lt;br /&gt;
Now when you test the script, it will work perfectly. Every 100 ticks it will print “hello”. The problem occurs when you save, and load the game. When you save, the value of &amp;lt;code&amp;gt;tick_to_print&amp;lt;/code&amp;gt; is not saved anywhere, And thus, when you load, it just uses the value its told to at the top of the script: &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Now it is clear that the value of &amp;lt;code&amp;gt;tick_to_print&amp;lt;/code&amp;gt; has changed by saving and loading, thus we say it is not save/load stable. If a players joins a MP game with this script, they would desync as soon as one of the scripts prints as the result of a comparison against &amp;lt;code&amp;gt;tick_to_print&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
So TL;DR - If you want to use something between ticks, then store it in &amp;lt;code&amp;gt;global&amp;lt;/code&amp;gt;. This will prevent 99% of possible desyncs.&lt;br /&gt;
&lt;br /&gt;
== Story script ==&lt;br /&gt;
&lt;br /&gt;
Story script is a Lua library designed to facilitate the scripting and flow of a story. It has some simple structure and supporting function to help things move along.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;--Initialize the story info&lt;br /&gt;
script.on_init(function()&lt;br /&gt;
  global.story = story_init()&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
--Register to update the story on events&lt;br /&gt;
script.on_event(defines.events, function(event)&lt;br /&gt;
  story_update(global.story, event)&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
--Story table is where the &#039;story&#039; is all defined.&lt;br /&gt;
story_table =&lt;br /&gt;
{&lt;br /&gt;
  {&lt;br /&gt;
    --branch 1&lt;br /&gt;
    {&lt;br /&gt;
      --First story event&lt;br /&gt;
&lt;br /&gt;
      --Initialise this event&lt;br /&gt;
      init = function(event, story)&lt;br /&gt;
        game.print(&amp;quot;First init of first story event&amp;quot;)&lt;br /&gt;
      end,&lt;br /&gt;
&lt;br /&gt;
      --Update function that will run on all events&lt;br /&gt;
      update = function(event, story)&lt;br /&gt;
        log(&amp;quot;updating&amp;quot;)&lt;br /&gt;
      end,&lt;br /&gt;
&lt;br /&gt;
      --Condition to move on. If the return value is &#039;true&#039;, the story will continue.&lt;br /&gt;
      condition = function(event, story)&lt;br /&gt;
        if event.tick &amp;gt; 100 then&lt;br /&gt;
          return true&lt;br /&gt;
        end&lt;br /&gt;
      end,&lt;br /&gt;
&lt;br /&gt;
      --Action to perform after condition is met&lt;br /&gt;
      action = function(event, story)&lt;br /&gt;
        game.print(&amp;quot;You completed the objective!&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      --Second story event - example.&lt;br /&gt;
      init = function(event, story)&lt;br /&gt;
        game.print(&amp;quot;Collect 100 iron plate&amp;quot;)&lt;br /&gt;
      end,&lt;br /&gt;
      condition = function(event, story)&lt;br /&gt;
        return game.players[1].get_item_count(&amp;quot;iron-plate&amp;quot;) &amp;gt;= 100&lt;br /&gt;
      end,&lt;br /&gt;
      action = function(event, story)&lt;br /&gt;
        game.print(&amp;quot;Well done&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    }&lt;br /&gt;
    --Once the end of a branch is reached, the story is finished.&lt;br /&gt;
    --The game will now display the mission complete screen.&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    --branch 2&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--Init the helpers and story table. Must be done all times script is loaded.&lt;br /&gt;
story_init_helpers(story_table)&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Branches are an optional system of the story system, and you can jump to another branch using &amp;lt;code&amp;gt;story_jump_to(story, name)&amp;lt;/code&amp;gt;. The story progresses from the top down, and when it reaches the last story event, the mission concludes.&lt;br /&gt;
&lt;br /&gt;
It is possible to leverage any number of clever Lua tricks and API calls in the story table. It is good form to try and keep each story part independant from its neighbors, as it makes maintanance and reworkings more manageable.&lt;br /&gt;
&lt;br /&gt;
Bad:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;  {&lt;br /&gt;
    action = function()&lt;br /&gt;
      player().insert(&amp;quot;iron-plate&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  },&lt;br /&gt;
  {&lt;br /&gt;
    init = function()&lt;br /&gt;
      player().print(&amp;quot;Use your iron plate to craft some belts&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  }&amp;lt;/source&amp;gt;&lt;br /&gt;
Good:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;  {&lt;br /&gt;
    init = function()&lt;br /&gt;
      player().insert(&amp;quot;iron-plate&amp;quot;)&lt;br /&gt;
      player().print(&amp;quot;Use your iron plate...&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  }&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are some utility functions to make things simpler on the scripting side:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;lua&amp;quot;&amp;gt;--Return true only after this many seconds has elasped&lt;br /&gt;
story_elapsed_check(5)&lt;br /&gt;
&lt;br /&gt;
--Update the objective for all players&lt;br /&gt;
set_goal({&amp;quot;objective-1&amp;quot;})&lt;br /&gt;
&lt;br /&gt;
--Flash the goal GUI for players (updating info doesn&#039;t flash it)&lt;br /&gt;
flash_goal()&lt;br /&gt;
&lt;br /&gt;
--Update the &#039;info gui&#039; for all players. This is quite powerful and can use custom function to build complex GUI&#039;s&lt;br /&gt;
set_info(&lt;br /&gt;
{&lt;br /&gt;
  text = {&amp;quot;info-1&amp;quot;},&lt;br /&gt;
  picture = &amp;quot;item/iron-plate&amp;quot;&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
--Exports entities in a Lua table format&lt;br /&gt;
export_entities(parameters)&lt;br /&gt;
&lt;br /&gt;
--Recreates entities saved using a Lua format&lt;br /&gt;
recreate_entities(entities, parameters)&lt;br /&gt;
&lt;br /&gt;
--Shorthand syntax for game.players[i], defaults i to 1&lt;br /&gt;
player(i)&lt;br /&gt;
&lt;br /&gt;
--Shorthand syntax for game.surfaces[i], defaults i to 1&lt;br /&gt;
surface(i)&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Sunarch</name></author>
	</entry>
</feed>