--- title: Операторы и основные функции: XML, MD и Lua summary: Памятка новичку с переводом символов на обычный язык, небольшими примерами и частыми ошибками. section: scripting kind: guide status: reference updated: 2026-10-26 tags: ["основы","новичку","операторы","функции","синтаксис","Lua","MD","XML"] sources: ["https://www.lua.org/manual/5.1/","https://luajit.org/extensions.html","https://wiki.egosoft.com/X%20Rebirth%20Wiki/Modding%20support/Mission%20Director%20Guide/"] --- ## Как пользоваться памяткой Сначала определите язык. Одинаковое намерение записывается по-разному в XPath, MD и Lua. Таблицы ниже - выбранные конструкции, нужные для чтения примеров этой вики и исходников проекта. Это не статистический рейтинг всех файлов X4 и не полный справочник. Если термины пока незнакомы, начните со статьи [как работает код X4](wiki:x4-code-basics). Все новые фрагменты здесь учебные; запуск в игровом мире для них не заявлен. ## Четыре базовых понятия **Переменная** хранит значение: например, число товаров. **Условие** отвечает, выполнять ли действие. **Функция** принимает аргументы и выполняет работу; иногда возвращает результат. **Обработчик события** - функция или узел MD, который вызывается при определённом событии. Различайте объявление, вызов и результат. В Lua `local function getName() ... end` объявляет функцию, `getName()` вызывает её, а `local name = getName()` сохраняет ответ. ## XML: элементы, атрибуты и селекторы | Запись | Значение | | --- | --- | | `` | Элемент с атрибутом; у него нет вложенного содержимого | | ` ... ` | Начало и конец контейнера | | `` | Комментарий XML | | `...` | Заменить выбранный узел или атрибут diff-патчем | | `...` | Добавить содержимое в выбранное место по правилам diff | | `` | Удалить выбранное | | `/properties/hull/@max` | Путь к атрибуту в XPath | | `[@name='имя']` | Фильтр элемента по атрибуту в XPath | Символ `&` внутри атрибута XML записывают как `&`, `<` - как `<`. Это правила XML, ещё до разбора выражения MD. Поэтому в условиях удобно читать `lt`, `le`, `gt`, `ge`. Селектор diff и значение `do_if` имеют разные грамматики. ## MD: небольшое действие за действием | Конструкция | Для чего применяется | | --- | --- | | `set_value` | Создать или изменить значение | | `do_if`, `do_elseif`, `do_else` | Выбрать ветвь действий | | `do_for_each` | Обработать элементы списка | | `append_to_list` | Добавить элемент в список | | `remove_value` | Удалить переменную или запись | | `debug_text` | Вывести диагностику | | `run_actions ref="..."` | Выполнить подходящую библиотеку действий | | `event_ui_triggered` | Условие приёма UI-события | | `raise_lua_event` | Отправить событие в Lua | Это имена элементов MD, а не стандартные функции XML. Их атрибуты и допустимый контекст определяет движок. Например, `run_actions` требует соответствующую library, а `event_ui_triggered` находится в условиях cue. Учебный фрагмент для `actions`, где `$Items` создаётся здесь же: ```xml ``` После цикла `$Count` равен `2`. `operation="add" exact="1"` означает прибавить единицу. Имя `$Item` обозначает текущий элемент; здесь его содержимое не используется. ### Выражения MD | Запись | Как прочитать | | --- | --- | | `$Count` | Значение переменной | | `Init.$States` | Переменная в явно указанном cue | | `$Count == 2`, `$Count != 2` | Равно / не равно | | `lt`, `le`, `gt`, `ge` | Меньше / не больше / больше / не меньше | | `and`, `or`, `not` | И / или / отрицание | | `+`, `-`, `*`, `/`, `%` | Арифметические действия; `%` - остаток | | `'Имя: ' + $Label` | Соединить строки | | `$Value?` | Проверить, разрешается ли переменная или свойство | | `$Object.exists` | Проверить существование игрового объекта | | `typeof $D == datatype.list` | Проверить тип значения | | `$D.{1}`, `$D.count` | Первый элемент списка / количество элементов | | `table[]`, `[]` | Пустая таблица / пустой список | | `if $Ready then 'да' else 'нет'` | Выражение, выбирающее одно значение | MD-списки в показанных примерах начинаются с `1`. `$Value?` не означает «значение истинно»: существующая переменная может содержать `false`. Существование переменной и существование объекта - разные проверки. Контекст переменных особенно важен в экземплярах cue; подробности - в [отдельной статье](wiki:md-variables). ## Lua: чтение обычной функции ```lua local function total(items) if type(items) ~= "table" then return 0 end local result = 0 for _, item in ipairs(items) do result = result + item.amount end return result end local amount = total({{amount = 3}, {amount = 5}}) ``` Это самостоятельный пример языка без функций X4. `amount` получается равным `8`. У каждого элемента предполагается числовое поле `amount`. `{}` создаёт таблицу. В Lua таблицы используются и как списки, и как записи с именованными полями. `item.amount` равно `item["amount"]`. В `for _, item` первая переменная получает индекс; `_` - обычное имя, которым автор показывает «это значение мне не нужно». ### Операторы Lua | Запись | Значение | Пример | | --- | --- | --- | | `=` | Присваивание | `count = 3` | | `==`, `~=` | Равенство / неравенство | `role ~= "host"` | | `<`, `<=`, `>`, `>=` | Сравнения | `count >= 1` | | `and`, `or`, `not` | Логические операции | `ready and loaded` | | `+`, `-`, `*`, `/`, `%` | Арифметика | `count % 2 == 0` | | `..` | Соединение строк | `"Имя: " .. name` | | `#value` | Длина строки или граница последовательности | `#items` | | `object.field` | Доступ к полю таблицы | `state.active` | | `object:method(x)` | Вызов с передачей `object` первым аргументом | Эквивалент `object.method(object, x)` | Не полагайтесь на `#table` как на число произвольных ключей: таблица с пропусками или строковыми ключами не является плотным списком. Длина строки считается в байтах, что важно для UTF-8. В Lua ложными считаются `false` и `nil`; `0` и пустая строка истинны. Выражение `value or fallback` выбирает запасной вариант также при `value == false`. `and`/`or` возвращают выбранное значение, а не обязательно `true` или `false`. Точная основа языка - [Lua 5.1](https://www.lua.org/manual/5.1/); расширения LuaJIT сверяются с [его документацией](https://luajit.org/extensions.html). ### Стандартные функции Lua | Вызов | Назначение и пример | | --- | --- | | `type(value)` | Узнать тип: `type("Север")` даёт `"string"` | | `tostring(value)` | Получить текстовое представление | | `tonumber(text)` | Попробовать прочитать число; ошибка формата даёт `nil` | | `ipairs(list)` | Последовательные числовые элементы с `1`, до первого отсутствующего | | `pairs(table)` | Перебрать ключи и значения без гарантии порядка | | `table.insert(list, value)` | Добавить элемент списка | | `table.remove(list, index)` | Удалить элемент с уплотнением списка | | `table.concat(list, "\|")` | Соединить последовательность подходящих значений разделителем | | `string.format("%s: %d", name, count)` | Собрать строку по шаблону | | `text:match(pattern)` | Найти совпадение с шаблоном Lua | | `text:gsub(pattern, replacement)` | Заменить совпадения | | `math.min(a, b)`, `math.max(a, b)` | Выбрать меньшее / большее | | `pcall(fn, arg)` | Вызвать функцию с перехватом ошибки Lua | | `require("module")` | Загрузить модуль по правилам среды | Не каждый стандартный модуль обязательно доступен в игровом окружении. Например, наличие `debug` или файловых операций нельзя выводить из одного знакомства с обычной Lua. `pcall` возвращает флаг и ответ/ошибку; проглоченная ошибка может скрыть проблему. Неверный нативный вызов не становится безопасным из-за `pcall`. ## Функции X4 и собственные функции мода Последние два имени приведены только для различения происхождения API. Они не доступны в обычном одиночном моде без кода соответствующего проекта. ID объекта нужно получить заранее в нужной форме. Не подставляйте в `GetComponentData` случайное число или имя корабля. Строковый сетевой ID, UI handle и 64-битный `UniverseID` нельзя свободно менять местами: [подробнее о типах ID](wiki:ids-and-precision). ## Пять ошибок, которые легко заметить при чтении 1. В Lua неравенство пишется `~=`, в MD - `!=`. 2. Соединение строк в Lua - `..`, в MD встречается `+`. 3. `=` в Lua присваивает значение; сравнение записывается `==`. 4. Изменение текста собственного окна ещё не означает изменение объекта мира. 5. Объявить обработчик недостаточно: файл должен загрузиться, событие - прийти, вход - пройти проверки. Для практики прочитайте [обмен Lua ↔ MD](wiki:md-lua-bridge) и попробуйте своими словами объяснить каждую строку до установки примера в тестовый профиль.