Lua-скриптинг: Устранение неполадок
Эта страница охватывает распространённые проблемы, с которыми вы можете столкнуться при написании или отладке Lua-способностей, а также советы по миграции для авторов, переходящих с EliteScript. Если вы отлаживаете NPC-скрипты, см. NPC-скрипты. Для рабочих примеров см. Примеры и паттерны. Если вы только начинаете, см. Начало работы.
EliteMobs использует движок Lua-скриптинга MagmaCore, общий для плагинов Nightbreak. Документацию по общим концепциям, таким как песочница, планировщик, зоны, API мира, таблицы сущностей и методы UI игрока, см. на странице Движок Lua-скриптинга MagmaCore.
Распространённые проблемы
1. Способность вообще не загружается
Проверьте серверную консоль на наличие ошибок при запуске сервера. Самая частая причина — синтаксическая ошибка Lua (отсутствие end, несовпадающие скобки и т.д.). Также убедитесь, что файл заканчивается на .lua и находится в правильном каталоге powers.
2. Хук никогда не срабатывает
Убедитесь, что имя хука написано точно так, как указано в списке хуков. Частые ошибки: on_boss_hit (неправильно) vs. on_boss_damaged_by_player (правильно), или on_tick (неправильно) vs. on_game_tick (правильно).
3. context.player равен nil
Не все хуки предоставляют игрока. on_spawn, on_game_tick и on_exit_combat не имеют игрока. on_enter_combat предоставляет context.player (игрока, который начал бой). В on_boss_damaged (общий урон) наносящий урон может не быть игроком. Всегда добавляйте проверку на nil перед использованием context.player.
4. Таймаут / превышен бюджет выполнения
Если хук или колбэк выполняется слишком долго, способность автоматически отключается, чтобы предотвратить лаги. Сообщение в консоли выглядит так:
[Lua] my_power.lua took 73ms in 'on_game_tick' (limit: 50ms) — script disabled to prevent lag.
Частые причины: перебор слишком большого числа сущностей, создание слишком большого числа зон за тик или выполнение затратных строковых операций в on_game_tick. Перенесите затратную работу за барьер перезарядки или уменьшите объём работы, выполняемой за один вызов.
5. Колбэк планировщика использует устаревшие данные
Вы, вероятно, используете внешний context вместо параметра колбэка. Измените function() ... context.boss ... end на function(tick_context) ... tick_context.boss ... end.
6. Запрос зоны не возвращает сущности
Дважды проверьте определение зоны. Для нативных зон убедитесь, что kind указан в нижнем регистре ("sphere", а не "SPHERE"). Для скриптовых утилит убедитесь, что shape указан в верхнем регистре ("CONE", а не "cone"). Также проверьте, что origin или Target действительно разрешаются в допустимую локацию.
7. Частицы не появляются
Убедитесь, что имя частицы — допустимое значение перечисления Particle Bukkit в UPPER_CASE. Частая ошибка: "flame" (неправильно) vs. "FLAME" (правильно). Также проверьте, что amount равен хотя бы 1, а локация находится в загруженном чанке.
8. Перезарядка, похоже, не работает
Убедитесь, что вы используете check_local(key, duration) (который проверяет И устанавливает за один вызов), а не local_ready(key) с последующим отдельным set_local(duration, key). Если вы используете только local_ready, вы лишь проверяете, но никогда не устанавливаете перезарядку.
9. Босс продолжает выполнять способность после смерти
Добавьте логику очистки в on_exit_combat и/или on_death для отмены задач планировщика. Если босс умирает, on_exit_combat должен сработать, но добавление явной очистки в оба хука безопаснее.
Чтение сообщений об ошибках
Когда что-то идёт не так в Lua-способности, консоль выводит дружественный блок ошибки с префиксом [Lua]. Эти сообщения сообщают вам точно, какой файл, какая строка, какой хук и что именно пошло не так — простым языком. Всегда читайте полное сообщение перед отладкой.
Типичная ошибка выглядит так:
[Lua] Error in 'push_zone.lua' at line 35 during 'on_boss_damaged_by_player':
[Lua] -> You tried to call a method or function that doesn't exist.
[Lua] -> Check the method name for typos, or make sure you're using ':' (colon) for method calls, not '.' (dot).
[Lua] -> Script has been disabled for this entity to prevent further errors.
Система переводит распространённые ошибки Lua на простой язык. Вот самые частые из них:
| Сырая ошибка Lua | Что говорит консоль |
|---|---|
attempt to call nil | Вы попытались вызвать несуществующий метод или функцию. Проверьте имя метода на опечатки или убедитесь, что используете : (двоеточие) для вызовов методов, а не . (точку). |
index expected, got nil | Вы попытались обратиться к полю чего-то, что равно nil. Проверьте, что более ранний код инициализировал это. |
attempt to index | Вы попытались обратиться к свойству nil или недопустимого значения. |
bad argument | Показывает конкретные детали несоответствия аргумента (ожидаемый тип vs. фактический тип). |
| Timeout | <filename> выполнялся Xмс в 'hook_name' (лимит: 50мс) — скрипт отключён для предотвращения лагов. |
Когда вы видите ошибку [Lua] в консоли, сообщение об ошибке точно сообщает вам, какой файл, какая строка, какой хук и что пошло не так простым языком. Прочитайте полное сообщение, прежде чем погружаться в код — обычно оно указывает прямо на решение.
Не предполагайте существование недокументированных псевдонимов
Lua API предоставляет определённый набор имён методов. Если вы пишете способности вручную или с помощью ИИ, не предполагайте, что существуют сокращённые или альтернативные имена. Следующие имена приведены как примеры тех, что не существуют и вызовут ошибки:
show_temporary_boss_bar()— используйтеplayer:show_boss_bar(title, color, style, duration).run_command_as_player()— используйтеplayer:run_command(command).em.location(...)— неправильное имя метода. Используйтеem.create_location(x, y, z), либоcontext.boss:get_location()/context.player.current_location.em.vector(...)— неправильное имя метода. Используйтеem.create_vector(x, y, z)или простые таблицы{x=0, y=1, z=0}.em.zone.sphere(...)— неправильное имя метода. Используйтеem.zone.create_sphere_zone(radius)или таблицу определения зоны вроде{kind = "sphere", radius = 5, origin = location}.entity:teleport_to(...)— используйтеentity:teleport_to_location(location).entity:set_velocity(...)— используйтеentity:set_velocity_vector(vector).entity:set_facing(...)— используйтеentity:face_direction_or_location(direction_or_location).
Если сомневаетесь, проверьте страницы Справочника API (Босс и сущности, Мир и окружение, Зоны и нацеливание). Если что-то не задокументировано там, оно не существует.
Советы по миграции для авторов EliteScript
Если вы уже пишете хорошие EliteScripts, самый простой способ изучить Lua-способности:
-
Продолжайте думать в терминах событий, целей, зон, относительных векторов и частиц. Концепции те же — меняется только синтаксис. События EliteScript становятся именами хуков вроде
on_spawnилиon_boss_damaged_by_player. Цели и зоны передаются как таблицы вcontext.scriptс использованием тех же имён полей, что задокументированы на страницах Зоны EliteScript и Цели EliteScript. -
Перенесите поток управления в Lua. Случайные броски, общие вспомогательные функции, циклы, постоянное состояние (
context.state) и планирование задач (context.scheduler) — это то, что Lua добавляет и что чистый EliteScript не может легко сделать. Начните с преобразования одной ветвящейся или условной способности в Lua, сохраняя всё остальное без изменений. -
Используйте
context.scriptдля нацеливания и геометрии зон. Скриптовые утилиты принимают те же имена полей, что и EliteScript (targetType,shape,Target,Target2,range,offset,coverage), поэтому вы можете продолжать использовать существующую документацию EliteScript как справочник для этих спецификаций. Это позволяет использовать знакомые паттерны, получая при этом гибкость Lua для логического слоя.
Путь обучения для начинающих
Если вы хотите изучить эту систему с нуля, хорошо работает такая последовательность:
- Напишите файл только с
api_version = 1иon_spawn. - Заставьте босса отправить сообщение или воспроизвести звук.
- Добавьте перезарядку с
context.cooldowns. - Добавьте один хук, вызываемый игроком, например
on_boss_damaged_by_player. - Добавьте одно отложенное действие с
context.scheduler:run_after(...). - Добавьте один простой запрос нативной Lua-зоны или один простой
context.script:target(...). - Только потом переходите к вращающимся атакам, конечным автоматам и многоэтапным механикам.
Каждый шаг строится на предыдущем, и вы можете тестировать на каждом этапе. Не пытайтесь написать многофазного босса в качестве своей первой Lua-способности.
Следующие шаги
- Начало работы — структура файлов, хуки, пошаговый разбор первой способности, шаблоны для копирования
- NPC-скрипты — скрипты близости, взаимодействия и жизненного цикла NPC
- Примеры и паттерны — полностью рабочие способности для изучения и адаптации
