Розробка мережевого коду для синхронізації гравців

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

Від імерсивних застосунків до ігрових світів і 3D-сцен

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

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

Наші компетенції

Які етапи розробки гри?

Останні роботи

  • image_games_mortal_motors_495_0.webp
    Розробка гри для компанії Mortal Motors
    683
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    Покрокова стратегія у фентезі сеттингу With Fire And Sword
    862
  • image_games_second_team_604_0.webp
    Розробка ігри для компанії Second term
    491
  • 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 режимі або через кастомний 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 тижні

Вартість розраховується після аналізу жанру гри, кількості гравців та вимог до точності синхронізації.