<?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=Ucrij+fender</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=Ucrij+fender"/>
	<link rel="alternate" type="text/html" href="https://wiki.factorio.com/Special:Contributions/Ucrij_fender"/>
	<updated>2026-04-13T04:54:56Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178486</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178486"/>
		<updated>2020-03-18T13:11:52Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Resolving common errors in modding */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 виглядати так]:&lt;br /&gt;
* (каталог користувача)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
*** prototypes&lt;br /&gt;
**** item.lua&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&lt;br /&gt;
&lt;br /&gt;
=== Створення прототипу ===&lt;br /&gt;
&lt;br /&gt;
Зараз у Factorio є два способи створення прототипів: короткий і довгий шлях. Довгий шлях вимагає копіювання існуючого визначення з одного з файлів lua за замовчуванням, забезпечених установкою Factorio, а короткий шлях просто використовує функцію lua для копіювання та зміни визначення. В цьому посыбнику ми зробимо це коротким шляхом.&lt;br /&gt;
В item.lua, зкопіюйте:&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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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;
Ми скопіювали визначення важкої броні, потім змінили її властивості та ввели її в ініціалізацію Factorio з data:extend. Перший рядок коду, мабуть, найцікавіший. &amp;lt;code&amp;gt;table.deepcopy&amp;lt;/code&amp;gt; повністю копіює таблицю в іншу з data.raw. &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; - це таблиця, яка буде використовуватися грою для налаштування всесвіту Factorio. Насправді він містить функцію &amp;lt;code&amp;gt;extend(self,prototypes)&amp;lt;/code&amp;gt; та таблицю, яку називають &amp;lt;code&amp;gt;raw&amp;lt;/code&amp;gt;. Перший - звичний спосіб додавання нових речей до другого. Фактично в data.raw описані усі прототипи для гри. (Ви можете переглянути реалізацію у файлі [https://github.com/wube/factorio-data/blob/master/core/lualib/dataloader.lua /factorio/data/core/lualib/dataloader.lua]). Важливо зазначити, що data.raw існує лише на етапі завантаження даних у грі. На етапі управління, коли гра працює, ви не можете прочитати ці дані; натомість ви читаєте оброблені значення через API з різних типів, таких як LuaEntityPrototype.&lt;br /&gt;
&lt;br /&gt;
Окрім визначення прототипу елемента, ми також визначаємо його рецепт. Це необхідно, якщо ви хочете вміти зробити річ. Ми також встановлюємо його як увімкнене, для розблокування не потрібна технологія.&lt;br /&gt;
&lt;br /&gt;
На даний момент мод виглядає [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 приблизно так].&lt;br /&gt;
&lt;br /&gt;
=== Більше data.raw ===&lt;br /&gt;
&lt;br /&gt;
Коли Factorio ініціалізується, всі прототипи поміщаються в таблицю під назвою data.raw. Ця таблиця містить усі типи, а в межах цих типів - окремі сутності. Ви раніше бачили, як ми скопіювали(deepcopied) визначення важкої броні та змінили деякі поля. Насправді переглянемо кожну лінію коду:&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.armor[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ми призначаємо змінну(variable) під назвою fireArmor, яка містить нашу копію визначення важкої броні. Зауважте як у data.raw знаходиться таблиця типів, яка містить усі визначення броні, а конкретна броня, яку ми шукаємо, називається важкою бронею. Наприклад, прототипом гравця буде:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оскільки прототипом гравця(в лапках) є гравець, той тип відповідає його імені. Ви можете визначити новий тип гравця за допомогою модифікації. Ви можете побачити всі прототипи поля для сутності в її довгій декларації в програмі Factorio, за адресою /data/base/prototypes.&lt;br /&gt;
&lt;br /&gt;
Ви, можливо, думаєте в цей момент: &amp;quot;Чи можу я змінити існуючі прототипи Factorio без створення нових?&amp;quot; Ну, відповідь - так! Ви просто отримаєте доступ до таблиці data.raw під час ініціадізації, у data-final-fixes.lua та зміните властивість. Наприклад, встановіть залізній скрині 1000 здоров&#039;я:&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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причина, по якій цей код повинен бути у data-final-fixes.lua або data-updates.lua, полягає в тому, що це останній запуск файлу після запуску всіх файлів мод. Це запобігає (певною мірою) вашим змінам не змішуватись іншими модами. Звичайно, все-таки можливі несумісності. Ви повинні зазначити все, що вам відомо в описі вашого мода. Слід переглянути [http://lua-api.factorio.com/latest/Data-Lifecycle.html документацію розробника] про дані для більшої зрозумілості та точності.&lt;br /&gt;
&lt;br /&gt;
Це також може бути застосоване до інших мод, а не лише до бази Факторио. Ви не можете модифікувати мод до тих пір, поки ви не додасте мод (який ви змінили своїм модом) до залежностей, щоб він завантажився першим.&lt;br /&gt;
&lt;br /&gt;
=== Контрольні сценарії ===&lt;br /&gt;
&lt;br /&gt;
А тепер, щоб доопрацювати мод, ми мусимо зробити це не просто простою бронею. Давайте подумаємо, що ми хочемо зробити броні. Ми хочемо, щоб броня періодично створювала вогонь по землі, коли ми ходимо з обладунками. Подія, яку ми будемо використовувати, називається on_tick, оскільки ми хочемо, щоб вогонь періодично створювався.&lt;br /&gt;
&lt;br /&gt;
У папці мод створіть файл під назвою &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Гра автоматично виконає цей файл, тому додавати до вимог його не потрібно.&lt;br /&gt;
&lt;br /&gt;
Всередині control.lua скопіюйте та вставте наступне:&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --поширений трюк, щоб зменшити частоту праці, ми не хочемо, щоб він виконувався не кожнен тік а кожні 30, коротше двічі на секунду&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --цикл для всих гравців на сервері або в локальній грі&lt;br /&gt;
            --якщо гравець носить нашу броню&lt;br /&gt;
            if player.character and player.get_inventory(defines.inventory.character_armor).get_item_count(&amp;quot;fire-armor&amp;quot;) &amp;gt;= 1 then&lt;br /&gt;
               --створити вогонь на місці стояння гравця&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;
   end&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
За допомогою коментарів lua у вищенаведеному коді досить легко зрозуміти як все працює, як ви отримаєте поточну броню, яку носить гравець, з defines.inventory.character_armor, яка є постійною інвентарем та як створювати вогонь. Прочитати список визначень [http://lua-api.factorio.com/latest/defines.html#defines.inventory можливо тут].&lt;br /&gt;
&lt;br /&gt;
=== Локалізація ===&lt;br /&gt;
&lt;br /&gt;
Якщо ви вже пробували завантажувати Factorio і намагаєтеся з модифікацією, можливо, ви помітили, що назва предмета броні говорить &amp;quot;Unknown key&amp;quot;(невідоме значення). Це означає, що Factorio має внутрішню назву, але він не знає, як він повинен виглядати для користувача. Отже, нам потрібно створити локалізацію для нашого мода.&lt;br /&gt;
&lt;br /&gt;
У папці створіть папку під назвою &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt;, потім створіть іншу папку всередині, яка називається &amp;lt;code&amp;gt;en&amp;lt;/code&amp;gt;([https://uk.wikipedia.org/wiki/ISO_639-1 ISO 639] для більшого), потім файл під назвою &amp;lt;code&amp;gt;config.cfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Якщо ви знаєте іншу мову, ви також можете перекласти свій мод, зробивши інші файли кодових мов всередині локалі, наприклад de для німецької.&lt;br /&gt;
&lt;br /&gt;
В config.cfg, вставте наступне:&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;
[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;
Зверніть увагу, щр це не файл lua. Локальна обробка обробляється файлами конфігурації C, тому формат відрізняється.&lt;br /&gt;
&lt;br /&gt;
== Закінчення підручника ==&lt;br /&gt;
&lt;br /&gt;
Ну, мод закінчений. Оскільки цей мод є лише навчальним, балансу в ньому мало.&lt;br /&gt;
&lt;br /&gt;
Однак ви можете взяти цей мод і змінити його для власного використання, змінюючи рецепти, додаючи технології, що завгодно.&lt;br /&gt;
&lt;br /&gt;
== Вирішення поширених помилок під час модінгу ==&lt;br /&gt;
&lt;br /&gt;
Якщо ви продовжите писати моди з нуля, а не з туторіалів, ви можете зіткнутися з поширеними помилками. Існує кілька типів помилок, з якими ви можете зіткнутися в програмуванні взагалі, і знання способів вирішення цих помилок дозволить вам продовжувати працювати.&lt;br /&gt;
=== Синтаксичні помилки ===&lt;br /&gt;
&lt;br /&gt;
Мова програмування lua очікує, що речі будуть викладені певним чином. Якщо ви пропустите дужку, знак або крапку, ви побачите помилку синтаксису. Як приклад:&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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Починаючи з версії 0.15, ви побачите помилку, подібну до наведеної вище, кожного разу, коли будете робити помилки синтаксису в межах визначення прототипу. Гра запропонує перезапустити, відключити тривожний мод, відключити всі модни або вийти. Розберемо помилку.&lt;br /&gt;
&lt;br /&gt;
Відразу ми бачимо причину, чому Factorio не запустився. &amp;quot;Failed to load mods:&amp;quot; не вдалося завантажити модифікації. Отже, ми знаємо яка модифікація має помилку. Щоразу, коли у lua-рушія Factorio виникає синтаксична помилка, він надрукує міні стек-стежку, яка слідує за всіма потребами, перелічуючи порядок виклику. По-перше, ми бачимо, що проблема була опосередковано спричинена рядком 1 у data.lua. Тут немає жодних проблем, тому це повинен бути наступний запис, рядок 36 prototypes/item.lua. Після того, як він вказав, де це, він спробує дати вам оцінку, де в рядку проблема. Не довіряйте цій оцінці, лише приблизно довіряйте номеру рядка плюс-мінус кілька рядків.&lt;br /&gt;
&lt;br /&gt;
В лінії 36 файла item.lua можна знайти:&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;
recipe.enabled true&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це не виглядає правильно. Ви можете бачити, чого не вистачає? Ми залишили &amp;quot;знак прирівнювання&amp;quot;. Для новачків в програмуванні такі може бути неочевидним.&lt;br /&gt;
=== Нелогічні дії та нуль(nil) ===&lt;br /&gt;
&lt;br /&gt;
У lua &amp;quot;нічого&amp;quot; визначається як nil. Це схоже на null в інших мовах програмування. Кожен раз, коли програміст намагається отримати доступ до чогось у таблиці, яка є нульовою, вони отримають помилку на зразок наступного:&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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;
Помилка &amp;quot;attempt to index field ...&amp;quot;(спроба індексувати поле) часто викликана тим, що моддер вибирає з таблиці неіснуючих даних. Ці типи помилок завжди будуть ідентифіковані за їх рядком підпису, &amp;quot;спроба індексувати поле&amp;quot;. Якщо ми подивимось на рядок 3 з control.lua, ми побачимо:&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;
Яке припущення зробив тут моддер? Ну, насправді є дві проблеми. Перше, що моддер припустив, що &amp;lt;code&amp;gt;game.players[23]&amp;lt;/code&amp;gt; є дійсним гравцем, що не так. Ці помилки важко налагодити, якщо ви добре не знаєте входів та виходів модуляційного API.&lt;br /&gt;
&lt;br /&gt;
Друга проблема набагато тонкіша, і вона не спрацює. Модер намагається надрукувати таблицю даних користувачів. [http://lua-api.factorio.com/latest/LuaPlayer Гравець] - це таблиця з кількома значеннями. Спробу надрукувати його буде помилкою, замість цього потрібна функція для друку.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178485</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178485"/>
		<updated>2020-03-18T08:19:12Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* The finished tutorial mod */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 виглядати так]:&lt;br /&gt;
* (каталог користувача)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
*** prototypes&lt;br /&gt;
**** item.lua&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&lt;br /&gt;
&lt;br /&gt;
=== Створення прототипу ===&lt;br /&gt;
&lt;br /&gt;
Зараз у Factorio є два способи створення прототипів: короткий і довгий шлях. Довгий шлях вимагає копіювання існуючого визначення з одного з файлів lua за замовчуванням, забезпечених установкою Factorio, а короткий шлях просто використовує функцію lua для копіювання та зміни визначення. В цьому посыбнику ми зробимо це коротким шляхом.&lt;br /&gt;
В item.lua, зкопіюйте:&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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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;
Ми скопіювали визначення важкої броні, потім змінили її властивості та ввели її в ініціалізацію Factorio з data:extend. Перший рядок коду, мабуть, найцікавіший. &amp;lt;code&amp;gt;table.deepcopy&amp;lt;/code&amp;gt; повністю копіює таблицю в іншу з data.raw. &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; - це таблиця, яка буде використовуватися грою для налаштування всесвіту Factorio. Насправді він містить функцію &amp;lt;code&amp;gt;extend(self,prototypes)&amp;lt;/code&amp;gt; та таблицю, яку називають &amp;lt;code&amp;gt;raw&amp;lt;/code&amp;gt;. Перший - звичний спосіб додавання нових речей до другого. Фактично в data.raw описані усі прототипи для гри. (Ви можете переглянути реалізацію у файлі [https://github.com/wube/factorio-data/blob/master/core/lualib/dataloader.lua /factorio/data/core/lualib/dataloader.lua]). Важливо зазначити, що data.raw існує лише на етапі завантаження даних у грі. На етапі управління, коли гра працює, ви не можете прочитати ці дані; натомість ви читаєте оброблені значення через API з різних типів, таких як LuaEntityPrototype.&lt;br /&gt;
&lt;br /&gt;
Окрім визначення прототипу елемента, ми також визначаємо його рецепт. Це необхідно, якщо ви хочете вміти зробити річ. Ми також встановлюємо його як увімкнене, для розблокування не потрібна технологія.&lt;br /&gt;
&lt;br /&gt;
На даний момент мод виглядає [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 приблизно так].&lt;br /&gt;
&lt;br /&gt;
=== Більше data.raw ===&lt;br /&gt;
&lt;br /&gt;
Коли Factorio ініціалізується, всі прототипи поміщаються в таблицю під назвою data.raw. Ця таблиця містить усі типи, а в межах цих типів - окремі сутності. Ви раніше бачили, як ми скопіювали(deepcopied) визначення важкої броні та змінили деякі поля. Насправді переглянемо кожну лінію коду:&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.armor[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ми призначаємо змінну(variable) під назвою fireArmor, яка містить нашу копію визначення важкої броні. Зауважте як у data.raw знаходиться таблиця типів, яка містить усі визначення броні, а конкретна броня, яку ми шукаємо, називається важкою бронею. Наприклад, прототипом гравця буде:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оскільки прототипом гравця(в лапках) є гравець, той тип відповідає його імені. Ви можете визначити новий тип гравця за допомогою модифікації. Ви можете побачити всі прототипи поля для сутності в її довгій декларації в програмі Factorio, за адресою /data/base/prototypes.&lt;br /&gt;
&lt;br /&gt;
Ви, можливо, думаєте в цей момент: &amp;quot;Чи можу я змінити існуючі прототипи Factorio без створення нових?&amp;quot; Ну, відповідь - так! Ви просто отримаєте доступ до таблиці data.raw під час ініціадізації, у data-final-fixes.lua та зміните властивість. Наприклад, встановіть залізній скрині 1000 здоров&#039;я:&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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причина, по якій цей код повинен бути у data-final-fixes.lua або data-updates.lua, полягає в тому, що це останній запуск файлу після запуску всіх файлів мод. Це запобігає (певною мірою) вашим змінам не змішуватись іншими модами. Звичайно, все-таки можливі несумісності. Ви повинні зазначити все, що вам відомо в описі вашого мода. Слід переглянути [http://lua-api.factorio.com/latest/Data-Lifecycle.html документацію розробника] про дані для більшої зрозумілості та точності.&lt;br /&gt;
&lt;br /&gt;
Це також може бути застосоване до інших мод, а не лише до бази Факторио. Ви не можете модифікувати мод до тих пір, поки ви не додасте мод (який ви змінили своїм модом) до залежностей, щоб він завантажився першим.&lt;br /&gt;
&lt;br /&gt;
=== Контрольні сценарії ===&lt;br /&gt;
&lt;br /&gt;
А тепер, щоб доопрацювати мод, ми мусимо зробити це не просто простою бронею. Давайте подумаємо, що ми хочемо зробити броні. Ми хочемо, щоб броня періодично створювала вогонь по землі, коли ми ходимо з обладунками. Подія, яку ми будемо використовувати, називається on_tick, оскільки ми хочемо, щоб вогонь періодично створювався.&lt;br /&gt;
&lt;br /&gt;
У папці мод створіть файл під назвою &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Гра автоматично виконає цей файл, тому додавати до вимог його не потрібно.&lt;br /&gt;
&lt;br /&gt;
Всередині control.lua скопіюйте та вставте наступне:&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --поширений трюк, щоб зменшити частоту праці, ми не хочемо, щоб він виконувався не кожнен тік а кожні 30, коротше двічі на секунду&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --цикл для всих гравців на сервері або в локальній грі&lt;br /&gt;
            --якщо гравець носить нашу броню&lt;br /&gt;
            if player.character and player.get_inventory(defines.inventory.character_armor).get_item_count(&amp;quot;fire-armor&amp;quot;) &amp;gt;= 1 then&lt;br /&gt;
               --створити вогонь на місці стояння гравця&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;
   end&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
За допомогою коментарів lua у вищенаведеному коді досить легко зрозуміти як все працює, як ви отримаєте поточну броню, яку носить гравець, з defines.inventory.character_armor, яка є постійною інвентарем та як створювати вогонь. Прочитати список визначень [http://lua-api.factorio.com/latest/defines.html#defines.inventory можливо тут].&lt;br /&gt;
&lt;br /&gt;
=== Локалізація ===&lt;br /&gt;
&lt;br /&gt;
Якщо ви вже пробували завантажувати Factorio і намагаєтеся з модифікацією, можливо, ви помітили, що назва предмета броні говорить &amp;quot;Unknown key&amp;quot;(невідоме значення). Це означає, що Factorio має внутрішню назву, але він не знає, як він повинен виглядати для користувача. Отже, нам потрібно створити локалізацію для нашого мода.&lt;br /&gt;
&lt;br /&gt;
У папці створіть папку під назвою &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt;, потім створіть іншу папку всередині, яка називається &amp;lt;code&amp;gt;en&amp;lt;/code&amp;gt;([https://uk.wikipedia.org/wiki/ISO_639-1 ISO 639] для більшого), потім файл під назвою &amp;lt;code&amp;gt;config.cfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Якщо ви знаєте іншу мову, ви також можете перекласти свій мод, зробивши інші файли кодових мов всередині локалі, наприклад de для німецької.&lt;br /&gt;
&lt;br /&gt;
В config.cfg, вставте наступне:&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;
[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;
Зверніть увагу, щр це не файл lua. Локальна обробка обробляється файлами конфігурації C, тому формат відрізняється.&lt;br /&gt;
&lt;br /&gt;
== Закінчення підручника ==&lt;br /&gt;
&lt;br /&gt;
Ну, мод закінчений. Оскільки цей мод є лише навчальним, балансу в ньому мало.&lt;br /&gt;
&lt;br /&gt;
Однак ви можете взяти цей мод і змінити його для власного використання, змінюючи рецепти, додаючи технології, що завгодно.&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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178484</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178484"/>
		<updated>2020-03-18T08:14:44Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Locale */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 виглядати так]:&lt;br /&gt;
* (каталог користувача)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
*** prototypes&lt;br /&gt;
**** item.lua&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&lt;br /&gt;
&lt;br /&gt;
=== Створення прототипу ===&lt;br /&gt;
&lt;br /&gt;
Зараз у Factorio є два способи створення прототипів: короткий і довгий шлях. Довгий шлях вимагає копіювання існуючого визначення з одного з файлів lua за замовчуванням, забезпечених установкою Factorio, а короткий шлях просто використовує функцію lua для копіювання та зміни визначення. В цьому посыбнику ми зробимо це коротким шляхом.&lt;br /&gt;
В item.lua, зкопіюйте:&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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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;
Ми скопіювали визначення важкої броні, потім змінили її властивості та ввели її в ініціалізацію Factorio з data:extend. Перший рядок коду, мабуть, найцікавіший. &amp;lt;code&amp;gt;table.deepcopy&amp;lt;/code&amp;gt; повністю копіює таблицю в іншу з data.raw. &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; - це таблиця, яка буде використовуватися грою для налаштування всесвіту Factorio. Насправді він містить функцію &amp;lt;code&amp;gt;extend(self,prototypes)&amp;lt;/code&amp;gt; та таблицю, яку називають &amp;lt;code&amp;gt;raw&amp;lt;/code&amp;gt;. Перший - звичний спосіб додавання нових речей до другого. Фактично в data.raw описані усі прототипи для гри. (Ви можете переглянути реалізацію у файлі [https://github.com/wube/factorio-data/blob/master/core/lualib/dataloader.lua /factorio/data/core/lualib/dataloader.lua]). Важливо зазначити, що data.raw існує лише на етапі завантаження даних у грі. На етапі управління, коли гра працює, ви не можете прочитати ці дані; натомість ви читаєте оброблені значення через API з різних типів, таких як LuaEntityPrototype.&lt;br /&gt;
&lt;br /&gt;
Окрім визначення прототипу елемента, ми також визначаємо його рецепт. Це необхідно, якщо ви хочете вміти зробити річ. Ми також встановлюємо його як увімкнене, для розблокування не потрібна технологія.&lt;br /&gt;
&lt;br /&gt;
На даний момент мод виглядає [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 приблизно так].&lt;br /&gt;
&lt;br /&gt;
=== Більше data.raw ===&lt;br /&gt;
&lt;br /&gt;
Коли Factorio ініціалізується, всі прототипи поміщаються в таблицю під назвою data.raw. Ця таблиця містить усі типи, а в межах цих типів - окремі сутності. Ви раніше бачили, як ми скопіювали(deepcopied) визначення важкої броні та змінили деякі поля. Насправді переглянемо кожну лінію коду:&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.armor[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ми призначаємо змінну(variable) під назвою fireArmor, яка містить нашу копію визначення важкої броні. Зауважте як у data.raw знаходиться таблиця типів, яка містить усі визначення броні, а конкретна броня, яку ми шукаємо, називається важкою бронею. Наприклад, прототипом гравця буде:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оскільки прототипом гравця(в лапках) є гравець, той тип відповідає його імені. Ви можете визначити новий тип гравця за допомогою модифікації. Ви можете побачити всі прототипи поля для сутності в її довгій декларації в програмі Factorio, за адресою /data/base/prototypes.&lt;br /&gt;
&lt;br /&gt;
Ви, можливо, думаєте в цей момент: &amp;quot;Чи можу я змінити існуючі прототипи Factorio без створення нових?&amp;quot; Ну, відповідь - так! Ви просто отримаєте доступ до таблиці data.raw під час ініціадізації, у data-final-fixes.lua та зміните властивість. Наприклад, встановіть залізній скрині 1000 здоров&#039;я:&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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причина, по якій цей код повинен бути у data-final-fixes.lua або data-updates.lua, полягає в тому, що це останній запуск файлу після запуску всіх файлів мод. Це запобігає (певною мірою) вашим змінам не змішуватись іншими модами. Звичайно, все-таки можливі несумісності. Ви повинні зазначити все, що вам відомо в описі вашого мода. Слід переглянути [http://lua-api.factorio.com/latest/Data-Lifecycle.html документацію розробника] про дані для більшої зрозумілості та точності.&lt;br /&gt;
&lt;br /&gt;
Це також може бути застосоване до інших мод, а не лише до бази Факторио. Ви не можете модифікувати мод до тих пір, поки ви не додасте мод (який ви змінили своїм модом) до залежностей, щоб він завантажився першим.&lt;br /&gt;
&lt;br /&gt;
=== Контрольні сценарії ===&lt;br /&gt;
&lt;br /&gt;
А тепер, щоб доопрацювати мод, ми мусимо зробити це не просто простою бронею. Давайте подумаємо, що ми хочемо зробити броні. Ми хочемо, щоб броня періодично створювала вогонь по землі, коли ми ходимо з обладунками. Подія, яку ми будемо використовувати, називається on_tick, оскільки ми хочемо, щоб вогонь періодично створювався.&lt;br /&gt;
&lt;br /&gt;
У папці мод створіть файл під назвою &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Гра автоматично виконає цей файл, тому додавати до вимог його не потрібно.&lt;br /&gt;
&lt;br /&gt;
Всередині control.lua скопіюйте та вставте наступне:&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --поширений трюк, щоб зменшити частоту праці, ми не хочемо, щоб він виконувався не кожнен тік а кожні 30, коротше двічі на секунду&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --цикл для всих гравців на сервері або в локальній грі&lt;br /&gt;
            --якщо гравець носить нашу броню&lt;br /&gt;
            if player.character and player.get_inventory(defines.inventory.character_armor).get_item_count(&amp;quot;fire-armor&amp;quot;) &amp;gt;= 1 then&lt;br /&gt;
               --створити вогонь на місці стояння гравця&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;
   end&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
За допомогою коментарів lua у вищенаведеному коді досить легко зрозуміти як все працює, як ви отримаєте поточну броню, яку носить гравець, з defines.inventory.character_armor, яка є постійною інвентарем та як створювати вогонь. Прочитати список визначень [http://lua-api.factorio.com/latest/defines.html#defines.inventory можливо тут].&lt;br /&gt;
&lt;br /&gt;
=== Локалізація ===&lt;br /&gt;
&lt;br /&gt;
Якщо ви вже пробували завантажувати Factorio і намагаєтеся з модифікацією, можливо, ви помітили, що назва предмета броні говорить &amp;quot;Unknown key&amp;quot;(невідоме значення). Це означає, що Factorio має внутрішню назву, але він не знає, як він повинен виглядати для користувача. Отже, нам потрібно створити локалізацію для нашого мода.&lt;br /&gt;
&lt;br /&gt;
У папці створіть папку під назвою &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt;, потім створіть іншу папку всередині, яка називається &amp;lt;code&amp;gt;en&amp;lt;/code&amp;gt;([https://uk.wikipedia.org/wiki/ISO_639-1 ISO 639] для більшого), потім файл під назвою &amp;lt;code&amp;gt;config.cfg&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Якщо ви знаєте іншу мову, ви також можете перекласти свій мод, зробивши інші файли кодових мов всередині локалі, наприклад de для німецької.&lt;br /&gt;
&lt;br /&gt;
В config.cfg, вставте наступне:&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;
[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;
Зверніть увагу, щр це не файл lua. Локальна обробка обробляється файлами конфігурації C, тому формат відрізняється.&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178483</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178483"/>
		<updated>2020-03-18T08:02:36Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* The control scripting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 виглядати так]:&lt;br /&gt;
* (каталог користувача)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
*** prototypes&lt;br /&gt;
**** item.lua&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&lt;br /&gt;
&lt;br /&gt;
=== Створення прототипу ===&lt;br /&gt;
&lt;br /&gt;
Зараз у Factorio є два способи створення прототипів: короткий і довгий шлях. Довгий шлях вимагає копіювання існуючого визначення з одного з файлів lua за замовчуванням, забезпечених установкою Factorio, а короткий шлях просто використовує функцію lua для копіювання та зміни визначення. В цьому посыбнику ми зробимо це коротким шляхом.&lt;br /&gt;
В item.lua, зкопіюйте:&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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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;
Ми скопіювали визначення важкої броні, потім змінили її властивості та ввели її в ініціалізацію Factorio з data:extend. Перший рядок коду, мабуть, найцікавіший. &amp;lt;code&amp;gt;table.deepcopy&amp;lt;/code&amp;gt; повністю копіює таблицю в іншу з data.raw. &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; - це таблиця, яка буде використовуватися грою для налаштування всесвіту Factorio. Насправді він містить функцію &amp;lt;code&amp;gt;extend(self,prototypes)&amp;lt;/code&amp;gt; та таблицю, яку називають &amp;lt;code&amp;gt;raw&amp;lt;/code&amp;gt;. Перший - звичний спосіб додавання нових речей до другого. Фактично в data.raw описані усі прототипи для гри. (Ви можете переглянути реалізацію у файлі [https://github.com/wube/factorio-data/blob/master/core/lualib/dataloader.lua /factorio/data/core/lualib/dataloader.lua]). Важливо зазначити, що data.raw існує лише на етапі завантаження даних у грі. На етапі управління, коли гра працює, ви не можете прочитати ці дані; натомість ви читаєте оброблені значення через API з різних типів, таких як LuaEntityPrototype.&lt;br /&gt;
&lt;br /&gt;
Окрім визначення прототипу елемента, ми також визначаємо його рецепт. Це необхідно, якщо ви хочете вміти зробити річ. Ми також встановлюємо його як увімкнене, для розблокування не потрібна технологія.&lt;br /&gt;
&lt;br /&gt;
На даний момент мод виглядає [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 приблизно так].&lt;br /&gt;
&lt;br /&gt;
=== Більше data.raw ===&lt;br /&gt;
&lt;br /&gt;
Коли Factorio ініціалізується, всі прототипи поміщаються в таблицю під назвою data.raw. Ця таблиця містить усі типи, а в межах цих типів - окремі сутності. Ви раніше бачили, як ми скопіювали(deepcopied) визначення важкої броні та змінили деякі поля. Насправді переглянемо кожну лінію коду:&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.armor[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ми призначаємо змінну(variable) під назвою fireArmor, яка містить нашу копію визначення важкої броні. Зауважте як у data.raw знаходиться таблиця типів, яка містить усі визначення броні, а конкретна броня, яку ми шукаємо, називається важкою бронею. Наприклад, прототипом гравця буде:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оскільки прототипом гравця(в лапках) є гравець, той тип відповідає його імені. Ви можете визначити новий тип гравця за допомогою модифікації. Ви можете побачити всі прототипи поля для сутності в її довгій декларації в програмі Factorio, за адресою /data/base/prototypes.&lt;br /&gt;
&lt;br /&gt;
Ви, можливо, думаєте в цей момент: &amp;quot;Чи можу я змінити існуючі прототипи Factorio без створення нових?&amp;quot; Ну, відповідь - так! Ви просто отримаєте доступ до таблиці data.raw під час ініціадізації, у data-final-fixes.lua та зміните властивість. Наприклад, встановіть залізній скрині 1000 здоров&#039;я:&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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причина, по якій цей код повинен бути у data-final-fixes.lua або data-updates.lua, полягає в тому, що це останній запуск файлу після запуску всіх файлів мод. Це запобігає (певною мірою) вашим змінам не змішуватись іншими модами. Звичайно, все-таки можливі несумісності. Ви повинні зазначити все, що вам відомо в описі вашого мода. Слід переглянути [http://lua-api.factorio.com/latest/Data-Lifecycle.html документацію розробника] про дані для більшої зрозумілості та точності.&lt;br /&gt;
&lt;br /&gt;
Це також може бути застосоване до інших мод, а не лише до бази Факторио. Ви не можете модифікувати мод до тих пір, поки ви не додасте мод (який ви змінили своїм модом) до залежностей, щоб він завантажився першим.&lt;br /&gt;
&lt;br /&gt;
=== Контрольні сценарії ===&lt;br /&gt;
&lt;br /&gt;
А тепер, щоб доопрацювати мод, ми мусимо зробити це не просто простою бронею. Давайте подумаємо, що ми хочемо зробити броні. Ми хочемо, щоб броня періодично створювала вогонь по землі, коли ми ходимо з обладунками. Подія, яку ми будемо використовувати, називається on_tick, оскільки ми хочемо, щоб вогонь періодично створювався.&lt;br /&gt;
&lt;br /&gt;
У папці мод створіть файл під назвою &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Гра автоматично виконає цей файл, тому додавати до вимог його не потрібно.&lt;br /&gt;
&lt;br /&gt;
Всередині control.lua скопіюйте та вставте наступне:&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --поширений трюк, щоб зменшити частоту праці, ми не хочемо, щоб він виконувався не кожнен тік а кожні 30, коротше двічі на секунду&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --цикл для всих гравців на сервері або в локальній грі&lt;br /&gt;
            --якщо гравець носить нашу броню&lt;br /&gt;
            if player.character and player.get_inventory(defines.inventory.character_armor).get_item_count(&amp;quot;fire-armor&amp;quot;) &amp;gt;= 1 then&lt;br /&gt;
               --створити вогонь на місці стояння гравця&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;
   end&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
За допомогою коментарів lua у вищенаведеному коді досить легко зрозуміти як все працює, як ви отримаєте поточну броню, яку носить гравець, з defines.inventory.character_armor, яка є постійною інвентарем та як створювати вогонь. Прочитати список визначень [http://lua-api.factorio.com/latest/defines.html#defines.inventory можливо тут].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178482</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178482"/>
		<updated>2020-03-18T07:31:49Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* More on data.raw */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 виглядати так]:&lt;br /&gt;
* (каталог користувача)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
*** prototypes&lt;br /&gt;
**** item.lua&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&lt;br /&gt;
&lt;br /&gt;
=== Створення прототипу ===&lt;br /&gt;
&lt;br /&gt;
Зараз у Factorio є два способи створення прототипів: короткий і довгий шлях. Довгий шлях вимагає копіювання існуючого визначення з одного з файлів lua за замовчуванням, забезпечених установкою Factorio, а короткий шлях просто використовує функцію lua для копіювання та зміни визначення. В цьому посыбнику ми зробимо це коротким шляхом.&lt;br /&gt;
В item.lua, зкопіюйте:&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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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;
Ми скопіювали визначення важкої броні, потім змінили її властивості та ввели її в ініціалізацію Factorio з data:extend. Перший рядок коду, мабуть, найцікавіший. &amp;lt;code&amp;gt;table.deepcopy&amp;lt;/code&amp;gt; повністю копіює таблицю в іншу з data.raw. &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; - це таблиця, яка буде використовуватися грою для налаштування всесвіту Factorio. Насправді він містить функцію &amp;lt;code&amp;gt;extend(self,prototypes)&amp;lt;/code&amp;gt; та таблицю, яку називають &amp;lt;code&amp;gt;raw&amp;lt;/code&amp;gt;. Перший - звичний спосіб додавання нових речей до другого. Фактично в data.raw описані усі прототипи для гри. (Ви можете переглянути реалізацію у файлі [https://github.com/wube/factorio-data/blob/master/core/lualib/dataloader.lua /factorio/data/core/lualib/dataloader.lua]). Важливо зазначити, що data.raw існує лише на етапі завантаження даних у грі. На етапі управління, коли гра працює, ви не можете прочитати ці дані; натомість ви читаєте оброблені значення через API з різних типів, таких як LuaEntityPrototype.&lt;br /&gt;
&lt;br /&gt;
Окрім визначення прототипу елемента, ми також визначаємо його рецепт. Це необхідно, якщо ви хочете вміти зробити річ. Ми також встановлюємо його як увімкнене, для розблокування не потрібна технологія.&lt;br /&gt;
&lt;br /&gt;
На даний момент мод виглядає [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 приблизно так].&lt;br /&gt;
&lt;br /&gt;
=== Більше data.raw ===&lt;br /&gt;
&lt;br /&gt;
Коли Factorio ініціалізується, всі прототипи поміщаються в таблицю під назвою data.raw. Ця таблиця містить усі типи, а в межах цих типів - окремі сутності. Ви раніше бачили, як ми скопіювали(deepcopied) визначення важкої броні та змінили деякі поля. Насправді переглянемо кожну лінію коду:&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.armor[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ми призначаємо змінну(variable) під назвою fireArmor, яка містить нашу копію визначення важкої броні. Зауважте як у data.raw знаходиться таблиця типів, яка містить усі визначення броні, а конкретна броня, яку ми шукаємо, називається важкою бронею. Наприклад, прототипом гравця буде:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Оскільки прототипом гравця(в лапках) є гравець, той тип відповідає його імені. Ви можете визначити новий тип гравця за допомогою модифікації. Ви можете побачити всі прототипи поля для сутності в її довгій декларації в програмі Factorio, за адресою /data/base/prototypes.&lt;br /&gt;
&lt;br /&gt;
Ви, можливо, думаєте в цей момент: &amp;quot;Чи можу я змінити існуючі прототипи Factorio без створення нових?&amp;quot; Ну, відповідь - так! Ви просто отримаєте доступ до таблиці data.raw під час ініціадізації, у data-final-fixes.lua та зміните властивість. Наприклад, встановіть залізній скрині 1000 здоров&#039;я:&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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Причина, по якій цей код повинен бути у data-final-fixes.lua або data-updates.lua, полягає в тому, що це останній запуск файлу після запуску всіх файлів мод. Це запобігає (певною мірою) вашим змінам не змішуватись іншими модами. Звичайно, все-таки можливі несумісності. Ви повинні зазначити все, що вам відомо в описі вашого мода. Слід переглянути [http://lua-api.factorio.com/latest/Data-Lifecycle.html документацію розробника] про дані для більшої зрозумілості та точності.&lt;br /&gt;
&lt;br /&gt;
Це також може бути застосоване до інших мод, а не лише до бази Факторио. Ви не можете модифікувати мод до тих пір, поки ви не додасте мод (який ви змінили своїм модом) до залежностей, щоб він завантажився першим.&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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178461</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178461"/>
		<updated>2020-03-15T17:34:14Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Prototype creation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 виглядати так]:&lt;br /&gt;
* (каталог користувача)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
*** prototypes&lt;br /&gt;
**** item.lua&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&lt;br /&gt;
&lt;br /&gt;
=== Створення прототипу ===&lt;br /&gt;
&lt;br /&gt;
Зараз у Factorio є два способи створення прототипів: короткий і довгий шлях. Довгий шлях вимагає копіювання існуючого визначення з одного з файлів lua за замовчуванням, забезпечених установкою Factorio, а короткий шлях просто використовує функцію lua для копіювання та зміни визначення. В цьому посыбнику ми зробимо це коротким шляхом.&lt;br /&gt;
В item.lua, зкопіюйте:&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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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;
Ми скопіювали визначення важкої броні, потім змінили її властивості та ввели її в ініціалізацію Factorio з data:extend. Перший рядок коду, мабуть, найцікавіший. &amp;lt;code&amp;gt;table.deepcopy&amp;lt;/code&amp;gt; повністю копіює таблицю в іншу з data.raw. &amp;lt;code&amp;gt;data&amp;lt;/code&amp;gt; - це таблиця, яка буде використовуватися грою для налаштування всесвіту Factorio. Насправді він містить функцію &amp;lt;code&amp;gt;extend(self,prototypes)&amp;lt;/code&amp;gt; та таблицю, яку називають &amp;lt;code&amp;gt;raw&amp;lt;/code&amp;gt;. Перший - звичний спосіб додавання нових речей до другого. Фактично в data.raw описані усі прототипи для гри. (Ви можете переглянути реалізацію у файлі [https://github.com/wube/factorio-data/blob/master/core/lualib/dataloader.lua /factorio/data/core/lualib/dataloader.lua]). Важливо зазначити, що data.raw існує лише на етапі завантаження даних у грі. На етапі управління, коли гра працює, ви не можете прочитати ці дані; натомість ви читаєте оброблені значення через API з різних типів, таких як LuaEntityPrototype.&lt;br /&gt;
&lt;br /&gt;
Окрім визначення прототипу елемента, ми також визначаємо його рецепт. Це необхідно, якщо ви хочете вміти зробити річ. Ми також встановлюємо його як увімкнене, для розблокування не потрібна технологія.&lt;br /&gt;
&lt;br /&gt;
На даний момент мод виглядає [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 приблизно так].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178460</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178460"/>
		<updated>2020-03-15T17:09:45Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* info.json */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 виглядати так]:&lt;br /&gt;
* (каталог користувача)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
*** prototypes&lt;br /&gt;
**** item.lua&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178459</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178459"/>
		<updated>2020-03-15T17:08:59Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Туторіал */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен[https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 виглядати так]:&lt;br /&gt;
* (каталог користувача)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
*** prototypes&lt;br /&gt;
**** item.lua&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178458</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178458"/>
		<updated>2020-03-15T17:06:44Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Об&#039;єкт&lt;br /&gt;
! Пояснення&lt;br /&gt;
|-&lt;br /&gt;
| name&lt;br /&gt;
| Внутрішнє ім&#039;я модифікації, воно використовується для ідентифікації вашого мода в коді.&lt;br /&gt;
|-&lt;br /&gt;
| version&lt;br /&gt;
| Версія модифікації. Це може бути все, що завгодно, за умови, що це числа розділені точками. Деякі моди починаються з 0.0.1 або 0.1.0, а інші слідують за версіями Factorio і починаються з 0.17.0 (для версії Factorio 0.17.x)&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| Примітна назва вашого мода, це відображатиметься на екрані управління модифікаціями та під час надсилання його на портал модів.&lt;br /&gt;
|-&lt;br /&gt;
| author&lt;br /&gt;
| Назвисько(nickname) або ім&#039;я.&lt;br /&gt;
|-&lt;br /&gt;
| contact&lt;br /&gt;
| Контактна інформація, щоб хтось міг знайти вас у разі проблеми.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| Ваш власний веб-сайт свого мода. Не вимагається.&lt;br /&gt;
|-&lt;br /&gt;
| factorio_version&lt;br /&gt;
| Версія гри для якої призначений мод, вона повинна відповідати версії, для якої ви розробляєте мод, 0.17 в цьому випадку.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Будь-які залежності вашого мода. &amp;quot;base&amp;quot; завжди мусить бути тут, тому база спочатку завантажується.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| &#039;&#039;Короткий&#039;&#039; опис модифікації&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
І це все, щодо info.json! Наступний файл - це data.lua:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Це досить простий файл, все, що ми робимо тут, - це лише змушуємо гру виконати файл під назвою item.lua в прототипах, який ми збираємося створити. Створіть у FireArmor_0.1.0 папку під назвою &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, потім всередині прототипів створіть файл під назвою &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Ваш каталог мод тепер повинен відповідати [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 цим знімкам github].&lt;br /&gt;
&lt;br /&gt;
Зверніть увагу на зазначення каталогів та файлів.&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178457</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178457"/>
		<updated>2020-03-15T16:49:55Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* The info.json file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
**** data.lua&lt;br /&gt;
**** info.json&lt;br /&gt;
&lt;br /&gt;
=== info.json ===&lt;br /&gt;
&lt;br /&gt;
Потім всередині info.json скопіюйте та вставте в нього:&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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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;
Для пояснень:&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178456</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178456"/>
		<updated>2020-03-15T16:48:52Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Creation of the directory structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Створення структури каталогів ===&lt;br /&gt;
&lt;br /&gt;
Як було згадано раніше, існує загальний неофіційний стандарт того, як робиться структура модифікації. Це в поєднанні зі [[Tutorial:Mod structure|стандартами самої гри]] трохи обмежує нас. Для початку створіть папку у папці [[Application directory|каталогу даних користувача]]/модів. Ця папка повинна мати конкретне ім&#039;я, &amp;lt;code&amp;gt;FireArmor_0.1.0&amp;lt;/code&amp;gt;. Закінчивши, каталог моди повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Потім всередині FireArmor_0.1.0 створіть два файли, &amp;lt;code&amp;gt;info.json&amp;lt;/code&amp;gt; та &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Тепер каталог повинен виглядати так:&lt;br /&gt;
&lt;br /&gt;
* (каталог користувача, наприклад .factorio)&lt;br /&gt;
** mods&lt;br /&gt;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178455</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178455"/>
		<updated>2020-03-15T16:39:55Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* The tutorial mod */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&lt;br /&gt;
&lt;br /&gt;
== Туторіал ==&lt;br /&gt;
А тепер мить на яку ви чекали. Тож почнемо робити свій перший мод. Вам знадобиться:&lt;br /&gt;
&lt;br /&gt;
* Власне сама Factorio&lt;br /&gt;
* Текстовий редактор або пре-процесор&lt;br /&gt;
* Розуміння написаного вище&lt;br /&gt;
* Розуміння Lua як мови програмування. Досить знати синтаксис і як він працює. Якщо у вас є попередній досвід програмування, працювати з ним не мусить бути складним.&lt;br /&gt;
&lt;br /&gt;
Після того, як у вас з’явиться все це, ми можемо почати.&lt;br /&gt;
&lt;br /&gt;
Для цього мода ми зробимо набір броні, який залишає вогонь позаду вас під час прогулянки. Броня буде повністю стійка до вогню, але слабша до фізичного пошкодження, ніж важка болня, зробивши її бронею для тактики &amp;quot;стріляй та біжи&amp;quot;(run&amp;amp;gun).&lt;br /&gt;
&lt;br /&gt;
=== Creation of the directory structure ===&lt;br /&gt;
&lt;br /&gt;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178454</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178454"/>
		<updated>2020-03-15T11:12:22Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* The major components to any Factorio mod */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&lt;br /&gt;
&lt;br /&gt;
== Основні компоненти будь-якої модифікації Factorio ==&lt;br /&gt;
&lt;br /&gt;
В більшості випадків модифікації мають декілька компонентів, які змушують функціонувати мод.&lt;br /&gt;
&lt;br /&gt;
Модам, що визначають нові сутності, потрібно буде оголосити ці сутності в &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;
Модам з ігровими ефектами також знадобиться файл &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;, щоб додати сценарій.&lt;br /&gt;
&lt;br /&gt;
Моди з налаштованими налаштуваннями користувача будуть використовувати &amp;lt;code&amp;gt;ettings.lua&amp;lt;/code&amp;gt; для опису цих параметрів.&lt;br /&gt;
&lt;br /&gt;
Моди, що визначають будь-який ігровий елемент з читабельним іменем, також можуть містити каталог &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt; та підкаталоги з іменами/описами на одній або кількох мовах.&lt;br /&gt;
&lt;br /&gt;
Мод, який ми будемо робити в цьому підручнику, буде включати в себе як прототипи data.lua, так і сценарії control.lua, щоб ви змогли ознайомитися з обома.&lt;br /&gt;
&lt;br /&gt;
З часом спільнота визначилася з деякими умовами щодо того, як повинна виглядати структура каталогів модів. Дотримуватися їх до точно не потрібно, але слідуючи стандартам, можна покращити читабельність скриптів та полегшити обговорення помилок модів. Детальніше про структуру каталогів нижче.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178451</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178451"/>
		<updated>2020-03-15T10:54:32Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Runtime */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Час виконання(Runtime) ===&lt;br /&gt;
&lt;br /&gt;
На цьому етапі мод встановлюється, і збереження працює. Доступ до всіх таблиць, що надаються в грі, можна зробити всередині обробників подій. (Більше про те, що нижче).&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178450</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178450"/>
		<updated>2020-03-15T10:50:21Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* КонтрольControl */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Контроль ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178449</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178449"/>
		<updated>2020-03-15T10:50:10Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Control */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== КонтрольControl ===&lt;br /&gt;
&lt;br /&gt;
У більшості модифікацій є файл, який називається &amp;lt;code&amp;gt;control.lua&amp;lt;/code&amp;gt;. Цей файл містить сценарії, які змушують мод робити речі під час гри, а не просто додавати суб&#039;єкти до гри. Під час цього етапу запускається control.lua кожного мода, в його власномій інстанції lua (це означає відсутність взаємозв&#039;язку без спеціальних налаштувань), яким він буде володіти на протязі решти сеансу відтворення. Оскільки це запускається щоразу, коли файл збереження створюється або завантажується, вам не потрібно перезапускати гру, щоб побачити зміни, внесені до файлу control.lua. Просто перезапуск або перезавантаження збереження повторно запустить цей етап. &#039;&#039;&#039;На цьому етапі є кілька інших застережень. Ознайомитися з ними можна на сторінці [http://lua-api.factorio.com/latest/Data-Lifecycle.html життєвих циклів даних] на веб-сайті API.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178448</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178448"/>
		<updated>2020-03-15T10:45:08Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Migrations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Міграції(Migrations) ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Міграції] це сценарії, які використовуються для &amp;quot;виправлення&amp;quot; збереження після оновлення модів. Кожного разу, коли прототипи змінюються в межах модифікації, необхідно мігрувати, щоб виправити всі старі екземпляри прототипованої сутності у світі. Це потрібно зробити для всіх оновлених об&#039;єктів, інакше старі об&#039;єкти будуть видалені зі світу, що є непрофесійним резервом, який змушує користувачів не любити вас. Хоча цей посібник не буде обговорювати міграції, є багато ресурсів щодо міграцій, які можна знайти у спільноті та на веб-сайті API.&lt;br /&gt;
&lt;br /&gt;
are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Control ===&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. Because this 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 [http://lua-api.factorio.com/latest/Data-Lifecycle.html data life cycle] page on the API site provides the best overview.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178439</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178439"/>
		<updated>2020-03-15T10:14:18Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* The data stage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&lt;br /&gt;
&lt;br /&gt;
=== Стадія даних ===&lt;br /&gt;
&lt;br /&gt;
Це найбільш обмежена частина ініціалізації програми Factorio, тут ви майже нічого не можете, крім декларування прототипів для технологій та об&#039;єктів. Такі речі, як маніпулювання файлами, які впливають на світ або інше блокуються/недоступні. Насправді будь-які внесені функції або зміни будуть відкинуті, оскільки сеанс Lua припиняється. Ви також не можете взаємодіяти з таблицею даних, але це буде визначено помилкою або ігноруватися. Використовуючи &amp;lt;code&amp;gt;data:extend({})&amp;lt;/code&amp;gt;, воно очікуватиме певного формату, докладніше про це пізніше.&lt;br /&gt;
&lt;br /&gt;
Під час запуску цього етапу гра переглядає всі моди для файлу під назвою &amp;lt;code&amp;gt;data.lua&amp;lt;/code&amp;gt;. Після того, як data.lua виконано для всіх модів виконується &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;. Ці 3 різні фази на етапі даних дозволяють змінювати дані інших мод без необхідності покладатися на залежності для завантаження останнього. Наприклад, базовий мод створює рецепти стволів для всіх наявних рідин у data-updates.lua. Це означає, що якщо ви додасте рідину в data.lua, базовий мод data-updates.lua додасть для нього рецепти &amp;quot;крафтингу&amp;quot;(barreling recipes,барелінгу), незалежно від відповідності версії вашого моду від бази(base mode). Звичайно, це також означає, що якщо ви додаєте рідину в data-final-fixes.lua, вона створюється після запуску коду барелінгу в data-updates.lua, тому що жоден рецепт не створюється навіть за бажанням, щоб виключити рідину з барелінгу створіть її в data.lua та використовуйте &amp;quot;auto_barrel = false&amp;quot; на рідині. Через такі та подібні модифікаційні взаємодії рекомендується створювати прототипи якомога раніше.&lt;br /&gt;
&lt;br /&gt;
Усі інші файли для завантаження повинні бути. Усі файли, запущені тут, не повинні містити нічого, крім визначення прототипу та коду для створення визначень прототипу. Детальніше про необхідність файлів пізніше.&lt;br /&gt;
&lt;br /&gt;
=== Migrations ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Migrations] are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Control ===&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. Because this 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 [http://lua-api.factorio.com/latest/Data-Lifecycle.html data life cycle] page on the API site provides the best overview.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178427</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178427"/>
		<updated>2020-03-15T09:43:47Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Стадія налаштування */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після ініціалізації settings.lua для всіх модів, виконується ініціалізація &amp;lt;code&amp;gt;settings-updates.lua&amp;lt;/code&amp;gt; і нарешті &amp;lt;code&amp;gt;settings-final-fixes.lua&amp;lt;/code&amp;gt;. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших модів, без потреби покладатися на залежність для останнього. Усі інші файли для завантаження потрібні. Усі файли, запущені тут, не повинні щось містити, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до прототипів або бібліотеки середовища виконання, оскільки це було завантажене на попередньому етапі. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування модів не охоплені в цьому підручнику, див. [[Tutorial:Mod settings]] для отримання додаткової інформації.&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 and entities. 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;
=== Migrations ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Migrations] are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Control ===&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. Because this 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 [http://lua-api.factorio.com/latest/Data-Lifecycle.html data life cycle] page on the API site provides the best overview.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178421</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178421"/>
		<updated>2020-03-15T09:31:57Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* The settings stage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&lt;br /&gt;
&lt;br /&gt;
=== Стадія налаштування ===&lt;br /&gt;
Найперша стадія - це етап налаштувань. В ній визначаються всі параметри модів, які згодом відображаються в інтерфейсі GUI з налаштуваннями ігрового режиму, без інших функцій чи можливостей. Під час запуску цього етапу гра переглядає всі моди для файлів, назви яких були записані в &amp;lt;code&amp;gt;settings.lua&amp;lt;/code&amp;gt;. Після того, як settings.lua був виконаний для всіх модів, виконується &amp;lt;code&amp;gt; settings-updates.lua &amp;lt;/code&amp;gt; кожного мода, і, нарешті, виклик &amp;lt;code&amp;gt; settings-final-fixes.lua &amp;lt;/code&amp;gt; кожного мода. Ці 3 різні фази етапу налаштування дозволяють змінювати налаштування інших мод, не потрібно покладатися на залежність для останнього завантаження. Усі інші файли для завантаження повинні бути потрібні. Усі файли, запущені тут, не повинні містити нічого, крім встановлення визначень та коду для створення визначень параметрів.&lt;br /&gt;
&lt;br /&gt;
Етап налаштувань не має доступу до даних прототипу або часу виконання, оскільки він завантажений перед цими етапами. Очікується, що налаштування матимуть певний формат, а весь додатковий код буде відкинутий після завершення етапу.&lt;br /&gt;
&lt;br /&gt;
Налаштування моди не охоплені в цьому підручнику, див. [[Підручник: Налаштування моди]] для отримання додаткової інформації про них.&lt;br /&gt;
&lt;br /&gt;
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 and entities. 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;
=== Migrations ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Migrations] are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Control ===&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. Because this 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 [http://lua-api.factorio.com/latest/Data-Lifecycle.html data life cycle] page on the API site provides the best overview.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178420</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178420"/>
		<updated>2020-03-15T09:18:51Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Послідовність завантаження */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливають на порядок модифікацій, а натомість запобігають завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&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 and entities. 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;
=== Migrations ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Migrations] are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Control ===&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. Because this 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 [http://lua-api.factorio.com/latest/Data-Lifecycle.html data life cycle] page on the API site provides the best overview.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178418</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178418"/>
		<updated>2020-03-15T09:15:20Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: /* Послідовність завантаження */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&lt;br /&gt;
На етапі завантажування модів, вони завантажуються залежно, потім за алфавітом. Це &#039;&#039;&#039;дуже важливо&#039;&#039;&#039;, щоб зрозуміти, оскільки це може спричинити проблеми, якщо ви нехтуєте цим і намагаєтеся додати модифікацію в інший мод.&lt;br /&gt;
&lt;br /&gt;
Factorio має три види залежності. Існують необхідні та необов&#039;язкові залежності. Третій вид, обмежуючі залежності, не впливає на порядок модифікацій, а натомість запобігає завантаженню гри, якщо знайдеться інший мод. Потрібні залежності завантажуються першими завжди. Гра не ініціалізується, якщо якогось мода немає. Необов&#039;язкові залежності завантажуються спочатку, якщо вони є, але не повинні бути присутніми. Це корисно для включення бонусних функцій, якщо моднифікації використовуються разом. Необхідні залежності повинні використовуватися для бібліотек модифікацій та подібих інфраструктур.&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 and entities. 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;
=== Migrations ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Migrations] are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Control ===&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. Because this 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 [http://lua-api.factorio.com/latest/Data-Lifecycle.html data life cycle] page on the API site provides the best overview.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
	<entry>
		<id>https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178417</id>
		<title>User:Ucrij fender/Tutorial:Modding tutorial/Gangsir/uk</title>
		<link rel="alternate" type="text/html" href="https://wiki.factorio.com/index.php?title=User:Ucrij_fender/Tutorial:Modding_tutorial/Gangsir/uk&amp;diff=178417"/>
		<updated>2020-03-15T08:53:45Z</updated>

		<summary type="html">&lt;p&gt;Ucrij fender: Created page with &amp;quot;{{Languages}} &amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Стаття ще не перекладена повністю.&amp;#039;&amp;#039;&amp;#039; &amp;lt;/pre&amp;gt;...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Languages}}&lt;br /&gt;
&amp;lt;pre style=&amp;quot;background-color:#0F0F0F!important;color:#FF0000;border:1px solid red;&amp;quot;&amp;gt; &#039;&#039;&#039;Стаття ще не перекладена повністю.&#039;&#039;&#039; &amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Languages}}&lt;br /&gt;
Це туторіал по модінгу для Factorio 0.17. В ньому автор пояснить, що твориться за кулісою Factorio, як модифікувати Factorio, де знайти документацію та пояснить поняття.&lt;br /&gt;
&lt;br /&gt;
== Загальні відомості==&lt;br /&gt;
Перед початком, декілька зауважень:&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;
Щоразу, коли код доданий до модифікації, коментар Lua з ім&#039;ям файлу буде на початку зеленої коробки. Скопіюйте код у вікні у файл з такою назвою. Наприклад:&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;
Код виділений фіолетовим кольором, як цей, не має бути включеним до складу модифікації, це просто приклади.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Цей посібник був оновлений до версії 0.17, тому &#039;&#039;в майбутньому, ви повинні відзначити, що деякі незначні зміни можуть бути внесені&#039;&#039;, і варто переглядати журнали змін до поточної версії.&lt;br /&gt;
&lt;br /&gt;
== Термінологія ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж розпочати, слід вияснити кілька термінів та визначень для кращого розуміння.&lt;br /&gt;
&lt;br /&gt;
; Модифікація/Мод/Mod : Сценарій(скрипт) або серія скриптів, що дозволяють змінювати гру через API.&lt;br /&gt;
; Суб&#039;єкт/Сутність/Entity : Суб’єкт у Factorio - це все в грі, яке не є типом, змінною, поняттям, подією чи плиткою. Приклади об&#039;єктів включають символи, складальну машину, кусаку і т.д. Це можуть бути &amp;quot;машини&amp;quot; або об&#039;єкти, що рухаються, як гравець.&lt;br /&gt;
; Персонаж/Character : Фактична сутність, через яку гравець маніпулює світом.&lt;br /&gt;
; Гравець/Player : Усі дані, що визначають гравця, такі як ім&#039;я користувача, положення в таблиці гравців тощо. Усі гравці мають персонажа, але всередині персонажа не має гравців.&lt;br /&gt;
; Прототип/Об&#039;єкт/Prototype : Прототип описує якусь сутність, трохи схожу на шаблон. Він визначає статистику(stats, наприклад здоров&#039;я), що таке сутність насправді і т.д. Прототип використовується для створення сутності, і багато функціонально-однакових сутностей будуть використовувати один і той же прототип.&lt;br /&gt;
; Поверхня/Surface : Поверхня трохи схожа на вимір(dimension, простір, в математичному значенні). Вона складається з місцевості, наприклад трави, піску, води та всіх структур на поверхні. За замовчуванням у Factorio є лише одна поверхня, яку внутрішньо називають &amp;quot;nauvis&amp;quot; або &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;game.surfaces&amp;lt;/code&amp;gt;, але модифікації можуть створювати додаткові поверхні за допомогою API.&lt;br /&gt;
; Подія/Event : Подія - це повторювана ... подія, що викликається грою всередині. Існує кілька подій, які модифікації можуть підключати до функції, такі як &amp;lt;code style=&amp;quot;background-color:#DDA0DD; color:black&amp;quot;&amp;gt;on_entity_died&amp;lt;/code&amp;gt;, тощо. &lt;br /&gt;
&lt;br /&gt;
Докладніше про це в розділі контрольних сценаріїв.&lt;br /&gt;
&lt;br /&gt;
== Перед початком модифікування ==&lt;br /&gt;
&lt;br /&gt;
Перш ніж ми зможемо почати модифікувати Factorio, ми повинні зрозуміти, що таке Factorio. Ви можете прочитати [[Factorio:About/uk|about page]], але саме так зробив би гравець. Оскільки ми намагаємося стати розробником модів, нам потрібно більш детальне пояснення. Factorio - це гра, написана мовою програмування C++, з API, розробленим Wube (розробниками Factorio) для модифікації Factorio на мові програмування Lua(версії 5.2.1). Це API дозволяє додавати скрипти до процесу ініціалізації Factorio, змінювати його без викриття вихідного коду базової гри або зміни пам&#039;яті. Це може відрізнятися від інших ігор, які пропонують модинг, але це більш професійний і правильний спосіб підтримки модінгу.&lt;br /&gt;
&lt;br /&gt;
Щоб допомогти у використанні цього API, розробники люб&#039;язно надали досить вичерпну документацію на своєму [http://lua-api.factorio.com/latest/ API сайті]. Звикайте використовувати цей сайт, оскільки ви будете часто відвідувати цей сайт, коли розробляєте модифікації. Він містить інформацію про [http://lua-api.factorio.com/latest/Classes.html класи], інформацію про [http://lua-api.factorio.com/latest/Concepts.html поняття] та інформацію про [http://lua-api.factorio.com/latest/events.html події], які ви можете підключити. Вам потрібно буде часто перевіряти цей сайт, тому автор рекомендує зробити закладку на ньому. Окрім цього веб-сайту, існує також багато ресурсів, створених спільнотою, наприклад, цей посібник.&lt;br /&gt;
&lt;br /&gt;
=== Налаштування ===&lt;br /&gt;
&lt;br /&gt;
Найкращий спосіб розробити мод - це розробити його там, де його можна легко перевірити. Крім того, рекомендується використовувати редактор, що дозволяє легко вводити текст та підтримувати мову Lua. Emacs, Vim, Sublime Text, VSCode та Notepad++ - рекомендовані кандидати. Цей автор віддає перевагу Emacs, але це не має значення в самому моді.&lt;br /&gt;
&lt;br /&gt;
== Як Factorio завантажує модифікації ==&lt;br /&gt;
&lt;br /&gt;
=== Послідовність завантаження ===&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 and entities. 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;
=== Migrations ===&lt;br /&gt;
&lt;br /&gt;
[http://lua-api.factorio.com/latest/Migrations.html Migrations] are scripts that are used to &amp;quot;fix&amp;quot; a save after a mod updates. Whenever prototypes change within a mod, migrations must be setup to correct 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 making changes to prototypes that effect prototype name, type, recipe, or technology. These things cannot be dynamically changed, and resetting techs or recipes may be necessary. Try to avoid these changes after shipping the mod out to the public. Try to come up with a finalized version of the prototype 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;
=== Control ===&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. Because this 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 [http://lua-api.factorio.com/latest/Data-Lifecycle.html data life cycle] page on the API site provides the best overview.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Runtime ===&lt;br /&gt;
&lt;br /&gt;
At this stage, the mod is setup, and the save is running. Access to all tables provided by the game can be done inside of event handlers. (More on those below.)&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;, or another file &amp;lt;code&amp;gt;require&amp;lt;/code&amp;gt;d by one of these three.&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;
Over time, the community has settled on some conventions for how a mod&#039;s directory structure should look. Following these to a T is not necessary, but can simplify things and make discussing mod bugs and improvements with other developers easier. More on directory structure below.&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, etc&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;
Like this tutorial mentioned earlier, there is a somewhat community standard around for how a mod is laid out. This, combined with [[Tutorial:Mod structure|how the game expects mods to be laid out]], limits us slightly. 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;FireArmor_0.1.0&amp;lt;/code&amp;gt;. 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;
*** FireArmor_0.1.0&lt;br /&gt;
&lt;br /&gt;
Then, inside FireArmor_0.1.0, 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;
*** FireArmor_0.1.0&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 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;FireArmor&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;contact&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;homepage&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
    &amp;quot;factorio_version&amp;quot;: &amp;quot;0.17&amp;quot;,&lt;br /&gt;
    &amp;quot;dependencies&amp;quot;: [&amp;quot;base &amp;gt;= 0.17&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 number. Some mods start at 0.0.1 or 0.1.0, while others follow Factorio versions and start at 0.17.0 (for Factorio version 0.17.x)&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;
| contact&lt;br /&gt;
| Put contact info here, so someone can find you in the event of a problem.&lt;br /&gt;
|-&lt;br /&gt;
| homepage&lt;br /&gt;
| The homepage of your mod, put a website here if you have one for the mod. Not required.&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, 0.17 in this case.&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Any dependencies of your mod. Some form of &amp;quot;base&amp;quot; should always be here, so base gets loaded first.&lt;br /&gt;
|-&lt;br /&gt;
| description&lt;br /&gt;
| A &#039;&#039;short&#039;&#039; description of your mod.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
And that&#039;s all for info.json! Next, in the data.lua file:&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;
require(&amp;quot;prototypes.item&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It&#039;s a pretty simple file, all we&#039;re doing here is just telling the game to execute the file called item.lua in prototypes, which we&#039;re about to create. Create a folder in FireArmor_0.1.0 called &amp;lt;code&amp;gt;prototypes&amp;lt;/code&amp;gt;, then inside prototypes, create a file called &amp;lt;code&amp;gt;item.lua&amp;lt;/code&amp;gt;. Your mod directory should now match [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/cf505cf536e136bccef3d675bf2fc5648c659d97 this github snapshot].&lt;br /&gt;
&lt;br /&gt;
Notice how our earlier require used the folder and file name in it?&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. The long way requires copying an existing definition from one of the default lua files provided with an install of Factorio, and the short way just uses a lua function to copy and modify a definition. For the sake of this tutorial, we&#039;ll do it the short way.&lt;br /&gt;
&lt;br /&gt;
In item.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;
--item.lua&lt;br /&gt;
&lt;br /&gt;
local fireArmor = table.deepcopy(data.raw.armor[&amp;quot;heavy-armor&amp;quot;])&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;
      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;
local recipe = table.deepcopy(data.raw.recipe[&amp;quot;heavy-armor&amp;quot;])&lt;br /&gt;
recipe.enabled = true&lt;br /&gt;
recipe.name = &amp;quot;fire-armor&amp;quot;&lt;br /&gt;
recipe.ingredients = {{&amp;quot;copper-plate&amp;quot;,200},{&amp;quot;steel-plate&amp;quot;,50}}&lt;br /&gt;
recipe.result = &amp;quot;fire-armor&amp;quot;&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 heavy armor, then changed it&#039;s 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 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 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;
At this point, the mod looks like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/2fc7dc944f5d523216762793f7c1bd31c6792b40 this].&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 types, and within those types, individual entities. 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.armor[&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. For example, the player&#039;s prototype would be:&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.player[&amp;quot;player&amp;quot;]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because the player is &#039;&#039;the&#039;&#039; player, his type matches his name. You could define a new type of player with a mod. You can see all the prototype fields for an entity in it&#039;s long declaration in the Factorio install, at (Install)/data/base/prototypes.&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, 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.container[&#039;iron-chest&#039;].max_health = 1000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The reason why this code must be in data-final-fixes.lua or data-updates.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 [http://lua-api.factorio.com/latest/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 periodically create fire on the ground as we walk with the armor on. The event we&#039;re going to use is called on_tick, since we want the fire to be periodically created.&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_tick},&lt;br /&gt;
   function (e)&lt;br /&gt;
      if e.tick % 30 == 0 then --common trick to reduce how often this runs, we don&#039;t want it running every tick, just every 30 ticks, so twice per second&lt;br /&gt;
         for index,player in pairs(game.connected_players) do  --loop through all online players on the server&lt;br /&gt;
            &lt;br /&gt;
            --if they&#039;re wearing our armor&lt;br /&gt;
            if player.character 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;
      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 is wearing, with defines.inventory.character_armor, which is an inventory constant. You can read the list of defines [http://lua-api.factorio.com/latest/defines.html#defines.inventory here].&lt;br /&gt;
&lt;br /&gt;
At this point, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial/tree/26b75c799834b9a8323d500af11b0233b824d002 this].&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 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;config.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 config.cfg, 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;
Finally, the mod will look like [https://github.com/TheRealGangsir/FactorioModdingTutorial this].&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. Additionally, don&#039;t try submitting it 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;
== 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 mods: __FireArmor__/data.lua:1:__FireArmor__/prototypes/item.lua:36: syntax error near &#039;true&#039;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As of version 0.15, 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 mods:&amp;quot;. So, we know that it&#039;s a mod that messed up, and by extension, we know it&#039;s our mod. 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 indirectly caused by line 1 of data.lua. There&#039;s no problem there, so it must be the next entry, line 36 of prototypes/item.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 36 of item.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;
recipe.enabled true&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 = between enabled and true. 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 FireArmor::on_tick (ID 0)&lt;br /&gt;
__FireArmor__/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. [http://lua-api.factorio.com/latest/LuaPlayer A player] is a table of several values. Trying to print it will error, instead a function to print it is needed.&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 FireArmor::on_tick (ID 0)&lt;br /&gt;
Unknown entity name: fire-flam&lt;br /&gt;
stack traceback:&lt;br /&gt;
__FireArmor__/control.lua:6: in function &amp;lt;__FireArmor__/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 6 of control.lua, inside of an on_tick 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:106: Map tick at moment of crash: 432029&lt;br /&gt;
696.148 Error Util.cpp:76: 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;
&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 [http://lua-api.factorio.com/latest/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;
=== Selective requiring ===&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 setting1 then&lt;br /&gt;
   require(&amp;quot;settingOne.lua&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Selective requiring, aka requiring different lua files based on settings or other criteria will also cause desyncs, and in some cases can cause connection rejections as the checksum of the mods will not match, as they load different data. All clients&#039; mods must require the same series of files.&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 [http://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;
== Extended learning ==&lt;br /&gt;
&lt;br /&gt;
One of the best ways to learn how to mod beyond this is to look at other mods. As all mods can be opened and looked at, looking at the mods of experienced modders can help significantly when making your own mod.&lt;br /&gt;
&lt;br /&gt;
=== Keeping your mod working ===&lt;br /&gt;
&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;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Modding]]&lt;br /&gt;
* [[Modding FAQ]]&lt;/div&gt;</summary>
		<author><name>Ucrij fender</name></author>
	</entry>
</feed>