Запустити фізичне моделювання як на клієнті, так і на сервері?


13

Я впроваджую багатокористувацький клон астероїдів, щоб дізнатися про архітектуру мережі клієнт / сервер в іграх. Я витратив час на читання публікацій GafferOnGames та Valve на своїх клієнтських / серверних технологіях. У мене проблеми з двома поняттями.

  1. В даний час у мене є авторитетний ігровий сервер, який імітує фізику з box2d і розсилає клієнтам стан світу приблизно 20 разів на секунду. Кожен клієнт відслідковує останні декілька отриманих знімків та перескакує між двома станами, щоб згладити рух спрайтів. Однак це не так гладко. Він може бути певним на деякий час, потім трохи смикатися, потім повернутися до гладкого і т. Д. Я спробував і TCP, і UDP, обидва приблизно однакові. Будь-яка ідея, яка моя проблема може бути? (Примітка: я реалізував це спочатку для одного гравця, а спрайт-рух ідеально плавний при 60 кадрів в секунду, коли оновлено світ фізики лише 20 разів за секунду).

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

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

Спасибі!

Відповіді:


10

Однозначно запустити моделювання як на клієнтах, так і на сервері. У будь-якому іншому є занадто довга затримка. Ви повинні бути впевнені, що симуляції відповідають, вставляючи об'єкти в одному порядку, використовуючи фіксований крок часу та уникаючи порівняння вказівників. Я не пробував цього з Box2D, але, як правило, можна досягти однакової поведінки на всіх машинах у фізичному моделюванні. Вся математика, як правило, заснована на IEEE 754 бінарних32 поплавців, і їх поведінка суворо визначена для таких операцій, як+-*/ назвати декілька. Ви повинні бути обережними sin,cosі вподобання жорсткі, оскільки вони можуть відрізнятися між часом виконання (це особливо важливо при розробці для декількох платформ). Також переконайтеся, що ви використовуєте суворий параметр для плаваючих оптимізацій у вашому компіляторі. Ви все ще можете синхронізувати об'єкти, періодично надсилаючи стан об'єктів із сервера. Не оновлюйте, якщо різниця не перевищує поріг, щоб уникнути зайвого заїкання.

Одне з питань, що спадає на думку - це створення нових об'єктів і як це змінить моделювання між клієнтами. Один із способів виправити це - дозволити серверу створювати всі об’єкти. Якщо поточний крок часу t, сервер планує об'єкт, який потрібно додати t+d. Таким чином, список нових об’єктів, з об'єктами, які потрібно додати та коли їх додати, можна підтримувати на всіх клієнтах та оновлювати їх сервером заздалегідь. Якщо dвона досить велика, ви мінімізуєте ризик різних результатів. Якщо ви справді не можете впоратися з різницею, ви можете змусити клієнта чекати інформації про нові об’єкти протягом певного часу, перш ніж моделювати цей крок часу.


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

Ерін Катто вважає, що намагатися синхронізувати весь стан декількох світів Box2D - це програючий бій ( box2d.org/forum/viewtopic.php?f=3&t=8462 )
Павло,

Заява "IEEE 754 binary32 floats [..] поведінка суворо визначена для таких операцій, як +-*/" є повністю помилковим. Усі ці операції в IEEE-754 можуть залежати від реалізації. Дивіться тут і тут для отримання додаткової інформації.
BlueRaja - Danny Pflughoeft

1
Ні. Це абсолютно правда. Проблема, яку описує ваше посилання, пов’язана з різними режимами x87 fpu та реалізацією трансценденталів. IEEE 754 binary32 є строго визначеним для основних операцій. Ви самі вирішите встановити правильні режими та скористатись правильними інструкціями, щоб дотримуватись стандарту. Просто використання інструкцій SSE, а не x87 fpu дуже допомагає.
rasmus

4

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

У GameDev є стара стаття про використання кубічних сплайнів для прогнозування положення об'єкта повз точку, де ви востаннє мали дані про нього. Потім ви використовуєте цю позицію, а потім коригуєте сплайн, коли отримуєте нові дані для врахування його нового положення. Це, ймовірно, набагато дешевше, ніж виконання другого фізичного моделювання, і це означає, що вам не доведеться вирішувати, кому ви довіряєте, оскільки ви явно реалізували клієнта, складаючи його в процесі роботи. :)


Це може бути так. Що я намагаюся зробити - це затримка, поки я не отримаю 3 знімки з сервера. У моменті я лерп від пострілу 1 до пострілу 2. Потім від пострілу 2 до пострілу 3. Якщо в будь-який момент я пропускаю пакет, я можу лерпувати від 1 до 3, замість 1 до 2, якщо це має сенс. Я, мабуть, не реалізую це правильно, хоча Дякуємо за посилання на статтю!
Venesectrix

1

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

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


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

1

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

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

Що стосується питання 1, я скажу, що проблемою були коливання затримки, оскільки немає абсолютної гарантії того, що між кожним отриманням знімка буде абсолютно ідеальний інтервал 20 секунд. Дозвольте проілюструвати (будучи "t" часом, виміряним в мілісекундах):

1) На t = 20 з початку гри клієнт отримав знімок і зробив інтерполяцію успішно і плавно.

2) При t = 40 спостерігалася затримка між сервером і клієнтом, і знімок трапився фактично лише при t = 41.

3) При t = 60 сервер надіслав ще один знімок, але одна секунда моделювання була витрачена даремно клієнтом через затримку. Якщо знімок доходить до t = 60, клієнт не буде робити інтерполяцію з 40 і 60 екземплярів, а фактично з інстанцій 41 до 60, породжуючи іншу поведінку. Ця неточність може бути причиною можливої ​​"ривки".

Що стосується питання 2, то ваша ідея може спрацювати, якщо ви реалізуєте щось, що ефективно відстежує, чи справді кожен об'єкт синхронізований клієнт-сервер, без необхідності надсилати пакетам кожен кадр, інформуючи про позицію об'єктів. Навіть якщо ви робите це з дискретні проміжки часу, ви не тільки будете працювати над тією ж проблемою питання 1, але і матимете занадто великі кількості даних, які можна перенести навколо (що погано).


Я не впевнений, що я дотримуюся того, що ви говорите у своєму першому абзаці. Якщо моделювання працює лише на сервері, а ви транслюєте лише зміни швидкості / прискорення, то як клієнт знає, куди слід звернути спрайти? Клієнти повинні були б імітувати об'єкти на основі отриманої швидкості / прискорення, щоб правильно їх намалювати. Я думаю, ви можете мати рацію щодо отримання знімків з інтервалом, відмінним від того, що я очікую. Будь-яка ідея, як з цим боротися?
Venesectrix

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