Разработка мультиплеера мобильной игры (реального времени)
Real-time мультиплеер в мобильной игре — это не просто WebSocket и отправка координат. Это управление задержкой в 50-200 мс, компенсация пакетных потерь, синхронизация физики и работа с прерывистым 4G-соединением. Мобильный клиент теряет пакеты чаще десктопа: смена WiFi на LTE, тоннели, фоновый режим ОС — всё это ломает наивную реализацию уже на первых тестах.
Архитектура: авторитарный сервер и предсказание на клиенте
Первая ошибка — доверять клиенту. Клиент отправляет «я переместился сюда», сервер применяет без проверки. Через неделю читеры телепортируются по карте.
Правильная архитектура: authoritative server. Клиент отправляет ввод (нажатые кнопки, вектор движения), сервер симулирует физику, рассылает результирующие состояния. Клиент применяет те же вычисления локально — это client-side prediction. Когда приходит ответ сервера, клиент сравнивает: если расхождение выше порога, применяет reconciliation — откат к последнему подтверждённому состоянию и воспроизведение буфера неподтверждённых вводов.
В Unity это реализуется через Netcode for GameObjects или Mirror, но архитектурный паттерн одинаков. Каждый тик игры (обычно 20-60 Hz для мобильных):
- Клиент отправляет
InputPayload { tick, moveDirection, shootPressed } - Сервер применяет ввод, вычисляет
StatePayload { tick, position, health, ... } - Сервер рассылает снэпшот всем клиентам (обычно не каждый тик — delta compression)
- Клиент получает снэпшот, сравнивает с предсказанным состоянием, корректирует
Delta compression критична для мобильного: вместо полного состояния мира (300 байт) рассылать только изменения (10-30 байт). При 20 Hz на 10 игроков разница между полным состоянием и delta — трафик 60 КБ/с vs 6 КБ/с.
Транспортный уровень: UDP vs TCP
TCP гарантирует доставку и порядок пакетов за счёт retransmit при потере. В real-time игре потерянный пакет с позицией игрока за 200 мс назад не нужен — нужна актуальная позиция. TCP будет ждать и переотправлять устаревшие данные, пока новые ждут в очереди. Это добавляет 100-400 мс к видимой задержке на плохих каналах.
UDP — отправил и забыл. Потери обрабатываются на прикладном уровне: позиционные обновления не требуют надёжности (новый пакет перетрёт старый), а важные события (урон, смерть) требуют подтверждения — реализуется простой ACK-схемой поверх UDP.
На мобильных платформах raw UDP доступен через System.Net.Sockets.UdpClient в Unity или NWConnection с .udp параметром на iOS. Android использует DatagramSocket через Java/Kotlin.
Практика: Photon Realtime использует собственный протокол поверх UDP с встроенной надёжной доставкой для критичных сообщений. LiteNetLib — open-source альтернатива с аналогичными возможностями.
Lag compensation и интерполяция
На клиенте объекты других игроков двигаются не напрямую по снэпшотам — это даёт рывки при нестабильном соединении. Interpolation: клиент хранит буфер последних 2-3 снэпшотов и рендерит состояние с задержкой 50-100 мс, интерполируя между ними. Движение становится плавным, цена — искусственная задержка.
Lag compensation на сервере: когда игрок A стреляет в игрока B, сервер "отматывает" состояние мира на RTT/2 назад и проверяет коллизию в том месте, где B был с точки зрения A. Без этого попасть в быстрого противника при высоком пинге физически невозможно.
Особенности мобильной платформы
Фоновый режим iOS (через 5-10 секунд UIApplicationWillResignActiveNotification) разрывает сокет. Нужен BGTaskScheduler для фонового reconnect или graceful disconnect с сохранением сессии на сервере.
Android: WakeLock и WifiLock для удержания соединения во время матча. Без WifiLock.WIFI_MODE_FULL_HIGH_PERF WiFi-модуль переходит в power-saving режим и добавляет 30-80 мс к latency.
Переход с WiFi на мобильный интернет — ConnectivityManager.NetworkCallback на Android, NWPathMonitor на iOS. При смене сети — быстрый reconnect без потери игровой сессии.
Стек и инструменты
| Компонент | Варианты |
|---|---|
| Сетевой фреймворк | Photon Realtime, Mirror, NGO, LiteNetLib |
| Транспорт | UDP, Photon Cloud, WebSocket (fallback) |
| Серверная часть | Photon Server, Nakama, custom Node.js/Go |
| Синхронизация | Snapshot interpolation + client prediction |
| Профилирование | Unity Profiler, Photon Dashboard, Wireshark |
Этапы работы
Аудит требований (жанр, количество игроков, платформы) → выбор фреймворка → прототип с базовой синхронизацией позиций → реализация client prediction и reconciliation → lag compensation на сервере → нагрузочное тестирование → полировка под мобильные ограничения.
Прототип с базовым мультиплеером для 2-4 игроков: 3-4 недели. Полноценная real-time система на 10-20 игроков с lag compensation и мобильной оптимизацией: 2-4 месяца. Стоимость зависит от жанра, количества игроков и требований к серверной инфраструктуре.







