Lua Scripting & Event SDK
Программирование на Lua: хуки событий мира, регистрация команд, управление инвентарем, песочница и отладка через /lua.
Lua Scripting & Event SDK
Скриптовый слой Metron позволяет писать геймплейную логику на языке Lua 5.4.
Скрипты загружаются из папок datapacks/*/scripts/*.lua при запуске игры и при каждом нажатии F3+T.
Архитектура и ограничения песочницы
Скриптовый хост построен на базе библиотеки mlua 0.12. Чтобы обеспечить стабильные 20 TPS и безопасность игроков, в движке действуют три правила:
- Безопасная стандартная библиотека:
- Разрешены:
table,string,math,coroutine,print. - Запрещены:
io,os, вызовы системных библиотек.
- Разрешены:
- Бюджет 500 микросекунд на тик (
SCRIPT_BUDGET_US = 500):- Каждый вызов события или команды контролируется счётчиком инструкций.
- Скрипт, превысивший время выполнения, мгновенно прерывается с ошибкой
ScriptError::Timeout, защищая сервер от зависаний.
- Изоляция горячих путей:
- Мешинг, свет и расчёт столкновений выполняются строго на нативном Rust без обращений к скриптам.
Глобальные события (Хуки мира)
Для обработки событий достаточно объявить глобальную функцию с соответствующим именем:
1. on_block_break(x, y, z, block_id)
Срабатывает, когда игрок или игровая механика разрушает блок в мире.
function on_block_break(x, y, z, block_id)
-- block_id: числовой ID сломанного блока (u16)
print(string.format("[Script] Игрок сломал блок %d на (%d, %d, %d)", block_id, x, y, z))
end
2. on_block_place(x, y, z, block_id)
Срабатывает при установке блока игроком.
function on_block_place(x, y, z, block_id)
print(string.format("[Script] Установлен блок %d на (%d, %d, %d)", block_id, x, y, z))
end
3. on_entity_interact(entity_id, action)
Срабатывает при взаимодействии с сущностями. На данный момент активно используется при подборе выпадающих предметов магнитом (action == "use").
function on_entity_interact(entity_id, action)
if action == "use" then
print(string.format("[Script] Поднят предмет от entity #%d", entity_id))
end
end
Регистрация команд чата (commands)
Движок предоставляет глобальный объект commands для регистрации кастомных команд:
commands:register("heal", function(sender, args)
-- sender: имя игрока, вызвавшего команду
-- args: строка аргументов после имени команды
return "Игрок " .. sender .. " успешно исцелен!"
end)
- Команда регистрируется без символа
/. - Если функция возвращает строку, она выводится игроку в чат в качестве ответа.
- Если функция возвращает
nil, ответ не отправляется.
Работа с инвентарем (metron.inventory)
Моды могут читать и изменять содержимое локального инвентаря игрока.
Нумерация слотов:
0 .. 8: Хотбар (активная панель быстрого доступа)9 .. 35: Основной инвентарь (3 ряда по 9 ячеек)36 .. 45: Специальные слоты (крафт, броня)- Всего:
46слотов (TOTAL_PLAYER_SLOTS)
Чтение слота: metron.inventory.get(slot)
Возвращает таблицу { item_id, count, display_name } или nil, если слот пуст.
local slot_0 = metron.inventory.get(0)
if slot_0 then
print(string.format("В первом слоте: предмет #%d в количестве %d шт.", slot_0.item_id, slot_0.count))
else
print("Первый слот пуст!")
end
Запись в слот: metron.inventory.set(slot, item_id, count [, display_name])
Записывает стак предметов в указанный слот:
-- Выдать 64 единицы камня (ID 1) в первый слот
metron.inventory.set(0, 1, 64)
-- Выдать кирку с кастомным NBT-именем во второй слот
metron.inventory.set(1, 200, 1, "Кирка первопроходца")
-- Очистить слот
metron.inventory.set(2, 0, 0)
Внутриигровой отладчик /lua
В одиночной игре вы можете выполнять любой Lua-код прямо из строки чата:
/lua print("Текущий тик жив!")
/lua metron.inventory.set(0, 1, 64)
/lua local s = metron.inventory.get(0); print(s.count)
Результат выполнения и вывод print() сразу отобразятся в консоли разработчика.