Разработка сетевого кода для синхронизации игроков

Наша компания по разработке видеоигр ведет независимые проекты, совместно с клиентом создает игры и оказывает дополнительные операционные услуги. Опыт нашей команды позволяет нам охватить все игровые платформы и разработать потрясающий продукт, соответствующий видению клиента и предпочтениям игроков.

От иммерсивных приложений до игровых миров и 3D-сцен

Наша выделенная команда для VR/AR/MR-разработки, Unity-продакшна и 3D-моделирования и анимации с собственными кейсами и презентациями.

Посетить персонализированный сайт
Показано 1 из 1 услугВсе 242 услуг
Разработка сетевого кода для синхронизации игроков
Сложная
от 2 недель до 3 месяцев
Часто задаваемые вопросы
Наши компетенции
Какие этапы разработки игры?
Последние работы
  • image_games_mortal_motors_495_0.webp
    Разработка игры для компании Mortal Motors
    671
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    Пошаговая стратегия в фэнтези сеттинге With Fire And Sword
    860
  • image_games_second_team_604_0.webp
    Разработка игры для компании Second term
    490
  • image_games_phoenix_ii_606_0.webp
    3D-анимация — тизер для игры phoenix 2.
    533

Разработка сетевого кода для синхронизации игроков

100 мс latency — это не задержка, которую игрок не замечает. В шутере от первого лица за 100 мс противник перемещается на 30–50 сантиметров. Без client-side prediction стрелять в движущуюся цель становится физически некомфортно. Именно поэтому для competitive multiplayer нет варианта «просто синхронизировать позиции через RPC» — нужна полноценная архитектура с предсказанием на клиенте и авторитетным сервером.

Это самая технически сложная часть геймдев-разработки. Ошибки в сетевой архитектуре не исправляются точечными фиксами — они требуют переработки системы.

Почему naive-синхронизация не работает

Простой подход: сервер рассылает позиции всем клиентам. Клиент получает обновление позиции, перемещает объект. При 100 мс RTT объект будет всегда отставать от реального положения на сервере. При движении — видимый lag. При прыжке — «дёрганье».

NetworkTransform с интерполяцией (встроенный в Netcode for GameObjects) — следующий уровень. Клиент не телепортирует объект, а интерполирует между двумя известными позициями. Это убирает визуальное дёрганье, но не решает проблему авторитетности: клиент сам управляет своим персонажем, сервер доверяет клиенту. Это открывает возможности для читерства и не решает lag compensation.

Client-side prediction + server reconciliation — правильное решение для action-игр. Клиент применяет input немедленно локально. Одновременно отправляет input на сервер. Сервер обрабатывает input, возвращает авторитетное состояние. Клиент сравнивает своё предсказанное состояние с серверным и, если есть расхождение, корректирует (rollback + replay). При правильной реализации игрок не замечает никакой задержки — его персонаж реагирует мгновенно.

В Unity NGO (Netcode for GameObjects) это реализуется через NetworkRigidbody с NetworkTransform в Interpolate mode или через кастомный ClientNetworkTransform. В Photon Fusion — встроенный NetworkMecanimAnimator и KCC (Kinematic Character Controller) с prediction out-of-the-box.

Lag compensation для попаданий

Separate хардкорная проблема: игрок стреляет и видит попадание, но на момент выстрела на сервере цель уже в другой позиции. Lag compensation — техника, при которой сервер «перематывает» состояние игровой сцены назад во времени (на величину latency клиента) для проверки попадания.

Реализуется через History Buffer на сервере: каждый тик сохраняем snapshot позиций всех игроков. При обработке shoot-запроса от клиента — восстанавливаем snapshot из прошлого, делаем raycast, возвращаемся к текущему состоянию.

В Mirror это реализуется вручную через NetworkTime.time и кольцевой буфер снапшотов. В Photon Fusion — частично через fusion's built-in lag compensation API (LagCompensatedHit).

Из практики: мобильный тактический шутер, 4 игрока в матче. Первая реализация — simple NetworkTransform + RPC для стрельбы. На устройствах с 80–120 мс latency промахи были очевидны визуально — игрок целится в противника, попаданий нет. После внедрения client-side prediction для движения + lag compensation 150мс на сервере — «честность» попаданий стала приемлемой для casual-аудитории.

Синхронизация состояния игры, не только позиций

State Synchronization выходит далеко за пределы движения персонажей. HP, инвентарь, состояние игровых объектов (двери, ловушки, снаряды) — всё это требует синхронизации. Два основных подхода:

State sync — сервер периодически рассылает полное состояние (или delta) всем клиентам. Надёжно, но дорого по bandwidth при большом количестве объектов.

Event-driven — клиенты рассылают события (игрок открыл дверь), другие клиенты применяют событие локально. Дешевле по bandwidth, но требует идемпотентности событий и обработки потери пакетов.

Для большинства проектов — гибрид: редкие события через reliable RPC, частые обновления (позиции, анимации) через unreliable channel с интерполяцией.

NetworkVariable в NGO — удобная абстракция для синхронизации значений: NetworkVariable<int> Health. Автоматически синхронизируется при изменении, поддерживает OnValueChanged callback. Для HP, score, game state — идеально. Для быстро меняющихся данных (позиция каждый кадр) — избыточно.

Как мы строим сетевой код

Начинаем с network diagram — схема всех игровых систем с указанием, что авторитетно на сервере, что на клиенте, какие данные синхронизируются и с какой частотой. Это основа архитектуры.

Выбор сетевого стека под проект: NGO для Unity с UGS Relay, Mirror + собственный dedicated server, Photon Fusion для competitive action, Nakama для casual с game backend.

Разработка ведётся в NetworkSimulator — тестируем с искусственными задержками 50/100/200 мс и packet loss 1–5%. Проблемы с синхронизацией проявляются только под условиями реальной сети.

Масштаб задачи Ориентировочные сроки
Базовая синхронизация позиций (2–8 игроков) 2–4 недели
Client-side prediction + lag compensation 4–8 недель
Полная сетевая архитектура с game state sync 6–12 недель
Оптимизация существующего сетевого кода 2–4 недели

Стоимость рассчитывается после анализа жанра игры, количества игроков и требований к точности синхронизации.