Що надіслати на сервер FPS-гру в режимі реального часу?


23

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

З підходом до надсилання входів: Що робити, якщо плеєр утримує клавіші напрямку? Це означає, що мені потрібно надсилати пакет на сервер у кожному кадрі. Хіба це не надто багато? А також є обертання гравця від введення миші. Ось приклад:

http://www.gabrielgambetta.com/fpm_live.html

Як щодо відправлення позиції у фіксованому інтервальному підході. Він надсилає занадто мало повідомлень на сервер. Але це також знижує чуйність.

То який спосіб краще?

Відповіді:


19

Проста відповідь: обманюйте чи не будьте точні!

Якщо ви грали в якийсь шутер в Інтернеті, ви, швидше за все, пережили так звану "гумку", якщо ваш зв’язок із сервером поганий.

Це викликано тим, що ваш клієнт час від часу коректує вашу позицію.

В основному, що відбувається з двох сторін:

  • Сервер буде відслідковувати ваш рух та надсилати оновлення клієнтам, як очікувалося. Вони не завжди повинні бути повними оновленнями. Кожен х кадрів може бути повним оновленням, а всі інші кадри ви надсилаєте лише нові вектори швидкості (якщо є якісь зміни).

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

Але як обробляється вхід? Ваш клієнт відправить вашу позицію на сервер "Я переїхав туди". Сервер перевірить це оновлення (наприклад, чи маєте ви змогу так швидко переміщатися туди?), І якщо воно дійсно перемістить вас (або відхилить ваше оновлення, що призведе до "гумової смуги").

Так, так, ваш підхід з фіксованим інтервалом, швидше за все, спрацює і вистачить.

Але навіть якщо ви хочете надсилати введення та рухи рухом з обох сторін, майте на увазі, що вам не доведеться надсилати "кнопку все одно натискають". Натомість надсилайте одну подію при натисканні кнопки та іншу після відпускання кнопки.


5
Так, я можу відстежувати натискання та звільнення кнопки. А як щодо введення миші? Він постійно змінюється.
syloc

6
"Натомість, надішліть одну подію, коли кнопку натиснуто, та іншу, коли кнопку відпущено." - Правда, але потрібно перевірити, що подія "у звільненні" зрештою вимушена, залежно від правил гри. Наприклад, у мультиплеєрі Rainbow Six Vegas 2 гравець може почати стріляти зі свого пістолета, і (на жаль, поширена помилка) викликає повідомлення про "зупинку стрільби", яке не вдалося досягти сервера. Це призводить до того, що звук вогнепального вогнища залишається у нескінченному циклі до кінця матчу. Лише один приклад, з яким слід насторожитися. youtu.be/GOQIbLCy7m8?t=9m10s
Майк Бакстер

@syloc: Просто обробіть його на стороні клієнта і дозвольте серверу визначити, чи є рух дійсним / можливим (щоб запобігти тому, як хакери в телепортах тощо).
Маріо

@syloc Просто встановіть інтервал для миші, але для збереження додаткової пропускної здатності все-таки зробіть перевірку на стороні клієнта, щоб побачити, чи змінилася вона. Якщо є певний проміжок часу, коли миша не рухається, вам не потрібно продовжувати надсилати повідомлення про це.
agweber

На одному з моїх робочих місць у нас був інженер, який практично зводив з розуму, оптимізуючи поведінку пружини для пропущених оновлень позиції для комутації (13 років тому). Зараз я бачу ігри з великою пропускною здатністю та смішно низькою затримкою, що страждають від цього випуску, здається, ця проблема ніколи не піде назад, або що людей цим дбають набагато менше.
Андон М. Коулман

5

Якщо ви ще цього не зробили, пропоную прочитати ці дві глибокі, але зрозумілі статті: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking та http://fabiensanglard.net/quake3/network.php .

Вони пояснюють, чому рекомендується використовувати "фіксований інтервал" надсилання пакетів. Коротше кажучи, це насправді важливо для пакетів, що надсилаються сервером.

Відправлення пакету має фіксовану вартість, а максимальний розмір мережевого пакету - близько 1,5 Кб. Отже, якщо у вас на сервері є, наприклад, 16 гравців, кожен кадр, коли ви обчислюєте рух для гравця, наївний код може надсилати пакет оновлень кожному гравцеві після кожного дозволу руху, тому 16 * 16 = 256 пакетів. Якщо у вас частота кадрів 30, це 7680 пакетів.

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

Тепер ви надсилаєте лише 480 пакетів за секунди для однакових результатів.

У випадку "гравець-сервер" це означає, що ви повинні надсилати в одному пакеті максимум даних, наприклад; виглядала позиція, дії називали цей кадр тощо.

Щодо другої частини вашого запитання - я вибрав спосіб зменшити відставання, щоб передати цю інформацію серверу на кожен кадр:

  • фактична поточна позиція гравця (використовується сервером для перевірки того, чи є позиції на стороні сервера та стороні гравця не надто синхронізовані).

  • Орієнтовна позиція гравця за 1 секунду: обчислюється клієнтом: якщо гравець не змінить напрям миші і не залишить клавіатуру в поточному стані протягом 1 секунди, де буде гравець? (нас не хвилює зіткнення) Якщо гравець не рухається, то його орієнтовна позиція за 1 секунду - це його поточне положення.

  • Позиція, на яку він дивиться.

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

Гравці ніколи точно не синхронізовані, але відповідь на вхід миттєва (для мене найважливіше), і я знайшов прогнозовані позиції для мене досить точними.


"Гравці ніколи не бувають абсолютно синхронізованими". Я думаю, що також важливо згадати, що рівень точності тут залежить від фактичної гри (гри). Наприклад, класичному MMO, де ви просто натискаєте та вибираєте об'єкти, не знадобиться ідеальна точність для майже всього, але для шутера необхідна ідеальна синхронізація.
Маріо

Справа в тому, що ніхто з розумом не використовує TCP для FPS. Вони швидше матимуть справу зі складним перенастроченням та пропущеними дейтаграмами, ніж зазнають накладних витрат TCP.
Андон М. Коулман
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.