Игровая сеть физика столкновения - PullRequest
50 голосов
/ 07 мая 2009

Как имитировать столкновение двух (управляемых клиентом) транспортных средств (разумно) в типичной настройке клиент / сервер для сетевой игры? Я прочитал это выдающееся сообщение в блоге о том, как делать физику распределенных сетей в целом (без традиционного предсказания клиента), но этот вопрос конкретно о том, как обрабатывать столкновения принадлежащих объектов.

Пример

Скажем, клиент A на 20 мс опережает сервер, клиент B на 300 мс опережает сервер (с учетом как задержки, так и максимального дрожания). Это означает, что при столкновении двух транспортных средств оба клиента увидят другого на расстоянии 320 мс - в противоположном направлении скорости другого транспортного средства. Личная встреча на шведском шоссе означает разницу в 16 метров / 17,5 ярдов!

Что не попробовать

Практически невозможно экстраполировать позиции, поскольку у меня также есть очень сложные транспортные средства с шарнирами и кузовами повсюду, которые, в свою очередь, имеют линейные и угловые положения, скорости и ускорения, не говоря уже о состояниях из пользовательского ввода.

Ответы [ 8 ]

13 голосов
/ 07 мая 2009

Я не знаю идеального решения, и у меня такое чувство, что его не существует. Даже если вы сможете точно предсказать будущее положение транспортного средства, вы не сможете предсказать, как пользователь будет управлять элементами управления. Таким образом, проблема сводится к минимизации негативных последствий отставания клиент / сервер. Имея это в виду, я бы подошел к этому с позиции принципа наименьшего удивления (перефразировано из Википедии):

В дизайне пользовательского интерфейса принцип наименьшего удивления (или удивления) гласит, что, когда два элемента интерфейса конфликтуют или неоднозначны, поведение должно быть таким, которое будет меньше всего удивлять пользователя в момент возникновения конфликта .

В вашем примере каждый пользователь видит два автомобиля. Свои и чужие. Пользователь ожидает, что его собственное транспортное средство будет вести себя точно так, как он его контролирует, поэтому мы не можем играть с этим аспектом симуляции. Однако пользователь не может точно знать, как другой пользователь контролирует его транспортное средство, и я бы использовал эту неоднозначность, чтобы скрыть отставание от пользователя.

Вот основная идея:

  1. Сервер должен принять решение о предстоящем столкновении. Алгоритм обнаружения столкновений не должен быть идеальным на 100%, он должен быть достаточно близким, чтобы избежать очевидных несоответствий.
  2. Как только сервер определил, что столкнулись два автомобиля, он отправляет каждому из двух пользователей сообщение о том, что столкновение неизбежно.
  3. На клиенте A положение транспортного средства B корректируется (реально), чтобы гарантировать, что столкновение произойдет.
  4. На клиенте B положение транспортного средства A корректируется (реально), чтобы гарантировать, что столкновение произойдет.
  5. Во время после столкновения положение каждого транспортного средства может быть отрегулировано, при необходимости, так, чтобы конечный результат соответствовал остальной части игры. Эта часть является именно тем, что «Ликвидация» предложил в своем ответе .

Таким образом, каждый пользователь по-прежнему полностью контролирует свое транспортное средство. Когда происходит столкновение, оно не будет неожиданным. Каждый пользователь увидит движение другого транспортного средства к ним, и у него все еще будет ощущение симуляции в реальном времени. Приятно, что этот метод хорошо реагирует в условиях низкой задержки. Если оба клиента подключаются к серверу с малой задержкой, размер настройки будет небольшим. Конечный результат, конечно, будет ухудшаться с увеличением отставания, но это неизбежно. Если кто-то играет в динамичный экшен по соединению с задержкой в ​​несколько секунд, он просто не получит полного опыта.

6 голосов
/ 07 мая 2009

Возможно, лучшее, что вы можете сделать, это не показывать фактическое столкновение в реальном времени, а создать иллюзию того, что все происходит в реальном времени.

Так как клиент находится позади сервера (задержка), и сервер должен показать результат столкновения, возможно, что вы можете сделать, на стороне клиента, показать вспышку или взрыв или какую-то другую графику, чтобы отвлечь пользователя и купите достаточно времени на стороне сервера, чтобы рассчитать результат столкновения. Когда вы закончите с прогнозом, вы отправите его обратно на сторону клиента для презентации.

2 голосов
/ 14 февраля 2010

По поводу "Чего не попробовать". Вы предполагаете, что вам нужно точно предсказать, но вы никогда не найдете идеального решения в игре со сложной физикой. Приближение, вероятно, лучшее, что вы можете сделать (например, большинство коммерческих физических движков могут навести форму на физическую сцену и вернуть первую точку столкновения).

Например, я реализовал некоторые важные части физики сети для Mercenaries 2 под руководством Гленна (упомянутый вами пост в блоге). Было невозможно протолкнуть все необходимое физическое состояние через провод даже для одного твердого тела. Физика Havok постепенно генерирует точки контакта в каждом кадре, поэтому текущий «контактный коллектор» является необходимой частью состояния физики для сохранения детерминированности симуляции. Это также слишком много данных. Вместо этого мы отправили желаемое преобразование и скорости и использовали силы и моменты, чтобы мягко подтолкнуть тела на место. Ошибки неизбежны, поэтому вам нужна хорошая схема исправления ошибок.

2 голосов
/ 07 мая 2009

Извините, что отвечаю «Что не попробовать», но я никогда не слышал о решении, которое не предполагает прогнозирование результата на стороне клиента. Рассмотрим упрощенный пример:

Клиент А стоит на месте и наблюдает, как автомобиль клиента Б приближается к утесу. Транспортное средство клиента B способно мгновенно снизить скорость до 0 и делает это в самый последний момент перед тем, как проехать через обрыв.

Если клиент A пытается показать состояние клиента B в режиме реального времени, у клиента A нет другого выбора, кроме как предсказать, что клиент B упал с обрыва. Вы часто видите это в MMORPG, разработанных таким образом, что персонаж игрока способен сразу остановиться при беге на полной скорости. В противном случае клиент A может просто показывать состояние клиента B при поступлении обновлений состояния, но это невозможно, поскольку клиент A должен иметь возможность взаимодействовать с клиентом B в реальном времени в вашем сценарии (я полагаю).

Не могли бы вы попытаться упростить модели столкновений, чтобы экстраполяция была возможна для прогнозирования в реальном времени? Возможно, ваши «суставы и тела повсюду» будут иметь физические модели с меньшей интенсивностью процессора, например, несколько кубов или сфер. Я не слишком знаком с тем, как повысить эффективность обнаружения столкновений, но я предполагаю, что это делается путем обнаружения столкновений моделей, которые являются менее сложными, чем визуальные модели.

1 голос
/ 20 июля 2015

Мало мыслей.

  1. Peer to peer лучше справляется с задержками и высокими скоростями.

Так что, если это ваш собственный движок, переключитесь на одноранговый. Затем вы экстраполируете транспортное средство других пиров на основе их кнопки ввода, чтобы двигаться вперед, где он сейчас находится. Вы настроили столкновение таким образом, что вы сталкиваетесь с другим транспортным средством, как будто это мир. То есть вы принимаете удар.

Это означает, что когда вы сталкиваетесь с другим, вы отскакиваете, в сети пира они отскакивают от вас, так что это выглядит примерно правильно. Чем меньше задержка, тем лучше она работает.

  1. Если вы хотите перейти клиент / сервер, то это будет уступать p2p

Вещи, чтобы попытаться o) Экстраполировать клиентов вперед, как в p2p, чтобы выполнить обнаружение коллизий. o) Отправить результаты столкновения обратно клиентам и экстраполировать вперед

Обратите внимание, это НИКОГДА не будет так же хорошо, как p2p. Принципиально высокая скорость и задержка = ошибка, поэтому устранение задержки - лучшая стратегия. P2P делает это.

1 голос
/ 21 мая 2010

В итоге я просто пропустил предсказание и просто сделал следующее:

  1. Клиент очень много говорит о своей позиции,
  2. Сервер (почти) говорит о позиции клиента-владельца только тогда, когда произошло столкновение с высокой энергией с другим динамическим объектом (т.е. не в статической среде).
  3. Клиент получает meshoffset=meshpos-physpos при получении позиционного обновления с сервера, а затем устанавливает meshpos=physpos+meshoffset каждый кадр и постепенно уменьшает meshoffset.

В большинстве случаев это выглядит довольно неплохо (в ситуации с малой задержкой), мне даже не нужно пускать кватернионы для получения плавных переходов.

Пропуск предсказания, вероятно, дает клиентам с большим временем ожидания ужасный опыт, но у меня нет времени на это останавливаться, если я когда-нибудь собираюсь выпустить эту инди-игру. Время от времени приятно создавать полусерое решение, которое работает достаточно хорошо, но лучше. ;)

Редактировать: В итоге я добавил функцию «владения», которую Глен Фидлер (блогер, упомянутый в вопросе) реализовал для Mercenaries 2: каждый клиент получает право собственности на (динамические) объекты, с которыми он сталкивается какое-то время. Это было необходимо, поскольку проникновение в противном случае становится глубоким в ситуациях с высокой задержкой и высокой скоростью. Это решение работает так же хорошо, как вы думаете, когда видите видеопрезентацию GDC, определенно рекомендую!

0 голосов
/ 09 июля 2009

В дополнение к прогнозированию на стороне клиента, где может находиться другой пользователь, и отправке информации о коллизиях и того, как вы обрабатываете ее на сервере, большинство mmo делают, чтобы справиться с задержкой, когда сервер работает «в прошлом». как было. В основном они буферизуют последние входные данные, но реагируют только на то, что произошло .1сек в прошлом. Это позволяет вам «заглядывать в будущее», когда вам нужно (то есть, когда в вашем временном интервале должно произойти столкновение, вы можете посмотреть на буферизованный ввод, чтобы увидеть, что произойдет, и решить, является ли столкновение реальным).

Конечно, это добавляет дополнительный уровень сложности вашей программе, поскольку вы должны учитывать, какие данные отправлять своим клиентам и как они должны реагировать на это. Например, вы можете отправить клиентам весь «будущий» буфер и позволить им увидеть, какие возможные коллизии действительно произойдут, а какие нет.

0 голосов
/ 08 мая 2009

Росс имеет хорошую точку зрения. Вы можете упростить модель, которую вы используете для обнаружения столкновений, абстрагировав ее до некоторого более простого объема (то есть грубого квадратного контура транспортного средства). Затем вы можете делать прогнозы на основе простого объема и подробных расчетов точных объемов, пока пользователь отвлекается на «взрыв». Возможно, он не идеален, но позволит ускорить обнаружение столкновений.

...