Как мы чинили баг на Godot 4

Скриншот с полей разработки Киберментов
Скриншот с полей разработки Киберментов

На днях починили один из самых противных багов в игре. Расскажем о нём подробно, вдруг кому пригодится. [Godot 4.2.2 stable]

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

До введения звуков в игру всё было хорошо. Основные проблемы с FPS были связаны с отображением мира, домов, объектов на карте. С этими трудностями справиться было нелегко, но и не трудно. Средне. После введения звуков и решение очевидных оптимизационных проблем с ними всё стало жутко лагать.Всего лишь 16 полицейских и 16 преступников на карте генерили столько нагрузки, что было 12 FPS в среднем.

До введения звуков
До введения звуков

Баг было поймать непросто. Очевидное удаление звуков из игры напрочь помогло, 55-60 фпс на месте, да вот только мы не можем шиппить игру без звуков. Нужно было думать.

На две долгие недели (в системе исчисления инди это 14 вечеров) разработка встала из-за этого вопроса. Казалось, что это полный тупик, коленки дрожали, из-за гнева и страха не выпустить игру или потерять время на тотальную переработку концепта игры.

Интуиция подсказывала, что дело не в Godot. Почти всегда руки сами варят кашу, которую надо потом разгребать. Нужны были гипотезы.

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

Как мы чинили баг на Godot 4

И вот в один прекрасный момент этот поиск полным перебором привёл к виновнику - звук выстрела лазерами. Полицейских было на карте 16 штук во время тестов. Каждый из них стрелял с частотой 600 лазеров / мин или 10 лазеров / сек. У каждой полицейской машины своя нода AudioStreamingPlayer3D, которая отвечает звук выстрела. Полифония была 32, то есть одновременно можно было играть 32 звука на этой ноде.

То есть ничего не выглядело каким-то странным или некорректным. Мозг взрывался от того факта, что содание нового лазера 10 раз в секунду быстрее, чем проигрывание звука, который уже создан давно и лежит в RAM.

Каким-то чудом в момент агонии мы случайно заменили один звук выстрела лазером на другой и проблема исчезла. 60 FPS и квадратные глаза программиста. Полезли смотреть файлы - в исходном звуке лазера звук на 0,6 сек и ещё 1,1 сек тишины. В случано подставленном звуке - весь файл продолжительностью 0,4 сек.

Снизу звук, ставший проблемным
Снизу звук, ставший проблемным

То есть по факту проблемный звук лазера длился 1,7 секунд, где 1,1 последних секунд - тишина. По логике вещей если 10 раз / сек стреляет лазер, то максимальный оверлап звуков - это 17 при полифонии в 32. Должно было работать как часы. Но по неизвестной нам причине (все идеи приветствуются в комментариях) это жёстко влияло на производительность.

Исправленный звук стал длиной в 0,6 сек, проблема исчезла, AudioServer не грузит игру. Впереди ещё миллиард подобных особенностей, но это дело закрыто.

1313
8 комментариев

Сделайте дорожки часто вызываемых эффектов в формате wav без компрессии. Тогда процессорное время не будет тратится на дикомпрессию.

Так же привяжите AudioStreamPlayer3D к Area3D. Если игрок вне радиуса этого area - звук даже не пытаться проигрывать.

Либо привяжите звуковые эффекты к listener игрока и по нему определяйте, производить звук или нет.

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

3
Ответить

Обязательно попробую, спасибо за дельный совет! Люди, сохраняйте инфу

Ответить

Скорее всего эксепшен при переполнении пула звуков дорогой

Ответить

В движке нет исключений.
Он либо работает, либо сразу крашится =)
Он компилируется с флагом no-exception =)

Ответить
Ответить