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 | Низкий | Средняя | Высокая |
Что входит в разработку сетевого кода
Разработка сетевого кода под ключ включает несколько этапов:
- Анализ игры — определение жанра, количества игроков (от 2 до 64), требований к точности синхронизации и античит.
- Проектирование архитектуры — создание network diagram с указанием авторитетности каждого компонента.
- Выбор стека — NGO с UGS Relay, Mirror с dedicated server, Photon Fusion, Nakama.
- Реализация — написание кода с client-side prediction, lag compensation, state sync.
- Тестирование — в NetworkSimulator с задержками 50/100/200 мс и потерями пакетов 1–5%.
- Оптимизация — снижение bandwidth на 30%, уменьшение draw calls, настройка LOD.
- Документация и обучение — передача кода, описание архитектуры, обучение команды.
- Поддержка — сопровождение в 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.
Получите консультацию по выбору архитектуры синхронизации для вашей игры — мы подготовим детальный план и оценку работ. Закажите аудит существующего сетевого кода, чтобы выявить узкие места до релиза.






