Основные понятия
Основные понятия
В многопользовательских играх сетевое взаимодействие позволяет игрокам подключаться к центральному серверу или непосредственно друг к другу, обмениваться данными и играть вместе в реальном времени. На устройстве каждого игрока одновременно работает один и тот же экземпляр игры, а действия игроков синхронизируются по сети.
СЕРВЕР
КЛИЕНТ
КЛИЕНТ
КЛИЕНТ
В сетевой многопользовательской игре одно и то же приложение работает одновременно на нескольких устройствах.
Архитектура типичной сетевой игры включает два основных компонента: клиенты и серверы. Клиенты - это экземпляры игры, запущенные на устройствах игроков: компьютерах, консолях или мобильных телефонах. Они выводят графику, воспроизводят звук, обрабатывают пользовательский ввод и сообщают серверу о действиях игрока.
Серверы, в свою очередь, управляют состоянием игры - актуальными данными обо всех ее элементах. Они обеспечивают обмен между клиентами и следят за соблюдением игровых правил. Сервер может быть выделенным процессом без графического интерфейса, которым управляет разработчик, либо работать на устройстве одного из игроков, одновременно выступающего хостом.
КЛИЕНТ
КЛИЕНТ
КЛИЕНТ
КЛИЕНТ
КЛИЕНТ
Сервер получает ввод от клиентов, обрабатывает игровую логику и отправляет обновления обратно. Хотя окончательные полномочия над состоянием игры принадлежат серверу, клиенты поддерживают локальные копии данных, чтобы игровой процесс оставался отзывчивым. Постоянная синхронизация обеспечивает максимально согласованное состояние игры для всех участников в реальном времени.
СЕРВЕР
КЛИЕНТ
КЛИЕНТ
КЛИЕНТ
Клиент-серверная архитектура
Серверы без графического интерфейса Сервер без графического интерфейса - это сервер, который работает без графического пользовательского интерфейса и выполняет исключительно серверные задачи.
Поскольку такие серверы не отрисовывают графику, их проще масштабировать; обычно их развертывают на выделенном оборудовании или в облачной среде. Подробнее см. раздел «Выделенный игровой сервер» в главе о сетевых топологиях.
Пакеты 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
Конвейеры
Встроенный сетевой драйвер
Встроенная абстракция платформы
Уровни разработки сетевого кода
Basic concepts
In multiplayer gaming, networking enables players to connect to a central server or directly to each other. This allows them to share data and play together in real-time. The same game application runs simultaneously on each player’s device, and each player’s actions are then synchronized across the network.
In networked multiplayer, the same game application runs across multiple devices.
A typical networked game consists of two main components in its architecture, clients and servers. Clients are the instances of the game running on players’ devices – PCs, consoles, or mobile phones. Clients render the game graphics, play the audio, handle user input, and send updates to the server about the player’s actions. Servers, on the other hand, manage the game state, the current status of all the elements in the game. They handle communication between clients and enforce the game’s rules. Servers can be dedicated, headless machines run by the game developers or they can be playerhosted, where one of the players also acts as the server.
The server receives inputs from clients, processes game logic, and sends updates back to clients. Although the server is the final authority on the game state, clients maintain local copies for responsive gameplay. Constant synchronization then keeps the game as consistent as possible for all players in real-time.
The client-server architecture
Headless servers A headless server is a server that operates without a graphical user interface, focusing solely on backend tasks. Because they don’t render graphics, they can scale more easily and are often deployed on dedicated hardware or cloud environments. For more information, see Dedicated game server under Network Topologies.
UDP packets Clients and servers communicate by exchanging data packets using standard Internet protocols like UDP (User Datagram Protocol). In real-time applications, especially fast-paced games like first-person shooters, UDP is preferred to TCP (Transmission Control Protocol) because it gives full control to the game to prioritize different aspects of the communication. Unlike TCP, UDP does not require acknowledgement from the recipient. This makes UDP a more efficient and flexible foundation but it also puts the burden on the application to handle cases when such functionality is required. Each UDP packet consists of a header and a payload. The UTP payload contains additional protocol-specific sections, each with their own headers and payloads. In networking terminology, this nesting is known as encapsulation. The IP and UDP headers are of a fixed size and contain important metadata like the address of the sender and receiver (IP address and ports). The payload varies in size, structure, and content, depending on the specific game and context. For example, a payload could carry player inputs or a snapshot of the game state at one moment in time.
Simplification of a UDP packet
UDP packets favor low latency and speed, essential for real-time applications; however, this speed comes with a lack of reliability as a tradeoff. The UDP protocol doesn’t provide any mechanisms for reliability, ordering, or congestion control. A packet traveling through the internet could experience errors, including: —
Packet Loss: Sometimes a packet may get lost and never arrive at its destination. This could be due to network congestion, faulty hardware, or other issues.
Duplication: A packet might be duplicated, resulting in the same packet arriving multiple times at the receiver. This can happen due to misconfigured network hardware or software.
Reordering: Packets may arrive at the receiver in a different order than they were sent. This can happen if packets take different routes to the destination that have varying latencies.
Corruption: Packet contents may get altered during transmission, resulting in unusable data.
UDP versus TCP A network protocol is a set of rules and conventions that govern how data is transmitted and received over a network. Protocols define how to establish connections, format messages, handle errors, and transmit data. UDP is typically preferred over Transmission Control Protocol (TCP) in game development due to its fast and lightweight nature. TCP, while reliable and suitable for web browsing, ensures ordered data delivery by retransmitting lost or out-of-order packets; this can introduce lag or stutter that don’t make it suitable for real-time gaming. In contrast, UDP accepts some data loss to prioritize real-time performance. This means that games can run smoothly at 60 fps or higher without freezing, even if dropping some non-critical data. UDP usually strikes a better balance between responsiveness and occasional data loss, making it ideal for networked multiplayer games. The following techniques can mitigate UDP’s unreliability. Unlike the built-in functionality in TCP, they can be fine-tuned for use in real-time games. Technique
What it does
Sequence numbers
Each packet has a unique, increasing sequence number. The receiver uses this to detect missing or out-of-order packets.
Acknowledgement (ACK) and ACK bitmasks
Packets include the sequence number of the last received packet, letting the sender know which packets have been delivered. An ACK bitmask tracks the status of multiple packets at once, allowing for quicker detection of lost packets.
Retransmission timeout adjustment (RTO)
This is a technique that makes use of measuring round trip time in TCP approximation. For example, you can measure the round trip time and then use it to adjust client-side interpolation or client-side prediction.
Timeouts
If an acknowledgment isn’t received within a certain period, the packet is considered lost.
Ticks and updates In a multiplayer game, the server handles the core game logic, physics simulations, and other gameplay functions, even if it doesn’t have a display. As the server is only handling the global game state, it takes its input from the clients, much like a single-player game handles inputs from a local player. Instead of having a mouse and keyboard, the server processes those inputs to maintain the “authoritative game state” – this includes everything from current player positions and object states to physics calculations and game progress. The heart of server-side processing is the server tick. A server tick is a cycle during which the server updates the game state based on received inputs. This happens at a fixed interval known as the tick rate, measured in Hertz (Hz) or ticks per second. This tick rate determines the frequency at which the game world is updated. Conversely, the update rate refers to how frequently the client exchanges data with the server. A higher update rate can enhance the responsiveness of the game but requires more bandwidth and processing power. It’s typically constrained by the client’s network capabilities and computing resources.
Tick rate versus update rate
A higher tick rate can improve the game’s responsiveness but may strain server resources. Similarly, a higher update rate enhances interaction smoothness at the expense of greater data transmission. Creating a smooth and responsive multiplayer experience hinges on finding
the right balance between the tick rate and the update rate. The actual tick rate can vary based on gameplay needs. A fast-paced first person shooter often runs at tick rates of 60 Hz or higher to reflect fast player movements and split-second shots. A real-time strategy game, on the other hand, doesn’t rely on twitch reflexes, so a tick rate of 30 Hz may be sufficient. Meanwhile, a large-scale strategy MMO might use a fairly low tick rate of 10 Hz in order to support an extensive number of concurrent players.
Latency Latency is the time it takes for data to travel from the source to the destination. Round-trip time (RTT) measures how long it takes for a packet to travel to its destination and return with a response, providing a gauge of network latency. While subjective, a general rule of thumb is that users notice gameplay degradation around 200ms of latency. Different types of games can tolerate more or less latency. For example, first-person shooter games perform best with less than 100ms of latency, whereas real-time strategy games might allow higher latency values of up to 500 ms.
Round-trip time is a gauge of network latency.
Lower latency produces a responsive experience for the player. Ideally, there is minimal delay between a user’s action and seeing the expected result in a multiplayer game. High latency leads to noticeable delays during gameplay. Sometimes latency results from non-network components. For example, there may be a delay in detecting user input or a hiccup in the render pipeline. Another culprit is Vsync: Though this feature can stop screen tearing, it does so at the cost of additional latency. More often, the network itself is the major source of latency. It can involve several types of delays: —
Processing delay: Routers take time to read packet headers and forward packets to their destination. Though usually minimal, this delay can accumulate across multiple hops.
Transmission delay: This is the time required to put packets onto the network, directly affected by packet size. This is more apparent on end-user networks with lower bandwidth.
Queueing delay: When packets are held in queues due to congestion or limited interface capacity, this delay can significantly increase latency.
Propagation delay: Signals take time to travel across the network. This type of delay results primarily from the physical distance between servers and users, the physical media (fiber, copper, air) and type of signal (electrical, optical, radio wave).
While some latency is unavoidable, especially in internet-based games, there are many techniques (e.g., anticipation, prediction, interpolation) to minimize its impact. We’ll examine a few of these later.
Other networking terms Here are some other terms that you may encounter when discussing latency: Ping: This involves sending and receiving back a basic message to gauge network responsiveness. Think of it as a simplified version of Round Trip Time (RTT). Jitter: This is the variation in RTT due to fluctuating network conditions, which can affect latency mitigation and cause packets to arrive out of order. Bandwidth: This is the amount of data that can be transmitted over a network in a given amount of time. Higher bandwidth can be important for games that need to transmit large amounts of state data. You can find these terms and more in this glossary page of Multiplayer Networking Terminology.
Network synchronization To stay in sync, clients and the server continuously exchange messages in order to maintain a consistent game state across all players. Typically, clients usually send user commands to the server at a high frequency – often at 60 Hz, or about every 16 milliseconds. These commands might be actions or inputs; for example, mouse or gamepad movements or button presses for jumping and shooting. Once the server receives and processes the client commands, it then sends updates about the game world back to the clients. The faster the game reacts to player input, the more responsive it feels. Just bear in mind that the server’s tick rate, the client’s update rate, and the client’s frame rate serve different purposes and don’t need to match. In fact, achieving perfect synchronization is uncommon. A server and its clients are constantly in flux, exchanging a continuous stream of dynamic data. The objective is to reduce their discrepancies, thereby creating the illusion that all clients are playing in unison.
Techniques for network synchronization State synchronization involves the periodic transmission of the state of network objects from the server to the clients. How frequently these game updates happen can vary based on the specific needs of the game genre (e.g. a competitive shooter versus a co-op strategy game). Remote procedure calls (RPCs) invoke functions on the server or other clients remotely. Use RPCs for client-to-server communication, such as sending player inputs, requesting specific actions, or triggering one-time game events. Bandwidth management can significantly impact performance. Synchronization consumes bandwidth, so implement strategies like the following to reduce data transmission over the network: —
Data culling: This reduces network traffic by excluding non-essential updates, focusing only on what is necessary for gameplay. For instance, you can sync only critical axes of movement or trigger VFX and animations locally using events instead of continuously synchronizing them. Any reduction in network traffic can enhance game performance.
Delta compression: This also goes by the term delta encoding. It allows the server to send only the changes (deltas) since the last update. Clients then apply only these deltas to their local game state to keep it in sync with the server.
Interest management: This prioritizes data synchronization based on several criteria. Spatial relevance determines the priority of objects based on their distance from the player and their visibility. Age (or staleness) prioritizes objects or data that haven’t been transmitted recently, making them higher-priority until updated. Interaction focuses on objects that have recently interacted with the player or are likely to do so soon.
These techniques can help you optimize network performance, ensuring a smoother and more efficient gameplay experience.
Network topologies Simply put, a network topology defines how devices are connected and communicate in a multiplayer environment. Each network model has its own advantages and disadvantages. Choosing one depends on the type of game, the desired level of control over the game state, and the resources available for server infrastructure. Topologies can impact the game’s architecture, performance, and the overall player experience. Netcode for GameObjects supports two primary topologies: client-server and distributed authority. Let’s unpack what that means.
Client-server topology The client-server topology is a common network model that divides responsibilities between client devices and a central server to optimize performance and manage the game effectively. A client represents a player’s game instance, handling local inputs, rendering, and partial simulation of the game state. Clients send local inputs like character movements to the server and receive updates in return. The server maintains the definitive, accurate representation of the game world, processing player inputs and enforcing game rules. This central server resolves conflicts and validates actions, ensuring a consistent and fair experience for all players. This setup also helps prevent cheating by controlling game state centrally. Clients and servers can communicate with each other over the internet or a local area network (LAN). Offline LAN games connect multiple devices within the same physical vicinity through a local network without needing internet access. This setup bypasses the internet and ensures minimal latency, high security, and reliable connectivity due to the close proximity of the devices. This makes it suitable for LAN parties, esports tournaments, and environments where the internet is unstable. There are two types of servers within the client-server topology:
Dedicated game server A dedicated game server is a separate entity that only processes data and doesn’t participate as a player. It can offer the highest performance while handling all major simulations and player interactions in networked games. Dedicated servers are integral for games where minimizing cheating is paramount. However, this setup can introduce communication latency as all player state changes need to be processed by the server before being relayed to other clients. Dedicated servers are particularly well-suited for performance-sensitive, competitive games such as first-person shooters. They can be essential to maintaining fairness and reducing disruptive behavior.
A dedicated game server handles all major game simulations.
Client-hosted listen server A client-hosted listen server acts as both server and client, allowing the host to play the game. This can help reduce costs but gives the host a latency advantage (since no packets need to be sent across the network). This setup often results in degraded server performance since the same machine is tasked with running the game server and generating the visual output for the host player. Also, because the hosting client services connections via a residential internet connection, it can be slower than using a dedicated server in a remote data center. This is because residential internet service providers typically prioritize download performance over upload performance.
A client-hosted listen server acts as both a server and client.
Distributed authority The distributed authority network model decentralizes control and management of game state among all participating clients. Each client is responsible for owning, tracking, and managing a portion of the state of objects within the game, with the ability to spawn and manage these objects autonomously. A central, lightweight service monitors changes in object states and manages the routing of network traffic, but it does not simulate the game itself. This topology offers several benefits, including reduced costs and lower input latency, as it eliminates the need for a central server to process all game actions and reduces network round-trips since each client is authoritative over its own objects. For example, that means it can handle actions like movement, attacks, or other game inputs locally without waiting for permission from a server. This results in more immediate feedback for the player, which in turn makes the game feel more responsive. However, it also can be subject to increased vulnerability to cheating as there’s no single authoritative server to validate all actions. Distributed authority is less suitable for games requiring precise simulations or high competitiveness but works well for games with less critical interaction needs.
You can learn more about Unity’s new Distributed Authority package (beta) for Netcode for GameObjects in this Unite 2024 session.
The distributed authority model decentralizes control and game management.
Local or couch multiplayer Local multiplayer games use a single client runtime instance that can be played by two or more people on the same screen in the same physical location. This setup is ideal for social gaming scenarios, offering direct interaction among players without any need for networking. It’s popular in party games and co-op modes, providing a straightforward way for friends and family to play together.
Peer-to-peer (P2P) Each device functions as both client and server, allowing for direct connections between players. This resembles distributed authority but disposes of the lightweight server altogether. This method helps reduce the need for centralized servers, lowering costs and complexity. However, it can introduce challenges in ensuring fairness and consistent latency, as there is no central authority to manage game state and security.
What is an authoritative server? An authoritative server refers to a server setup that is the central controller of game states and logic. As the name implies, it’s the final authority in a networked game. Rather than splitting authority of what is happening in the game across the player machines, an authoritative server runs the full game simulation itself and dictates what is happening in the game. Clients simply send their inputs to the server, which then updates the game and sends back the latest game state. The server also enforces game rules and resolves conflicts. Authoritative servers are one of the simplest ways to implement networked game logic and the one least prone to exploitation by cheaters, ensuring a uniform experience for everyone playing the game.
Network stack A protocol stack, or network stack, is generally speaking software that implements various communication protocols to enable data transmission across networks. It’s organized like a layered cake:
The Network stack (source: Wikipedia)
Each layer only interacts with the layers directly above and below it, providing modularity and simplifying network management. Application layer: The high-level of the stack where most Unity development takes place. Packages like Netcode for GameObjects or Netcode for Entities abstract away the complexities of lower-level networking, allowing developers to focus on implementing multiplayer functionality. Transport layer: The transport layer is responsible for providing reliable data transfer, error detection and correction, flow control, and ensuring end-to-end communication between devices in a network. It facilitates the segmentation and reassembly of data packets and provides mechanisms for error recovery and data integrity. Network layer: The network layer is responsible for routing data packets between networked devices across different networks. It relies on the network infrastructure and protocols, such as IP (Internet Protocol), to handle communication.
Data link and physical layers: These layers directly handle physical transmission of data packets over the network medium, such as Ethernet or Wi-Fi. The data link layer and physical layers are typically handled by the operating system and network hardware. As a Unity developer, you’ll primarily work with the high-level application layer to implement multiplayer features, such as synchronizing GameObjects, managing game state, and handling player interactions. Generally, you won’t need to worry about the lower layers unless your application has specific requirements. This simplifies the network stack to something that looks like this:
Netcode development layers