Реалізація синхронізації стану мобільної гри

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Реалізація синхронізації стану мобільної гри
Складний
~5 днів
Часті запитання

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

Етапи розробки

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

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Реалізація синхронізації стану мобільної гри

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

Snapshot vs State delta vs Event sourcing

Три основних підходи до розповсюджування стану:

Full snapshot: сервер кожні N мс відправляє повний стан світу. Просто, але розтратливо. При 20 сутностях по 50 байт кожна, 20 Hz = 20 КБ/с на клієнта. При 10 клієнтах сервер розсилає 200 КБ/с. Підходить для невеликих ігор.

Delta compression: відправляємо тільки зміни від попередньо підтвердженого снимка. Клієнт підтверджує ack: last_received_tick, сервер обчислює delta. Скорочує трафік у 3-10 раз на динамічних сценах. Реалізація складніша: зберігати історію стану для delta-обчислення, обробляти втрату пакета з delta (без базового снимка delta не застосунку).

Event sourcing: сервер розсилає події (PlayerMoved, BulletFired, EntityDied), клієнт їх відновлює на базовому стані. Добре для детерміністичних ігор: шахи, карти, стратегія. Погано для фізики: будь-яка float-погрішність викликає розходження через 30 секунд.

Детермінізм та Floating Point

Event sourcing критична вимога: обидві платформи (iOS ARM64, Android ARM64/x86) повинні давати однаковий результат одних і тих же обчислень. Стандартний float у C#—детерміністичний на одній платформі, але може різнитися на різних CPU.

Рішення—fixed-point математика: замість float 1.5f використовуємо FixedPoint 15000 (масштаб 1/10000). Додавання та множення цілих чисел детерміністичні скрізь. Бібліотека FixedMath.Net для Unity, libfixmath для нативного C++.

Godot використовує детерміністичну фізику через _physics_process—усі кроки фіксовані. Unity Physics (DOTS) підтримує детермінізм при однаковому порядку обробки об'єктів. Classic PhysX—не детерміністичний між платформами.

Client-side prediction та reconciliation

Деталізована розбивка паттерну для real-time ігор:

Client tick 100: застосуємо вхід локально, надішлемо InputPayload{tick:100, input}
Client tick 101-110: продовжуємо прогнозувати локально
Server: отримує InputPayload{tick:100}, симулює, відповідає StatePayload{tick:100, pos, vel}
Client tick 112: отримуємо відповідь сервера за тик 100
  → Порівнюємо передбачений стан на тик 100 з серверним
  → Якщо відхилення > поріг: відкатуємо до серверного стану на тик 100
  → Повторно застосовуємо буфер входів 101-112

Буфер входів—циклічний масив фіксованого розміру (звичайно 64-128 тиків). Кожен елемент: { tick, inputData, predictedState }. При reconciliation—ітерація по буферу та повторне застосування.

Поріг reconciliation: не нуль. Якщо 0.001 юнита відхилення—постійний відкат → клієнт підергується. Типовий поріг: 0.1-0.5 юнита залежно від швидкості персонажа.

Інтерполяція для інших гравців

Власний персонаж—client prediction. Інші гравці—interpolation:

Клієнт зберігає буфер снимків з міцками часу сервера:

[{time: 1000ms, pos: (10,0,5)}, {time: 1050ms, pos: (10.5,0,5)}, ...]

Рендеринг відбувається з затримкою interpolation_delay (звичайно 2-3 снимки = 100-150 мс при 20 Hz). Знаходимо два найближчих снимки та лінійно інтерполюємо позицію:

float t = (renderTime - fromState.time) / (toState.time - fromState.time);
renderPosition = Vector3.Lerp(fromState.position, toState.position, t);

Ротація—Quaternion.Slerp. Для швидкості—потрібна Hermite interpolation або Catmull-Rom по кількох точках—плавніше при зміні напрямку.

Проблема розходження (desync)

У детерміністичних іграх розходження проявляється не одразу. Стандартна діагностика—state hash comparison: усі клієнти відправляють hash поточного стану на сервер кожні N тиків. Якщо хеші не збігаються—desync, сервер розсилає повний снимок для ресинхронізації.

Hash обчислюється від критичних полів стану (позиції, hp, статусу)—не від всього, щоб не включати несуттєві різниці (анімаційні ваги, UI стан).

Пропускна спроможність та мобільні обмеження

Мобільний інтернет нестабільний. Проектуйте для гіршого сценарію: 150 мс RTT, 5% втрата пакетів, бюджет 50 КБ/с на гравця.

Практичні заходи:

  • Позиції: int16 замість float32 з масштабуванням (50% економія)
  • Ротація: quaternion → два кути int8 (75% економія)
  • Сутності поза viewport: не розсилайте або зменшіть частоту оновлень
  • Priority-based updates: швидкі об'єкти оновлюються частіше

BitPacking бібліотеки: NetStack (C#), LiteNetLib BitWriter—упакуйте кілька малих значень в один байт.

Графік

Snapshot-синхронізація з інтерполяцією для 4-10 гравців: 2-3 тижні. Client prediction, reconciliation, delta compression, desync detection: 1,5-3 місяці. Детерміністична симуляція з fixed-point математикою: додає 3-6 тижнів. Вартість розраховується індивідуально.