dollar
@dollar
Делай добро и бросай его в воду.

Что делать при несовпадении координат на клиенте и сервере?

Игрок нажимает стрелку вправо - персонаж начинает двигаться вправо (в реальном времени).
На клиенте - сразу (предсказание).
На сервере - с задержкой 100 мс.
Далее игрок отпускает стрелку вправо - персонаж останавливается.
На клиенте - сразу (при этом посылает сигнал об остановке на сервер).
На сервере - через 100 мс (при этом посылает координаты последней позиции клиенту).
Но локальные и присланные координаты не совпадают, т.к. пинг всегда чуть разный.
Как быть?
  • Вопрос задан
  • 225 просмотров
Решения вопроса 3
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Всегда доводим интерполяционно торможение персонажа на клиенте, используя координаты сервера.
1. Вправо отпустили
2. На сервер отправили и получили координаты остановки
3. Клиента медленно, в течение 10-15мс (если он двигается в этот момент) и 250-300мс (если замер на месте и не поворачивается) ставим на эту позицию.

Если Вы держите полностью игровой мир на сервере, значит сервер всегда главный.

UPD: Добавлю, что можно также позже проверить на сервере через расчёт координат с клиента и сделать реверс-тесты по контрольным точкам событий на сервере, чтобы дать заключение о корректности события, рассчитанного клиентом.

Например, чтобы попадание было распознано как засчитанное с именно этих координат и именно из этого оружия, нужно проверить в обратную сторону (по временной линии событий) точку выстрела и возможность выстрела, путь перемещения и время между предыдущей проверкой и текущей.
Т.е., восстановить на основе ряда факторов предыдущее состояние игрока, которое не было отправлено (или не успело ещё доставиться) на сервер между пакетами из-за длительности пинга.
Ответ написан
@napa3um
Тема оооочень глубокая и сложная, тут простых ответов быть не может. Решение будет зависеть от геймплея, технических ресурсов сервера и клиентов, от желаемого качества того или иного аспекта реализации и т.д. Универсального ответа нет, есть лишь "бэст практики" для каких-то типовых проблем (а решать, являются ли они проблемами - вам в вашем конкретном проекте).

https://habr.com/post/328702/
https://habr.com/post/302394/
https://habr.com/company/pixonic/blog/415959/
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
Я об играх, где игрок управляет одним объектом: шутерах, гонках…
Клиент и сервер держат несколько исторических положений.

Координаты СЕБЯ, ЛЮБИМОГО — клиентские. Если серверные координаты в такт 1234 не совпадают с нашими — откатываемся к серверным, повторно прокрутив нужное количество тактов управления.
Вещи неуправляемые/слабоуправляемые, вроде запаса жизни, берутся подтверждённые сервером.

Координаты ВРАГОВ — серверные (возможно, каким-то образом экстраполированные).

Для физики пуль пишется т.н. «компенсация пинга»: если клиент пишет, что в такт 1234 он стреляет, сервер восстанавливает, что КЛИЕНТ ВИДЕЛ в такт 1234, и сравнивает попадание именно с ТЕМ положением клиента. Для медленных снарядов компенсация обычно не пишется.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
jamakasi666
@jamakasi666
Просто IT'шник.
Конкретно в Вашем случае ответ очень прост.
Клиент предсказывает свое положение но сервер должен ответить координатами где клиент находится и этот ответ будет более приоритетным. Чтобы все это заработало правильно синхронизируйте клиента и сервера по тикам сервера а значит и храните последние N состояний мира на сервере и клиенте т.е. получится следующая схема:
Клиент предсказывает свое положение и отправляет серверу что двигаюсь вправо тик 10
Сервер принял пакет, смотрит тик, откатывает состояние мира до этого тика и задает движение вправо.
Сервер отправляет клиентам состояние игрового мира с номером своего тика.
Клиент приняв пакет со своими координатами и тиком сервера откатывает мир на этот тик и смотрит угадало ли предсказание координаты. Если угадало то ничего не меняешь, если не угодало то откат на эту позицию и слушать сервер дальше.
Кроме того этот механизм сразу решит проблемы с выстрелами и взаимодействиями т.к. сервер может востановить картину что видел игрок в конкретный момент времени и мог ли он попасть в объект\игрока.

По сути и простыми словами выглядит это так:
Сервер всегда находится в настоящем времени но может заглядывать в прошлое.
Клиент всегда видит прошлое состояние мира но сам(и объекты с предсказанием) находятся в настоящем.
Ко всему сказанному сервер может(точнее обязательно должен! ) вводить искуственную задержку для клиентов(в пределах разумного, вычислять среднюю для всех клиентов или некую фиксированную), это гарантированно заставит всех клиентов видеть одинаковое состояние мира независимо от их задержки сети.

Вот, это если вкратце и простыми словами.
Ответ написан
Комментировать
PavelK
@PavelK
Координаты использовать "диапазонные" с поправкой на пинг.
К примеру, выясняем задержку между клиентом и сервером в 100 мс, знаем, что за это время игрок может переместиться, максимум на 5, поэтому на сервере имеем ввиду, что клиент может в этот момент быть от текущей присланной координаты в сфере на +-5. В некоторых случаях вообще лучше задавать общение сразу клиент<=>клиент, но тут Вам решать.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы