Lua-скрипты: начало работы
На этой странице вы создадите первый Lua-скрипт для пропса FreeMinecraftModels: от пустого файла до работающего интерактивного объекта. Вы познакомитесь с хуками, контекстом, API пропсов и общей структурой скрипта.
Освоив основы, переходите к следующим страницам:
- API пропсов —
context.prop,context.event,context.worldи другие API контекста - Примеры и приёмы: скрипты пропсов с указаниями по настройке для изучения и адаптации
- Устранение неполадок — распространённые ошибки, отладка и список проверок качества
Lua-скрипты пропсов пока экспериментальны. Названия хуков, вспомогательные методы и поведение могут меняться по мере развития FreeMinecraftModels. Тщательно проверяйте скрипты перед использованием на рабочем сервере.
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:. Создание асинхронное, поэтому при первом появлении скриптов у пропса не будет. Они заработают после создания файла и добавления имён скриптов.
Порядок действий:
- Поместите модель в
models/. - Создайте пропс один раз: FMM автоматически создаст
.yml. - Добавьте имена скриптов в созданный
.yml. - После изменения 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, а не внутри возвращаемой таблицы.
Первый рабочий скрипт пропса по шагам
Подготовка конфигурации
- Поместите модель, например
my_prop.fmmodel, вplugins/FreeMinecraftModels/models/. - Создайте пропс один раз, чтобы появился конфигурационный файл
.yml. - Создайте скрипт
plugins/FreeMinecraftModels/scripts/first_test.lua. - Отредактируйте
plugins/FreeMinecraftModels/models/my_prop.yml:
isEnabled: true
scripts:
- first_test.lua
- Сохраните 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
}
Первый практический рабочий процесс
Создавая новый скрипт пропса, действуйте в таком порядке:
- Создайте
.luaи добейтесь вызоваon_spawn. - Добавьте имя скрипта в конфигурацию
.ymlпропса. - Перейдите к нужному хуку, например
on_right_click. - Сначала добавьте сообщение в лог, затем анимации или эффекты.
- Добавьте один эффект: анимацию, звук или частицы.
- После этого добавляйте вспомогательные функции, состояние, планировщик или зоны.
После каждой правки 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.
Следующие шаги
- API пропсов — полный справочник
context.prop,context.event,context.world,context.zonesиcontext.scheduler - Примеры и приёмы: скрипты пропсов с пояснениями и указаниями по настройке
- Устранение неполадок — распространённые проблемы, отладка и список проверок качества
Если вы также пишете Lua-способности боссов EliteMobs, песочница, api_version, таблица состояния, перезарядки и структура хуков будут знакомы. Однако контекст босса использует методы EliteMobs. Точный API боссов приведён в документации Lua EliteMobs.