Полномочия боя
В сетевом мире ход разрешает сервер, а клиент его рисует.
Эту фразу легко написать и трудно выдержать. Большинство «авторитетных» боевых систем авторитетны насчёт исхода и расплывчаты насчёт всего, что происходит по дороге, — а по дороге как раз и смотрит игрок. Если урон решает сервер, а то, был ли удар суперэффективным, решает клиент, то двое игроков, смотрящих один бой, увидят разные бои.
Поэтому сервер присылает не результат. Он присылает что произошло, факт за фактом, а работа клиента — анимировать ровно это.

Ничто на этом снимке не нарисовано из локального решения. Дикого Caterpie выбрал сервер, его уровень
пришёл вместе с ним, а четыре действия справа — единственные, которые клиенту позволено предложить:
каждое становится запросом, а не исходом. Плашка внизу (32ms · Server: US-East) и полоса каналов
сверху — та же сессия: это одно соединение, а не бой, привинченный к лобби.
Что возвращается с хода
Каждое отправленное действие возвращается одной записью хода. Интересно, какая её часть — это повествование, а не числа:
| Поле | Что клиент с ним делает |
|---|---|
PlayerMoveName, EnemyMoveName | Называет приёмы, которые действительно разрешились |
PlayerDamageDealt, EnemyDamageDealt | Урон, который прошёл |
PlayerHpRemaining, EnemyHpRemaining | Здоровье, которое, по словам сервера, осталось |
PlayerFainted, EnemyFainted | Кто упал |
BattleEnded | Терминальное: победа, поражение, захват или побег |
FleeAttempted, FleeSucceeded, FleeChance, RunAwayAttempts | Вся история побега |
EnemySubstituteMonsterId, EnemySubstituteSpeciesId | Кто вышел, когда упал монстр тренера |
TurnNumber | Счётчик ходов сервера, а не клиента |
Обратите внимание на поля здоровья. Клиент не вычитает урон из того здоровья, которое, как ему кажется, у него было, — он берёт число, названное сервером. Это не одно и то же, и при расхождении выживает только одно из них.
Обратите внимание и на поля замены. Когда монстр тренера падает, сервер говорит, какой монстр вышел, по id и по виду. Более ранняя версия сообщала лишь то, что замена произошла, а «кто-то вышел» — этого недостаточно, чтобы это нарисовать.
Отказ — полноправный ответ
Для самого важного случая существуют три поля:
| Поле | Значение |
|---|---|
Refused | Сервер отказался разрешать этот ход |
RefusalReason | Почему, словами |
RefusalFactor | Конкретное, что он не смог смоделировать |
Сервер, встретивший фактор, которого он не моделирует — эффект, взаимодействие предметов, правило из незнакомой сборки, — отказывает ходу и называет то, что его остановило. Он не разрешает его нейтрально.
В этом весь замысел, и альтернатива хуже, чем кажется. Сервер, который молча разрешает неизвестный фактор как «без эффекта», выдаёт бой, доходящий до конца и неверный так, что этого никто не видит. Игрок смотрит, как приём ничего не делает, и за ключает, что приём плохой. Отказ громкий; догадка тихая, и дорогим провалом оказывается тишина.
Отказ показывается игроку. Он никогда не переводится в «тогда разреши этот бой на клиенте». В тот миг, когда один ход разрешился локально, запись сервера и игра игрока разошлись, и ничто дальше по цепочке не сможет сказать, какая из них настоящая.
Что это даёт
Поскольку ход разрешается на стороне сервера, у целого набора эксплойтов просто нет поверхности:
- Дикие встречи генерирует сервер — вид, уровень, характеристики и редкая окрас ка. Клиент не может перебрасывать, пока результат ему не понравится.
- Захваты проверяются на сервере. Бросок на захват не принадлежит клиенту.
- Разброс урона, критические удары и ступени характеристик — броски сервера.
- PP, «Борьбу» и применение предметов списывает сервер, так что клиент не может потратить то, чего у него нет.
Честная граница
Полномочия сервера ограничены сетевым режимом. Автономный боевой путь ядра не тронут: тот же движок играет одиночную игру точно так же, как раньше, без какого-либо сервера. Эта граница намеренная: сетевой слой — подключаемый модуль, и покупатель, который его никогда не включит, никогда за это не заплатит.
См. также: PvP‑бои — подбор соперников, наблюдение и рейды, и Настройки мира — правила, которые сервер применяет к уровням тренеров.