397 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Как сделать рассинхрон в онлайн играх

Рассинхрон

Gospodin_Blinoff #1 Отправлено 06 сен 2013 – 14:38

Хотелось бы получить ответ от кого-нибудь от разработчиков, что значит понятие “рассинхрон” в игре и как он происходит?

Например, я так понимаю, связь с сервером осуществляется при помощи пакетов, которые передают клиент и сервер друг другу. Клиент передаёт серверу пакеты о действиях игрока, сервер клиенту – о действиях других игроков и обработанные данные о взаимодействии с игровым миром, полёте снарядов, пробитии брони и нанесённом уроне. Клиент игры всё это интерполирует и мы получаем непрерывную картинку. Для меня не совсем понятно, как может получаться так, что данные о движении танка обрабатываются правильно, а о полёте снарядов нет, например, при пролетании снарядов сквозь танк.

Разработчики, расскажите, пожалуйста, поподробнее, как происходит обмен данными между сервером и клиентом, как формируются пакеты, получаемые от клиента и сервера? Думаю многим будет это интересно, даже если будет много сложных терминов, желание разобраться есть. Мне кажется, это даже можно отнести к игровой механике, и это может помочь, например, при “уворачивании” от снарядов а-ля Джов.

RenamedUser_18117268 #2 Отправлено 06 сен 2013 – 14:42

Gospodin_Blinoff (06 Сен 2013 – 14:38) писал:

Хотелось бы получить ответ от кого-нибудь от разработчиков, что значит понятие “рассинхрон” в игре и как он происходит?

Например, я так понимаю, связь с сервером осуществляется при помощи пакетов, которые передают клиент и сервер друг другу. Клиент передаёт серверу пакеты о действиях игрока, сервер клиенту – о действиях других игроков и обработанные данные о взаимодействии с игровым миром, полёте снарядов, пробитии брони и нанесённом уроне. Клиент игры всё это интерполирует и мы получаем непрерывную картинку. Для меня не совсем понятно, как может получаться так, что данные о движении танка обрабатываются правильно, а о полёте снарядов нет, например, при пролетании снарядов сквозь танк.

Разработчики, расскажите, пожалуйста, поподробнее, как происходит обмен данными между сервером и клиентом, как формируются пакеты, получаемые от клиента и сервера? Думаю многим будет это интересно, даже если будет много сложных терминов, желание разобраться есть. Мне кажется, это даже можно отнести к игровой механике, и это может помочь, например, при “уворачивании” от снарядов а-ля Джов.

enepomnyaschih

Супер-пупер школа программирования

Исследование идеального UI Framework’а, программирование игр, веб-программирование, задачи и решения

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

Реальное и игровое время

Будем различать понятия реального времени и игрового времени. Реальное время – это время в формате h:m:s.ms, в котором мы живем и которое сейчас у нас на часах. Игровое время – это количество прошедших итераций игры. То есть у каждой игры в реальном времени есть свой внутренний таймер, который отмеряет игровые итерации. Ускорение и замедление игры вызывает увеличение и уменьшение частоты таймера игрового времени соответственно.

Пусть таймер игрового времени при нормальной скорости игры имеет частоту 100 итераций в секунду.

Реальное время 15:00:00.000. Игровое время – 0. Начинается игра.
Реальное время 15:00:10.000. Игровое время – 1000. Игрок нажимает на паузу.
Реальное время 15:00:30.000. Игровое время не изменилось – 1000. Игрок продолжает игру.
Реальное время 15:00:40.000. Игровое время – 2000. Игрок ускоряет игру в 2 раза.
Реальное время 15:00:50.000. Игровое время идет быстрее – 4000.

Варианты синхронизации

Пусть имеется игра с частотой таймера игрового времени 100 раз в секунду. Пусть имеется сервер С и 2 клиента А и Б со скоростями доступа 20 мс и 200 мс соответственно (2 итерации и 20 итераций игрового времени). Протокол соединения поддерживает возможность передачи пакетов как от клиента к серверу, так и обратно.

Читать еще:  Как сделать фотошоп на весь экран

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

Если клиент А отдает команду, что персонаж хочет идти вперед, то на сервер посылается запрос. Проходит (t) итераций игрового времени. В момент получения запроса (t0) сервер может пойти тремя путями:

  1. Представить, что команда выполнилась на итерации (t0 – t) и попытаться восстановить историю событий до момента (t0). После чего разослать эту информацию всем клиентам, которые, в свою очередь попытаются восстановить историю событий от момента (t0) до момента прихода пакета (синхронный вариант с предсказанием).
  2. Выполнить команду на итерации (t0) и разослать эту информацию всем клиентам. Клиенты, получив эту информацию пытаются восстановить историю событий от момента (t0) до момента прихода пакета (простойсинхронный вариант).
  3. Взять наибольшее время доставки пакета – 20 итераций и поставить команду на выполнение через 20 итераций. При этом отправить всем клиентам информацию о выполнении команды (синхронный вариант с перестраховкой).

Рассмотрим эти схемы более подробно.

Синхронный вариант с предсказанием

Игровое время – 0. Клиент А отдает команду. Посылается запрос на сервер. Клиент А сразу начинает двигать персонаж, не дожидаясь ответа от сервера.
Игровое время – 2. Сервер принимает пакет. Сервер представляет, что в момент 0 выполнилась данная команда и воспроизводит историю до текущего момента. Сервер отправляет пакет на клиент Б.
Игровое время – 22. Клиент Б принимает пакет. Он пытается воспроизвести историю событий до текущего момента и показывает ее на экране.

Преимущества

  • Клиент А выполняет действие сразу, безо всякой задержки

Недостатки

  • История воспроизводится дважды, что может привести к рассинхронизации и багам
  • На клиенте Б в момент приема пакета проявляется жестокий лаг, как персонаж А прыгает
  • Система поддается взлому. Достаточно клиенту А послать запрос с указанием очень давнего момента времени, как вся история игры пересчитывается, как вам угодно. И сервер ничего не может с этим поделать. Он всего лишь воспроизводит команды по просьбе клиента. А в реальности игровым процессом управляет клиент

Несмотря на свои недостатки, эта схема часто встречается в практике начинающих программистов. Все игры, известные мне и написанные по приведенному протоколу синхронизации, имели тучи багов и полностью отказывались работать через минуту игры на плохом Интернете (пинг

Простой синхронный вариант

Игровое время – 0. Клиент А отдает команду. Посылается запрос на сервер. Клиент А ждет ответа от сервера.
Игровое время – 2. Сервер принимает пакет. Сервер выполняет команду в момент 2 и рассылает клиентам сигнал о событии.
Игровое время – 4. Клиент А принимает пакет. Он пытается воспроизвести историю событий до текущего момента и показывает ее на экране.
Игровое время – 22. Клиент Б принимает пакет. Он пытается воспроизвести историю событий до текущего момента и показывает ее на экране.

Преимущества

  • Система устойчива к взлому. Все действия изначально порождаются на сервере и запросы от клиента к серверу не содержат информации об игровом времени
  • Лаги уменьшаются в 2 раза по размеру

Недостатки

  • История все еще воспроизводится на клиентах, что может привести к рассинхронизации и багам
  • Лаги проявляются на всех клиентах, даже на клиенте А, несмотря на то, что он спровоцировал событие

Синхронный вариант с перестраховкой

Игровое время – 0. Клиент А отдает команду. Посылается запрос на сервер. Клиент А ждет ответа от сервера.
Игровое время – 2. Сервер принимает пакет. Сервер, зная наибольшее время доставки пакета – 20 итераций, рассылает клиентам информацию о том, что в момент 22 происходит событие.
Игровое время – 4. Клиент А принимает пакет. Он запоминает, что в момент 22 персонаж двинется вперед.
Игровое время – 22. Клиент Б принимает пакет. Везде синхронно обрабатывается событие, как на сервере, так и на клиентах.

Читать еще:  Как организовать туалетный столик: 5 советов и 22 варианта оформления

Преимущества

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

Недостатки

  • Приходится постоянно держать свежую информацию о пинге всех клиентов
  • Наличие всего лишь одного клиента с большой задержкой дает задержку на всех клиентах – даже клиент А с хорошей сетью вынужден ждать 220 мс до совершения действия
  • Система слабо устойчива к вариациям пинга. Что, если пакет идет до клиента Б не 20 итераций, а 25? Прийдется как-то исхитряться, воспроизводя историю этих 5 итераций

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

Асинхронная синхронизация

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

Как такое возможно? Очень просто! Достаточно периодически отмерять пинг каждого клиента и отодвигать клиенты в игровом времени на то самое время передачи пакета от сервера к клиенту. Представьте, что перед вами рядом стоят клиенты А и Б. И вы ясно видите, что все действия на клиенте А совершаются на 180 мс раньше, чем на клиенте Б. Это сыграет ключевую роль в протоколе. Сразу обратимся к примеру и все станет ясно.

Игровое время: С/А/Б – 100/98/80. Клиент А отдает приказ о движении вперед. Отправляется запрос на сервер и ожидается ответ.
Игровое время: С/А/Б – 102/100/82. Сервер принял пакет. Сервер выполняет команду и начинает двигать персонаж вперед в 102 момент времени. Сервер рассылает информацию об этом клиентам.
Игровое время: С/А/Б – 104/102/84. Как раз в 102 момент игрового времени клиент А принял пакет о том, что в 102 момент времени персонаж начинает идти вперед . Клиент сразу реагирует на событие и воспроизводит команду.
Игровое время: С/А/Б – 122/120/102. Как раз в 102 момент игрового времени клиент Б принял пакет о том, что в 102 момент времени персонаж начинает идти вперед. Клиент сразу реагирует на событие и воспроизводит команду.

Задержка на клиенте А от момента нажатия на кнопку до выполнения действия составила 4 итерации, то есть как раз пинг – то самое время, которое пакет идет от клиента к серверу и обратно.

Игровое время: С/А/Б – 100/98/80. Клиент Б отдает приказ о движении вперед. Отправляется запрос на сервер и ожидается ответ.
Игровое время: С/А/Б – 120/118/100. Сервер принял пакет. Сервер выполняет команду и начинает двигать персонаж вперед в 120 момент времени. Сервер рассылает информацию об этом клиентам.
Игровое время: С/А/Б – 122/120/102. Как раз в 120 момент игрового времени клиент А принял пакет о том, что в 120 момент времени персонаж начинает идти вперед. Клиент сразу реагирует на событие и воспроизводит команду.
Игровое время: С/А/Б – 140/138/120. Как раз в 120 момент игрового времени клиент Б принял пакет о том, что в 120 момент времени персонаж начинает идти вперед. Клиент сразу реагирует на событие и воспроизводит команду.

Читать еще:  Как сделать самому вибростол для блоков

Задержка на клиенте Б от момента нажатия на кнопку до выполнения действия составила 40 итераций, то есть как раз пинг – то самое время, которое пакет идет от клиентак серверу и обратно.

Преимущества

  • Никаких лагов
  • Никаких воспроизведений истории
  • Никаких лишних задержек, только необходимые
  • Задержка зависит только от вашей собственной сети, и никак не зависит от других клиентов
  • Система устойчива к взлому. Все действия изначально порождаются на сервере и запросы от клиента к серверу не содержат информации об игровом времени
  • Система гибкая – мы можем свободно варьировать отставанием клентов от сервера при вариациях пинга. Правда, при этом игра будет похожа на слайд-шоу, но зато без багов
  • Система проста в реализации

Недостатки

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

Мне кажется, приведенные недостатки с запасом перебиваются преимуществами данной схемы. Данная схема по внешним симптомам, очевидно, используется во многих популярных играх, таких как Warcraft 3 и World of Warcraft.

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

Рассинхрон

Gospodin_Blinoff #1 Отправлено 06 сен 2013 – 14:38

Хотелось бы получить ответ от кого-нибудь от разработчиков, что значит понятие “рассинхрон” в игре и как он происходит?

Например, я так понимаю, связь с сервером осуществляется при помощи пакетов, которые передают клиент и сервер друг другу. Клиент передаёт серверу пакеты о действиях игрока, сервер клиенту – о действиях других игроков и обработанные данные о взаимодействии с игровым миром, полёте снарядов, пробитии брони и нанесённом уроне. Клиент игры всё это интерполирует и мы получаем непрерывную картинку. Для меня не совсем понятно, как может получаться так, что данные о движении танка обрабатываются правильно, а о полёте снарядов нет, например, при пролетании снарядов сквозь танк.

Разработчики, расскажите, пожалуйста, поподробнее, как происходит обмен данными между сервером и клиентом, как формируются пакеты, получаемые от клиента и сервера? Думаю многим будет это интересно, даже если будет много сложных терминов, желание разобраться есть. Мне кажется, это даже можно отнести к игровой механике, и это может помочь, например, при “уворачивании” от снарядов а-ля Джов.

RenamedUser_18117268 #2 Отправлено 06 сен 2013 – 14:42

Gospodin_Blinoff (06 Сен 2013 – 14:38) писал:

Хотелось бы получить ответ от кого-нибудь от разработчиков, что значит понятие “рассинхрон” в игре и как он происходит?

Например, я так понимаю, связь с сервером осуществляется при помощи пакетов, которые передают клиент и сервер друг другу. Клиент передаёт серверу пакеты о действиях игрока, сервер клиенту – о действиях других игроков и обработанные данные о взаимодействии с игровым миром, полёте снарядов, пробитии брони и нанесённом уроне. Клиент игры всё это интерполирует и мы получаем непрерывную картинку. Для меня не совсем понятно, как может получаться так, что данные о движении танка обрабатываются правильно, а о полёте снарядов нет, например, при пролетании снарядов сквозь танк.

Разработчики, расскажите, пожалуйста, поподробнее, как происходит обмен данными между сервером и клиентом, как формируются пакеты, получаемые от клиента и сервера? Думаю многим будет это интересно, даже если будет много сложных терминов, желание разобраться есть. Мне кажется, это даже можно отнести к игровой механике, и это может помочь, например, при “уворачивании” от снарядов а-ля Джов.

Источники:

https://forum.worldoftanks.ru/index.php?/topic/990631-%D1%80%D0%B0%D1%81%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD/
https://enepomnyaschih.livejournal.com/1610.html
https://forum.worldoftanks.ru/index.php?/topic/990631-%D1%80%D0%B0%D1%81%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD/

голоса
Рейтинг статьи
Ссылка на основную публикацию
Статьи c упоминанием слов:

Для любых предложений по сайту: [email protected]