Розробка сетевого кода для синхронізації гравців
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 режимі або через кастомний ClientNetworkTransform. У Photon Fusion — вбудований NetworkMecanimAnimator та KCC (Kinematic Character Controller) з prediction out-of-the-box.
Lag Compensation для попадань
Окремо хардкор проблема: гравець стріляє та бачить попадання, але на момент выстріла на сервері ціль вже в іншій позиції. 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 тижні |
Вартість розраховується після аналізу жанру гри, кількості гравців та вимог до точності синхронізації.





