--- title: Как работает код X4: от файла до действия summary: Что исполняет игра, зачем нужны XML, MD, AI и Lua и как читать небольшой мод с нуля. section: start kind: guide status: reference updated: 2026-10-26 tags: ["основы","новичку","код","языки","XML","MD","Lua","как работает X4"] sources: ["https://wiki.egosoft.com/X4%20Foundations%20Wiki/Modding%20Support/","https://wiki.egosoft.com/X%20Rebirth%20Wiki/Modding%20support/Mission%20Director%20Guide/"] --- ## Начните с одной мысли Код мода - это инструкции и данные, которые X4 читает в подходящий момент. В моде нет обязательного единственного файла `main`, через который проходят все события. Данные корабля загружаются как ресурсы, MD ждёт условия, AI выполняет поведение, а Lua обрабатывает интерфейс. Движок - исполняемая часть игры: он создаёт объекты, считает движение, хранит мир и выполняет доступные скриптам операции. Полные исходники движка не лежат в папке мода. Автор расширения работает через предоставленные форматы и API. **API** - набор доступных обращений к системе: например, прочитать имя объекта или послать событие. ## Почему здесь несколько языков Разным задачам нужны разные способы описания. Прочность корпуса удобно хранить как число в документе. Реакцию на событие - как обработчик. Кнопку - как элемент окна с функцией нажатия. | Слой | Где обычно находится | Что делает | Пример задачи | | --- | --- | --- | --- | | XML-данные | `assets/`, `libraries/`, `t/` | Описывают свойства и контент | Прочность, товар, перевод | | XML diff | Файл по пути изменяемого ресурса | Меняет выбранную часть документа | Заменить один атрибут | | Mission Director, MD | `md/*.xml` | Реагирует на события и выполняет действия мира | Получить запрос и переименовать объект | | AI-скрипты | `aiscripts/*.xml` | Описывают поведение исполнителя | Движение и выполнение приказа | | Lua UI | `ui/*.lua`, подключение в `ui.xml` | Строит окна и обрабатывает ввод | Кнопка, таблица, выбранная строка | | Нативный код | Движок; у некоторых модов отдельная DLL | Работает с более низким уровнем | Специализированная интеграция | MD и AI используют XML, но у них свои наборы элементов и правила исполнения. Файл с расширением `.xml` ещё не говорит, что именно он делает. Посмотрите на корневой элемент и каталог. Python и C# могут встречаться в инструментах и сложных проектах. Они не становятся от этого встроенными языками MD. Для первого XML-патча достаточно описания расширения и самого патча. ## Что происходит при загрузке расширения Упрощённая схема, полезная для чтения проекта: ```text extensions/имя_мода/content.xml → игра узнаёт расширение и его зависимости → получает ресурсы с учётом расширений и патчей → загружает подходящие скрипты и UI → события и callbacks вызывают обработчики → движок меняет состояние мира ``` Это схема ответственности, а не обещание точного порядка загрузки каждого файла. На результат влияют версия X4, DLC, зависимости, другие моды и состояние сохранения. `content.xml` - паспорт расширения. В нём важны уникальный `id`, версия и зависимости. `ui.xml` перечисляет Lua-файлы для конкретного UI-окружения. Число в `version` манифеста и версия, написанная для человека, имеют разное представление; не переносите произвольную строку `0.1.0` в числовое поле без изучения формата. ## Пример 1: XML хранит свойство Вот **сокращённая иллюстрация**, не полный macro для установки: ```xml ``` Здесь `hull` - элемент, `max` - его атрибут, `1800` - записанное значение. Сам XML не запускает цикл и ничего не вычисляет. Игра знает, как интерпретировать это поле в соответствующем ресурсе. Чтобы изменить поле, используют отдельный diff по тому же пути ресурса: ```xml 3600 ``` Разберём `sel`: | Часть | Как прочитать | | --- | --- | | `/macros/macro` | Найти элемент `macro` внутри `macros` | | `[@name='ship_arg_s_fighter_02_a_macro']` | Оставить macro с указанным именем | | `/properties/hull` | Перейти к свойствам корпуса | | `/@max` | Выбрать атрибут `max` | Это **XPath-селектор**: он выбирает место в XML-документе. Он не является условием MD и не ищет живой корабль в секторе. Изменение ресурса также не заменяет проверку уже существующего корабля в сейве. Полный путь установки и проверка описаны в [первом патче](wiki:editing-parameters). ## Пример 2: MD выполняет действия Внутри `actions` можно встретить такие инструкции: ```xml ``` Читается так: записать `3` в переменную `$Count`; если значение больше нуля, вывести диагностическое сообщение. Фрагмент предполагает, что вы уже находитесь в подходящем MD cue. Это не самостоятельный файл расширения. Важная разница: ```xml ``` Внешние двойные кавычки относятся к XML. Внутри `exact` находится выражение MD. `3` - число; `'Три'` - строка. Одинарные кавычки здесь имеют смысл для языка выражений. Полный MD-скрипт содержит `mdscript`, `cues`, отдельные `cue`, их условия и действия. **Cue** - узел логики со своим состоянием: он может ждать, стать активным и завершиться. Это полезнее представлять как «когда произойдёт событие, выполнить действия», чем как программу, которая непрерывно перечитывает весь файл сверху вниз. В нашем коде встречаются обработчики `instantiate="true" namespace="this"`: повторные события получают экземпляры, а локальные переменные разрешаются в их собственном контексте. Подробности и оговорки - в [cues](wiki:md-cues) и [переменных MD](wiki:md-variables). Общий принцип MD описан в [руководстве Egosoft](https://wiki.egosoft.com/X%20Rebirth%20Wiki/Modding%20support/Mission%20Director%20Guide/); доступность конкретного действия нужно сверять с X4 своей версии. ## Пример 3: Lua вызывается из интерфейса Учебный Lua-фрагмент, не использующий API игры: ```lua local function makeLabel(name) if type(name) ~= "string" or name == "" then return "Без имени" end return "Корабль: " .. name end local label = makeLabel("Север") ``` `local` создаёт локальное имя. `function` объявляет функцию. Аргумент `name` получает входное значение. `return` возвращает результат. `..` соединяет строки. В итоге `label` содержит `Корабль: Север`. Когда функция назначена обработчиком кнопки, её вызывает UI при нажатии. Такой обработчик называют **callback**. Назначить функцию и вызвать её прямо сейчас - разные действия: ```lua local callback = makeLabel -- сохранить саму функцию local result = makeLabel("Север") -- вызвать и сохранить ответ ``` Конкретную кнопку и регистрацию меню создают средствами UI X4. Здесь показан только принцип функций, без вымышленного API кнопок. ## Как связаны окно и мир В игре есть Lua API для чтения данных и некоторые операции движка. MD предоставляет другой набор действий и свойств. Поэтому выбор слоя определяется доступной операцией и её жизненным циклом; не всякий игровой эффект обязательно проходит через MD. Один распространённый путь обмена выглядит так: ```text Lua: AddUITriggeredEvent(screen, control, payload) → MD: event_ui_triggered → данные запроса: event.param3 → действия и чтение результата → MD: raise_lua_event → Lua: RegisterEvent(name, callback) ``` `AddUITriggeredEvent` и `RegisterEvent` - функции среды X4, их нет в обычном интерпретаторе Lua. `set_value` и `raise_lua_event` - элементы MD, их нельзя вызвать как Lua-функции. Готовый парный пример есть в [статье об обмене событиями](wiki:md-lua-bridge). ## Почему после изменения файла результат бывает прежним Проверьте, какой слой вы меняли. Патч мог выбрать другой macro или получить другое итоговое значение из-за совместимости модов. Lua-файл мог не попасть в `ui.xml`. Cue мог уже завершиться и восстановиться таким из сейва. Ссылка на объект могла устареть после загрузки. Сохранение хранит состояние мира и MD, а не просто «запускает все файлы заново». Некоторые изменения требуют новой инициализации или миграции старых данных. Поэтому отдельно проверяются новая игра и загрузка подходящего сейва. Полезно задавать три отдельных вопроса: 1. Файл загрузился без ошибки? 2. Нужный обработчик действительно вызвался? 3. Нужное свойство настоящего объекта изменилось и сохранилось? Сообщение в журнале может подтвердить второй пункт, но само по себе не подтверждает третий. ## Что читать дальше Следующий шаг - [операторы и основные функции с примерами](wiki:x4-language-cheatsheet). Затем выберите [патч параметра](wiki:editing-parameters), [первый MD-скрипт](wiki:first-extension) или [своё окно](wiki:create-ui). Официальная отправная точка для поиска форматов и инструментов - [Modding Support](https://wiki.egosoft.com/X4%20Foundations%20Wiki/Modding%20Support/).