Калбеки
От словосочетания вызов + обратно, именно с помощью них мы и будем осуществлять регистрацию обработчиков событий. Как и следует из названия, мы получим вызов, а после сможем отменить дальнейшее действие. Впрочем, не все действия можно отменить, а те которые можно могут быть отменены к ак другим модом, так и движком. Но остановимся на обработке калбеков.
Регистрация обработчика
Для события производится с помощью метода Callback.addCallback:
- JavaScript
- TypeScript
Callback.addCallback("НазваниеСобытия", function(/* его аргументы */) {
// действие которое будет вызвано вследствии события
}, 0 /* приоритет */);
Callback.addCallback("НазваниеСобытия", (/* его аргументы */) => {
// действие которое будет вызвано вследствии события
}, 0 /* приоритет */);
Указание аргументов для события опционально, для всех действий в результате событий приходит одинаковое количество аргументов. Если событие поддерживает отмену действия, вы можете воспользоваться Game.prevent, а также проверить было ли оно уже отменено с помощью Game.isActionPrevented.
Приоритет определяет порядок выполнения событий. Чем он больше, тем раньше других будет вызван ваш обработчик. Не указывайте слишком большие числа, ограничьтесь, скажем, значениями от 0 до 9. Если приоритет не указан, будет использоваться стандартный (0).
В противном случае, новое действие калбека будет дублироваться вместе с каждым вызовом события.
Вы можете провести эксперимент с одним из существующих примеров в Callback, там приведен полный список игровых событий на текущий момент.
Вызов своих событий
Производится с помощью метода Callback.invokeCallback. Общий синтаксис весьма прост:
Callback.invokeCallback("НазваниеСобытия", /* аргументы, которые будут переданы в событие */);
Общее количество аргументов для передачи может быть не более 10. Ни в коем случае не вызывайте игровые события таким образом! Выделите необходимую часть кода в отдельную функцию или собственное событие при необходимости.
Знакомство с миром событий
В качестве простого примера, можно вывести Привет, Мир!
с помощью регистрации обработчика на новое событие и его последующего вызова. Дополним код выше:
- JavaScript
- TypeScript
Callback.addCallback("MyMod:HelloWorld", function(who) {
alert("Привет, " + who + "!");
});
Callback.invokeCallback("MyMod:HelloWorld", "Мир");
Callback.addCallback("MyMod:HelloWorld", who => alert(`Привет, ${who}!`));
Callback.invokeCallback("MyMod:HelloWorld", "Мир");
Замените Мир, скажем, на свое имя.
Гарантии и требования
-
Прежде чем действие в следствии события будет обработано, все события, зарегистрированные на это действие, должны быть завершены.
Это означает, что вы не должны осуществлять большую нагрузку во время события. В противном случае, если хотя бы пару модов будут совершать нагрузку, пользователь начнет различать подвисания и откажется от игры с вашим модом.
Исключениями на этот случай являются открытие интерфейса или операции, которые видит сам пользователь, понимая, что все работает точно так как и планировалось.
-
Все действия, зарегистрированные на событие, выполняются последовательно.
И в порядке добавления событий с помощью Callback.addCallback, включая приоритеты.
-
Ограничтесь одной функцией для одного события.
У вас возникнет необходимость использования нескольких проверок для обнаружения события. Мододелы постоянно не учитывают, что совместно с их модом может быть установлен еще десяток-другой.
Выделите отдельный файл исключительно для событий. Выносите все необходимые условия в одну функцию. Поверьте опыту, это улучшит производительность.
-
Тик и некоторые виды таймеров не асинхронны с игрой.
В первую очередь для обеспечения более стабильной работы, однако это может сыграть с вами злую шутку. Например, размещение большого количества блоков за один тик будет означать их постепенную отрисовку в мире, а не мгновенную установку как можно было ожидать.
В зависимости от мощности устройства, это может привести как к лагам, так и к вылету. Выходом из этой ситуации будет подразделение работы в тике или переход на другие типы событий, конечно, если такое возможно.
Однако, гарантируется, что время в игре и время тика будут практически идентичны в любой момент времени.
-
Делайте более простые проверки перед созданием нагрузки.
Например, в случае взаимодействия с блоком, сначала проверяйте что это именно тот блок который вам нужен из переданных аргументов события, а уже после, обращайтесь к дополнительным методам.
Только от вас зависит производительность игры. Мы, в свою очередь, делаем максимум чтобы направить вас на использование правильных инструментов и, как разработчики, обеспечиваем стабильную работу модифицированного клиента.