Какие проблемы возникают при реализации многопользовательских игр в реальном времени?

StackOverflow https://stackoverflow.com/questions/90423

Вопрос

У меня есть некоторый опыт создания мультиплеера пошаговая игры, использующие сокеты, но я никогда не пробовал играть в игры в реальном времени.С какими дополнительными проблемами мне придется иметь дело?Нужно ли мне вести историю действий игроков на случай, если отстающие игроки что-то сделали в прошлом?Действительно ли мне нужно использовать пакеты UDP или TCP будет достаточно?Что еще?

Я еще не решил, что делать, но для целей этого вопроса вы можете рассмотреть 2D-игру для 10 игроков с движением X-Y.

Это было полезно?

Решение

  • «клиент-сервер» или «одноранговая сеть» или что-то среднее между ними:какой компьютер имеет право на какие игровые действия.

В пошаговых играх обычно очень легко просто сказать: «У сервера есть высшие полномочия, и все готово».В играх в реальном времени часто именно этот дизайн является отличным началом, но как только вы добавляете задержку, движения/действия клиента кажутся неотзывчивыми.Таким образом, вы добавляете своего рода «сокрытие задержки», позволяющее входным данным клиентов немедленно влиять на их персонажей или юнитов, чтобы решить эту проблему, и теперь вам приходится иметь дело с согласованием проблем, когда игровое состояние клиента и сервера начинает расходиться.В 9 случаях из 10 это нормально, вы выталкиваете или перемещаете объекты, на которые повлиял клиент, на авторитетную позицию, но в 1 из 10 раз объектом является аватар игрока или что-то в этом роде, такое решение неприемлемо, поэтому вы начинаете предоставить клиенту полномочия на некоторые действия.Теперь вам нужно согласовать несколько игровых состояний на сервере и открыть себя для потенциального «читерства» через вредоносный клиент, если вас волнуют подобные вещи.По сути, именно здесь и возникает каждый телепорт/обман/любая ошибка/чит.

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

  • «синхронизированный» или «асинхронный»

Общая стратегия обеспечения того, чтобы все игроки работали в одном и том же игровом состоянии, состоит в том, чтобы просто согласовать список входных данных игрока (с помощью одной из моделей, описанных выше), а затем синхронно воспроизвести симуляцию игрового процесса на всех машинах.Это означает, что логика моделирования должна точно совпадать, иначе игры рассинхронизируются.На самом деле это и проще, и сложнее, чем кажется.Это проще, потому что игра — это всего лишь код, а код выполняется практически одинаково, когда он предоставляет одинаковые входные данные (даже генераторы случайных чисел).Это сложнее, потому что есть два случая, когда это не так:(1) когда вы случайно используете случайное значение вне игровой симуляции и (2) когда вы используете числа с плавающей запятой.Первое исправляется введением строгих правил/утверждений относительно того, какие ГСЧ в каких игровых системах используются.Последнее решается отказом от использования поплавков.(на самом деле у плавающих чисел есть две проблемы: одна из них работает по-разному в зависимости от конфигурации оптимизации вашего проекта, но даже если это было решено, они работают непоследовательно на разных архитектурах процессоров, лол).Starcraft/Warcraft и любая игра, предлагающая «повтор», скорее всего, используют эту модель.Фактически, наличие системы повторов — отличный способ проверить синхронизацию ваших ГСЧ.

При использовании асинхронного решения органы управления состоянием игры просто транслируют все это состояние всем остальным клиентам на определенной частоте.Клиенты берут эти данные и вводят их в свое игровое состояние (и обычно выполняют некоторую упрощенную экстраполяцию, пока не получат следующее обновление).Здесь «udp» становится жизнеспособным вариантом, поскольку вы рассылаете спам по всему состоянию игры каждые ~1 секунду или около того, удаление некоторой части этих обновлений не имеет значения.Для игр, в которых относительно мало игрового состояния (Quake, World of Warcraft), это зачастую самое простое решение.

Другие советы

Есть несколько факторов, влияющих на настройку многопользовательской игры.

  1. Протокол, важно, чтобы вы решили, хотите ли вы TCP или UDP.UDP имеет меньшие издержки, но не гарантирует доставку.И наоборот, TCP более надежен.Для каждой игры будет свой предпочтительный протокол.UDP, например, подойдет для шутера от первого лица, но может не подойти для стратегии в реальном времени, где информация должна быть согласованной.

  2. Брандмауэр/Соединение.Убедитесь, что ваша многопользовательская игра не требует создания 2000 исходящих подключений и использует стандартный порт, чтобы упростить переадресацию портов.Взаимодействие с брандмауэром Windows, вероятно, будет дополнительным бонусом.

  3. Пропускная способность.Это важно: какой объем данных вы собираетесь передавать через сетевое соединение?Я думаю, это будет зависеть от производительности тестирования и записи.Если вам требуется более 200 Кбит/с для каждого клиента, возможно, вам стоит переосмыслить некоторые вещи.

  4. Нагрузка на сервер.Это тоже важно, сколько обработки требуется серверу для нормальной игры?Вам нужен супер-8-ядерный сервер с 16 ГБ ОЗУ для его работы?Есть ли способы его уменьшить?

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

Планирование — ваш лучший друг.Выясните, каковы ваши действительно потребности.

Загрузка данных:Будут ли все компьютеры иметь одинаковые модели и графику, а в сети будут перемещаться только имена и местоположения?Если каждый игрок может настроить своего персонажа или другие предметы, вам придется перемещать эти данные.

Мошенничество:тебе стоит об этом беспокоиться?Можете ли вы доверять тому, что говорит каждый клиент?Если нет, то логика на стороне сервера будет отличаться от логики на стороне клиента.Представьте себе простой случай: каждый из ваших 10 игроков может иметь разную скорость движения из-за бонусов.Чтобы свести к минимуму читерство, вам следует рассчитать, как далеко каждый игрок может переместиться между обновлениями связи с сервером, иначе игрок может взломать там скорость, и ничто его не остановит.Если игрок постоянно работает немного быстрее, чем ожидалось, или совершает однократный прыжок, сервер просто переместит его в ближайшее возможное место, потому что это, вероятно, сдвиг часов или однократное прерывание связи.Однако, если игрок постоянно перемещается вдвое дальше, чем возможно, возможно, будет разумно выгнать его из игры.Чем больше математических вычислений, чем больше частей состояния игры вы можете дважды проверить на сервере, тем более последовательной будет игра, кстати, это затруднит мошенничество.

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

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

Насколько важно избегать измен?[Можете ли вы доверять любой информации, поступающей от клиента, или им можно доверять и аутентифицировать их?]

Объектная модельКак объекты передаются от одной машины к другой?Как выполняются действия над объектом?

Вы используете клиент/сервер или одноранговую систему?

Случайные числаЕсли вы используете одноранговую сеть, вам необходимо обеспечить их синхронизацию и синхронизацию случайных чисел.

Если вы используете клиент/сервер, как вы справляетесь с задержками?[счисление ?]

Существует множество нетривиальных проблем, связанных с сетевым кодированием.

Посетите RakNet, где можно бесплатно загрузить код, а также его дискуссионные группы.

TCP подойдет, если вы работаете в локальной сети.Но если вы хотите играть онлайн, вы должны использовать UDP и реализовать свой собственный TCP-подобный уровень:необходимо пропустить NAT через маршрутизаторы.

Вам нужно выбрать между одноранговой связью или связью клиент-сервер.В модели клиент-сервер синхронизацию и состояние мира реализовать проще, но вам может не хватать реакции в сети.В Pee-to-peer сложнее, но быстрее для игрока.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top