Зараз я працюю над досить простим багатокористувацьким платформером. Я читав зовсім небагато статей про методики, які використовуються для приховування затримки, але я все ще не можу обернутись певними поняттями. Я вважаю тему дуже цікавою і люблю спробувати ідеї власноруч, але думаю, що запитання gamedev stackexchange буде ефективнішим для мого питання. Я постараюся описати мою поточну ситуацію та питання, яке виникало на цьому шляху.
Зараз я хочу лише синхронізувати одного гравця із сервером. Теоретично я припускав, що гравець сам із передбаченням на стороні клієнта не потребуватиме коректив сервера, оскільки немає зовнішніх факторів, які впливають на його рух. Тому в моєму прототипі наразі є лише один програвач, синхронізований із сервером, без корекції сервера.
Якщо ви знайомі з ігровими мережами, я думаю, що ви можете пропустити розділи контексту, хоча, можливо, я теж щось зробив неправильно.
Клієнтський цикл (один раз на кадр, раз на 16,67 мс)
Спрощений цикл клієнта виглядає так:
Перевірте місцевий вхід (WASD) і запакуйте їх як дії (наприклад
Type=MoveLeft, Time=132.0902, ID=15
). Ми зберігаємо упаковані дії, щоб з часом їх надсилати пізніше. Також ми безпосередньо застосовуємо бажану дію до локального фізичного моделювання гри. Наприклад, якщо ми маємоMoveLeft
дію, ми застосовуємо силу вліво на швидкість гравця.Поставте прапорець, щоб надіслати дії. Щоб запобігти зловживанню пропускною здатністю клієнта, надсилайте лише упаковані дії через певні інтервали (наприклад, 30 мс).
Застосувати модифікації сервера. У певний момент це буде обробляти дельти та виправлення, отримані сервером, і застосовувати їх до локального моделювання гри. Для цього конкретного питання це не використовується.
Оновіть місцеву фізику. Запустіть цикл фізики на головному плеєрі. В основному, це прогнозує рух гравця на стороні клієнта. Це додає гравітації швидкості гравця, застосовує швидкість гравця до його позиції, фіксує зіткнення по дорозі і т. Д. Я повинен зазначити, що фізичне моделювання завжди виконується з фіксованою дельта-секундою (називається багаторазовою залежністю від реальних дельта секунд) .
Я пропускаю декілька конкретних деталей про фізику та інші розділи, тому що я вважаю, що вони не потрібні для цього питання, але не соромтесь повідомити мені, чи вони відповідатимуть цьому питанню.
Цикл сервера (кожні 15 мс)
Спрощений цикл сервера виглядає так:
Обробляйте дії. Перевірте отримані пакети дій від клієнтів та застосуйте їх до моделювання фізики сервера. Наприклад, ми могли б отримати 5
MoveLeft
дій, і ми застосували б силу до швидкості 5 разів . Важливо зауважити, цілий пакет дій виконується на одному "кадрі" , навпаки клієнту, де він застосовується, як тільки дія відбувається.Оновіть логіку гри. Ми оновлюємо фізику гри, переміщення гравців та виправлення зіткнень і т. Д. Ми також пакуємо будь-які важливі події, які траплялися надіслані гравцям (наприклад, здоров'я гравця впало, гравець помер тощо).
Надішліть виправлення. Ми регулярно (наприклад, раз на 35 хвилин) надсилаємо дельти іншим гравцям (наприклад, позиції гравців, стан здоров'я тощо), якщо вони нещодавно змінилися. Ця частина наразі не реалізована, тому що я хочу, щоб моделювання одного гравця дало однакові результати на клієнті та сервері без виправлень, щоб переконатися, що прогноз на стороні клієнта працює добре.
Проблема
Нинішня система працює нормально за простих обставин, і я був щасливо здивований, побачивши, що вона дала дуже схожі результати простими горизонтальними рухами (я вважаю, що неточності пояснюються помилками точності з плаваючою комою):
Будь ласка, ігноруйте графіку прототипу. Білий прямокутник = гравець, червоний прямокутник = перешкоди, синій - фон
Однак, я отримую помилки синхронізації, роблячи рухи, залежні від часу, такі як стрибки та переміщення близько до ізольованої перешкоди:
Теоретично я б очікував, що обидва завжди матимуть однакові результати, оскільки для клієнта немає зовнішніх факторів, які впливають на його позицію. На практиці, однак, я думаю, що я розумію проблему.
Оскільки стрибки навколо такої перешкоди дуже залежать від часу гравця, невеликі зміни того, коли швидкість буде застосована до позиції, матимуть наслідки для результату (наприклад, клієнт міг би відійти просто вчасно, щоб уникнути зіткнення з перешкода, в той час як сервер зробив би це так, як пізніше отримає весь пакет дій і залишиться на заваді на невелику кількість часу, змінивши кінцевий результат). Різниця між тим, як клієнт і сервер обробляє це, головним чином полягає в тому, що клієнт виконує всі свої дії по мірі того, як вони трапляються, в той час як сервер виконує їх усі, коли він їх отримує.
Питання
Цей довгий контекст, нарешті, призводить до мого запитання (дякую за те, що ви прочитали цього часу): чи нормально вимагати корекцій сервера навіть тоді, коли синхронізований із сервером лише один гравець, чи я повинен використовувати певні прийоми, щоб уникнути десинхронізації у ситуаціях, що залежать від часу. ?
Я продумав певні можливі рішення, з якими мені менш комфортно:
Запровадити корекцію сервера. Просто припустимо, що це нормальна поведінка і виправляйте помилки в міру їх виникнення. Я хотів це все-таки реалізувати, але я просто хотів переконатися, що те, що я зробив до цього часу, є прийнятним.
Використовуйте наданий клієнтом час, щоб застосувати бажані дії. Я думаю, це було б схоже на компенсацію відставання, вимагаючи "повернутися у часі" та перевірити на рух. Начебто ви хочете застосувати корективи сервера, поверніться у часі і повторіть наступні дії після цього. Мені дуже не подобається ідея. Це виглядає складно, дорого в ресурсах і вимагає довіритися заданому часу клієнта (хоча я дійсно планую перевірити, чи час виглядає відносно законним).
Попросіть GameDevelopment StackExchange для нової чудової ідеї, яка виправить усі мої проблеми.
Я тільки починаю в світі ігрових мереж, тому, будь ласка, не соромтесь виправляти / критикувати / ображати будь-яку з вищезгаданих концепцій або давати ідеї / ресурси, які могли б допомогти мені на шляху мого подорожі до Чудового світу мереж. Вибачте, якщо я міг би знайти свою відповідь деінде, я не зазнав цього.
Дуже дякую за дорогоцінний час.