Unity 6.3
0 онлайн 55 гостей 3 в системе
Вход
Введение в сетевое взаимодействие многопользовательских игр Глава 3 из 11 Оригинал, стр. 9

Основные понятия

Основные понятия

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

СЕРВЕР

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

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

Архитектура типичной сетевой игры включает два основных компонента: клиенты и серверы. Клиенты - это экземпляры игры, запущенные на устройствах игроков: компьютерах, консолях или мобильных телефонах. Они выводят графику, воспроизводят звук, обрабатывают пользовательский ввод и сообщают серверу о действиях игрока.

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

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

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

СЕРВЕР

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

Клиент-серверная архитектура

Серверы без графического интерфейса Сервер без графического интерфейса - это сервер, который работает без графического пользовательского интерфейса и выполняет исключительно серверные задачи.

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

Пакеты UDP Клиенты и серверы взаимодействуют, обмениваясь пакетами данных по стандартным интернет-протоколам, например UDP (User Datagram Protocol - протокол пользовательских дейтаграмм). В приложениях реального времени, особенно в динамичных играх вроде шутеров от первого лица, UDP обычно предпочитают TCP (Transmission Control Protocol - протокол управления передачей), поскольку он позволяет самой игре определять приоритеты различных видов трафика. В отличие от TCP, UDP не требует подтверждения доставки от получателя. Благодаря этому UDP служит более эффективной и гибкой основой, но необходимые механизмы надежности приложение должно реализовать самостоятельно. Каждый UDP-пакет состоит из заголовка и полезной нагрузки. Полезная нагрузка UTP содержит дополнительные разделы конкретного протокола, у каждого из которых есть собственные заголовок и полезная нагрузка. В сетевой терминологии такая вложенность называется инкапсуляцией.

[IP-заголовок] IP-адрес отправителя: 192.168.0.10 IP-адрес получателя: 192.168.0.20 [UDP-заголовок] Порт отправителя: 5000 Порт получателя: 7777 [Заголовок Netcode for GameObjects]

Заголовки IP и UDP имеют фиксированный размер и содержат важные метаданные, в том числе адреса отправителя и получателя - IP-адреса и порты. Размер, структура и содержимое полезной нагрузки зависят от конкретной игры и ситуации. Например, в ней могут передаваться команды игрока или снимок состояния игры в определенный момент.

Идентификатор протокола: 0x4E4654 (NGO) Порядковый номер: 1234 Удалённый ID: 5678 Тип: данные

[Полезная нагрузка] Обновления GameObject: - ID GameObject: 1001 - Transform: - Позиция: (10.0, 20.0, 30.0) - Поворот: (0.0, 45.0, 90.0) - Игрок: - Здоровье: 80 - ID GameObject: 1002

Упрощенная структура UDP-пакета

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

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

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

Сравнение UDP и TCP Сетевой протокол - это набор правил и соглашений, которые определяют, как данные передаются и принимаются по сети. Протоколы определяют, как устанавливать соединения, форматировать сообщения, обрабатывать ошибки и передавать данные.

При разработке игр UDP обычно предпочитают Transmission Control Protocol (TCP) благодаря его скорости и небольшим накладным расходам. TCP надежен и хорошо подходит, например, для просмотра веб-страниц: он обеспечивает доставку данных в правильном порядке, повторно отправляя потерянные пакеты и пакеты, пришедшие не по порядку. Однако это может вызывать задержки и рывки, неприемлемые для игр реального времени.

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

Механизм Порядковые номера

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

Подтверждения (ACK) и битовые Пакет содержит номер последнего полученного пакета. маски ACK Битовая маска ACK показывает состояние нескольких пакетов и ускоряет обнаружение потерь.

Настройка тайм-аута повторной передачи (RTO)

Оценка времени кругового пути помогает настраивать интерполяцию и прогнозирование на стороне клиента.

Тайм-ауты

Если подтверждение не получено за заданное время, пакет считается потерянным.

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

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

Основа серверной обработки - серверный тик. Это цикл, в течение которого сервер обновляет состояние игры по полученным входным данным. Циклы выполняются с фиксированным интервалом, а их частота называется частотой тиков и измеряется в герцах (Гц), то есть тиках в секунду. Она определяет, как часто обновляется игровой мир. Частота обновлений, в свою очередь, показывает, как часто клиент обменивается данными с сервером. Ее увеличение может сделать игру отзывчивее, но потребует большей пропускной способности и вычислительных ресурсов. Обычно частоту ограничивают возможности сети и оборудования клиента.

30 Гц: ПРИЁМ И ПЕРЕДАЧА

33,33 мс

КЛИЕНТ

33,33 мс

30 Гц

СЕРВЕР

60 Гц: ПРИЁМ И ПЕРЕДАЧА

16,66 мс

КЛИЕНТ

16,66 мс

60 Гц

СЕРВЕР

Частота тиков и частота обновлений

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

правильный баланс между частотой тиков и частотой обновлений.

Требуемая частота тиков зависит от игрового процесса. Динамичный шутер от первого лица часто работает с частотой 60 Гц и выше, чтобы точно отражать быстрые перемещения и мгновенные выстрелы. Стратегия в реальном времени меньше зависит от скорости реакции, поэтому ей может быть достаточно 30 Гц. А масштабная стратегическая MMO способна использовать сравнительно низкую частоту 10 Гц, чтобы обслуживать множество одновременно подключенных игроков.

Задержка Задержка - это время, за которое данные проходят от источника до получателя. Время приема-передачи (round-trip time, RTT) показывает, сколько занимает путь пакета до адресата и возвращение ответа, и служит показателем сетевой задержки. Оценка субъективна, но обычно ухудшение игрового процесса становится заметным при задержке около 200 мс. Допустимый уровень зависит от жанра: шутеры от первого лица лучше всего работают при задержке менее 100 мс, тогда как стратегия в реальном времени может оставаться приемлемой при значениях до 500 мс.

10 мс

ПИНГ КЛИЕНТА = 20 мс (10 мс + 10 мс)

КЛИЕНТ

10 мс

СЕРВЕР

Время приема-передачи служит показателем сетевой задержки.

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

- Задержка передачи: время, необходимое для помещения пакета в сеть; оно напрямую зависит от размера пакета. Особенно заметно в сетях конечных пользователей с невысокой пропускной способностью. - Задержка в очереди: при перегрузке или ограниченной пропускной способности интерфейса пакеты ожидают отправки в очереди, что может существенно увеличить общее время доставки.

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

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

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

Ping: отправка простого сообщения и получение ответа для оценки отзывчивости сети. Это упрощенный вариант измерения времени приема-передачи (RTT). Jitter: колебания RTT из-за изменения состояния сети. Они могут снизить эффективность компенсации задержки и привести к нарушению порядка доставки пакетов.

Пропускная способность: объем данных, который сеть может передать за единицу времени. Высокая пропускная способность особенно важна для игр, пересылающих большие объемы данных о состоянии. Эти и другие определения приведены в глоссарии Multiplayer Networking Terminology.

Сетевая синхронизация Для синхронизации клиенты и сервер постоянно обмениваются сообщениями, поддерживая согласованное состояние игры у всех игроков. Обычно клиенты часто отправляют серверу команды пользователя - например, с частотой 60 Гц, то есть примерно каждые 16 мс. Это могут быть действия или входные данные: движение мыши или стика геймпада, а также нажатия кнопок прыжка и стрельбы.

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

Методы сетевой синхронизации Синхронизация состояния предполагает, что сервер периодически передает клиентам состояние сетевых объектов. Частота таких обновлений зависит от потребностей жанра - например, у соревновательного шутера и кооперативной стратегии они различаются. Удаленные вызовы процедур (RPC) позволяют вызывать функции на сервере или других клиентах. Их используют для обмена между клиентом и сервером: отправки команд игрока, запроса конкретного действия или запуска однократного игрового события. Грамотное управление пропускной способностью существенно влияет на производительность. Синхронизация расходует сетевой ресурс, поэтому объем передаваемых данных следует сокращать, например с помощью следующих приемов:

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

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

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

Топология влияет на архитектуру и производительность игры, а также на впечатления игроков. Netcode for GameObjects поддерживает две основные топологии: клиент-сервер и Distributed Authority. Разберемся, что это означает.

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

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

В клиент-серверной топологии применяются серверы двух типов:

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

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

СЕРВЕР

КЛИЕНТ

КЛИЕНТ

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

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

КЛИЕНТ

Выделенный игровой сервер обрабатывает все основные игровые симуляции.

Listen-сервер на клиенте Listen-сервер на клиенте одновременно выступает сервером и клиентом, поэтому хост может участвовать в игре. Это снижает расходы, но дает хосту преимущество по задержке, поскольку его пакетам не приходится проходить через сеть.

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ КЛИЕНТ-ХОСТ

КЛИЕНТ

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

КЛИЕНТ

КЛИЕНТ

Listen-сервер на клиенте одновременно работает как сервер и как клиент.

Распределенные полномочия Модель Distributed Authority децентрализует контроль и управление состоянием игры между участвующими клиентами. Каждый клиент владеет частью игровых объектов, отслеживает их состояние и может самостоятельно создавать эти объекты и управлять ими.

Центральный облегченный сервис отслеживает изменения состояния объектов и маршрутизирует сетевой трафик, но не выполняет симуляцию самой игры. У этой топологии есть несколько преимуществ: более низкая стоимость и меньшая задержка ввода. Центральному серверу не приходится обрабатывать все игровые действия, а число сетевых циклов приема-передачи сокращается, поскольку каждый клиент имеет полномочия над собственными объектами. Например, движение, атаки и другие команды можно обработать локально, не ожидая разрешения сервера. Игрок быстрее видит результат, и управление ощущается отзывчивее. Однако отсутствие единого авторитетного сервера, проверяющего все действия, повышает уязвимость к читерству.

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

Подробнее о новом beta-пакете Unity Distributed Authority для Netcode for GameObjects можно узнать из доклада Unite 2024.

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

КЛИЕНТ

Модель Distributed Authority децентрализует контроль и управление игрой.

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

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

Что такое авторитетный сервер? Авторитетным называют сервер, который централизованно управляет состоянием и логикой игры. Именно он принимает окончательные решения в сетевой игре.

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

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

Сетевой стек Стек протоколов, или сетевой стек, - это программное обеспечение, реализующее различные протоколы связи для передачи данных по сети. Он устроен подобно слоеному пирогу: Единица данных

Уровни хоста

Данные

Данные

Данные

Сегменты

Уровни среды

Пакеты

Кадры

Биты

Уровни Прикладной Сетевой процесс приложения

Представления Представление и шифрование данных

Сеансовый Обмен между хостами

Транспортный Сквозные соединения и надёжность

Сетевой Выбор маршрута и логическая адресация (IP)

Канальный Физическая адресация (MAC и LLC)

Физический Среда, сигнал и передача битов

Сетевой стек (источник: Wikipedia)

Каждый уровень взаимодействует только с соседними уровнями сверху и снизу. Это обеспечивает модульность и упрощает управление сетью. Прикладной уровень: верхняя часть стека, где выполняется основная работа разработчика Unity. Пакеты Netcode for GameObjects и Netcode for Entities скрывают сложность низкоуровневого сетевого взаимодействия, позволяя сосредоточиться на реализации многопользовательских возможностей.

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

Сетевой уровень: отвечает за маршрутизацию пакетов между устройствами в разных сетях. Для обмена он использует сетевую инфраструктуру и протоколы, например IP (Internet Protocol - интернет-протокол).

Канальный и физический уровни: непосредственно обеспечивают передачу пакетов по физической среде, например Ethernet или Wi-Fi. Обычно работу этих уровней выполняют операционная система и сетевое оборудование. Разработчик Unity в основном работает с высокоуровневым прикладным уровнем, реализуя многопользовательские функции: синхронизацию GameObject, управление состоянием игры и обработку взаимодействий игроков. Обычно нижние уровни не требуют внимания, если у приложения нет особых требований. Поэтому сетевой стек можно представить в упрощенном виде:

Игровая логика

Собственный Netcode

Конвейеры

Встроенный сетевой драйвер

Встроенная абстракция платформы

Уровни разработки сетевого кода