Многопользовательская игра на основе плитки: загрузка сервера и клиента

Я разрабатываю многопользовательскую игру на основе плитки (представьте себе habbo) и испытываю определенные проблемы с движением. Идея состоит в том, чтобы щелкнуть по плитки (целевой плитки), чтобы ваш аватар двигался туда, и каждый может видеть, как вы двигаетесь туда. Для этого есть функция поиска пути.

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

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

Я прочитал несколько случаев, когда pathfinder запускается на сервере, клиент просто отправляет целевой фрагмент и получает каждые x мсеку обновление с сервера с помощью вычислений пути для каждого аватара в движении (даже самого себя). Проблема, которую я нахожу здесь, заключается в том, как установить это «x mseconds» и что это может означать большую нагрузку на сервер, обрабатывая все вычисления поиска пути ...

Каковы преимущества и недостатки каждого подхода?

5 голосов | спросил Carlos Navarro Astiasarán 2 J0000006Europe/Moscow 2013, 19:14:09

4 ответа


2

Вот как мы это сделали в Подземелья :

  • Клиент отправляет целевую плиту на сервер.
  • Сервер распределяет целевую плиту всем клиентам
  • Сервер и все клиенты запускают один и тот же детерминированный алгоритм поиска пути и пути.
  • Как защитник, время от времени (например, каждые 3 секунды) сервер отправляет текущую позицию всем клиентам.

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

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

ответил Imi 5 J0000006Europe/Moscow 2013, 17:04:58
1

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

ответил petervaz 4 J0000006Europe/Moscow 2013, 17:34:33
1

При создании многопользовательских игр с моделью клиент-сервер сервер должен хранить «главную копию» симуляции. Именно это делает сервер авторитетным .

Когда игрок нажимает на плитку для перемещения:

  1. Отправьте эту позицию плитки на сервер.
  2. Сделать сервер определением, действительна ли эта позиция плитки для перемещения. Здесь вы можете убедиться, что плитка находится на границе карты, действительна, и игрок может ее достичь.
  3. Если позиция плитки верна, отправьте команду всем клиентам для обновления имитации.
  4. Если есть ошибка, помните, что на сервере хранится «главная копия»! Сервер может отправлять данные клиенту, который синхронизирует состояния игры.
  

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

Сколько клиентов вы хотите обрабатывать сразу? Если вы не обрабатываете сотни или тысячи игроков, производительность должна быть чем-то, что вы должны проверить, прежде чем делать предположения. Дайте частоте обновления начальное значение, например 10 или 15 раз в секунду. Если у вас есть проблемы с пропускной способностью или производительностью, вы должны внести дополнительные изменения.

Последнее примечание: НИКОГДА слепо не доверяйте данным клиента. Сервер должен выполнять проверку ввода и оставаться в состоянии контроля, когда это имеет значение.

ответил Nick Caplinger 5 J0000006Europe/Moscow 2013, 07:19:42
1

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

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

Шаблон «обновить каждый х мс», который я читаю здесь снова и снова, - это анти-шаблон . Нет причин отправлять какую-либо информацию, которая является избыточной или легко предсказуемой. Когда это возможно, сообщите только клиентам, когда информация действительно изменилась. Когда информация изменяется предсказуемой (например, позиция объекта, движущегося с постоянной скоростью в постоянном направлении), вам нужно сообщить об этом игроку только тогда, когда этот предсказуемый вектор изменится.

ответил Philipp 5 J0000006Europe/Moscow 2013, 13:42:23

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132