Сетевой код — это общий термин , который чаще всего используется геймерами в отношении сетевых соединений в онлайн-играх , часто ссылаясь на проблемы синхронизации между клиентами и серверами. Игроки часто делают вывод о «плохих сетевых кодах», когда сталкиваются с задержками или когда их входные данные теряются. К распространенным причинам таких проблем относятся высокая задержка между сервером и клиентом, потеря пакетов , перегрузка сети и внешние факторы, не зависящие от качества сети, такие как время рендеринга кадра или непостоянная частота кадров . [1] [2] Сетевые коды могут быть разработаны для поддержания синхронного и бесперебойного взаимодействия между пользователями, несмотря на эти сетевые проблемы.
В отличие от локальной игры, где вводы всех игроков выполняются мгновенно в одной и той же симуляции или экземпляре игры, в онлайн-игре есть несколько параллельных симуляций (по одной для каждого игрока), где вводы от соответствующих игроков принимаются мгновенно, в то время как вводы для того же кадра от других игроков поступают с определенной задержкой (большей или меньшей в зависимости от физического расстояния между игроками, качества и скорости сетевых подключений игроков и т. д.). [3] Во время онлайн-матча игры должны получать и обрабатывать ввод игроков в течение определенного времени для каждого кадра (равного 16,66 мс на кадр при 60 FPS ), и если ввод удаленного игрока определенного кадра (например, кадра номер 10) поступает, когда другой уже выполняется (например, в кадре номер 20, 166,66 мс позже), происходит рассинхронизация между симуляциями игроков. Существует два основных решения для разрешения этого конфликта и обеспечения плавного хода игры:
Классическим решением этой проблемы является использование сетевого кода на основе задержки. Когда входы удаленного игрока поступают с опозданием, игра соответственно задерживает входы локального игрока, чтобы синхронизировать два входа и запустить их одновременно. Эта дополнительная задержка может быть разрушительной для игроков (особенно при высокой задержке), но в целом изменение не очень заметно. Однако эти задержки могут быть непоследовательными из-за внезапных колебаний текущей задержки. Если задержка между игроками превышает установленное буферное окно для удаленного игрока, игра должна ждать, в результате чего экраны «замораживаются». Это происходит из-за того, что сетевой код на основе задержки не позволяет продолжать симуляцию, пока не получит входы от всех игроков в рассматриваемом кадре. [4] Эта переменная задержка приводит к непоследовательному и неотзывчивому опыту по сравнению с офлайн-игрой (или игрой по локальной сети ) и может негативно повлиять на производительность игрока в чувствительных к времени и быстро меняющихся жанрах, таких как файтинги . [5]
Альтернативной системой предыдущего сетевого кода является откат сетевого кода. Эта система немедленно запускает вводы локального игрока (чтобы они не задерживались, как в случае с сетевым кодом на основе задержки), как если бы это была офлайн-игра, и предсказывает вводы удаленного игрока или игроков, а не ждет их (предполагая, что они сделают тот же ввод, что и в предыдущем такте). Как только эти удаленные вводы прибудут (предположим, например, через 45 мс), игра может действовать двумя способами: если прогноз верен, игра продолжается как есть, полностью непрерывным образом; если прогноз был неверен, состояние игры возвращается, и игровой процесс продолжается с исправленного состояния, что рассматривается как «прыжок» к другому игроку или игрокам (эквивалентно 45 мс, следуя примеру). [1] Некоторые игры используют гибридное решение, чтобы замаскировать эти «прыжки» (которые могут стать проблематичными по мере роста задержки между игроками, поскольку остается все меньше и меньше времени для реагирования на действия других игроков) с фиксированной задержкой ввода и последующим использованием отката. Откат довольно эффективен для сокрытия всплесков задержки или других проблем, связанных с несоответствиями в соединениях пользователей, поскольку прогнозы часто оказываются верными, а игроки даже не замечают этого. Тем не менее, эта система может быть проблемной, когда игра клиента замедляется (обычно из-за перегрева), поскольку могут быть вызваны проблемы разлома, приводящие к обмену билетами между машинами с неравной скоростью. Это создает визуальные сбои , которые прерывают игровой процесс тех игроков, которые получают ввод в более медленном темпе, в то время как игрок, чья игра замедляется, будет иметь преимущество перед остальными, получая ввод от других с нормальной скоростью (это известно как односторонний откат). [6] Для решения этой неравномерной входной поток (и, следовательно, неравномерный поток кадров) существуют стандартные решения, такие как ожидание поступления поздних записей на все машины (аналогично модели сетевого кода на основе задержки) или более гениальные [ требуется ссылка ] решения, такие как то, которое в настоящее время используется в Skullgirls , которое заключается в систематическом пропуске одного кадра каждые семь, чтобы, когда игра сталкивается с рассматриваемой проблемой, она могла восстановить пропущенные кадры, чтобы постепенно синхронизировать экземпляры игр на различных машинах. [7]
Откат сетевого кода требует, чтобы игровой движок мог вернуть свое состояние, что требует внесения изменений во многие существующие движки, и поэтому реализация этой системы может быть проблематичной и дорогостоящей в играх класса AAA (которые обычно имеют надежный движок и сеть с высоким трафиком), как прокомментировал продюсер Dragon Ball FighterZ Томоко Хироки и другие. [8]
Хотя эта система часто ассоциируется с одноранговой архитектурой и файтингами, существуют формы откатных сетей, которые также широко используются в клиент-серверных архитектурах (например, агрессивные планировщики, используемые в системах управления базами данных, включают функциональность отката) и в других жанрах видеоигр . [1]
Существует популярная библиотека GGPO , лицензированная MIT , которая предназначена для реализации откатной сети в играх (в основном файтингах). [9]
Задержка неизбежна в онлайн-играх, и качество игрового опыта строго связано с этим (чем больше задержка между игроками, тем сильнее ощущение, что игра не реагирует на их действия). [1] Задержка сети игроков (которая в значительной степени находится вне контроля игры) — это не единственный рассматриваемый фактор, но также задержка, присущая способу запуска игровых симуляций. Существует несколько методов компенсации задержек , используемых для маскировки или преодоления задержек (особенно при высоких значениях задержек). [10]
Одно обновление игровой симуляции называется тиком. Скорость, с которой симуляция выполняется на сервере, часто называют тикрейтом сервера; по сути, это серверный эквивалент частоты кадров клиента , при отсутствии какой-либо системы рендеринга. [11] Тикрейт ограничен продолжительностью времени, необходимого для выполнения симуляции, и часто намеренно ограничивается еще больше, чтобы уменьшить нестабильность, вызванную флуктуирующим тикрейтом, и снизить затраты на ЦП и передачу данных. Более низкий тикрейт увеличивает задержку при синхронизации игровой симуляции между сервером и клиентами. [12] Скорость тика для игр, таких как шутеры от первого лица, часто составляет от 128 тиков в секунду (как в случае Valorant ) , 64 тиков в секунду (в таких играх, как Counter-Strike: Global Offensive и Overwatch ), 30 тиков в секунду (как в Fortnite и консольной версии Battlefield V ) [13] и 20 тиков в секунду (такие спорные случаи как Call of Duty: Modern Warfare , Call of Duty: Warzone и Apex Legends ). [14] [15] Более низкая скорость тика также естественным образом снижает точность моделирования, [11] что само по себе может вызвать проблемы, если зайти слишком далеко или если клиентское и серверное моделирование выполняются с существенно разной скоростью.
Из-за ограничений в объеме доступной полосы пропускания и процессорного времени, которое занимает сетевая связь, некоторые игры отдают приоритет определенным жизненно важным коммуникациям, ограничивая частоту и приоритет менее важной информации. Как и в случае с тикрейтом, это эффективно увеличивает задержку синхронизации. Игровые движки могут ограничивать количество раз, когда обновления (симуляции) отправляются конкретному клиенту и/или конкретным объектам в игровом мире, в дополнение к снижению точности некоторых значений, отправляемых по сети, чтобы помочь с использованием полосы пропускания. Этот недостаток точности может быть в некоторых случаях заметен. [11] [16]
Различные ошибки синхронизации симуляции между машинами также могут подпадать под «проблемы сетевого кода». Они могут включать ошибки, из-за которых симуляция на одной машине протекает по-разному, чем на другой, или из-за которых некоторые вещи не передаются, когда пользователь считает, что они должны передаваться. [2] Традиционно, в стратегических играх в реальном времени (таких как Age of Empires ) использовались модели одноранговых сетей с протоколом lockstep , в которых предполагается, что симуляция будет работать одинаково на всех клиентах; однако, если один клиент по какой-либо причине выпадет из цикла, десинхронизация может усугубиться и стать неустранимой. [11] [17]
Выбор игрой протокола транспортного уровня (а также его управление и кодирование) также может повлиять на воспринимаемые сетевые проблемы.
Если игра использует протокол управления передачей (TCP), между игроками будет увеличена задержка. Этот протокол основан на соединении между двумя машинами, в котором они могут обмениваться данными и считывать их. Эти типы соединений очень надежны, стабильны, упорядочены и просты в реализации. Однако эти соединения не совсем подходят для скоростей сети, которые требуются для игр с быстрым действием, так как этот тип протокола ( протоколы потоковой передачи в реальном времени ) автоматически группирует данные в пакеты (которые не будут отправлены, пока не будет достигнут определенный объем информации, если только этот алгоритм — алгоритм Нейгла — не отключен), которые будут отправлены через установленное соединение между машинами, а не напрямую (жертвуя скоростью ради безопасности). Этот тип протокола также имеет тенденцию очень медленно реагировать всякий раз, когда они теряют пакет или когда пакеты приходят в неправильном порядке или дублируются, что может быть очень пагубным для онлайн-игры в реальном времени (этот протокол не был разработан для этого типа программного обеспечения).
Если игра вместо этого использует протокол пользовательских дейтаграмм (UDP), соединение между машинами будет очень быстрым, потому что вместо установления соединения между ними данные будут отправляться и приниматься напрямую. Этот протокол намного проще предыдущего, но ему не хватает надежности и стабильности, и он требует реализации собственного кода для обработки необходимых функций для связи между машинами, которые обрабатываются TCP (таких как разделение данных через пакеты, автоматическое обнаружение потери пакетов и т. д.); это увеличивает сложность движка и само по себе может привести к проблемам. [18]