Как стать автором
Обновить

Клиент-серверное взаимодействие в новом мобильном PvP-шутере и устройство игрового сервера: проблемы и решения

Время на прочтение 10 мин
Количество просмотров 18K
Всего голосов 35: ↑34 и ↓1 +33
Комментарии 19

Комментарии 19

1.А почему вы используете в input структуре такие емкие типы данных? Разве нельзя обрезать лишние байты?


  1. Насколько мне известно, в мобильной сети чаще происходят групповые ошибки. Поэтому, если потерялся какой-то пакет, то и следующие несколько с большой вероятностью потеряются. Получается, что повторную отсылку лучше выполнять с каким-то периодом. А если за это время придёт ответ от сервера, то вообще можно не выполнять.
  2. Почему вы не используете относительно временную метку?
  3. Вы предотвращает повторную пересылку ранних пакетов, когда сервер уже ответил на более поздний?

Такие типы данных использованы для удобства. Наш упаковщик данных режет лишние байты и биты. Если посмотрите на пример его вызова packer.PackUInt32((uint)((s.AimMagnitudeCompressed — min)/step), CalcFloatRangeBits(min, max, step)) — второй аргумент — это как раз количество значимых бит. В каждом компоненте мы помечаем допустимые значения, а автоматический генератор создаёт на основе этого оптимальный код для передачи по сети с использованием упаковщика.
По остальным вопросам:


  1. Размер серии вводов в пакете не превышает 200 байт. Потому следить за тем, что сервер уже получил, а чего нет, с точки зрения трафика, избыточно. Проще отправлять всё подряд и надеяться, что данные, сдублированные несколько раз рано или поздно будут доставлены. Если же нет, то тут либо дисконнект, либо слишком поздно досылать ввод. Сервер его уже все равно не примет.
  2. Относительно чего? Не совсем понял. Временная метка у нас только одна — номер тика симуляции.
  3. Нет. В этом случае сервер просто отбрасывает ввод игрока, т.к. если сервер обработал более поздний тик, чем клиент, значит клиенту надо подстроить свою локальную симуляцию под тики сервера так, чтобы опережать его на необходимое для досылки данных время. Этот процесс хорошо описан в нашей предыдущей статье.
Спасибо. Я бы конечно сделала всё по-другому)) Но всегда надо знать альтернативные варианты.
Возникла опечатка. Я про относительную временную метку. Относительно синхронизированного состояния. Этот вопрос был в догонку к первому.
Так где все таки можно сыграть в ваш шутер? А то расписываете хорошо, но как оно на деле выглядит?

Играется очень неплохо. К сожалению, пощупать можно будет только после глобального релиза :)

И когда релиз?

Приятно читать и осознавать что все (кроме дельта-комперссии) сделано так же:D


На тему задержек: мы вот с такой проблемой сталкиваемся: у Wi-Fi роутера иногда случается буфферизация, которая на 0.1-0.4 секунды задерживает пакеты, а потом выдает их все пачкой. (Пакеты — UDP, проверяли с помощью wireshark)


Вроде причина такая: сети 2.4 GHz очень уж плотно населяют наш мир. И две точки на соседних каналах не могут говорить одновременно. Так что если кто-то посторонний начинает активно орать в эфир, наша точка стоит и ждёт своей очереди.
В пользу этой теории говорит тот факт, что подобных провисаний на роутере 5GHz не наблюдается.


Вы с таким сталкивались? Какое у вас решение этой проблемы?

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


Единственное, что могу сказать — проблемы потери нескольких пакетов подряд при игре в реальных условиях (через мобильные сети, публичные wi-fi точки) — сильно преувеличены. Мы это видим на основе определённых данных, которые собираем в процессе тестирования. Если же wi-fi эфир действительно нагружен до предела, то все сетевые игры будут лагать. Как пример — на той же перегруженной wi-fi сети смотрели на Clash Royale и игра вела себя крайне нестабильно. Попробуйте поиграть в Overwatch на такого рода соединении.

Везет вам, у вас есть UDP. В браузерном мире это недоступное удовольствие =)
в браузерном мире есть webrtc, который вполне можно применять
… И хотя WebRTC позволяет удобно отправлять ненадёжные «беспорядочные» данные из браузера в браузер, он терпит крах, когда требуется передача данных между браузером и выделенным сервером.

Проблема возникает из-за чрезвычайной сложности WebRTC. Причины этой сложности понятны: WebRTC в первую очередь был разработан для обмена данными peer-to-peer между браузерами, поэтому для обхода NAT и передачи пакетов он в худшем случае требует поддержки STUN, ICE и TURN.

Source

теоретически, можно сделать на сервере webrtc-шлюз, которому не нужны будут ни stun ни torn. А их поддержка в браузерах уже есть. Да это сложнее чем udp но все же реализуемо. Вопрос нужно ли такое решение для игр
Поговаривают, что Photon тоже скоро будет поддерживать WebRTC

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

Почему тот же фотон не использовали? Это бы сократило количество используемых технологий?

Photon не очень хорошо предназначен для подобного. Инфраструктура на Java гораздо более приспособлена под такого рода задачи.

Правильно ли я понимаю, что у вас только Игровые сервера на Photon работают. Остальное что-то самописаное?
mrguardian вы когда-нибудь тестили Гугловский реал-тайм мультиплеер?
developers.google.com/games/services/cpp/realtimeMultiplayer
Что-нибудь можете про него сказать?

Именно 200мс пинг? Разве региональные сервера эту проблему не решают?
По поводу готового решения от Google — нет не смотрели. Спасибо за ссылку, посмотрим.
200мс — это то, что мы видим на большом наборе данных. Это среднее значение и физически у вас вряд ли получится поставить по серверу в каждой стране. По крайней мере, в нашем кейсе это так.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий