Я реализую многопользовательский клон астероидов, чтобы узнать об архитектуре клиент-серверной сети в играх. Я потратил время на чтение публикаций GafferOnGames и Valve о технологиях клиент / сервер. У меня проблемы с двумя понятиями.
В настоящее время у меня есть авторитетный игровой сервер, симулирующий физику с box2d и рассылающий информацию о состоянии мира клиентам примерно 20 раз в секунду. Каждый клиент отслеживает последние несколько снимков, которые он получил, и переключается между двумя состояниями, чтобы сгладить движение спрайтов. Однако это не так гладко. Это может быть некоторое время сглаживанием, затем немного подергиванием, затем возвращением к сглаживанию и т. Д. Я пробовал оба протокола TCP и UDP, оба они примерно одинаковы. Есть идеи, в чем может быть моя проблема? (Примечание: я реализовал это сначала для одиночной игры, и движение спрайтов было совершенно плавным при 60 кадрах в секунду при обновлении мира физики только 20 раз в секунду).
Чтобы решить первую проблему, я подумал, что, возможно, клиент также должен запустить симуляцию box2d и просто обновить позиции своих спрайтов, чтобы они соответствовали снимкам сервера, когда они не совпадают. Я подумал, что это может быть более плавным, поскольку моя однопользовательская реализация гладкая. Это хорошая идея?
Даже если это не решит вышеуказанную проблему, нужно ли это для предсказания на стороне клиента? Например, если игрок пытается переместить свой корабль, как он узнает, что он ударил астероид, стену или вражеский корабль без физического моделирования? Похоже, что их корабль пройдет через объект, с которым он должен столкнуться, прежде чем они получат снимок с сервера, который говорит, что они попали в объект.
Благодарность!
источник
+-*/
» полностью ложно. Все эти операции в IEEE-754 могут различаться в зависимости от реализации. Смотрите здесь и здесь для получения дополнительной информации.Вероятно, это выглядит не очень хорошо, поскольку интерполяция между ними зависит от наличия следующего набора данных для интерполяции. Это означает, что, если есть короткий скачок лага, все должно ждать, чтобы наверстать упущенное.
В GameDev есть старая статья об использовании кубических сплайнов для прогнозирования положения объекта после точки, в которой у вас в последний раз были данные для него. Затем вы используете эту позицию, а затем корректируете сплайн при получении новых данных для учета его новой позиции. Это также, вероятно, намного дешевле, чем запускать второе физическое моделирование, и это означает, что вам не нужно решать, кому вы доверяете, так как вы явно реализовали клиент, создающий его, по ходу дела. :)
источник
Я сделал что-то подобное сам и запускал Box2D только на клиентах. То, как я это сделал, состояло в том, чтобы позволить клиенту самостоятельно запускать собственное моделирование, отправляя текущую скорость (и вращение) каждого синхронизирующего пакета на сервер. Затем сервер отправляет эту информацию другим игрокам, которые устанавливают вновь полученные скорости для реплицируемых объектов. Это было очень гладко, без каких-либо заметных различий между клиентами.
Конечно, проблема в том, что здесь нет централизованного контроля над сущностями, но я думаю, что это можно сделать и на стороне сервера, выполнив также и симуляцию физики на стороне сервера.
источник
Лично я предпочел бы запускать симуляции только на сервере и передавать на него любые изменения линейных / угловых скоростей / ускорений задействованных объектов всякий раз, когда они происходят. Когда определенный объект по какой-либо причине изменяет какие-либо свои физические свойства (например, вышеупомянутые скорости и ускорения), это конкретное изменение будет отправлено с сервера на клиент, и клиент изменит свою сторону данные объекта соответственно.
Преимущество этого по сравнению с вашей текущей реализацией состоит в том, что это избавит от необходимости интерполяции на стороне клиента и будет генерировать очень точное поведение на объектах. Проблема в том, что этот метод весьма уязвим к задержкам, которые становятся очень большой проблемой, когда игроки географически находятся слишком далеко друг от друга.
Что касается вопроса 1, я говорю, что проблема заключается в колебаниях латентности, потому что нет абсолютной гарантии, что между каждым получением снимка будет абсолютно точный 20-секундный интервал. Позвольте мне проиллюстрировать (будучи "т" время, измеренное в миллисекундах):
1) В момент времени t = 20 с начала игры клиент получил снимок и успешно и беспроблемно выполнил интерполяцию.
2) В момент времени t = 40 между сервером и клиентом возникла задержка, и моментальный снимок фактически пришел только к моменту времени t = 41.
3) При t = 60 сервер отправил еще один снимок, но одна секунда моделирования была потрачена впустую на стороне клиента из-за задержки. Если моментальный снимок достигается при t = 60, клиент не будет выполнять интерполяцию 40 и 60 моментов, а фактически из моментов 41–60, генерируя другое поведение. Эта неточность может быть причиной возможной «вялости».
Что касается вопроса 2, ваша идея может сработать, если вы реализуете что-то, что будет эффективно отслеживать, действительно ли каждый объект синхронизирован клиент-сервер, без необходимости посылать пакеты каждый кадр, информирующий о положении объектов. Даже если вы делаете это с дискретными интервалами, вы не только столкнетесь с той же проблемой, что и в вопросе 1, но и получите слишком большое количество данных для передачи (что плохо).
источник