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

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

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

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

Посетить персонализированный сайт
Показано 1 из 1Все 242 услуг
Разработка сетевого кода для синхронизации игроков
Сложный
от 2 недель до 3 месяцев
Часто задаваемые вопросы

Наши компетенции

Какие этапы разработки игры?

Последние работы

  • image_games_mortal_motors_495_0.webp
    Разработка игры для компании Mortal Motors
    1457
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    Пошаговая стратегия в фэнтези сеттинге With Fire And Sword
    979
  • image_games_second_team_604_0.webp
    Разработка игры для компании Second term
    605
  • image_games_phoenix_ii_606_0.webp
    3D-анимация — тизер для игры phoenix 2.
    674
  • image_training-quizzes_kids_shopping_quiz_614_0.webp
    Обучающая викторина для детей «Покупки в магазине»
    29

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

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

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

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.

Пример реализации client-side prediction на Unity
public class PlayerController : NetworkBehaviour
{
    private Rigidbody rb;
    private InputState currentInput;
    private List<InputState> inputHistory = new List<InputState>();

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        if (!IsOwner) return;
        // Собираем ввод и применяем локально
        currentInput = GatherInput();
        ApplyInput(currentInput);
        inputHistory.Add(currentInput);
        // Отправляем на сервер
        CmdSendInput(currentInput);
    }

    [Command]
    void CmdSendInput(InputState input)
    {
        // Сервер обрабатывает и отправляет авторитетное состояние обратно
        ApplyInputAuthoritative(input);
        TargetReceiveState(GetComponent<NetworkTransform>().Position);
    }

    [TargetRpc]
    void TargetReceiveState(Vector3 serverPosition)
    {
        // Rollback и replay при расхождении
        if (Vector3.Distance(transform.position, serverPosition) > 0.1f)
        {
            transform.position = serverPosition;
            // Replay inputs after correction
        }
    }
}

Как реализовать lag compensation для попаданий

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

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

В Mirror это реализуется вручную через NetworkTime.time и кольцевой буфер снапшотов. В Photon Fusion — частично через встроенный API LagCompensatedHit.

Описание техники lag compensation можно найти в документации Source Engine.

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

Что такое 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 — идеально. Для быстро меняющихся данных (позиция каждый кадр) — избыточно.

Подход Bandwidth Надёжность Сложность реализации
State sync Высокий Высокая Средняя
Event-driven Низкий Средняя Высокая

Что входит в разработку сетевого кода

Разработка сетевого кода под ключ включает несколько этапов:

  1. Анализ игры — определение жанра, количества игроков (от 2 до 64), требований к точности синхронизации и античит.
  2. Проектирование архитектуры — создание network diagram с указанием авторитетности каждого компонента.
  3. Выбор стека — NGO с UGS Relay, Mirror с dedicated server, Photon Fusion, Nakama.
  4. Реализация — написание кода с client-side prediction, lag compensation, state sync.
  5. Тестирование — в NetworkSimulator с задержками 50/100/200 мс и потерями пакетов 1–5%.
  6. Оптимизация — снижение bandwidth на 30%, уменьшение draw calls, настройка LOD.
  7. Документация и обучение — передача кода, описание архитектуры, обучение команды.
  8. Поддержка — сопровождение в production, исправление багов.

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

Начинаем с 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 недели

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

За 5 лет на рынке мы выполнили более 10 проектов с синхронизацией от 2 до 64 игроков, включая мобильные шутеры, PC-экшены и VR-игры. Наши инженеры имеют подтверждённый опыт в Unity и Unreal Engine.

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

Мультиплеер и сетевое взаимодействие

Мы знаем ситуацию: игра уже стабильно работает в одиночном режиме, и вдруг приходит задача — добавить мультиплеер. Именно здесь команды часто недооценивают масштаб работы. Мультиплеер — это не «добавить синхронизацию», а переосмысление игровой логики, выбор сетевой модели и выстраивание серверной инфраструктуры с нуля. Наш опыт разработки сетевого кода для шутеров и стратегий показывает, что правильная архитектура экономит до 40% бюджета на инфраструктуре.

Как выбрать между relay и авторитативным сервером?

Это первое и самое важное архитектурное решение. От него зависит всё: стоимость инфраструктуры, защита от читов, сложность разработки, задержки для игроков. Подробнее о клиент-серверной архитектуре можно прочитать в Wikipedia.

Relay-архитектура (P2P с ретрансляцией)

В relay-схеме клиенты не соединяются напрямую, а обмениваются данными через промежуточный сервер, который просто пересылает пакеты без игровой логики. Такое решение подходит для кооперативных игр с низкой конкуренцией, прототипов и небольших студий без серверной экспертизы.

Инструменты: Photon Relay — быстрый старт, готовые SDK, тарификация по CCU; Unity Gaming Services Relay — встроен в UGS, работает с Lobby и Netcode for GameObjects.

Проблема relay — читерство. Клиент как источник истины может отправлять любые данные. В конкурентных жанрах (шутеры, файтинги, спортивные симуляторы) relay неприемлем.

Авторитативный сервер

Вся игровая логика выполняется на сервере. Клиент отправляет только инпут, а сервер считает физику, коллизии, урон и рассылает результаты. Читер может отправить фиктивный инпут, но сервер его проверит или проигнорирует.

Стек под Unity:

  • Netcode for GameObjects (NGO) — официальное решение для авторитативного мультиплеера. Поверх Unity Transport: NetworkVariable, NetworkObject, RPC-вызовы. Активно развивается.
  • Mirror — форк uNet, зрелый и документированный. Множество транспортов (KCP, Telepathy, WebSockets). Проще в освоении для тех, кто работал с uNet.
  • Nakama — open-source игровой бэкенд с авторитативной логикой на Lua/TypeScript/Go. Подходит, когда нужен матчмейкинг, профили, инвентарь, лидерборды.

Стек под Unreal — встроенная сетевая система на основе авторитативного сервера (Dedicated Server, репликация, RPC). Для большинства жанров хватает нативных инструментов.

Unity documentation: «Netcode for GameObjects is a high-level networking library that simplifies adding multiplayer to Unity projects»

Почему важна компенсация задержки?

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

Проблема

Игрок видит врага и нажимает выстрел. Между моментом нажатия и получением пакета сервером проходит время — RTT/2. Враг мог сместиться. Если сервер проверяет попадание по текущей позиции, игрок чувствует, что «пули не попадают».

Клиентское предсказание (Client-Side Prediction)

Клиент не ждёт подтверждения от сервера — сразу применяет свои действия локально (движение, анимации, звуки). Когда приходит ответ, клиент сверяет состояние. Если не совпадает — делает reconciliation: откатывается к серверному состоянию и «переигрывает» непотверждённые инпуты.

Требуется хранить историю инпутов и уметь быстро пересчитывать состояние. В NGO реализуется вручную через NetworkBehaviour с кастомной логикой. В Mirror есть NetworkTransformReliable с базовым предсказанием.

Пример кода клиентского предсказания на C# ```csharp public class ClientPrediction : NetworkBehaviour { [ClientRpc] void ApplyInput(InputData input) { transform.position += input.direction * speed * Time.deltaTime; } } ```

Серверная перемотка (Server-Side Rewind)

Когда сервер получает команду «выстрел», он берёт временную метку пакета и «перематывает» мировое состояние назад — к моменту, который видел клиент. Проверяет попадание в той «старой» позиции врага. Если попал — засчитывает хит.

Реализация требует:

  • хранить историю состояний всех объектов за последние 200–500 мс;
  • эффективно интерполировать состояния по временной метке;
  • ограничивать глубину перемотки, чтобы не давать преимущество игрокам с высоким пингом.

Без этого механизма игроки с пингом 100+ мс постоянно «промахиваются» по врагам. С ним игра ощущается честной для 95% участников.

Интерполяция vs. экстраполяция на клиенте

Удалённые объекты (враги) клиент не предсказывает — он их интерполирует между двумя последними известными состояниями. Это создаёт визуальное отставание на 1–3 фрейма, но движение плавное. Экстраполяция даёт меньшую задержку, но при изменении направления — резкие «скачки». Большинство шутеров используют интерполяцию.

Серверная инфраструктура

Матчмейкинг и лобби

  • Nakama — матчмейкинг из коробки с кастомными правилами на TypeScript/Go.
  • PlayFab (Microsoft) — бэкенд с инвентарём, облачными сохранениями, аналитикой. Интегрируется с Azure.
  • Unity Gaming Services Lobby — простой для инди-проектов.

Dedicated Servers

Для авторитативного мультиплеера нужны выделенные серверы. Выбор между четырьмя подходами зависит от масштаба и экспертизы. Самостоятельный VPS даёт полный контроль и низкую стоимость при высокой нагрузке, но требует DevOps. Multiplay (Unity) автоматически масштабируется, но дороже и вызывает vendor lock-in. Agones на Kubernetes — гибкий open-source, но сложен. AWS GameLift — зрелая платформа с глобальным размещением, но дорога для малых проектов.

Транспортный протокол

  • UDP — стандарт для real-time игр. Низкая задержка, возможны потери. Большинство библиотек работают поверх UDP с кастомной надёжностью.
  • WebSocket — нужен для WebGL. Работает через TCP, чуть большая задержка, но приемлемо для казуальных жанров. Photon и Mirror поддерживают.
  • KCP — UDP-протокол с элементами надёжности, компромисс между скоростью и надёжностью (используется в Mirror).

Социальные функции

Мультиплеер — это не только технический синхрон. Игрокам нужны инструменты для взаимодействия. Что мы обычно реализуем:

  • Друзья и инвайты — через платформенные API (Steam Friends, Game Center, Google Play Games) или кастомный сервис в Nakama/PlayFab.
  • Голосовой чат — Vivox (стандарт для PC/консолей, интеграция через UGS), Agora (кроссплатформенно, включая мобайл).
  • Текстовый чат — фильтрация контента: PlayFab Chat или кастомный WebSocket-канал с модерацией.
  • Лидерборды — Nakama, PlayFab, GameSparks. Разделяем глобальные и друзей-based.
  • Клановая система — нестандартная функция, для большинства проектов достаточно группировки в Nakama.

Аутентификация

Никогда не изобретайте свою систему авторизации. Используйте готовые провайдеры:

  • PlayFab — анонимный вход, Steam, Google, Apple, кастомный ID.
  • Nakama — аналогично, плюс email/пароль.
  • Firebase Auth — хорошо для мобильных игр, глубокая интеграция с Analytics и Remote Config.

Для конкурентных игр важна защита аккаунтов: двухфакторная аутентификация, детектирование подозрительных входов, быстрая блокировка.

Что входит в разработку мультиплеера

Мы занимаемся геймдевом более 8 лет, реализовали 15+ проектов с мультиплеером, включая шутеры с 64 игроками на сервере. В рамках работы предоставляем:

  1. Архитектурное проектирование (выбор модели, протоколов, инструментов).
  2. Реализация сетевого кода (синхронизация, авторитет, компенсация задержки).
  3. Интеграция бэкенда (аутентификация, матчмейкинг, профили, чат).
  4. Тестирование с имитацией задержек и потерь пакетов.
  5. Документация и обучение команды.

Что мы фиксируем до старта

  1. Жанр и уровень конкуренции — от этого зависит выбор между relay и авторитативным сервером.
  2. Максимальное число игроков в сессии — 2–4 или 64 — принципиально разные задачи.
  3. Целевые платформы — WebGL требует WebSocket, консоли — сертификации.
  4. Ожидаемый пик CCU — влияет на выбор инфраструктуры.
  5. Требования к античиту — нужен ли серверный авторитет или интеграция с EasyAntiCheat/BattlEye.

Свяжитесь с нами для консультации — оценим ваш проект за 2 дня. Закажите разработку мультиплеера под ключ: мы проанализируем игру и предложим оптимальную архитектуру.