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

Режим GM

Режим GM — это способ проверить вашу игру на вашем работающем сервере.

Когда сервер становится авторитетным, приёмы, которыми вы пользовались офлайн, перестают работать. Нельзя выдать себе монстра 40-го уровня, отредактировав файл сохранения, потому что файл сохранения больше не место, где живёт истина, — ею стал сервер. Задайте уровень локально, и следующая синхронизация команды его перезапишет, а то и не перезапишет, и вы потратите день на погоню за ошибкой, которая существует только на вашей машине.

В этом вся причина его существования. Отладочный инструмент, который пишет в локальное сохранение, пока авторитет у сервера, — не инструмент, а генератор призрачных ошибок. Поэтому каждое действие GM — это RPC сервера, разрешаемое сервером, сохраняемое сервером и видимое каждому клиенту, который спросит.

Для кого это

Режим GM предназначен для человека, который управляет сервером: вас, во время разработки, и того, кто ведёт вашу игру после запуска. Это не функция для игроков и не меню читов, которое поставляется включённым. См. Защита.

Два способа входа​

Одни и те же восемь RPC доступны из двух мест, потому что они нужны для двух разных задач.

Панель в игреВкладка GM в Hub
ГдеВ запущенной игре, F9Tools → MCE → OpenMon Hub → GM
ДляТестирования во время игрыУправления без запуска игры
ТребуетсяОнлайн-сессия с выполненным входомСобственный вход по почте и паролю

Панель в игре (F9)​

Горячая клавиша устанавливается сама — ничего не нужно перетаскивать в сцену, и это намеренно: инструмент оператора должен работать в любой сцене, включая те, которые вы создаёте после покупки движка, а сцена, настроенная вручную, в следующей сцене забывается.

Исправлено 2026-08-29

Так было не всегда. GmModeHotkey поставлялся как компонент с нулём ссылок — ни префаб, ни сцена, ни ассет не упоминали его, поэтому его никто не создавал, и F9 не мог работать ни в одной игре. Это обнаружили, управляя игрой, а не читая код: нажатие F9 в живой онлайн-сессии под настоящим гейм-мастером вообще не отправляло gamemaster_status на сервер.

Панель GM, открытая поверх работающего мира

Это панель поверх живого онлайн-мира, открытая клавишей F9 под аккаунтом, который сервер распознаёт. Строка внизу — "10 verbos disponibles" — не подпись, написанная клиентом: это собственный ответ сервера на gamemaster_status, поэтому аккаунт без разрешения видит, что панель отказывается открываться, а не открывается пустой.

F9 выбрана по умолчанию, потому что она вне диапазона, который MCE использует для игры: клавиши движения, Z/X и привязки меню не затронуты, так что панель не может перехватить ввод, нужный игре. Привязка находится в GmModeHotkey.cs и представляет собой обычное поле Key, так что её можно изменить.

Панель появляется только для аккаунта, который сервер считает гейм-мастером. Она спрашивает, а не предполагает. При открытии она вызывает gamemaster_status, и ответ касается вызывающего: нет способа спросить «является ли тот аккаунт GM», поэтому этот RPC нельзя использовать, чтобы перечислить, у кого на вашем сервере есть власть.

Вкладка GM в Hub​

Вкладка GM в OpenMon Hub

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

Каждая другая панель Hub, которая обращается к серверу, — в первую очередь засев, — общается от сервера к серверу с помощью http_key рантайма Nakama. У этого ключа нет привязанного пользователя. А все семь действующих глаголов требуют ctx.userId, потому что каждый из них записывает строку с указанием, кто это сделал.

Мы могли бы добавить варианты глаголов с http_key. Мы отказались, и причина укладывается в одно предложение: строка аудита сказала бы «это сделал http_key», и журнал потерял бы подлежащее — единственное, о чём кто-либо когда-либо спрашивает журнал администратора.

http_key — не гейм-мастер

Это два разных учётных данных с двумя разными значениями. Обладание ключом засева позволяет писать в хранилище от сервера к серверу. Оно не делает вас гейм-мастером и никогда не даёт глагол GM. Не путайте их и не помещайте ни тот, ни другой в свой репозиторий.

Вкладка также различает четыре состояния, а не сводит их к одной ошибке. «Вы не вошли», «вы вошли, но не GM», «вы GM, но на этом сервере включён аварийный выключатель» и «готово» отправляют вас в четыре разных места. Единственное «не удалось подключиться» заставило бы вас проверять учётные данные, когда на самом деле нужно разрешение, или засевать право, которое у вас уже есть, когда нужно поговорить с тем, кто управляет сервером.

подсказка

Вкладка не запоминает ваш пароль между сессиями редактора. Хост, порт, ключ сервера и почта сохраняются; пароль — нет.

Восемь глаголов​

Один задаёт вопрос. Семь действуют.

RPCЧто делает
gamemaster_statusЯ гейм-мастер? Включён ли здесь режим GM? Какие глаголы существуют?
gamemaster_mint_monsterСоздаёт монстра заданного вида на сервере с идентификатором, назначенным сервером
gamemaster_set_levelМеняет уровень монстра
gamemaster_set_hpЗадаёт текущее HP — в том числе вплоть до нуля, чтобы добраться до путей потери сознания
gamemaster_heal_partyПолностью восстанавливает команду
gamemaster_force_encounterПринудительно вызывает следующую дикую встречу
gamemaster_set_dexОтмечает вид как увиденный или пойманный
gamemaster_set_variableЗаписывает игровую переменную

gamemaster_mint_monster заслуживает замечания. Он создаёт монстра на сервере, и идентификатор назначает сервер. Нет пути клиента, который мог бы создать монстра: исходящий канал может обновлять семь полей, которые игрок меняет в процессе игры, и это всё, что он может. Если вам нужно, чтобы монстр существовал, это единственная дверь.

Почему это лучше, чем переигрывать контент​

gamemaster_set_level существует потому, что проверка анимации эволюции раньше стоила 126 сражений. Функция, которую он заменил, не была обходным путём вокруг тестирования; это была разница между тестом, который запускают, и тестом, который не запускают.

Защита​

Три независимых условия должны выполняться все сразу, прежде чем глагол выполнится. Любого одного достаточно, чтобы его остановить.

1. Таблица гейм-мастеров. Аккаунт является GM, только если он есть в этой таблице. Таблица начинается пустой, и пустая означает никто — не «все», не «первый аккаунт», не «тот, у кого есть ключ». У свежего сервера вообще нет гейм-мастеров.

2. Аварийный выключатель. Установка переменной окружения MCE_GM_MODE_DISABLED=true отключает все глаголы, не трогая таблицу. Используйте его на продакшен-узле: разрешения остаются ровно как есть, и ничего нельзя вызвать. Повторное отключение восстанавливает то, что у вас уже было, так что вам никогда не придётся восстанавливать таблицу по памяти во время инцидента.

3. Проверка на каждый глагол. requireGameMasterVerb выполняется при каждом вызове, включая gamemaster_status. Отклонённый вызов тоже записывается.

Два журнала аудита — намеренно​

Каждое действие GM записывает две записи, и они существуют для двух разных читателей.

gm_audit — журнал оператора. Он принадлежит системе, называет гейм-мастера, глагол и цель и записывается для каждого вызова, включая те, что были отклонены. Отказ — это ровно то событие, для которого существует журнал администратора.

Вторая запись попадает под собственный аккаунт целевого игрока и читаема этим игроком. Это та половина, которую легко пропустить и которая важна с этической точки зрения: игрок всегда может узнать, что кто-то с властью тронул его данные. Состояние «их тронули и ничего не сказали» — не то, что эта система может представить: видимая игроку строка едет в той же записи хранилища, что и сам эффект, поэтому нет окна, в котором одно дошло, а другое — нет.

Настройка​

  1. Запустите сервер — см. Настройка.
  2. Создайте аккаунт, с которым хотите работать (поиграйте один раз или зарегистрируйтесь).
  3. Выдайте ему права гейм-мастера в таблице game_masters. Клиент этого сделать не может: вызов от сервера к серверу mce_gamemaster_seed принимает { "grant": [userId, ...], "revoke": [userId, ...] } и требует http_key рантайма Nakama, как и другие вызовы засева. Он идемпотентен и никогда не отзывает аккаунт, не указанный в revoke.
  4. Откройте вкладку GM в Hub, войдите и убедитесь, что строка состояния говорит, что вы GM.
  5. В игре нажмите F9.

Если панель не появляется, читать нужно вызов состояния: он говорит, какое из трёх условий вас остановило.

Перед выпуском​

  • Задайте MCE_GM_MODE_DISABLED=true на любом узле, доступном игрокам, если только вы намеренно не хотите живые инструменты GM в продакшене.
  • Держите таблицу гейм-мастеров небольшой и под аудитом. Каждый аккаунт в ней может писать в данные любого игрока.
  • Читайте gm_audit после инцидентов. Он написан именно для этого момента.