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

Lua-скриптинг: Устранение неполадок

На этой странице рассмотрены типичные проблемы, с которыми вы можете столкнуться при написании или отладке скриптов пропов FreeMinecraftModels, а также советы по работе с системой отложённой генерации конфигурации. Рабочие примеры можно найти на странице Примеры и шаблоны. Если вы только начинаете, ознакомьтесь с разделом Начало работы.


Типичные проблемы

1. Файл конфигурации не загружается / Скрипт не привязан

Симптом: Проп появляется, но не реагирует на клики или какие-либо хуки.

Причины и решения:

  • Файл конфигурации .yml ещё не существует. FMM генерирует конфигурацию отложенно при первом спавне пропа. При первом появлении модели FMM создаёт конфигурацию .yml асинхронно со значениями по умолчанию (включено, без скриптов). Вам нужно отредактировать сгенерированную конфигурацию, чтобы добавить имена файлов скриптов, а затем заново заспавнить проп.

  • В конфигурации указано isEnabled: false. Откройте файл .yml рядом с файлом модели и установите isEnabled: true.

  • Список scripts: пуст. Добавьте имена файлов ваших скриптов:

    isEnabled: true
    scripts:
    - my_script.lua
  • Имя файла .yml не совпадает с именем файла модели. Конфигурация должна иметь то же базовое имя, что и файл модели. Например, для torch_01.fmmodel нужен torch_01.yml в том же каталоге.


2. Файл скрипта не найден

Симптом: Консоль показывает: [FMM Scripts] Script 'my_script.lua' not found in scripts/ folder

Причины и решения:

  • Неправильный каталог. Файлы скриптов должны находиться в plugins/FreeMinecraftModels/scripts/, а не рядом с файлом модели.

  • Несоответствие имени файла. Имя в конфигурации .yml должно точно совпадать с именем файла в папке scripts/, включая регистр и расширение .lua.

  • Файл отсутствует. Убедитесь, что файл .lua действительно существует в папке scripts/.


3. Скрипт вообще не загружается

Симптом: Ошибок в консоли нет, но хуки не срабатывают.

Проверьте серверную консоль на наличие синтаксических ошибок Lua при запуске. Наиболее частые причины:

  • Отсутствует end для закрытия функции или блока if
  • Несовпадающие скобки
  • Отсутствует запятая между определениями хуков в возвращаемой таблице
  • Файл не заканчивается на .lua

Если есть ошибка Lua, консоль выведет блок ошибки [Lua] с именем файла, номером строки и описанием.


4. Хук никогда не срабатывает

Симптом: Скрипт загружен (вы видите сообщение [FMM Scripts] Bound script), но конкретный хук не срабатывает.

Убедитесь, что имя хука написано точно так, как указано в справочнике хуков. Частые ошибки:

Неправильное имяПравильное имя
on_clickon_right_click или on_left_click
on_interacton_right_click
on_hiton_left_click
on_tickon_game_tick
on_removeon_destroy
on_arrow_hiton_projectile_hit

Также убедитесь, что у пропа действительно есть связанная сущность armor stand. Некоторые конфигурации пропов могут не создавать кликабельную сущность.


5. Тайм-аут / Превышен бюджет выполнения

Симптом: Консоль показывает сообщение вида:

[Lua] my_script.lua took 73ms in 'on_game_tick' (limit: 50ms) -- script disabled to prevent lag.

Скрипт выполнял слишком много работы за один вызов хука. Типичные причины:

  • Перебор слишком большого числа сущностей в on_game_tick
  • Создание слишком большого числа частиц за тик
  • Выполнение ресурсоёмких циклов без распределения работы по тикам

Решение: Перенесите тяжёлую работу за откат на основе состояния или используйте scheduler:run_repeating() с разумным интервалом вместо on_game_tick.


6. context.event равен nil в хуке клика

Это обычно не должно происходить для on_left_click и on_right_click, но всегда используйте проверку:

if context.event then
context.event.cancel()
end

Внутри callback-ов планировщика context.event всегда равен nil -- это ожидаемое поведение. Модификация событий возможна только внутри самого хука события.


7. Анимация не воспроизводится

Симптом: play_animation() возвращает false, или ничего видимого не происходит.

Причины и решения:

  • Неправильное имя анимации. Имя должно точно совпадать с тем, что определено в файле модели. Проверьте имя анимации в файле .bbmodel или .fmmodel.

  • У модели нет анимаций. Не все модели имеют анимации. Убедитесь, что файл модели действительно содержит данные анимации.

  • Игроки не в зоне действия ресурспака. Анимация выполняется на сервере, но игрокам нужно иметь загруженный ресурспак FMM, чтобы видеть модель.


8. Частицы не появляются

  • Убедитесь, что имя частицы является допустимым значением enum Particle Bukkit в ВЕРХНЕМ_РЕГИСТРЕ: "FLAME", а не "flame".
  • Убедитесь, что местоположение находится в загруженном чанке. Если поблизости нет игроков, чанк может быть выгружен.
  • Убедитесь, что count равен как минимум 1.
  • Некоторые частицы (такие как DUST) требуют определённых дополнительных данных, которые базовый spawn_particle() может не поддерживать. Используйте стандартные частицы, такие как FLAME, HEART, HAPPY_VILLAGER, NOTE, ENCHANT и т.д.

9. Звук не воспроизводится

  • Убедитесь, что имя звука является допустимой константой enum Sound Bukkit в ВЕРХНЕМ_РЕГИСТРЕ. Пример: "BLOCK_NOTE_BLOCK_HARP", а не "block.note_block.harp".
  • Убедитесь, что координаты местоположения правильные (не все нули или NaN).
  • Убедитесь, что громкость больше 0.

10. Состояние сбрасывается неожиданно

context.state существует для каждого экземпляра пропа и сохраняется на протяжении его жизни. Если состояние кажется сброшенным:

  • Проп мог быть удалён и заспавнен заново (каждый спавн создаёт новый экземпляр).
  • Вы можете читать состояние в callback-е планировщика, используя неправильную переменную контекста. Всегда используйте собственный параметр контекста callback-а.

Как работает отложённая генерация конфигурации

Понимание системы отложённой конфигурации поможет избежать путаницы при настройке новых пропов:

  1. Первый спавн: Когда проп появляется и рядом нет файла .yml, FMM создаёт конфигурацию асинхронно. Это означает, что файл записывается в фоновом потоке и не доступен сразу.

  2. Значения по умолчанию: Сгенерированная конфигурация содержит isEnabled: true и пустой список scripts: [].

  3. Нет скриптов при первом спавне: Поскольку конфигурация создаётся после того, как проп уже появился (и не имеет перечисленных скриптов), при первом спавне у пропа не будет привязанных скриптов.

  4. Редактирование и повторный спавн: После того как FMM создаст конфигурацию, вы редактируете её, чтобы добавить имена файлов скриптов. При следующем спавне пропа скрипты будут загружены.

  5. Расположение конфигурации: Файл .yml создаётся в том же каталоге, что и файл модели, с тем же базовым именем. Например:

    • Модель: plugins/FreeMinecraftModels/models/fountain.fmmodel
    • Конфигурация: plugins/FreeMinecraftModels/models/fountain.yml
Быстрый рабочий процесс настройки
  1. Поместите модель в models/
  2. Поместите скрипт в scripts/
  3. Заспавните проп один раз (генерируется .yml)
  4. Отредактируйте .yml, добавив scripts: [my_script.lua]
  5. Заспавните проп повторно -- скрипт теперь активен

Чтение сообщений об ошибках

Когда что-то идёт не так в Lua-скрипте пропа, консоль выводит блок ошибки [Lua]. Эти сообщения сообщают вам точно, какой файл, какая строка, какой хук и что пошло не так на понятном языке.

Типичная ошибка выглядит так:

[Lua] Error in 'my_door.lua' at line 12 during 'on_right_click':
[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Вы попытались вызвать метод или функцию, которая не существует. Проверьте на опечатки и использование : vs. ..
index expected, got nilВы попытались обратиться к полю объекта, который равен nil. Проверьте, что предыдущий код его инициализировал.
attempt to indexВы попытались обратиться к свойству nil или невалидного значения.
bad argumentФункция получила неверный тип аргумента. Сообщение показывает ожидаемый и фактический тип.
TimeoutВаш скрипт занял Xмс в 'hook_name' (лимит: 50мс) -- скрипт отключён для предотвращения лагов.
подсказка

Всегда читайте полное сообщение об ошибке [Lua] перед тем, как погружаться в код. Обычно оно указывает прямо на решение.


Не предполагайте существование недокументированных методов

Lua API FMM предоставляет определённый набор методов. Не предполагайте, что существуют сокращённые или альтернативные имена. Распространённые ошибки:

  • context.prop:get_location() -- не существует. Используйте context.prop.current_location (поле, а не метод).
  • context.prop:set_animation("open") -- не существует. Используйте context.prop:play_animation("open", true, true).
  • context.event:setCancelled(true) -- не существует. Используйте context.event.cancel().
  • context.cooldowns:check_local(...) -- не существует в FMM. Используйте context.state с scheduler:run_later() для кулдаунов.
  • context.player -- не существует в скриптах пропов FMM. Используйте context.world:get_nearby_players() для поиска игроков рядом с пропом.
  • context.boss -- не существует. Это относится к EliteMobs. Используйте context.prop в FMM.

При сомнениях обратитесь к странице API пропов. Если это не задокументировано там, значит, этого не существует.


Советы по отладке

1. Активно используйте context.log:info()

Добавляйте логирующие сообщения на каждом шаге при отладке:

on_right_click = function(context)
context.log:info("Right click received!")
context.log:info("Event present: " .. tostring(context.event ~= nil))
context.log:info("State is_open: " .. tostring(context.state.is_open))
end

2. Проверяйте консоль при запуске

FMM записывает [FMM Scripts] Bound script 'X' to prop 'Y' для каждой успешной привязки. Если вы не видите это сообщение, конфигурация или скрипт не были загружены.

3. Проверьте путь к файлу модели

Конфигурация .yml должна быть файлом-соседом файла модели (тот же каталог, то же базовое имя). Проверьте это:

  • Путь к файлу модели: plugins/FreeMinecraftModels/models/my_model.fmmodel
  • Путь к файлу конфигурации: plugins/FreeMinecraftModels/models/my_model.yml

4. Тестируйте хуки по отдельности

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

5. Проверяйте опечатки в именах хуков

Самая распространённая причина, по которой хук не срабатывает -- это неправильно написанное имя хука. Скрипт загрузится без ошибок, но функция хука с опечаткой будет отклонена при валидации.


Путь обучения для начинающих

Если вы хотите изучить эту систему с нуля, следующая последовательность хорошо работает:

  1. Напишите файл с только api_version = 1 и on_spawn, который логирует сообщение.
  2. Добавьте скрипт в конфигурацию пропа и убедитесь, что сообщение появляется в логе.
  3. Добавьте on_right_click и логируйте, когда по пропу кликают.
  4. Добавьте on_left_click с context.event.cancel() для неуязвимости.
  5. Воспроизведите анимацию по правому клику.
  6. Добавьте звук по правому клику.
  7. Добавьте состояние и поведение переключения.
  8. Добавьте наблюдение за зоной для обнаружения приближения.
  9. Только после этого переходите к сложным скриптам с несколькими хуками и планировщиками.

Каждый шаг основывается на предыдущем, и вы можете тестировать на каждом этапе.


Дальнейшие шаги

  • Начало работы -- структура файлов, хуки, пошаговое руководство по первому скрипту, шаблоны для копирования
  • API пропов -- полный справочник API
  • Примеры и шаблоны -- полные рабочие скрипты для изучения и адаптации