netlib.narod.ru< Назад | Оглавление | Далее >

Создание архитектуры многопользовательской игры

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

Начните с понимания того, чему вам предстоит противостоять, используя сеть, и что вы можете сделать, чтобы обеспечить правильную работу. Будет полезно посмотреть как используется сетевая архитектура клиент/сервер. В главе 5, «Работа с сетью с DirectPlay», объяснялись основы работы с сетевыми коммуникациями на стороне клиента и сервера, а сейчас пришло время посмотреть как сервер и клиент могут эффективно работать вместе с точки зрения игрового процесса.

Работаем вместе: клиент и сервер

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

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

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

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

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


Рис. 15.4. Клиент отправляет сообщение и ждет ответа от сервера, ощущая задержку передачи (отставание)

Рис. 15.4. Клиент отправляет сообщение и ждет ответа от сервера, ощущая задержку передачи (отставание)


Чтобы обеспечить плавность событий и помочь смягчить эффекты задержки и отставания, клиентам позволяется производить незначительные изменения в игровом мире между поступающими с сервера обновлениями. Эти небольшие изменения обычно являются только обновлениями перемещения персонажа. В этом случае клиент не ждет обновлений от сервера, чтобы переместить персонажи; клиент может только предположить, как обновлять все персонажи, основываясь на их последнем известном состоянии (рис. 15.5). Подобные предположения называются расчетом траектории (dead reckoning) и применяются в сетевых играх.


Рис. 15.5. Благодаря расчету траектории, идущий персонаж продолжает движение, пока сервер не сообщит, что персонаж остановился

Рис. 15.5. Благодаря расчету траектории, идущий персонаж продолжает движение, пока сервер не сообщит, что персонаж остановился


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

Как упоминалось, вторая проблема при использовании сетевых систем — это отсчет игрового времени. Взгляните: попытка синхронизировать десятки клиентов практически нереальна. Каждый компьютер подключен к сети с различным временем запаздывания; некоторые клиенты дольше отправляют сообщения серверу и позже принимают их обратно от сервера.

На стороне клиента один игрок может выполнить перемещение точно в тот же момент, что и другой, но поскольку эти действиям требуется время, чтобы достичь сервера, у клиента с более быстрым соединением есть преимущество (рис. 15.6).


Рис. 15.6. У клиента слева задержка меньше, чем у игрока справа, поэтому его действия первыми достигнут сервера и будут обработаны раньше

Рис. 15.6. У клиента слева задержка меньше, чем у игрока справа, поэтому его действия первыми достигнут сервера и будут обработаны раньше


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

ВНИМАНИЕ!
Если вы оставляете важные решения (такие, как сражения) на стороне клиента, вас ждут неприятности, поскольку взломщики и мошенники будут использовать эти лазейки для получения преимуществ. Помните, что только сервер ответственен за отслеживание хода игры; клиенты — это просто порталы в игровой мир.

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

Взгляд на сервер

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

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

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

Полученное от клиента сетевое сообщение помещается в очередь сообщений (message queue). Использование очереди сообщений ускоряет сетевые операции и оставляет больше времени для работы основного приложения (а не потока с кодом работы с сетью). Сервер управляет очередью сообщений (стеком сообщений), хранящей все входящие сообщения. Поступающее сообщение добавляется в очередь. Сервер постоянно извлекает наиболее старые сообщения и перенаправляет их различным функциям для обработки. Этот процесс обработки сообщений показан на рис. 15.7.


Рис. 15.7. Сетевые сообщения вставляются в очередь в порядке их поступления

Рис. 15.7. Сетевые сообщения вставляются в очередь в порядке их поступления. Очередь сообщений гарантирует, что следующим сервером будет обработано самое старое из сообщений


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

СОВЕТ
Для улучшения синхронизации клиент и сервер вычисляют временную задержку получения сообщения. Вы увидите как вычислять задержку в разделе «Вычисление запаздывания» далее в этой главе.

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

Кроме работы с сетевыми сообщениями, сервер обновляет состояние игроков. Если последним известным состоянием персонажа игрока была ходьба в заданном направлении, игрок продолжает движение в этом направлении. Сервер, как ответственный за все, должен выполнять проверку столкновений, чтобы перемещающиеся персонажи не ходили сквозь стены!

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

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

Взгляд на клиента

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

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

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


Рис. 15.8. Клиент отсылает изменение состояния серверу только когда игрок выбирает перемещение в направлении отличном от предыдущего

Рис. 15.8. Клиент отсылает изменение состояния серверу только когда игрок выбирает перемещение в направлении отличном от предыдущего, что экономит время, поскольку не приходится пересылать одно и то же направление перемещения снова и снова


Если говорить об изменении действий игрока, какие точно действия может выполнять игрок? Например, перемещение. Когда игрок ходит по карте, направление его движения передается на сервер. Заметьте, что отправляется только направление движения.

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

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

Игроки могут выполнять обновления только каждые 33 мс. Это временное ограничение обновлений введено для того, чтобы клиенты не затопили сервер тысячами действий. Сохраняя минимальный уровень действий сервер может обрабатывать все более быстро и игровой процесс остается плавным.

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

Ладно, достаточно исследований; перейдем к созданию настоящей сетевой игры!


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz