Что отправить на сервер в режиме реального времени FPS?

23

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

С подходом отправки входов: что мне делать, если игрок удерживает клавиши со стрелками? Это означает, что мне нужно отправлять пакет на сервер в каждом кадре. Не слишком ли это много? И есть также вращение плеера с помощью мыши. Вот пример:

http://www.gabrielgambetta.com/fpm_live.html

Как насчет отправки позиции в фиксированном интервале. Он отправляет слишком мало сообщений на сервер. Но это также снижает отзывчивость.

Так какой путь лучше?

syloc
источник

Ответы:

19

Простой ответ: обмануть или не быть таким точным!

Если вы играли в шутеры онлайн, вы, скорее всего, испытали так называемую «резиновую полосу», если у вас плохое соединение с сервером.

Это вызвано тем, что ваш клиент время от времени корректирует вашу позицию.

В основном, что происходит с двух сторон:

  • Сервер будет отслеживать ваше движение и отправлять обновления клиентам, как и ожидалось. Это не всегда должны быть полные обновления. Каждый х кадров может быть полное обновление, все остальные кадры вы отправляете только новые векторы скорости (если есть какие-либо изменения).

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

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

Так что да, ваш подход с фиксированным интервалом, скорее всего, будет работать и будет достаточно.

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

Марио
источник
5
Да, я могу отслеживать нажатие и отпускание кнопки. Но как насчет ввода мышью? Это постоянно меняется.
syloc
6
«Вместо этого отправьте одно событие, когда кнопка нажата, и другое, когда кнопка отпущена». - Верно, но должны быть проверки на месте, чтобы убедиться, что событие «при выпуске» в конечном итоге форсировано, в зависимости от правил игр. Например, в многопользовательской игре Rainbow Six Vegas 2 игрок может начать стрелять, и (к сожалению, распространенная) ошибка приводит к тому, что сообщение «прекратить стрельбу» не достигает сервера. Это приводит к тому, что звук выстрела остается в бесконечном цикле до конца матча. Только один пример, который нужно с осторожностью. youtu.be/GOQIbLCy7m8?t=9m10s
Майк Бакстер
@syloc: просто обработайте его на стороне клиента и позвольте серверу определить, является ли движение допустимым / возможным (чтобы предотвратить такие вещи, как взломы телепорта и тому подобное).
Марио
@syloc Просто установите интервал для мыши, но чтобы сэкономить дополнительную пропускную способность, все же выполните проверку на стороне клиента, чтобы увидеть, изменилась ли она. Если есть период времени без движения мыши, вам не нужно продолжать отправлять сообщения об этом.
agweber
На одной из моих работ инженер практически сводил себя с ума, оптимизируя поведение пружины для пропущенных обновлений позиции для набора номера (13 лет назад). Теперь я вижу игры с большой пропускной способностью и смехотворно малой задержкой, страдающие от этой проблемы, кажется, что проблема никогда не исчезнет, ​​или что в наши дни люди гораздо меньше заботятся об этом.
Андон М. Коулман,
5

Если вы еще этого не сделали, я предлагаю вам прочитать эти две глубокие, но понятные статьи: https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking и http://fabiensanglard.net/quake3/network.php .

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

Отправка пакета имеет фиксированную стоимость, а максимальный размер сетевого пакета составляет около 1,5 КБ. Так, если на вашем сервере, например, 16 игроков, каждый кадр при расчете движения для игрока, простой код может отправлять пакет обновления каждому игроку после каждого разрешения движения, поэтому 16 * 16 = 256 пакетов. Если у вас частота кадров 30, это 7680 пакетов.

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

Теперь вы отправляете только 480 пакетов в секунду для тех же результатов.

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

Что касается второй части вашего вопроса - я решил уменьшить ощущение задержки, посылая эту информацию на сервер в каждом кадре:

  • текущая текущая позиция игрока (используется сервером для проверки того, не слишком ли десинхронизированы позиции на стороне сервера и на стороне игрока).

  • Расчетная позиция игрока за 1 секунду: рассчитывается клиентом: если игрок не меняет направление мыши и оставляет клавиатуру в ее текущем состоянии в течение 1 секунды, где будет игрок? (нас не волнуют столкновения) Если игрок не двигается, то его предполагаемая позиция в 1 секунду является его текущей позицией.

  • Положение, на которое он смотрит.

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

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

GaelFG
источник
«Игроки никогда точно не синхронизируются». Я думаю, что также важно упомянуть, что уровень точности здесь зависит от реальной игры (игры). Например, классическая MMO, в которой вы просто щелкаете и выбираете объекты, не будет нуждаться в идеальной точности практически для всего, но в шутере от хорошей до идеальной синхронизации очень важно.
Марио
Дело в том, что никто в здравом уме не использует TCP для FPS. Они скорее будут иметь дело со сложным повторным секвенированием и пропущенными дейтаграммами, чем с дополнительными издержками TCP.
Андон М. Коулман,