Модель выполнения
Скрипты в движке не работают как самостоятельные фоновые процессы. Их запуск строго регламентирован механизмом переходов. Понимание того, как и когда срабатывают переходы, критически важно для правильного написания логики, например, при работе с глобальным состоянием игры.
Анатомия перехода
Каждый запуск скрипта является следствием срабатывания перехода. Переход состоит из трех этапов:
- Событие — триггер, который сообщает движку о необходимости проверить условия (например: «Старт игры», «Прошёл код», «Закрылся уровень»).
- Условие — фильтр, определяющий, должен ли переход сработать в данной ситуации (например: «На уровне "Информация"», «Без условий»).
- Действие — операция, выполняемая при совпадении события и условия. Выполнение JavaScript-кода является одним из доступных действий.
Контекст выполнения и команды
Переход всегда выполняется в контексте конкретной команды (или списка команд). Это означает, что при запуске скрипта движок уже знает, к какой команде относится текущее действие.
Идентификатор текущей команды всегда доступен в системной переменной teamId.
Многократное срабатывание переходов
Одной из главных особенностей модели выполнения является обработка массовых событий. Если событие затрагивает несколько команд одновременно, переход выполнится отдельно для каждой команды.
Пример: Вы настроили переход:
- Событие: «Старт»
- Условие: «Без условий»
- Действие: Выполнить скрипт инициализации.
Если в игре участвует 10 команд, при старте игры данное событие наступит для всех участников, и привязанный к нему скрипт будет выполнен 10 раз (по одному разу для каждого teamId).
Безопасная инициализация глобальных переменных
Многократное выполнение скрипта при старте требует осторожности при инициализации глобальных переменных (ctx.game). Если просто присвоить значение глобальной переменной, оно будет перезаписано столько раз, сколько команд участвует в игре.
Чтобы инициализировать глобальное состояние (например, конфигурацию игры) только один раз, необходимо проверять, было ли оно уже создано:
// Проверяем, инициализирован ли уже глобальный объект state.
// Условия !ctx.game.state недостаточно, поскольку в редакторе переходов
// может быть указано начальное значение примитива,
// например, "0" для строки.
if (!(ctx.game.state && ctx.game.state.intitialized)) {
// Этот блок кода выполнится только один раз,
// при срабатывании перехода для первой по списку команды
ctx.game.state = {
intitialized: true,
shots: 6,
maxHP: 1000,
difficulty: "hard"
};
}
// Этот код выполнится для каждой команды
ctx.team.currentHP = ctx.game.state.maxHP;Зависимость контекста от события-триггера
Набор доступных системных переменных внутри скрипта напрямую зависит от того, какое Событие инициировало переход.
- Переменная
teamIdдоступна всегда, так как любое действие привязано к команде. - Переменная
code(содержащая текст введенного значения) будет доступна только в том случае, если скрипт вызван переходом с событием, подразумевающим ввод (например, «Прошёл код», который игрок вбил в мобильном приложении). При событии «Таймаут» переменная code будет отсутствовать.
При проектировании универсальных скриптов, которые могут вызываться разными событиями, необходимо учитывать возможное отсутствие специфичных системных переменных.