Я думал о многопользовательской игре RTS. Часть, которую я не могу обойти, - это синхронизация движения юнита. Если я переместу блок A, чтобы определить XY, я должен передать это обратно на сервер, который передает другому клиенту.
Мне интересно, как будут выглядеть сообщения. Не могли бы вы сообщить серверу, что я перемещаю блок A в XY из JZ? Может быть, вам нужно вместо этого сообщить координаты движения по координатам? Какова наиболее эффективная методология передачи движения единиц от одного клиента к другому?
РЕДАКТИРОВАТЬ
Это заданный вопрос из stackoverflow . Я обнаружил, что этот сайт, вероятно, был лучшим местом для вопроса.
Один из лучших ответов из этого поста:
Я предполагаю, что вы собираетесь использовать сетевую парадигму клиент-сервер? В этом случае вы не можете доверять клиентам обработку фактического расположения блоков, вы должны делегировать эту задачу на сервер. Затем вы берете список команд от каждого клиента за такт и вычисляете движение каждого подразделения, как только это будет выполнено, на следующем тике вы передаете положение каждого подразделения, относящегося к каждому клиенту (либо на основе всей карты, либо на основе просмотра) и запустите процесс заново.
Ответы:
Вы не хотите синхронизировать позиции всех юнитов от сервера до каждого клиента; что займет путь больше пропускной способности , чем вам нужно. Вам также придется иметь дело с интерполяцией / экстраполяцией позиций юнитов и т. Д. Практически ни один профессиональный RTS не использует клиент / сервер!
Вместо этого вы хотите отправлять только команды игроков. Вместо того, чтобы перемещать юниты сразу, когда игрок щелкает мышью, вы поставите команду перемещения в очередь на некоторое время в будущем - обычно всего пару кадров. Каждый отправляет свои команды всем. Через пару кадров каждый выполняет все команды, и, поскольку игра детерминирована, все они видят один и тот же результат.
Недостатком является то, что каждый игрок работает так же медленно, как и самый медленный игрок - если кто-то отстает в рассылке команд, все должны замедлиться и ждать, пока он не догонит (в Starcraft 2 это «XXX замедляет игру» " диалог".
На самом деле, обычно делается еще одна вещь: полностью исключить сервер . Пусть каждый клиент отправит свои команды каждому другому клиенту. Это уменьшает лаг (вместо команды, идущей от вас -> сервер -> противник, она просто идет от вас -> противник) и упрощает кодирование, поскольку вам больше не нужно кодировать отдельный сервер. Такая архитектура называется одноранговой (P2P).
Недостатком является то, что теперь вам нужен способ разрешения конфликтов, но, поскольку команды игроков независимы друг от друга в большинстве RTS, это обычно не составляет большой проблемы. Кроме того, он плохо масштабируется - каждый раз, когда вы добавляете нового игрока, каждый игрок должен отправить ему свои команды. Вы не собираетесь делать MMO RTS, используя P2P.
Эта настройка (отправка только команд с использованием P2P) - это то, как работает большинство RTS, включая Starcraft, C & C и AoE, и это единственный способ, которым AoE может поддерживать 1500 устройств при соединении со скоростью 28,8 Кбит / с .
Вот еще несколько советов по написанию P2P RTS:
rand()
иcos()
т. Д., Но почти все математические операции с плавающей точкой исключены (см. Здесь , здесь и здесь ) ! В этом случае вам лучше использовать клиент-сервер.источник
Я создал протокол RTS с сетью TCP, в котором я передавал сами команды, а не результаты команд . Например, игрок отдает приказ на ход. Если заказ на перемещение действителен в соответствии с этим клиентом, он отправляется на сервер. Затем сервер отправляет его обратно всем клиентам, которые проверяют и выполняют его.
Таким образом, все клиентские машины сами запускают игру, серверный код принимает сообщения и отправляет их всем клиентам. Если клиент отдает распоряжение на перемещение, он не начнет его выполнять, пока не будет получен обратно с сервера.
Сервер также посылает номер «тика», под которым нужно выполнить команду, что на несколько тиков впереди «текущего» тика. Таким образом, все команды могут быть выполнены в одно и то же время на всех машинах.
Одним из преимуществ этого метода является то, что он не зависит от какой-либо отдельной клиентской машины для проверки команды. Если я передам результаты этого перемещения, я смогу взломать его, чтобы быстрее переместить мои юниты. Все клиенты должны выполнять одну и ту же команду, и если один компьютер выполняет ее по-разному, это будет очевидно.
Проверка команды на стороне клиента перед отправкой на сервер не обязательна, но теоретически она экономит сетевой трафик. Я использовал тот же код проверки, чтобы сообщить пользовательскому интерфейсу, что переезд возможен, поэтому он не требует написания дополнительного кода.
Что касается того, как сообщения могут выглядеть. Я не был обеспокоен ультра эффективностью, так как это была моя первая сетевая игра. Я передал команды в виде строк. Команды будут отформатированы так:
"<player_id>:<command>:<parameters>"
Для надуманного примера, команда перемещения может выглядеть следующим образом :
"3:move:522:100:200"
. Это означает, что игрок3
хочетmove
присоединиться522
к (100
,200
).Сервер передает команду на всех клиентов, в том числе тот , кто послал его с номером клеща прилагается так:
"153238:3:move:522:100:200"
.Тогда все клиенты будут выполнять эту команду при выполнении отметки 153238.
источник