Когда сервер считает мир сам, клиент перестаёт быть игрой и становится витриной: он показывает состояние и отправляет команды, но ничего не решает. Звучит просто — до первого списка того, что такой клиент обязан уметь.

Что должен уметь клиент
Раз сервер авторитарный, на клиента ложится вот что:
интерфейс UI с разнообразными меню и кнопочками, джойстиком
клиентскую часть подключения к серверу по протоколу websocket (о котором я писал ранее) для отправки команд и получения ответа во время игры
возможность работать по http протоколу (для первичной регистрации, авторизации и загрузки на клиент графики и желательно асинхронно)
из желательного было так же поддержка тайловых карт из коробки
Начинал с 2D и с прицелом на 3D в будущем. С игровыми движками я до этого не работал, поэтому взял самый распространённый — Unity: подробная документация, в том числе на русском, много обучающих видео, C# для кода и готовый инструментарий для сцен, анимации, карт и камеры.

Порядок оказался обратным
Хотелось бы сказать, что сначала я сделал API и документацию, а потом клиент. На деле было наоборот: я не понимал, чего ждать, десятки раз переделывал и клиент, и сервер — не устраивала то архитектура, то скорость. Так ушло около четырёх месяцев, прежде чем появилась первая рабочая версия API и первые примеры добавления механик через веб-панель.
Схема работала так: создаёшь метод API, описываешь его код на Lua, JavaScript или PHP во встроенном редакторе, делаешь публичным — и вызываешь с клиента. Демонстрационный метод добавлял на карту гоблина.

Заодно понадобился отладчик запросов к API — свой аналог привычных инструментов, но внутри админ-панели. А поскольку Unity собирает игру и под браузер, рядом с запросом стало видно и то, что происходит в самой игре:


Как устроен клиент
Дальше код клиента пришлось приводить в порядок и оформлять плагином. Требования к нему я записал так:
Код должен представлять собой плагин для Unity и содержать функционал приемки и отправки пакетов.
Структура кода игры должна повторять структуру плагина расширяя его классы дополнительным функционалом.
Использовать ООП (объектно‑ориентированный подход) т. к. я уже привык с ним работать в PHP (хотя бы постараться его применять в коде игры).
Для описания запросов к серверу и ответов использовать «структуры» (позже из за проблем с кодированием и декодирования json
structпришлось переделать в обычные классы но их назначение осталось прежним).На каждом «префабе» в Unity (то есть на любом игровом объекте с которым можно взаимодействовать) должен быть «повешен» фаил — класс который принимает от главного контроллера пакетов пакет именно этого префаба и обновляет данные (например изменение позиции, жизней, маны, запуск новой анимации и т. д).
Должны быть из коробки решены проблемы с которыми сталкиваются разработчики при разработке онлайн игры (интерполяция, экстраполяция, поддержка работы с websocket соединением в версии для пк, мобильных устройств и браузеров и связанные с последней проблемы, такие как ввод теста, изменение размера окна, потеря фокуса и т. д.).
Поддержка функционала бесшовного мира сервера и переход между локациями.
В проекте должно быть 2 сцены (сцена авторизации/регистрации и пустая сцена, где на лету меняется карта и префабы на ней).
Readme к папкам и файлам проекта.
Клиентская часть лежит в открытом доступе. Как устроен проект, видно по структуре папок и readme:

Для тех, кому интересна именно связка Unity с серверным API, я разобрал устройство плагина в отдельном плейлисте — хотя при разработке игры залезать в него не требуется.
Что было дальше
Клиент дожил до текущей версии и оброс тем, чего тогда не было: скелетной анимацией существ, экипировкой, панелью умений и переходами между картами открытого мира без загрузочных экранов. Механики по-прежнему описываются на сервере, клиент под них не пересобирается.
Как это выглядит в игре, показываю на канале проекта: youtube.com/@mmogick_ru.
Если вы делали клиент к своему серверу — расскажите, что оказалось самым неприятным: сеть, ввод или сборка под разные платформы.
История:
Выбор технологий, протокола и архитектурный шаблон Entity Component System
Клиентская часть на Unity
FPS, Ping, паузы между командами, интерполяция и экстраполяция
Event-driven паттерн, JSON-RPC и почему не сервисная (SOA) архитектура
Сетевая карта и задержка кадра (Latency frame) по RFC 2544 (1242)
Конвейер контента для MMO: импорт анимации, экипировка и обновление игры без патчей

