Mutli Player Синхронизация игр - PullRequest
7 голосов
/ 07 января 2011

Ситуация:

Я хотел бы спросить, какова лучшая логика для синхронизации объектов в многопользовательской игре 1: 1 с использованием BT или веб-сервера.В игре два игрока, каждый из которых имеет несколько орудий и пуль, пули создаются динамически и через некоторое время исчезают, игроки перемещают объекты одновременно.

Проблема:

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

Возможности?

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

Что лучше всего обрабатывать задержку передачи в этом, поскольку BT может быть быстрее, чем переигрываниепаутина?Лучшим будет рабочий образец - большое спасибо!

Ответы [ 3 ]

10 голосов
/ 07 января 2011

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

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

так на авторитетном клиенте:

OnUpdate()
  gameTime = GetClockTime();
  msg.gameTime = gameTime
  SendGameTimeMessage(msg);

на другом клиенте может выглядеть примерно так:

OnReceivGameTimeeMessage(msg)
 lastGameTimeFromNetwork = msg.gameTime;
 lastClockTimeOfGameTimeMessage = GetClockTime();

OnUpdate()
 gameTime = lastGameTimeFromNetwork + GetClockTime() - lastClockTimeOfGameTimeMessage;

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

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

(2) синхронизация игрового состояния После того, как у вас есть согласованные игровые часы, вам все равно нужно будет разобраться, как последовательно имитировать и распространять свое игровое состояние. Для синхронизации игрового состояния у вас есть несколько вариантов:

асинхронный

  • каждая единица игрового состояния «принадлежит» одному процессу. только этот процесс может изменить это состояние игры. эти изменения распространяются на все остальные процессы.
  • если все принадлежит одному процессу, это часто называют игрой «клиент / сервер».
  • примечание: с этой моделью каждый клиент может по-разному смотреть на игровой мир.
  • примеры игр: quake, world of warcraft

Чтобы оптимизировать пропускную способность и скрыть задержку, вы можете часто выполнять локальное моделирование для полей с высокой частотой обновления. Пример:

drawPosition = lastSyncPostion + (currentTime - lastSyncTime) * lastSyncVelocity

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

синхронные

  • каждая единица игрового состояния одинакова во всех процессах.
  • Команды от каждого процесса передаются друг другу с их желаемым временем инициирования (когда-нибудь в будущем).
  • в своей простейшей форме один процесс (часто называемый хостом) отправляет специальные сообщения, указывающие, когда продвигать время игры. когда все получают это сообщение, им разрешено моделировать игру до этого момента.
  • требование «в будущем» приводит к большой задержке между входной командой и изменением игрового состояния.
  • в играх не в реальном времени, таких как цивилизация, это нормально. в такой игре, как starcraft, обычно звук, подтверждающий ввод, поступает немедленно, но действие, влияющее на состояние игры, задерживается. этот стиль не подходит для таких игр, как стрелялки, требующие чувствительных ко времени действий (в масштабе ~ 100 мс).

синхронно с переимуляцией

  • каждая единица игрового состояния одинакова во всех процессах.
  • каждый процесс отправляет всем остальным свои входные данные со своей текущей отметкой времени. кроме того, периодически отправляется сообщение «ничего не произошло».
  • каждый процесс имеет 2 копии состояния игры.
  • копия 1 состояния игры распространяется на «последнее самое раннее сообщение», полученное от всех других клиентов. это эквивалентно синхронной модели, но имеет тот недостаток, что представляет игровое состояние «немного назад»
  • копия 2 состояния игры - это копия 1 плюс все оставшиеся сообщения. это прогноз состояния клиента на текущий момент на клиенте, при условии, что ничего нового не произойдет.
  • игрок взаимодействует с некоторой комбинацией двух игровых состояний (в идеале 100% копия 2, но необходимо учитывать, чтобы избежать появления всплывающих окон при поступлении новых сообщений)
  • примеры игр: уличный боец ​​4 (интернет игра)

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

1 голос
/ 07 января 2011

, поскольку пули на одном устройстве могут быть быстрее, чем на другом

Этого не должно быть, если игра правильно спроектирована.

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

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

0 голосов
/ 12 мая 2011

для более подробной информации проверьте это сообщение: - Синхронизация в многопользовательской сетевой игре?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...