Jump to content

«Оптимизация Сетевого Кода»


STARL1GHT
 Share

Recommended Posts

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

 

 

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

 

Стабильный и надежный сетевой код как "Святой Грааль" для каждого сетевого программиста.

 

Ядро сетевого кода WARFRAME довольно старое, оно восходит к временам игры Dark Sector  и д.р. Я сделал "капитальное улучшение" кода, перед релизом The Darkness 2(что бы соответствовать тех. стандартам PS3 и X360) и казалось, что перед началом WARFRAME код был в хорошем состоянии.

Прошло несколько лет и мы сделали несколько серьёзных изменений в это же время( в т.ч WARFRAME), на начале в 2012 было  очевидно, что все в порядке, но в 2014 это больше не работает. Другая проблема в том, что WARFRAME намного больше The Darkness 2(D2). Для примера:

 

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

 

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

 

Сжатие сетевых данных

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

 

1. Контроль перегрузки.

 

Просто что бы дать вам представление или почему мы против: сервер посылает обновления по сети с определенной частотой, предположим, 30 раз в секунду. Так же, давайте предположим, что мы создали 30 NPS символов (не необычный номер для игры). Даже если мы используем 20 байт для символов, которых 30х20х30 = 18 000 байт/сек только для одних NPS! Добавим игроков(они, как правило, более затратные) и умножьте на 3( три клиента) и это 512кбайт/сек (= 64 кбайт/сек) соединение с сервером потеряно. 20 байт на символ -  ничего, что бы написать про дом, хотя, это едва ли хватает для полного точного положения и повтора данных, например, место для здоровья, анимации, информации про урон? 

 

С одной стороны - мы идем на уловки. Мы не посылаем информацию, если мы считаем, если мы можем уйти с ней(например, NPS не видно), мы не используем абсолютною точность для всего, мы разделяем свойства на несколько элементов(критическая/важная/нормальная/косметическая) и так далее - каждый разработчик имеет свой набор уловок. Более того, сетевые данные, как правило, сжаты. Улучшение сжатия имело значительные результаты, но сначала давайте рассмотри некоторую информацию сжатия сетевых данных и как она относится к игре. 

 

Сжатие сетевых данных само по себе интересная проблема, игровые пакеты, как правило, небольшие(несколько сотен байт), как алгоритмы, написанные для работы с мегабайтовыми данными в реальности не то, что подходит для сжатия сетевых данных. Мы не можем позволить себе тратить больше, чем несколько байт для заголовка, например. 

 

В течении долгого времени игра использует LZF алгоритм сжатия для всего сетевого трафика. Это невероятно быстро, легко доступно на всех платформах мы заботились о(я говорю не только о различном оборудовании, но также и об услугах, таких как наш сервер ретрансляции) и действительно дало достойный коэффициент сжатия. Эффективность варьируется от типа миссии, но в нашем самом требовательном сценарии(выживание) она колеблется вокруг 1.25:1(80%).

 

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

 

Я немного экспериментировал с другими алгоритмами, но было трудно значительно превзойти LZF-сжатие. К счастью, я узнал, что ребята с RAD Game Tools только что выпустили свою сеть и библиотеку по сжатию данных. Вам может быть  не знакомым имя RAD, но я уверен на 100% что играли в игру, которая включала их технологии. Эти люди выпустили видеокодек Brink и звуковое программное обеспечение Miles Sound System. Ребята из RAD, в основном, группа гениев кода, они, как правило, несколько программистов работающих над одним проектом, но эти программисты являются одними из ведущих специалистов в своей области. Мы попросили дать оценку, сделали несколько быстрых тестов, и результаты были многообещающими. Ихний способ сжатия данных работает, но сначала нужно научится использовать реальные данные, взятых их игры. Я собрал более 100 MB сетевого трафика игры для создания конечного словаря. Помните, я упомянул про 1:25(80%)? С нашей новой системой сжатия нам удалось достичь 1,8:1(55%) по том же сценарию. Так что те долгие кооперативные выживания в которых вы играете, используемые для работы с данными, отправленных на 80% от исходного размера, теперь сжаты в 55% от первоначального размера. Сжатие варьируется от типа миссии, но я пытался настроить его так, что бы она была самая большая и самая сложная ситуация( в конце концов, сжатие не важно, если мы не посылаем слишком много данных в любом случае). Сказав, что новая система сжатия данных справляется гораздо лучше, чем старая во всех сценариях, в которых я тестировал. Самый низкий предел что я видел около 1,4:1.

TL; DR версия: Игра использует новую систему сжатия сетевых данных, передает значительно меньше данных.

 

2. Сжатие сетевых данных

 

Как вы можете наблюдать, мы стараемся убедится, что посылаем как можно меньше данных, на сколько это возможно. Мы не хотим превысить вашу сетевую пропускную способность. Как, возможно, вы знаете, есть 2 основных сетевых протокола: TCP и UDP. Не в даваясь в кровавые подробности, TCP является гораздо более сложным и много делает вещей за вашей спиной, думайте о нем как о домашнем семейном фургоне.  В отличии от этого, UDP - голые кости, он позволяет отправлять и получать данные и имеет некоторую базовую поддержку контрольной суммы, но я думаю, это как автомобиль Формулы 1.

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

Просто если вам интересно, график, показывающий пропускную способность клиента, данный 2 клиентам(это немного грубо, но предназначено для внутреннего результата). Я в ручную ограничил пропускную способность хоста до 30 KB/s, так что в идеале, клиент получит 15 KB/s. Как можно увидеть, это на самом деле довольно примерно(горизонтальные линии).

 

G0IiOwA.gif

 

Клиент №2 в некоторый момент разрывает связь, Клиент №1 быстро понимает, что может использовать всю пропускную мощность. На самом деле он по началу превышает, зачем находит лимит и остается в пределах 29.5 KB/s. Это не всегда выглядит славно, но это, по правде говоря, первый захваченный запуск.

 

Я понимаю, что на уме у вас "Хорошо, хороший график, но какая мне разница будет ли он играться лучше?" На самом деле, я очень взволнован и нервничаю перед следующим обновлением,

 

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

Edited by STARL1GHT
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
 Share

×
×
  • Create New...