Сделайте хороший многопользовательский / mmo-клиент<> серверные игры используют задержку при расчетах перемещений?

StackOverflow https://stackoverflow.com/questions/1448997

Вопрос

Здесь есть пара вопросов.

Представьте, что у меня есть клиент A, который собирается отправить на сервер следующее сообщение:"НАЧНИТЕ ДВИЖЕНИЕ ВПЕРЕД".

Сервер не получит это сообщение мгновенно, так как существует задержка из-за задержки.

Вопрос 1:пинг (или лучше: время в пути туда и обратно) - это количество времени, необходимое клиенту для отправки сообщения на сервер и получения ответа обратно.Означает ли это следующее, если вы можете игнорировать время, необходимое серверу, чтобы заметить, что он получил сообщение, и начать отправлять ответ (он должен быть очень коротким)?

  1. время, необходимое клиенту для отправки чего-либо на сервер = время в оба конца / 2
  2. время, необходимое серверу для отправки чего-либо клиенту = время в оба конца / 2

Таким образом, когда клиент A отправляет это сообщение, сервер предположительно получит это сообщение в оба конца / через 2 миллисекунды после того, как клиент отправит сообщение.Это подводит меня к следующему вопросу.

Вопрос 2:должен ли клиент сначала отправить пакет, а затем подождать время в оба конца / 2 миллисекунды, прежде чем фактически выполнить эту команду на стороне клиента (в данном случае:двигаться вперед), чтобы компенсировать задержку?

Теперь сервер отправит следующее сообщение всем ближайшим игрокам:"КЛИЕНТ А СЕЙЧАС ПРОДВИГАЕТСЯ ВПЕРЕД".Затем эти клиенты убедятся, что персонаж клиента а начинает двигаться, это подводит меня к следующему вопросу.

Вопрос 3:должен ли клиент, получающий сообщение о том, что другой клиент переместился, учитывать, что это сообщение было отправлено сервером в оба конца / 2 миллисекунды назад?Так что текущее время, используемое для временных меток вычислений перемещения, должно быть уменьшено на время в оба конца / 2?

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

Это было полезно?

Решение

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

Другие клиенты вообще не позволили бы вам перемещаться без ответа от сервера в течение определенного промежутка времени.Это те моменты, когда вы испытывали бы "замораживание-запаздывание".

Конечно, бывают и случаи, когда сервер просто принимает позицию, отправленную клиентом, и слепо доверяет ей.Это игры, которые, как правило, уязвимы для взломов телепортации.

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

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

Конечно, это меняется от двигателя к двигателю, но это довольно общий подход.

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

Другие советы

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

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

Локальный клиент, удаленный клиент и сервер - все они предсказывают текущее местоположение с помощью алгоритмов.Следующие данные близки к типичным:

  • Время:t
  • Размещение:Положение (x, y, z) и ориентация (x, y, z, w)
  • Движение:Вектор линейного движения, задающий направление с длиной как скоростью (x, y, z), и вектор вращательного движения, задающий ось с длиной как скоростью вращения (x, y, z)

Вам нужны алгоритмы, которые экстраполируют из набора [T, P, M] на simtime.Я не буду приводить их здесь.

Когда клиент регистрирует изменение в приводе корабля в [T, P, M], это не попадет на сервер до T + deltaT.Но если deltaT находится в пределах допуска типичных сетевых задержек, сервер может сказать "Да, это произошло в T, я принимаю это". В противном случае он может захотеть исправить клиента, сказав "Нет, это выходит за рамки допуска, это произошло в мое время T'", и в этом случае клиенту придется воспроизвести все последующие изменения [T, P, M] с исправленного сервером (это означает, что вам нужно сохранить очередь или список из них).

Следующий клиент получит его по адресу T + deltaT +differentdeltaT.Он никак не может изменить то, что он уже смоделировал, поэтому, если он не откладывает свою симуляцию, он перескочит на удаленный корабль, и вы увидите кадр рывка.Вот почему моделирование судов с дистанционным управлением должно быть отложено на время, постоянно превышающее 2 * typicaldeltaT.Это должна быть постоянная задержка или задержка, которая меняется постепенно, и во времена сильного запаздывания вы, тем не менее, увидите отрывистые кадры

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

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

Нет, не откладывайте локальную симуляцию, когда перемещается локальный "аватар".Это казалось бы слишком безразличным.Вы могли бы немного отложить это (возможно, до 50 мс), чтобы улучшить синхронизацию, но задержка вплоть до RTT сделает вашу игру удручающе невосприимчивой.Установите параметр для локальной задержки и поиграйте с ним, потому что небольшая постоянная задержка может быть приемлемой и улучшить синхронизацию.Но это не обязательно и может вызвать массу проблем, поэтому я рекомендую выполнять этот код в последнюю очередь.(Если вы пытаетесь сыграть в рукопашную игру FPS, вам нужно будет сделать это и всю другую помощь, которую вы можете получить).

Что касается предотвращения мошенничества противплавность моделирования:Во-первых, клиенты не должны просто экстраполировать последнюю известную позицию, когда официальная позиция меняется.Он должен зарегистрировать вектор корректировки и медленно переходить от старого пути к новому для обеспечения плавности (но, как я сказал выше, делайте этот код последним, иначе он замаскирует другие ошибки).Во-вторых, сервер должен выдерживать широкий диапазон задержек...даже на машинах с одним и тем же Ethernet задержка пакета обычно составляет от 5 мс до 100 мс или около того...это довольно большой диапазон.Конечно, вам нужно прервать это и сказать: "если вы говорите, что переместились в момент T, но я получил пакет в T + some_large_number, то я думаю, что вы пытаетесь скорректировать прошлое и лжете мне". some_large_number не должен быть намного больше среднего RTT, чтобы люди были честны.

Симуляции никогда не будут строго синхронизированы.Они должны оставаться в пределах 400 мс или около того через Интернет, но, безусловно, будут выходить за его пределы во время задержек...до 30 секунд или больше, и вам нужно терпеть подобные вещи, потому что они не редкость.Учитывая, что Интернет ограничен скоростью света в меди, вы всегда можете ожидать, что задержки в одностороннем режиме обычно будут составлять минимум 100 мс для ваших клиентов far, часто 500 мс или дольше.

Поэтому я настоятельно рекомендую вам не пытаться создавать FPS-игры ближнего боя через Интернет (некоторые крупные компании пытаются, но всегда сталкиваются с проблемами).Есть трюки, которые вы можете выполнить, если используете снаряды (запустив их быстро в одной симуляции и медленно в другой), чтобы, даже если время не задано, они выглядели включенными.Кроме того, в играх FPS используется правило, согласно которому обнаружение попадания основано на симуляции атакующих...кажется более неправильным, когда нападающий знает, что он был точно в створ и промахнулся, чем когда защитник знает, что он был в стороне и все равно получил удар.Вы должны выбрать одно или другое, и психологически именно так это и было сделано.Ближний бой требует такого уровня синхронизации, который, откровенно говоря, невозможен, и большинство игровых компаний не будут использовать MMORPG FPS melee, а скорее будут использовать автоматическое таргетирование (попробуйте поиграть в Mortal Online, вы поймете, что я имею в виду).

Удачи.

для Q1:по-моему, это выглядит правильно.

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

Q3:клиентам действительно нужно знать только то, что они имитируют в момент X, а сервер сообщает, что набор событий {A, B, C} произошел в моменты времени {X, Y, Z}.Затем клиент и сервер могут имитировать пересылку с одной и той же информацией и, как правило, оставаться синхронизированными (за исключением случаев одновременного возникновения конфликтов).В таких случаях у вас есть сервер для повторной синхронизации, поэтому вы обычно получаете довольно ограниченный предел погрешности и в основном плавный процесс.

Если ваша цель состоит в том, чтобы улучшить восприятие задержки, вы также можете просто попробовать довериться клиенту.

Существует несколько сетевых моделей для решения этих проблем;

В сетевой игре вам нужно синхронизировать две вещи: одна - это время, другая - пространство.

  1. Модель сетевой игры под названием lockstep;

вам следует ознакомиться со статьей, написанной игровой студией age of empire2, в которой описываются детали модели lockstep.

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

Клиент в кадре 50, отправьте команду переместить вперед, но не запускайте ее немедленно, клиент сообщит серверу выполнить команду переместить в кадре 51;затем, когда наступит кадр 51, сервер и клиент выполнят команду одновременно.таким образом, логика клиента и сервера будет одинаковой.

В такой модели, в кадре 50, клиент и сервер будут запускать команду, выданную, возможно, в кадре 49, поэтому при обратной связи с вводом данных клиентом всегда существует задержка в 100 мс или более.

задержка между клиентом и сервером не только содержит сетевой RTT, но также содержит задержку логического кадра, которая составляет 100 мс;

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

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

  1. другие модели используют синхронизацию состояния

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

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

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

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

эти технологии включают в себя прогнозирование клиента, компенсацию задержки сервера, интерполяцию объектов Сервера.

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

В сетевой игре существует по крайней мере два вида команд, во-первых, как движение, команда будет выполняться в течение определенного времени, подобно постоянному потоку, который обладает свойством Непрерывности.

другой, как использование навыка в холодное время, командный эффект приобретет импульсивный характер, мы должны относиться к ним по-другому.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top