Резюме для тех, кто не любит длинные ответы ...
Это может быть сделано, но невозможно сделать идеальную физику многопользовательской игры, если есть задержка. Почему латентность влияет на физику, а затем предлагаются советы по снижению влияния задержки на симуляцию вашей физики.
Создание многопользовательской физической игры может быть сопряжено с опасностью. Невозможно создать «идеальный» многопользовательский физический опыт. Есть вещи, которые вы можете сделать, чтобы сделать это лучше, но нет способа сделать идеальную физику предполагающей какую-либо задержку.
Проблема в том, что физика должна быть быстрой и отзывчивой, чтобы быть реалистичной, но в то же время она должна рассчитываться на основе комбинированных действий ВСЕХ факторов, то есть комбинированных действий всех игроков. И если есть задержка, это не может быть сделано в режиме реального времени.
Вы, как разработчик, должны решить, можете ли вы держать под контролем различные факторы, и понять, что опыт игрока ухудшится, если задержка станет слишком высокой. Если вы можете жить с этим (и ваши игроки могут), то пойти на это. Посмотрите в конце этого поста некоторые заметки о том, как вы можете поддерживать плавность работы.
Пример, чтобы показать, как все может запутаться
Представьте себе игру, в которой два игрока (клиенты) подключены к серверу. Для передачи сообщения через Интернет от клиента к серверу требуется 100 миллисекунд (1/10 секунды). Когда игрок что-то делает, на сервер отправляется сообщение о том, что он сделал. Затем сервер передает сообщение другим игрокам, чтобы они все знали, что сделал действующий игрок.
Теперь создайте сценарий, в котором два игрока имеют ящик на земле, который является физическим объектом. Игрок A ударяет его по одной стороне, отправляя его в каком-то направлении. Однако в то же время игрок B ударяет по нему с другой стороны, отправляя в другом направлении.
Давайте посмотрим на различные способы справиться с этим и каковы будут результаты ...
Что если физика рассчитывается только на сервере?
Предположим, у нас есть физика, рассчитанная только на сервере. Игрок А отправляет на сервер сообщение «Я попал в ящик таким образом», а спустя 1/10 секунды сервер получает сообщение. Игрок Б отправляет сообщение «Я попал в ящик другим способом». Сервер вычисляет изменение физики на основе комбинации двух действий и отправляет сообщение обоим игрокам, говоря: «Хорошо, он движется так». Совершенная физика выполняется, основываясь на действиях обоих игроков вместе взятых.
Но проблема в том, что пройдет 2/10 секунды, прежде чем любой из игроков увидит, как сундук среагирует. Сообщения от обоих игроков занимают 1/10-ю секунды, чтобы добраться до сервера, затем еще 1/10-ю секунды для результатов расчета сервера, которые будут отправлены обоим игрокам.
Итог, затянувшийся геймплей.
Что, если физика просто рассчитана на клиента?
Предположим, у нас есть физика, рассчитанная только на клиента. Давайте посмотрим на это с точки зрения игрока А. Игрок А попадает в ящик, и он сразу же начинает идти в их направлении. На сервер также отправляется сообщение о том, что сделал Игрок А.
В то же время, однако, B сделал свой удар и увидел, что ящик движется в их направлении, и отправил на сервер сообщение о том, что они сделали.
2/10-й секунды спустя, сообщение приходит от сервера к клиентам. А говорят, что сделал Б, а Б говорят, что сделали. Проблема в том, что оба клиента говорят: «Хорошо, игрок X, возможно, сделал этот удар в этом месте, но в этом месте больше нет ящика, поэтому его удар ничего не сделал».
Суть в том, что две игры не синхронизированы и игроки не имеют общего опыта. Какой смысл в мультиплеере, если они оба видят разные вещи?
Что если физика рассчитана как на клиенте, так и на сервере?
В этом случае физика рассчитывается на клиенте, поэтому игроки видят немедленную реакцию без задержек, но она также рассчитывается на сервере, поэтому она «правильная» для всех игроков.
Оба игрока попадают в ящик в соответствующих направлениях, и каждый видит движение корзины, основываясь только на своем ударе. Но затем, спустя 2/10 секунды, сервер возвращается и говорит: «На самом деле, вы оба не правы. Ящик пошел по этому пути». Внезапно оба игрока видят, как ящик резко меняет направление и бросается в новое место.
Итог, глючная игра.
Вывод
В принципе, невозможно создать идеальную физическую игру с несколькими игроками, когда существует какая-либо задержка. Вы можете сделать довольно хорошую игру, но у вас всегда будет риск чрезмерной задержки, создающей плохой опыт для некоторых игроков. Однако есть вещи, которые вы можете сделать, чтобы ваш игровой опыт был хорошим.
Что вы можете сделать, чтобы многопользовательская игра работала хорошо
Используйте простые объемы столкновений. Не пытайтесь моделировать каждую деталь фигуры с помощью физики, когда подойдет простая фигура куба. Spikey Ball не должен быть смоделирован как spikey ball для физики. Вместо этого просто смоделируйте это как сферу.
Делайте небольшие несущественные объекты только для клиентов. Примером могут быть битые стекла из разбитого окна. Вы можете позволить каждому клиенту моделировать его самостоятельно, и это не будет иметь большого значения, если они разные.
Делайте объекты физическими объектами только в том случае, если они должны быть физическими объектами, чтобы число активных физических объектов было небольшим.
Запускайте игру в замедленном режиме, когда выполняете многопользовательскую физику Подумайте «время пули», может быть. Игры в замедленном темпе компенсируют задержку и позволяют нескольким игрокам взаимодействовать с физикой вместе.
Разрешить игрокам устанавливать ситуации в некотором роде вместе, а затем по некоторой подсказке симуляция физики для обоих игроков, и оба следят за результатом их объединенных действий. Игроки не могут вмешиваться в последовательность, пока она не будет завершена.
Разделяйте игроков физикой, чтобы они не могли мешать друг другу. Это было бы здорово для такой игры, как боулинг или пул, где только один игрок одновременно имеет контроль, или у каждого игрока есть своя «песочница» (например, дорожка для боулинга).
Если вы не можете победить их, присоединяйтесь к ним и сделайте физическое отставание частью вашей игры. Вообразите историю о том, чтобы быть в блестящей вселенной с нарушенными законами физики или кое-чем :)
Приложение: Как стрелялки справляются с этим
Стрелялки справляются с этим, не занимаясь чрезмерно сложной физикой. Они используют клиентские побочные эффекты, чтобы игроки могли видеть вещи быстро, но затем сервер делает последний звонок о том, что произошло.
Представьте себе сценарий, когда игрок A стреляет в игрока B. Ваша типичная стрелялка будет делать что-то вроде этого ...
- A будет локально подсчитывать, попали ли они в B, и если похоже, что есть попадание, он играет эффект «удара», как кровь. Это делается на стороне клиента, чтобы игрок сразу увидел реакцию на свои действия. Если вы этого не сделаете, игра будет тормозить.
- А также отправляет на сервер сообщение «Я стрелял по этому вектору»
- Когда сервер получает сообщение, он смотрит на то, где IT думает, что игроки находятся, и решает, ударил ли вектор броска A B.
- Если сервер решает, что А попадет в В, он решит, что В ударил, и отправит ОБА клиентам, что произойдет.
- Если сервер решает, что A НЕ ударил B, B в порядке, и A "отсутствует". Может показаться, что они попали («Я видел кровь!»), Но пропустили вызов серверов.
Так как же А мог пропустить Б, когда казалось, что они их бьют? Поскольку B, возможно, переехал, но A еще не видел его, потому что сервер еще не отправил клиенту сообщение "B двинуто сюда".
У Valve есть хорошая рецензия на их сайт по этому поводу. См. Http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
Я написал серию статей на эту тему здесь: http://www.gabrielgambetta.com/fpm1.html
Первые три статьи посвящены введению в тему, предсказанию на стороне клиента, согласованию сервера и интерполяции сущностей (эта часть отвечает на ваш конкретный вопрос). Четвертая статья (скоро) будет посвящена «стрельбе» :)
Ответ Тима Холта в значительной степени таков. В моих статьях есть пара диаграмм, которые могут помочь вам понять, что происходит, но мы с Тимом в основном говорим одно и то же.
источник
Неразумно делать полный прогноз своего персонажа для отзывчивости, а другие персонажи отстают на 100 мс для согласованности. Если это выглядит плохо, подумайте о том, чтобы ваш собственный персонаж немного отставал, чтобы синхронизировать их. В любом случае вам все еще понадобятся механизмы коррекции, чтобы сгладить неправильные прогнозы в случае скачков задержки, и эта система будет иметь дело с ситуациями, подобными той, которую вы описываете. Неважно, составляет ли задержка 100 мс или 1 мс - ваш клиент в некотором смысле всегда «опаздывает» и поэтому всегда должен вести себя так, как будто он имеет дело со старыми данными, и применять косметические эффекты, такие как интерполяция, чтобы они выглядели разумно.
источник
В конце концов, все дело в том, чтобы справиться с доступными сетевыми ресурсами. В идеале мы бы жили в мире с нулевой задержкой, и все было бы идеально синхронизировано. Реально, вы обновляете клиентов каждые 100, 200, 300 мс, и в клиенте должна быть логика, чтобы происходящее выглядело гладко. «Гладкость» очень важна, в конце концов, игра просто должна чувствовать себя гладкой, даже если на заднем плане происходит какая-то хаотическая синхронизация между клиентом и сервером.
Хороший пост и лучший ответ можно найти:
Как написать сетевую игру?
источник
Проблема не в латентности. Это может быть компенсировано и предсказано достаточно хорошо, чтобы скрыть любые проблемы, вызвавшие это. Потеря пакетов также не является проблемой - сетевая система должна быть написана, чтобы быть устойчивой и терпимой к потере пакетов. Тем не менее, проблема заключается в скачках задержки и непредсказуемой задержке. Пакеты поступают несинхронно, некоторые из них отбрасываются только из-за колебаний задержки, невозможности прогнозировать и интерполировать из-за колебаний задержки и т. Д.
источник