Улучшаем протокол передачи файлов CS2D

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

В самом начале протокол передачи файлов был относительно простым, потому что серверам не нужно было передавать много файлов — исключением были только карты с большим количеством ресурсов, например, RP и сюжетные карты. На то время скорость передачи файлов была очень низкой — 10 Кб/с были нормой для большинства серверов. Со временем в игру была добавлена поддержка HTTP-ресурсов, но поскольку большинство владельцев серверов были любителями, её очень редко настраивали — трата сил на её настройку не стоила того. Этот статус кво сохранялся несколько лет.

Однако ситуация начала меняться со становлением моддинга как неотъемлемой части геймплея CS2D. Внезапно игрокам стало передаваться намного больше файлов, и скоростей передачи стало не хватать. На улучшение сетевого кода было затрачено много сил, и скорости возросли — 20 Кб/с стали новым нижним уровнем, и возможными стали скорости до 200 Кб/с и выше. Скорость передачи файлов стала ограничиваться подключениями энтузиастов, державших многие серверы CS2D на своих компьютерах и ноутбуках. Это сделало процесс подключения к серверам намного плавнее и приятнее при загрузке больших файлов (в особенности музыки и аудио), но оставалась одно важное препятствие — передача множества маленьких файлов друг за другом.

Total number of files downloaded via CS2D
Объём папки gfx/ на относительно активной дистрибуции CS2D показывает, как много (мелких) файлов передаётся клиенту разными серверами.

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

Общее решение проблемы достаточно очевидно — если алгоритм хорошо справляется с большими данными, но плохо работает на множестве маленьких данных, то эти маленькие данные нужно склеить в большие. На деле внедрить такое решение труднее, чем его придумать, особенно в условиях великовозрастного кода, с которым мы имеем дело. Платформа BlitzMax уже достаточно устарела и всегда была относительно малоизвестна, а применимо к такому относительно мейнстримному проекту как CS2D она ещё и хрупка. Мы прошлись по классике — библиотекам gzip, lzma и другим, но из-за мистической природы BlitzMax их было трудно внедрить в наших условиях; к тому же для наших задач они были относительно тяжёлыми.

Однако в BlitzMax есть собственный функционал сжатия, который похож на gzip, и CS2D его использует со времён первых улучшений протокола передачи данных, поэтому мы решили использовать его. Мы быстренько слепили собственных формат архивов для игры и начали экспериментировать с объединением игровых ресурсов, чтобы отсылать их клиентам. CS2D всегда целилось на старое и бюджетное аппаратное обеспечение, в том числе когда дело касается Интернет-соединений — мы прекрасно отдаём себе отчёт в том, что у многих наших игроков ограниченные по объёмам трафика соединения. Поэтому у клиента остаётся возможность «выбирать» файлы, которые он будет получать, в зависимости от их размера — выбор оказывается немного смещён в пользу более низких размеров, потому что расчёты проводятся на несжатых файлах, но лучше потратить меньше данных, чем больше.

Приведённое выше видео сравнивает новый алгоритм со старой пофайловой передачей на двух сотнях мелких файлов. Нас ошеломили результаты, которые мы получили после тестового прогона нового алгоритма. На стандартных 25 Кб/с время до начала игры снизилось в 4-5 раз. Мы рассчитываем на ещё большую экономию времени на более высоких скоростях. Мы экспериментировали с разделением архивов на части, но такой подход не улучшил ситуацию — тем не менее, возможно, что его стоит включить во избежание повторения прерванных загрузок.

Мы всё ещё разбираемся и экспериментируем с алгоритмом на предмет стабильности. Возможно вы увидите его в деле в версии 1.0.0.9, для начала как один из режимов передачи файлов (выбранный по умолчанию) наряду со старым пофайловым, но со временем старый алгоритм передачи файлов может исчезнуть вообще.

Автор

EngiN33R

EngiN33R

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *