TL;DR производительность и потребление ресурсов очень зависят от выбранного стека; выбирайте стек, соответствующий задаче (если игра представляет собой виджет, не стоит писать её на Unity); проблемы с производительностью не всегда волнуют пользователей, и даже с ними можно зарабатывать деньги

5 марта 2025 года в Steam вышла игра Bongo Cat. Милый котик из мема, стучащий своими лапками по столу каждый раз, когда вы нажимаете какую-либо клавишу или кликаете мышью. Он сидит у вас на панели задач, не отвлекая от работы. Представляет из себя тамагочи-питомца: можно надевать ему шапочки, украшения, и т.д.
Создал её фактически один человек (!) — Marcel Zurawka, основавший Irox Games и издавший под её брендом эту игру.

steam preview
steam preview

Люди в умилении, пишут восторженные отзывы. Игра набрала 98% положительных отзывов, что превосходит такие шедевры как Detroit Become Human, Lethal Company, Subnautica... Мило, прикольно, необычно.

gameplay
gameplay

Чувствуете подвох? :)

Эта игра убивает ваши драгоценные системные ресурсы. Каким образом счётчик нажатий с метой в виде небольших украшений и скинов может требовать больше ресурсов, чем некоторые игры?!

Разберём игру по косточкам ("основная часть"), найдём ошибку автора и сделаем выводы ("часть выводов").


ОСНОВНАЯ ЧАСТЬ // Диагностика пациента

Взглянем на системные требования. Нас интересуют минимальные.

64-разрядные процессор и операционная система
ОС: Windows 10 / 11
Процессор: Intel i5 5200 or AMD Ryzen 5 5600X
Оперативная память: 1 GB ОЗУ
Видеокарта: Any
Сеть: Широкополосное подключение к интернету
Место на диске: 100 MB

А теперь... Реальность:

64-разрядные процессор и операционная система
ОС: Windows 10 / 11
Сомнительно Процессор: Intel i5 5200 or AMD Ryzen 5 5600X
Ложь Оперативная память: 1 GB ОЗУ
Сомнительно Видеокарта: Any
Сеть: Широкополосное подключение к интернету
Ложь!! Место на диске: 100 MB

Действие первое :: Проверяем симптомы

Для сбора информации я использую System Informer (aka Process Hacker 3). Отличная утилита для каждого разработчика. Итак, заходим в него, открываем свойства процесса, вкладку Performance...

performance
О ужас! (прим.: на рис.3 прилепил вес игры на диске)

Я собрал достаточно много тестовых данных. Итак:

  1. Программа сжигает 20-25% ЦП в простое. Мой процессор примерно в 2 раза производительней указанного, поэтому можно ожидать и бОльших чисел на более слабых процессорах (что затр��днит процесс работы/гейминга параллельно с Bongo Cat)

  2. Программа весит 440МБ. ((Привет, минимальные системные требования! :D ))

  3. Программа потребляет 850-1000МБ ОЗУ. Системные требования это требования ко всей системе, а не только к самой игре. Иметь систему с 1ГБ ОЗУ для запуска этого приложения недостаточно, ибо не останется памяти для самой системы. ((Да-да, существуют всякие файлы подкачки и т.д., но это уже нечестно.))

  4. Программа использует 400МБ видеопамяти, что тоже достаточно много. Да, любая офисная видеокарта справится с этим (редко где можно встретить видеокарту с <1ГБ видеопамяти). Но... Те, кто работает с графикой: дизайнеры, видео-монтажёры, создатели анимаций и так далее, явно не будут в восторге от кражи драгоценной видеопамяти.

  5. Если использовать мышь/клавиатуру (что-то печатать, напр.), потребление наоборот снижается.

  6. Если открыть UI, нагрузка на ЦП снижается (чего?!) ((учёт кликов продолжается))

  7. Если открыть UI, потребление ОЗУ начинает постепенно расти и на некоторое время сохраняется даже после его закрытия.

Действие второе :: Куда утекают ресурсы ПК? Поиск проблемы в коде

Честно говоря, я с самого начала думал, что разработчик — макака с ИИ. Зная, что ИИ может выдавать while (isRunning()) { pollEvents() } в примерах с GUI, я подумал, что "это оно!".

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

И... Меня шокировало, что это приложение написано на Unity! Это не совсем то, что я ожидал... Зачем стрелять из пушки по воробьям?! Серьёзно, почему автор решил выбрать именно Unity для создания этого... виджета?

Страсти накаляются. Скачиваю AssetRipper, загружаю папку с проектом...

Скрипты так просто не поддаются декомпиляции ((примечание: анализ исходников это тема для отдельной статьи)). Удалось декомпилировать лишь ассеты, которые были неприлично большого размера (именно они занимают 340МБ). Выяснилось, что ассеты хранятся в высоком разрешении (практически все). Шляпа 256x256 пикселей, несмотря на то, что её физический размер около 77x77 пикселей. Также, для хранения ассетов используется формат RGBA32. Никакого сжатия, никаких умных трюков с альфа-каналом (полупрозрачности здесь практически нету; только на краях).

too heavy hat :)
Шапка 39x69 пикселей занимает 256x256 пикселей! И весит в 24 раза больше, чем необходимо.

Кроме прямого анализа кода, есть ещё и косвенный. Можно проанализировать не код, а его автора :).

Обратимся к личности основателя, Marcel Zurawka.

Разработчиков двое: Lars ("создал весь UI") и Marcel (основатель). Нас интересует Марсель, как ответственный за эту игру и её качество.

Простым запросом в поисковике можно найти страницу Marcel Zurawka на Linkedin. Я открыл и посмотрел публичные подробности. Было указано, что данный человек окончил Мюнхенский технический университет. Неплохо. Значит, это не вкатун и не человек с улицы, а инженер ПО с вышкой.

Кроме линкедына, можно легко найти и его гитхаб. Уже интересно! Популярностью он не пользуется, как таковых публичных проектов / библиотек у него нет, вклад в OpenSource он не делал.

По репозиториям можно понять, что он начал программировать ещё в школе (9-м классе). Это был SudokuSolver на Java Swing, причём основную часть кода занимает именно алгоритм решения судоку.
Далее следует алгоритмический проект на Си и Ассемблере, который является вступительным на стажировку в gamedev-компанию. Проект с хорошей мат.базой.
Третий репозиторий — игра на Unity для Gamejam. Значит, Bongo Cat это не первое его приложение на C#/Unity.
Последний репозиторий это сайт (личная страница). Заглянем туда...

Нас встречает его старая игра Hotel Nero. Один из первых проектов. Игра создана для SemesterGameJam, в команде из 4 человек: ещё одним программистом, художником уровней и гейм-дизайнером.

hotel nero
Скриншот из игры Hotel Nero

Из всего этого мы делаем вывод, что:

  • автор - НЕ человек с улицы и вряд-ли вайбкодер. И уж точно не макака с ИИ. И даже не начинающий C#/Unity разработчик. А значит, он имеет понятие о том, что он делает, и в состоянии отследить & устранить проблемы с производительностью.

Вернёмся к пациенту.

Действие третье :: Окунёмся в профилировку (профайлинг). Осмотр полной картины

Где же тогда проблемы с производительностью/памятью, если автор в состоянии оптимизировать игру на хорошем уровне?

Закапываемся в System Informer поглубже.

Барабанная дробь...

exploring DLLs
[см. анализ ниже]

Поделим на категории:

  • 96 мегабайт уходит на 3D драйверы/библиотеки. Причём совершенно не используемые в данном приложении!

  • ещё 95 мегабайт уходит на драйверы nVidia и на сам Unity. Эти расходы тоже можно было бы сократить.

То есть... ОЗУ уходит в Unity. Причём в его неиспользуемые части.

Если открыть вкладку Memory (блоки памяти), ничего особо интересного там нет. Однако, я отдал это на анализ ИИ (вместе с кратким контекстом (без указания того, что здесь есть какие-то проблемы) и другими скриншотами: потоками и памятью модулей (DLL)). Получил такой ответ: (пересказ)

[ Мнение ИИ ]
Техническая причина "раздутости" (прим.: я не говорил ему о том, что приложение раздуто, а просил просто проанализировать) приложения найдена: это архитектурные особенности Unity + Mono Backend. Ваше приложение не "протекает" в классическом смысле, но использует неэффективную модель памяти для своей задачи.
Как оптимизировать приложение:
1. Докажите проблему через Unity Profiler (скриншоты Managed Heap и GC Alloc). (прим.: ничего я тебе доказывать не буду, железяка. Здесь и так всё понятно)
2. Оцените возможность перехода на IL2CPP — это может сократить потребление памяти в 2-3 раза.
3. Проведите оптимизацию ассетов и кода.
Даже в рамках текущего стека (Unity) оптимизация возможна и даст существенный результат.
Считаться ли с мнением ИИ — ваш выбор. Но я лично в этом случае ему верю, так как самолично просматривал HEX-дамп этой выделенной памяти, и заметил, что около 70% выделенной памяти просто заполнено нулями.

Просмотреть весь диалог с ИИ

Игра не собирается работать без Интернета.

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

Немного об отладке нагрузки на ЦП

В ходе расследования я обнаружил способ, как уменьшить нагрузку на ЦП до 5-6% (приемлемых значений). Для этого, зайдите в настройки и включите анимацию покачивания, либо отключите VSync. Нет, вопреки предупреждению, никакая производительность не ухудшится, а наоборот даже станет лучше. Нагрузка на GPU будет держаться на 3%, что полностью окупает снятие нагрузки с ЦП.

no internet
Если запустить кота без интернета, игровых данных у него не будет.

Если залезть в потоки, видим следующее:

threads
threads

"Особенно выделяется поток, потребляющий 24% ЦП (3 млрд тактов процессора в секунду)")

Выделяющийся поток это как раз основная функция Unity (UnityPlayer.dll!UnityMain()). Судя по вершине стека (KernelBase.dll!WaitForSingleObject()) (docs), этот поток наоборот должен уходить в режим ожидания и не потреблять ЦП.

Как же так получается, что поток уходит в режим ожидания и при этом потребляет 24% ЦП? Не ошибка ли это?
Проблемы с производительностью возникают не только у меня. Если Bongo Cat мешает другим играм работать, значит, эти 24% реальны.
Вдобавок, снова обратимся к помощи ИИ, вдруг он поможет нам что-то разгадать:

[ Мнение ИИ ]
Это парадоксальная ситуация, указывающая на активное ожидание (busy-wait) или спин-блокировку (spinlock) высокой интенсивности. Это крайне неэффективно и объясняет высокую нагрузку на CPU при, казалось бы, простой задаче.
<...>
Это классическая проблема "hyperactive main loop" в простых приложениях, где движку нечем себя занять, и он начинает "крутиться на месте".

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

ЧАСТЬ ВЫВОДОВ // Ставим диагноз. Анализируем опыт Bongo Cat, отвечаем на вопросы

— В чём же главная ошибка автора?

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

— Не меняя стек, можно ли что-то исправить?

Да! Что здесь можно сделать:

  1. Урезать ассеты; хранить их в сжатом формате. Насчёт трюков с альфа-каналом: теоретически возможно заменить, допустим, #000000 на прозрачный (а все "реальные" #000000 увеличить на единицу, естественно). Но тут всплывает вопрос о полу-прозрачности для сглаживания краёв. Если заняться этим вопросом, можно всё-таки избавиться от лишнего байта в каждом цвете.

  2. Разобраться с лишними DLL. Поискать способы отключить все 3D-возможности Unity, убрать тесную интеграцию с видеокартой.

  3. Выйти с отладчиком один-на-один и порешать все проблемы с нагрузкой на ЦП.

— Самое главное... А нужно ли вообще что-либо исправлять?

Необязательно! :). Вопреки здравому смыслу, большинству пользователей абсолютно всё равно на требования этого приложения. Дай им в руки милую вещицу, и они ни за что с ней не расстанутся.
Автор никак не спешит исправлять свои косяки. Он делает из этой игры продукт. И он очень хорошо себя продаёт. Вон, недавно он собрал 15 000 евро и провёл благотворительный ивент. Мы за благотворительность, "Thank you, cutiez <3", всё такое. В игру был добавлен мультиплеер, а самое главное, донат (наборы украшений по достаточно высоким ценам, а также Steam-рынок).

Тем не менее... Оптимизация — дело чести любого разработчика. К сожалению, в последнее время разработчики (и даже крупные компании) забывают о ней (а иногда намеренно игнорируют) и выпускают ПО, которое тратит в никуда неприличное количество системных ресурсов, и меня это огорчает. Я искренне надеюсь, что разработчики конкретно этой игры прислушаются к своей совести и сделают своё приложение более щадящим к системным ресурсам. И тогда этот тамагочи-кот станет отличной милой вещью, которую можно использовать во время игр и работы (как и заявлялось в описании самой игры).