Как Unity двигает индустрию разработки в правильное направление

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

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

DOTS

Собственно в Unity сидят не дураки и они это осознавали и мириться с этим не решили. В октябре 2018 Unity впервые поделились информацией о так называемом DOTS (Data oriented technology stack — технологический стек ориентированный на данные), который должен быть решить ранее озвученные проблемы.

Unity показали технодемку Megacity с впечатляющей графикой, числом деталей и масштабом присущим ААА. И чтобы закрепить успех презентации — технодемку запустили на айфоне с 60 фпс. Именно то, что на видео ниже было запущено на телефоне из 2018 года, всё верно.

Что же такое DOTS? По сути это комбинация нескольких технологий и инструментов состоящее из трёх основных пакетов: Jobs, Burst и ECS. Объясню вкраце что это.

Jobs - это система мультипоточности, которую Unity использовали под капотом в движке для своего кода долгие годы до DOTS. Её адаптировали под C# (на котором пишут разрабы игр на движке) и создали мощную систему потокобезопасности, сделав мультипоточность очень простой в разработке.

Burst - это компилятор высокопроизводительного кода для C#. Он имеет множество ограничений по сравнению с типичным C# кодом, но на выходе мы получаем производительность, которая иногда даже перегоняет С++. Чуть ниже — бенчарки различных алгоритмов для сомневающихся.

ECS — Entity Component System. Это иная парадигма программирования, разработанная (задолго до Unity) специально для разработки игр. Она полностью задействует два предыдущих пакета на все 100% и даже больше, используя недоступные простым разработчикам знания и инструменты. При этом она предлагает простой способ разработки игровой логики любой сложности.

Разработка DOTS

Несмотря на то, что представлено всё это добро было ещё в 2018 и уже тогда можно было пощупать все эти технологии, для разработки они ещё совсем не годились, поскольку были сырыми. Для Burst и Jobs более менее стабильные версии стали доступны только во второй половине 2020, хотя багов всё ещё было предостаточно, что вызывало много скептицизма у разработчиков.

В случае с ECS — разработка для Unity была наверное самым неприятным процессом. Изначальные планы включали в себя огромное число пакетов: аудио, спрайты (2д), анимации. Из них выжила только анимация и та до сих пор не доступна публично, когда как от ECS Audio и 2д они просто отказались.

После очень долгого затишья с конца 2020 Unity впервые рассказали о новой версии ECS только в апреле 2022. Уже в мае была выпущена 0.51 версия, которая была на удивление стабильна и уже предлагала достаточный инструментарий для разработки игр. Она не сильно отличалась от 2020 версии архитектурно, поэтому многие разработчики, которые уже имели смелость начать свои проекты с Unity ECS смогли перейти без больших проблем.

Уже в сентябре 2022 Unity представили экспериментальную 1.0 версию того, как ECS будет выглядеть на релизе, которая радикально отличалась от 0.51 в лучшую сторону (хоть и не везде), но была не очень совместима со старыми проектами, написанными на 0.51.

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

И только к лету 2023 ECS заклеймили как production-ready (готовым к разработке).

Процессоры и говнокод

Итак спросите вы, что же такого особого в DOTS и как Unity двигает индустрию в правильном направлении?

Зайду издалека и сначала расскажу о том, как развивались процессоры:

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

Но вот разработчики игр писать код, который работает мультипоточно не спешили, поэтому в 2010х годах условный i5 практически всегда уделывал по производительности топовые AMD Athlonы, несмотря на то, что суммарно производительность ядер последнего была куда больше чем у i5.

Помимо мультипоточности, новые процессоры предлагали аппартную поддержку параллельных математических операций (SIMD) — векторизацию, позволяющих за 1 раз выполнить математическую операцию на четырёх числах. По сути производительность умножалась на 4.

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

Также можно вспомнить яростные споры о процессорном кэше L1, L2, L3 среди диванных экспертов и о его влиянии. Ведь со временем он только увеличился, но толку от этого было трудно заменить. Для справки: скорость чтения информации с процессорного кэша в 500 раз быстрее, чем чтение той же информации из оперативной памяти. И снова всё дело в том, что разработчики со своим кодом, просто не задействовали его (эффективно).

Но кто же виной, что разработчики игр не применяли новые технологии? По сути это конечно же сами разработчики, но не совсем.

Главная причина, почему до сих пор мы видим кучу неоптимизированных игр с картиной хуже чем пастген — это использование устаревших парадигм программирования, которые даже в своём идеальном виде банально не способны реализовать потенциал процессоров. Отсюда оптимизация кажется чем-то сверх сложным или костыльным вроде "А движок можно поставить так что вдали деревья картинкой, когда подходиш они преобразовываются в 3-хмерные деревья".

Но тут на сцену вышел DOTS предложив альтернативу устаревшим парадигмам с лозунгом «Performance by default» — производительность по умолчанию. И они не соврали — запустить фотореалистичную картинку в нативном разрешении, да ещё и в 60 фпс на телефоне из 2018 года, в то время как разрабы на Unreal Engine 5 лочат игры в 30 фпс на консолях, да ещё и с длсс. А первое технодемо Nanite они и вовсе показывали на топовом железе в 30 фпс.

ECS vs OOP

И так, что же такого особенного в ECS и почему за ним будущее геймдева? Дело в том, что ECS — это парадигма, которая основана на том, как работают процессоры и код, написанный в ней не только очень легко отправить на потоки (сделать мультипоточным), но ко всему прочему ещё и добавить к нему векторизацию (SIMD) сверху. А поскольку все данные обрабатываются массивами — это также эффективно задействует процессорный кэш, поскольку в цикле следующие элементы массива уже загружены в кэш. Таким образом процессор задействуется полноценно и что куда важнее — эффективно.

Вот только впервые ECS (а вернее похожий дизайн) был использован ещё в 2007 в игре Operation Flashpoint: Dragon Rising и с тех пор разработчики движков не особо спешили переходить на него.

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

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

А вот Epic Games почуствовали угрозу от DOTS и начали эксперементировать своим ECS — Mass Entity, в то время как основной движок остаётся полностью объектно-ориентированным.

Так какие же проблемы с ООП? Если все топовые движки его используют, почему нужен этот ECS и почему нельзя просто оптимизировать игру на ООП?

Можно, но это куда сложнее и ты не сможешь добиться того же результата, как при ECS. А причиной тому, как именно работает ООП код. Немного технического объяснения (не претендует на 100% достоверность):

ООП функционирует за счёт абстракций и виртуальных методов, где выполняемая функция определяется за счёт объекта. Таким образом, процессор не знает, какая именно функция должна выполнится и вынужден загружать её каждый раз (поскольку кэш не бесконечный и предыдущие функции нужно отгрузить). Затем процессор не знает, над какими именно данными загруженная функция должна работать и точно также вынужден подгружать это всё во время выполнения и нередко делая это из оперативной памяти (вспоминаем, что процессорный кэш в 500 раз быстрее).

Ко всему прочему, неизвестность того, что именно выполняется и какие данные оно получает приводит к тому, что такой код сложно сделать потокобезопасным. Начинают применятся замки (lock/mutex), которые не только убивают производительность, но ещё и приводят к крашам, когда код содержит баги.

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

Тем временем что происходит в ECS:

Данные обрабатываются массивами, где исполняемая функция определяет какие именно данные загружаются. Таким образом ты можешь подгружать в кэш данные ещё до того как ты их обрабатываешь, что называется Cache prefetching.

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

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

Вывод

У руководства Unity хватило смелости одним из первых освоить новую парадигму и запустить её в массы, пока остальные даже не задумываются о ней, либо только начали это делать. Тут я конечно не беру в учёт разные фреймворки, которые существуют уже много лет, поскольку это не полноценные движки.

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

Также хочу уточнить, что ECS — решение не для всех игр. Условные визуальные новеллы или карточные игры будут неудачным выбором, но вот любая ААА игра — идеальный кандидат для ECS.

Игры, которые уже вышли на DOTS: Diplomacy is not an Option, V-Rising, Beyond Contact (все они заложники 0.51 версии и увы никогда не станут лучше обновившись до 1.0). Возможно есть и другие, о которых я не в курсе или забыл.

Ещё хочу упомянуть такой опен-сорс движок, как Bevy, который будет первым движком созданным исключительно для ECS. На текущей момент он всё ещё в разработке. Но тем не менее точно также двигает индустрию в нужное русло.

14K14K показов
6K6K открытий
273 комментария

какой бред ты несешь

Ответить

Чтобы не быть просто пиздаболом, который критикует автора, поясню, почему он несет бредь сумасшедшего. "У руководства Unity хватило смелости одним из первых освоить новую парадигму и запустить её в массы" - автор не понимает базы, что измененная модель монетизации юнити просто сделала бы невозможным зарабатывать деньги с большинства игр, которые закупают игроков (у них маржа 10-25%), а в процентном соотношении это подавляющее большинство игр. Что привело бы к банкротсву и закрытию этих студий. И это только один из примеров, почему юнити хуесосы а не "освоители новой парадигмы"

Ответить

Комментарий недоступен

Ответить

Ага, причем на серьезных таких щах.

Ответить

Они 5 лет это делали, и все еще недоделали, куда чего они там двигают? Этот идиотизм с кучей рендеров это прогресс? Это вообще самое тупое и производственно вредное решение. Наклепали кучу несовместимых версий движка, хер пойми на чем проект стартовать. Потому что с одной стороны фичи движка с другой не менее важные фичи от пользователей в ассетсторе.

Ответить

Доделали уже как несколько месяцев. Критичных багов, блокирующих разработку к счастью пока не обнаружили. Доступен ECS только на 2022 LTS, поэтому думать особо тут не нужно)

Ответить

Хорошая и правильная статья, автор молодец, все понятно расписал. Но к сожалению, мамкиным программистам и обычным игрокам пофигу на это всё - собственно, видим тут эти самые комменты. А настоящие инженеры и так уже про все про это знают и следят за разработкой. Остаются те, кто потом и кровью прошли через лабиринты оптимизаций, уткнулись в ботлнеки CPU (причем неважно на каком движке) и еще пока плохо понимают что с этим делать. Вот статья как раз для них. Хотя таких очень мало. Как призвать Апанасика? - пусть репостит.

Ответить