Перейти к основному содержимому

Lua-скрипты: начало работы

На этой странице вы создадите первый Lua-скрипт для пропса FreeMinecraftModels: от пустого файла до работающего интерактивного объекта. Вы познакомитесь с хуками, контекстом, API пропсов и общей структурой скрипта.

Освоив основы, переходите к следующим страницам:

Экспериментальная возможность

Lua-скрипты пропсов пока экспериментальны. Названия хуков, вспомогательные методы и поведение могут меняться по мере развития FreeMinecraftModels. Тщательно проверяйте скрипты перед использованием на рабочем сервере.

Связь с Lua в EliteMobs

FreeMinecraftModels использует среду Lua из MagmaCore. Если вы уже пишете Lua-способности для EliteMobs, основные понятия вам знакомы: файл возвращает таблицу, используются api_version, хуки, context, состояние, перезарядки, планировщик и песочница. Конкретные хуки и имена методов контекста зависят от плагина:

  • Скрипты EliteMobs работают с боссами и используют, например, on_boss_damaged_by_player и on_enter_combat.
  • Скрипты пропсов FMM работают с пропсами и используют, например, on_right_click, on_left_click и on_zone_enter.
  • Зачарования предметов используют отдельный контекст авторских зачарований.

Описанные здесь context.world, context.zones, context.scheduler, context.state и context.log — версии API FreeMinecraftModels/MagmaCore. Скрипты NPC EliteMobs используют те же общие таблицы MagmaCore и дополнительный context.npc; способности боссов EliteMobs используют специализированные версии нескольких таблиц. Эта страница посвящена пропсам FMM.


Что такое скрипты пропсов​

Скрипты пропсов — отдельные файлы .lua в папке plugins/FreeMinecraftModels/scripts/. Они указываются в YAML-конфигурации рядом с файлом модели и запускаются при появлении пропса в мире.

Для чего подходят скрипты пропсов​

С помощью скриптов можно создавать:

  • Интерактивные объекты, реагирующие на клики игрока: двери, рычаги, кнопки
  • Декоративные объекты, игнорирующие стандартный урон от левого клика
  • Триггеры, обнаруживающие вход игрока в область и выход из неё
  • Пропсы, воспроизводящие анимацию при взаимодействии или по таймеру
  • Пропсы, издающие звуки при клике или приближении игрока
  • Другую логику, выходящую за рамки статичного украшения

Для чисто декоративного пропса без взаимодействий скрипт не нужен.


Пользовательские предметы и зачарования​

Пользовательские предметы по-прежнему определяются в YAML-файле рядом с моделью и содержат material, но их эффекты теперь задаются зачарованиями с пространством имён. Старая среда скриптов экипированных предметов выведена из эксплуатации. Предмет с непустым списком scripts: пропускается с информационным сообщением в консоли; его определение остаётся без изменений.

Распознанные устаревшие Lua-скрипты экипированных предметов из scripts/ сохраняются в plugins/MagmaCore/outdated files/FreeMinecraftModels/<archive batch>/scripts/ перед обнаружением скриптов и после импорта. Для архивирования требуется корректное старое определение скрипта с выведенным из эксплуатации хуком предмета, например on_equip или on_attack_entity. Это правило не относит к устаревшим скриптам предметов скрипты пропсов, файлы только с общими хуками, некорректные скрипты и текущие эффекты из enchantments/. О восстановлении см. устаревшие файлы конфигурации.

Актуальные определения описаны в разделе пользовательские предметы и магическое оружие, а эффекты — в разделе авторские зачарования. Списки scripts: у пропсов продолжают работать.

Для кого эта страница​

Эта страница рассчитана на тех, кто:

  • Уже знаком с Lua в EliteMobs и хочет изучить хуки и API FMM
  • Только начинает писать Lua-скрипты и нуждается в полном справочнике с точными именами для пропсов
  • Использует ИИ для подготовки скриптов и хочет распознавать выдуманные возможности

Для полезных скриптов пропсов не обязательно полностью осваивать Lua. В большинстве случаев достаточно уметь:

  • Добавлять допустимый хук в возвращаемую таблицу
  • Читать значения из context
  • Завершать выполнение досрочно через if ... then return end
  • Вызывать нужные вспомогательные методы с точными именами

Краткое введение в Lua​

Большинство скриптов FMM используют лишь несколько понятий: переменные (local x = 5), функции (function foo() end), условия (if x then ... end), таблицы ({key = value}) и nil — отсутствие значения. Точки с запятой не нужны, а блоки завершаются словом end, а не фигурными скобками.

Подробное объяснение с примерами приведено в разделе Движок Lua MagmaCore — краткое введение в Lua. Эти основы общие для всех плагинов Nightbreak.


Расположение файлов​

Файлы скриптов​

Размещайте файлы .lua в общей папке скриптов:

plugins/
FreeMinecraftModels/
scripts/
invulnerable.lua
interactive_door.lua
proximity_sound.lua

При инициализации провайдера FMM рекурсивно обнаруживает файлы .lua в plugins/FreeMinecraftModels/scripts/ и кеширует исходники. Имена должны быть уникальны и между подпапками: привязки используют имя файла, а не относительный путь. После добавления или изменения Lua успешно завершите /fmm reload перед созданием новых привязок. Простое повторное создание пропса не перечитывает Lua.

Для ясности указывайте расширение .lua в списке scripts: модели. FMM также принимает имена без расширения и добавляет его самостоятельно. Файл на диске всё равно должен оканчиваться на .lua; регистр букв в именах имеет значение.

Файлы моделей и конфигурации​

Рядом с каждой моделью в той же папке может находиться конфигурация .yml:

plugins/
FreeMinecraftModels/
models/
torch_01.fmmodel
torch_01.yml <-- script config for torch_01
scripts/
invulnerable.lua <-- referenced by torch_01.yml

Именно файл .yml связывает модель со скриптами.


Формат конфигурации​

YAML-файл рядом с моделью содержит следующие поля:

isEnabled: true
voxelize: false
solidify: false
scripts:
- invulnerable.lua

Поля пропса:

ПолеТипПо умолчаниюОписание
isEnabledлогическое значениеtrueВключено ли определение
scriptsсписок строк[]Имена Lua-файлов пропса из scripts/
voxelizeлогическое значениеfalseПривязка размещения к сетке блоков и поворота к шагу 90 градусов
solidifyлогическое значениеfalseДобавление барьерных блоков через пакеты к вокселизированному пропсу

Каждый указанный скрипт пропса получает собственный экземпляр. Для предметов в руке вместо этого задавайте material, name, lore и enchantments с пространством имён. См. пользовательские предметы.

Создание конфигурации при первом появлении​

Если при появлении пропса соседний .yml отсутствует, FMM автоматически создаёт конфигурацию с isEnabled: true и пустым списком scripts:. Создание асинхронное, поэтому при первом появлении скриптов у пропса не будет. Они заработают после создания файла и добавления имён скриптов.

Порядок действий:

  1. Поместите модель в models/.
  2. Создайте пропс один раз: FMM автоматически создаст .yml.
  3. Добавьте имена скриптов в созданный .yml.
  4. После изменения YAML или Lua успешно выполните /fmm reload, затем разместите новый пропс и проверьте его журнал или взаимодействие. Настройки, проверки размещения и списки скриптов в меню используют общий подготовленный каталог. Повторное создание пропса само по себе не перечитывает YAML.

Справочник хуков​

Каждый Lua-скрипт пропса возвращает таблицу. Все её ключи, кроме api_version и priority, должны быть хуками из списка ниже. Среда выполнения вызывает соответствующую функцию при наступлении игрового события.

ХукКогда вызываетсяПримечание
on_spawnПропс появляется в мире или снова загружается вместе со своим чанкомОдин раз при каждой привязке скрипта
on_game_tickКаждый серверный тик (50 мс при 20 TPS)Только если этот хук определён
on_destroyПропс удаляется окончательноОсвобождение ресурсов. Не вызывается, когда чанк пропса выгружается или FMM перезагружается
on_left_clickИгрок бьёт пропс левым кликомcontext.event содержит флаг отмены стандартного урона FMM
on_right_clickИгрок нажимает на пропс правой кнопкойcontext.event содержит флаг отмены стандартного взаимодействия FMM
on_zone_enterИгрок входит в отслеживаемую зонуНужно настроить наблюдение за зоной
on_zone_leaveИгрок покидает отслеживаемую зонуНужно настроить наблюдение за зоной
on_projectile_hitСнаряд попадает в пропсcontext.projectile — снаряд; context.event.player — стрелок. См. API пропсов

Эффекты предметов​

Прежние хуки экипированных предметов больше не вызываются. Эффекты относятся к авторским зачарованиям, у которых собственные поддерживаемые хуки и контекст. Не подключайте Lua зачарований к списку scripts: пропса и не копируйте старый скрипт предмета без изменений.

Минимальные требования к файлу​

Каждый Lua-скрипт пропса должен возвращать таблицу через return.

Обязательные и необязательные поля верхнего уровня​

ПолеОбязательноТипПримечание
api_versionДаЧислоСейчас должно быть 1
priorityНетЧислоПри наличии проверяется, но FMM пока не сортирует по нему скрипты пропсов. Они выполняются в порядке списка scripts:
поддерживаемые имена хуковНетФункцияИмя должно точно совпадать с одним из имён в справочнике хуков

Правила проверки​

  • Файл обязан возвращать таблицу.
  • api_version обязателен и сейчас должен равняться 1.
  • Если указан priority, он должен быть числом.
  • Каждый дополнительный ключ верхнего уровня должен быть именем поддерживаемого хука.
  • Значением каждого хука должна быть функция.
  • Неизвестные ключи верхнего уровня отклоняются.
примечание

priority помогает переносить скрипты между средами на основе MagmaCore, но в FreeMinecraftModels порядок сейчас задаётся конфигурацией. Расположите скрипты в списке scripts: модели в нужном порядке выполнения.

Вспомогательные функции и локальные константы размещайте перед последним return, а не внутри возвращаемой таблицы.


Первый рабочий скрипт пропса по шагам​

Подготовка конфигурации​

  1. Поместите модель, например my_prop.fmmodel, в plugins/FreeMinecraftModels/models/.
  2. Создайте пропс один раз, чтобы появился конфигурационный файл .yml.
  3. Создайте скрипт plugins/FreeMinecraftModels/scripts/first_test.lua.
  4. Отредактируйте plugins/FreeMinecraftModels/models/my_prop.yml:
isEnabled: true
scripts:
- first_test.lua
  1. Сохраните Lua из шага 1 ниже, выполните /fmm reload и проверьте успешное завершение. При необходимости создайте пропс заново. Повторяйте успешную перезагрузку после каждой правки Lua в следующих шагах.

Шаг 1: загрузите файл​

return {
api_version = 1,

on_spawn = function(context)
end
}

Отсутствие ошибок в консоли — полезная первая проверка. Сообщение из шага 2 позволит убедиться, что:

  • Файл содержит корректный Lua-код
  • FMM обнаружил его в папке scripts/
  • Конфигурация правильно ссылается на него
  • Возвращаемая таблица имеет правильную структуру

Шаг 2: добавьте наблюдаемое действие​

return {
api_version = 1,

on_spawn = function(context)
context.log:info("Prop script loaded for: " .. (context.prop.model_id or "unknown"))
end
}

Посмотрите консоль сервера. Появление сообщения подтверждает вызов хука.

Шаг 3: отреагируйте на клик игрока​

return {
api_version = 1,

on_right_click = function(context)
context.log:info("Prop was right-clicked!")
end
}

Нажмите на пропс правой кнопкой в игре. Сообщение в консоли подтверждает, что хук клика работает.

Шаг 4: отмените урон от левого клика​

return {
api_version = 1,

on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}

Этот приём используется в готовом invulnerable.lua. Он отменяет стандартный урон FMM по пропсу от данного клика. Базовая сущность при этом не становится неуязвимой ко всем источникам урона.

Шаг 5: воспроизведите анимацию по клику​

return {
api_version = 1,

on_right_click = function(context)
context.prop:play_animation("open", true, false)
end
}

Это запрашивает неповторяющуюся анимацию open после текущего тика состояния. Модель должна содержать эту анимацию. blend не выполняет плавного смешивания; в очереди одно место, поэтому последующий запрос может заменить предыдущий. Конечное состояние смерти может отклонить запрос. Проверьте видимый результат в игре: принятие запроса не доказывает воспроизведение.


Что такое context?​

Каждый хук получает аргумент context. Это набор средств, который FMM передаёт при событии для взаимодействия с пропсом, миром, зонами и другими объектами.

Создавать context самостоятельно не нужно: FMM создаёт его и передаёт хуку. Общие API (context.state, context.log, context.cooldowns, context.scheduler, context.world, context.zones) подробно описаны на странице Движок Lua MagmaCore.


Основные API context​

Ниже приведён краткий обзор. Подробности см. в API пропсов.

  • context.prop — сущность пропса, доступная только скриптам пропсов. Предоставляет model_id, current_location, play_animation() и stop_animation().
  • context.player — игрок, вызвавший хук клика по пропсу или общий хук зоны, а в on_projectile_hit — стрелок, если снаряд выпустил игрок. Значение равно nil в хуках жизненного цикла пропса, запланированных вызовах и хуках без игрока.
  • context.event — флаг отмены FMM и игрок для хуков клика, событие попадания снаряда и его стрелок в on_projectile_hit либо таблица только с участником для общих хуков зон. Содержит event.player, is_cancelled, а для кликов и попаданий снарядов также cancel() / uncancel(). Полей Bukkit, таких как target, block, projectile или item, здесь нет. В хуках без события или игрока, например on_spawn и on_game_tick, значение равно nil.
  • context.projectile — сущность снаряда в on_projectile_hit и nil во всех остальных хуках. См. on_projectile_hit.
  • context.state — обычная Lua-таблица, сохраняющаяся на протяжении жизни экземпляра скрипта. См. context.state.
  • context.cooldowns — локальные и глобальные перезарядки. Для обычной перезарядки отдельного скрипта используйте context.cooldowns:check_local("key", ticks). См. context.cooldowns.
  • context.log — запись сообщений в консоль. См. context.log.
  • context.scheduler — отложенные и повторяющиеся задачи. См. context.scheduler.
  • context.world — взаимодействие с миром: частицы, звуки, запросы блоков, молнии и ближайшие сущности. См. context.world.
  • context.zones — создание и отслеживание пространственных зон: сфер, цилиндров и прямоугольных параллелепипедов. См. context.zones.

Синтаксис методов: : и .​

Разница между : и . в Lua объясняется на странице Движок Lua MagmaCore. API FMM принимает обе формы.


Начальные шаблоны для копирования​

Минимальный допустимый скрипт пропса​

return {
api_version = 1,

on_spawn = function(context)
end
}

Шаблон отмены урона от левого клика​

return {
api_version = 1,

on_left_click = function(context)
if context.event then
context.event.cancel()
end
end
}

Шаблон интерактивного пропса​

return {
api_version = 1,

on_spawn = function(context)
context.state.is_active = false
end,

on_right_click = function(context)
context.state.is_active = not context.state.is_active

if context.state.is_active then
context.prop:play_animation("activate", true, true)
else
context.prop:stop_animation()
end
end
}

Расширенная структура файла​

local ANIMATION_NAME = "idle"

local function do_something(context)
context.log:info("Doing something!")
end

return {
api_version = 1,
priority = 0,

on_spawn = function(context)
context.state.task_id = nil
end,

on_right_click = function(context)
do_something(context)
end,

on_destroy = function(context)
if context.state.task_id ~= nil then
context.scheduler:cancel(context.state.task_id)
end
end
}

Первый практический рабочий процесс​

Создавая новый скрипт пропса, действуйте в таком порядке:

  1. Создайте .lua и добейтесь вызова on_spawn.
  2. Добавьте имя скрипта в конфигурацию .yml пропса.
  3. Перейдите к нужному хуку, например on_right_click.
  4. Сначала добавьте сообщение в лог, затем анимации или эффекты.
  5. Добавьте один эффект: анимацию, звук или частицы.
  6. После этого добавляйте вспомогательные функции, состояние, планировщик или зоны.

После каждой правки Lua сохраните файл и успешно завершите /fmm reload, прежде чем проверять новое поведение. Меняйте по одной вещи за шаг, чтобы сообщение или видимый эффект показывали, что сработало.


Готовые скрипты​

FMM записывает четыре готовых Lua-скрипта, если они отсутствуют. Он также заменяет распознанные старые стандартные исходники, сохраняя остальные изменения существующих файлов. Если поведение отличается от текущих стандартных версий, проверьте установленный файл:

  • invulnerable.lua — отменяет стандартный урон FMM от левого клика. Не блокирует все возможные источники урона.
  • pickupable.lua: отменяет стандартный урон от левого клика и запрашивает изъятие после трёх разрешённых ударов. Счётчик принадлежит привязке и общий для игроков; задача через 100 серверных тиков сбрасывает его после предыдущего удара. Разрешённые удары запрашивают красную вспышку. Защищённые места и подземелья блокируются, кроме игроков с правом обхода защиты FMM или статусом оператора.
  • storage_double.lua: запрашивает инвентарь на 54 слота, звуки и анимации открытия и закрытия. Применяет ту же проверку защиты с исключением для оператора и проверяет учёт зрителей каждые 5 серверных тиков. Инвентарь пропса общий для всех зрителей и сохраняется, когда его закрывает последний зритель или когда выгружается чанк. Уничтожение запрашивает drop_inventory(), который сначала сохраняет открытый инвентарь, поэтому предметы, положенные в ещё открытый инвентарь, тоже выпадают. Подробности см. в prop:open_inventory.
  • storage_single.lua — то же, что storage_double, но с 3 рядами (27 слотами) вместо 6.

Другие примеры приведены на странице Примеры и приёмы.


Песочница Lua​

Скрипты пропсов работают в той же изолированной среде LuaJ, что и EliteMobs, с такими же ограничениями. Полный список удалённых глобальных имён и доступных функций стандартной библиотеки приведён на странице Движок Lua MagmaCore.


Следующие шаги​

Если вы также пишете Lua-способности боссов EliteMobs, песочница, api_version, таблица состояния, перезарядки и структура хуков будут знакомы. Однако контекст босса использует методы EliteMobs. Точный API боссов приведён в документации Lua EliteMobs.