Кросс-клиентская мультиплеерная игра в реальном времени для мобильных устройств (Unity 2021.3 LTS, Photon PUN 2). В постапокалиптическом открытом мире на автомобилях соревнуются за луч жизни - источник энергии, который появляется в случайной точке карты: нужно добыть ключ на одной из активных станций, добраться до луча, удержать его и зарядить аккумулятор, попутно отбивая ключи у соперников. Победитель определяется по накопленной энергии либо по истечении 10-минутного раунда. Проект реализует полный игровой цикл от матчмейкинга до экрана результатов с детерминированной синхронизацией мира между всеми клиентами.
Архитектура построена на авторитетной модели 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 строк прикладного кода.
- Оптимизация сетевого трафика: передается не состояние каждого кадра, а только события мира (создание/уничтожение луча, передача ключей, изменения энергии), что минимизирует нагрузку на канал - критично для мобильных сетей.
- Адаптация под мобильную платформу: альбомная ориентация, мультитач-камера, экранное управление - игра управляема одной рукой на сенсорном экране.