120 000
Информационные технологии и интернет
Январь 2025
Создать готовый к публикации мобильный мультиплеер в реальном времени, в котором:
- несколько игроков видят одинаковое состояние мира - позицию луча, активные станции, ключи, уровни энергии - независимо от момента входа в комнату;
- соревновательная механика устойчива к гонкам состояний (race conditions): одновременная зарядка от одного луча, кража ключей, одновременное завершение матча;
- раунд завершается синхронно у всех ровно через 10 минут, без расхождения таймеров;
- управление и камера комфортны для сенсорного экрана;
- весь стек укладывается в бесплатные/доступные инфраструктурные лимиты (relay-сервер Photon, без собственного бэкенда).
Основная сложность - не графика, а сетевой детерминизм: в peer-to-peer-модели Photon без выделенного авторитетного сервера нужно гарантировать, что у всех клиентов мир сходится к одному состоянию.
Архитектура построена на авторитетной модели master-client: один клиент-хозяин владеет генерацией событий мира и игровым таймером, остальные получают состояние через реплицируемые вызовы.
Матчмейкинг - автоматический вход в случайную комнату с фолбэком на создание новой (JoinRandomRoom, OnJoinRandomFailed, CreateRoom), лимит 3 игрока, авто-старт раунда при заполнении.
Репликация состояния через буферизированные RPC (RpcTarget.AllBufferedViaServer): создание луча, активация станций, передача ключей, изменение энергии буферизуются на сервере, поэтому поздно подключившийся клиент получает корректное состояние мира, а не пустую сцену.
Распределенная синхронизация времени: хозяин транслирует UTC-метку старта, каждый клиент локально отсчитывает обратный таймер от общей точки - раунд заканчивается одновременно у всех, без накопления дрейфа.
Детерминированная генерация событий: координаты луча и индексы двух активных станций вычисляются хозяином и рассылаются как параметры RPC, гарантируя идентичную геометрию мира на всех устройствах.
Соревновательная механика на синхронизированных счетчиках: общий счетчик игроков у луча (beamPlayers) исключает одновременную зарядку - при конфликте процесс зарядки прерывается; кража ключа реализована через raycast по направлению взгляда с обменом владением ключа и штрафом по заряду.
Кросс-сценовая передача данных: итоги раунда сериализуются через Json.NET в PlayerPrefs и восстанавливаются на экране результатов с сортировкой по очкам.
Мобильный UX: поверх Cinemachine FreeLook реализован собственный слой мультитач-жестов (pinch-zoom камеры с клампингом радиуса орбиты, свайп-орбита), экранные элементы управления автомобилем и динамический мини-радар.
Завершенный сквозной мультиплеерный цикл: матчмейкинг, синхронный раунд, подсчет очков, таблица результатов - без выделенного бэкенда, только на relay-инфраструктуре.
Детерминированное состояние мира у всех клиентов, включая поздно подключившихся, - устранены рассинхрон и пустые late-join-сессии.
Синхронное завершение раунда на всех устройствах независимо от момента входа и расхождения системных часов.
~12 связанных игровых систем (матчмейкинг, репликация, таймер, зарядка, кража ключей, мини-карта, камера, физика, UI, результаты) в компактной поддерживаемой кодовой базе из ~1000 строк прикладного кода.
Оптимизация сетевого трафика: передается не состояние каждого кадра, а только события мира (создание/уничтожение луча, передача ключей, изменения энергии), что минимизирует нагрузку на канал - критично для мобильных сетей.
Адаптация под мобильную платформу: альбомная ориентация, мультитач-камера, экранное управление - игра управляема одной рукой на сенсорном экране.