Перейти к основному содержимому
Сжатие трафика с помощью Oodle Network Plugin

Сжатие трафика с помощью Oodle Network Plugin

·672 слов·4 минут
Простой способ уменьшить трафик, если готовы потратить немного процессорного времени

Oodle Network
#

В Unreal Engine 5 уже встроен Oodle Network — библиотека от Rad Game Tools для сжатия сетевых данных. Подробнее можно посмотреть на официальной странице. Покупка отдельной лицензии не требуется, так как Rad Game Tools теперь часть Epic Family.

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

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

Тренировка словарей
#

Я немного отклонился от официальной инструкции и записывал пакеты через собранный сервер. После записи я скопировал полученные пакеты с сервера в папку с Unreal Engine. Примерно так выглядят данные, которые длжен получить Oodle для тренировки.

W:\TheGame\TheGame\Saved\Oodle
└───Server
    ├───Input
    │       PacketDump_UE5_0_7_2025.11.04-06.14.46_Input_1.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.46_Input_2.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.46_Input_3.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.52_Input.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.52_Input_1.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.52_Input_2.ucap
    │
    └───Output
            PacketDump_UE5_0_7_2025.11.04-06.14.45_Output.ucap
            PacketDump_UE5_0_7_2025.11.04-06.14.46_Output.ucap
            PacketDump_UE5_0_7_2025.11.04-06.14.46_Output_1.ucap
            PacketDump_UE5_0_7_2025.11.04-06.14.46_Output_2.ucap
            PacketDump_UE5_0_7_2025.11.04-06.14.46_Output_3.ucap

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

UE_LOG(OodleNetworkHandlerComponentLog, Log, TEXT("..."));

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

E:\Engine\Binaries\Win64\UnrealEditor-Cmd.exe W:\TheGame\TheGame.uproject -run=OodleNetworkTrainerCommandlet AutoGenerateDictionaries -CompressionTest
Generating dictionaries for Input folder
Generating dictionary for folder 'Input', outputting to: ...
Oodle trainer parameters:
- HashTableSize: 19
- DictionarySize: 4194304 (~4MB)
- Performing Trials: Yes
- DictionaryTrials: 3
- TrialRandomness: 200
- TrialGenerations: 1
- WriteDictionaryVersion: 9
Beginning dictionary generation...
- DictionaryPackets: 530412, Size: 28094424 (~26MB)
- DictionaryTestPackets: 530412, Size: 28095494 (~26MB), Overflowed: No
- TrainerPackets: 530412, Size: 28032284 (~26MB)
Dictionary generation may take a very long time (up to 7 mins for 1GB of packets).
Dictionary generation complete. Beginning Oodle state training...
Successfully processed packet captures, and wrote dictionary file.
Testing packet compression results...
Compression test results:
- CompressionTestPackets: 530411, Size: 28095912 (~26MB)
- Uncompressed: 28095912 (~26MB), Compressed: 14221937 (~13MB)
- Total Savings: 49.380760%
Successfully generated dictionary.
Generating dictionaries for Output folder
Generating dictionary for folder 'Output', outputting to: ...
Oodle trainer parameters:
- HashTableSize: 19
- DictionarySize: 4194304 (~4MB)
- Performing Trials: Yes
- DictionaryTrials: 3
- TrialRandomness: 200
- TrialGenerations: 1
- WriteDictionaryVersion: 9
DictionaryTestPackets overflowed into TrainerPackets (normal).
Beginning dictionary generation...
- DictionaryPackets: 365018, Size: 180712877 (~172MB)
- DictionaryTestPackets: 136180, Size: 67108992 (~64MB), Overflowed: Yes
- TrainerPackets: 593856, Size: 294049442 (~280MB)
Dictionary generation may take a very long time (up to 7 mins for 1GB of packets).
Dictionary generation complete. Beginning Oodle state training...
Successfully processed packet captures, and wrote dictionary file.
Testing packet compression results...
Compression test results:
- CompressionTestPackets: 365018, Size: 180287656 (~171MB)
- Uncompressed: 180287656 (~171MB), Compressed: 127685904 (~121MB)
- Total Savings: 29.176571%
Successfully generated dictionary.

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

Тестирование
#

Тестирование проводилось по той же методике, что и в предыдущей статье. Основная нагрузка — репликация перемещений и положения камеры.

После нескольких прогонов я получил следующие результаты входящего и исходящего трафика за 5 минут теста:

Без сжатия: входящий — 217 MB, исходящий — 918 MB
Со сжатием: входящий — 157 MB, исходящий — 567 MB

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

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

If your game changes patch to patch in appreciable ways, you need to retrain Oodle Network on new packet captures, and release new dictionaries with the patch.

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