Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
Game++. Часть 1.3: Архитектуры...

Game++. Часть 1.3: Архитектуры игровых движков

16 Июн 2026

Книга представляет собой сборник размышлений о языке программирования C++, алгоритмах и практиках в контексте разработки игр — о его сильных и слабых сторонах, практических решениях и устоявшихся способах работы. C++ на сегодняшний день остаётся основным языком в индустрии разработки игр благодаря сочетанию высокой производительности, гибкости и широких возможностей низкоуровневого контроля.

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

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

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

У каждой программы есть архитектура. Даже если всё написано внутри одного main() и "как-то работает", — это тоже архитектура. Но куда интереснее разобраться, что именно делает игровой движок хорошим.

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

Второй вариант: сама игра и есть и редактор, и движок, и билд-система, которая сможет собрать сама себя в качестве готовых уровней и логики. Все игровые движки и редакторы появились из игр, какие-то игры (и затем движки-редакторы) стали успешными, и разработчики решили на волне успеха получить дополнительное время и ресурсы для развития. К этому времени обычно в команде появляется (вырастает, реже — приглашают) человек, который определяет, уточняет, управляет и контролирует компоненты внутри игры-движка, обеспечивая их взаимодействие и целостность в рамках всей системы. Можно называть его "Архитектором", но чаще — это "Старейшина" инженерной части студии, которому больше всех перепало работать с отделом тестирования, программистами, дизайнерами и другими людьми.

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

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

Когда число разработчиков становится больше пяти человек, они начинают организовывать и согласовывать свою работу, и часто это приводит к разделению задач и обязанностей на основе технических возможностей каждого участника команды. Каждый делает то, что умеет и знает: внутреннюю БД, рендер, физику, редактор, тесты и т. д. Такое разделение выглядит вполне логичным с точки зрения организации — каждый человек на своём месте, что помогает снизить нагрузку и повысить эффективность. Но, тут есть нюанс, поскольку разделение знаний приводит к тому, что разные части системы не могут эффективно взаимодействовать, и разработка становится затруднённой, т. к. специалисты работают в изолированных подсистемах, не общаясь между собой по важным вопросам. Это искусственное разделение в итоге затрудняет обмен знаниями и приводит к слабой интеграции между компонентами игрового движка.

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

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

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

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

Внимание! Далее в тексте архитектурные ярлыки употребляются без строгих критериев и местами могут быть спорны.

Unity (Unitary Architecture)

Когда я впервые столкнулся с Unity, именно с архитектурой и внутренностями движка, а не внешним видом редактора, это был, мягко говоря, шок. Мои ожидания от игрового движка, покорившего мир мобилок, были из области вменяемой архитектуры, какого-то плана разработки, а вместо этого — "лоскутное одеяло" компонентов с тремя системами сборки (2014 год, всё могло поменяться, но я не слишком в это верю), кое-как собранных вместе и "обмазанных клеем" в виде mono-VM. Лишь бы всё работало, с кучей "костылей" под платформы и комментов в стиле "Не убирать этот пробел", "Не компилить в день независимости" или "Сначала собираете с этой константой, если не будет компилиться, ставите 0". Чтобы собрать редактор, была отдельная страница вики с расписанными шагами, в количестве 117 штук, что за чем делать, какие либы собирать первыми, какие пересобрать повторно на шаге Х, какие флаги и опции куда прописывать и кому молиться в случае неудачи. И для сборки редактора была своя отдельная билд-система. Но если вы посмотрите на историю возникновения Unity, то вопросов должно стать меньше.

Всё началось с разработки собственной игры GooBall, которую в 2001 году задумали студенты Дэвид Хельгасон, Йоахим Анти и Николас Фрэнсис. Их студия "Over the Edge Entertainment" столкнулась с типичными проблемами инди-разработчиков начала 2000-х: дорогие лицензии движков, сложный код и отсутствие ресурсов. Ребята игру сделали, но четыре года борьбы закончились провалом, игра не очень хорошо продавалась, зато на основе исходников той игры, тех подходов и той команды появился Unity.

В 2005 году Unity 1.0 тихо показали на конференции Apple. Казалось бы, у движка, сделанного под macOS X, мало шансов в мире, где почти все играют на Windows. Но это и стало его преимуществом: macOS была популярна среди дизайнеров, а чуть позже оказалась главным выбором для первых разработчиков под iPhone.

Unity сразу выделялся. Вместо сложного кода он предлагал компонентный подход: объекты можно было собирать как из кубиков LEGO — добавляя физику, анимацию или скрипты. Визуальный редактор, редкость для середины 2000-х, позволял просто перетаскивать элементы мышкой. А поддержка C# и упрощённого UnityScript делала скриптинг доступным. В итоге индустрия быстро обратила внимание на этот движок.

Перелом наступил в 2008-м, когда Unity вышла на Windows, удесятерив аудиторию. Но настоящий взлёт случился два года спустя, после запуска Unity Asset Store — маркетплейса готовых моделей, текстур и скриптов. А учитывая, что большая часть хлама была ценой в бакс, а то и вовсе бесплатной — это стало манной небесной для инди-студий и отдельных энтузиастов. Одновременно движок добавил поддержку iOS и Android, что совпало с бумом смартфонов. Внезапно любой, у кого был ноутбук и идея, мог создать игру мечты. Так появились Temple Run (2011) и Monument Valley (2014). Ещё через год в 2011 на движок обратили внимание фирмы EA, Blizzard и Ubisoft, заключив долгосрочные контракты на поддержку, и лицензировали (фактически выкупив исходники с исключительными правами) для внутреннего использования, а к 2015 году почти половина мобильных разработчиков применяла Unity.

"Под капотом" это всё по-прежнему оставалось "лоскутным одеялом" библиотек, трёх разных систем сборки, "парком велосипедов" всего и вся, с частично изменённой библиотекой EASTL, boost и стандартной библиотекой С++, причём разные части движка могли использовать различные STL, что приводило банально к необходимости копирования данных, например между рендером, который "жил" на EASTL и редактором, который использовал кастомные классы и контейнеры.

Добавьте сюда "прибитый сбоку гвоздями" Mono, с которым надо было обмениваться данными, и мы получим классическую архитектуру игрового движка начала 2000-х, чтобы быть не слишком "злюкой", назову такую архитектуру унитарной (Unitary). В англоязычном сегменте есть более точное определение для таких проектов.

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

Big Ball of Mud

Называют такой стиль написания кода без чёткой структуры термином "Big Ball of Mud" — это антипаттерн, популяризированный Брайаном Футом в середине 1990-х, но также среди моих коллег я слышал близкие по смыслу термины "cup of mud", "fancy barrel" и "dirty feet".

Примечание

"Big Ball of Mud — хаотичная, бессистемная, склеенная на скорую руку масса несовместимых компонентов. Такие системы демонстрируют явные признаки бесконтрольного роста и поспешных исправлений. Данные без разбора передаются между разными элементами системы, часто до такой степени, что почти вся важная информация становится глобальной или дублируется.

Общая структура системы может никогда не быть чётко определена. Если же она и была, со временем её может размыть до неузнаваемости. Разработчики с хоть каплей архитектурного чутья избегают таких "болот". Работать над подобными системами согласны лишь те, кому безразлична архитектура и кто готов мириться с рутиной ежедневных заплаток, едва сдерживающих хаос." Брайан Фут

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

Такой антипаттерн встречается повсеместно. Редко кто планирует создать "унитарную архитектуру", но многие проекты скатываются к этому из-за отсутствия контроля за качеством и структурой кода. В такой системе любое изменение в одном классе приводит к непредсказуемым побочным эффектам в других, превращая доработки в кошмар. В худшем случае под конец проекта там будет "месиво" из файлов исходников, ресурсов и технических файлов движка. То, что начиналось как проект трёх студентов, сейчас поддерживает команда из 400 инженеров. Компания Unity Technologies состоит из 5000 сотрудников, и менее 10% из них программисты. На рис. 2.1 представлена схема частей Unity Engine, где с виду всё выглядит прилично и даже неплохо... Пока ты не лезешь в "плюсовые кишки" движка и не пробуешь что-то поменять.

На этом этапе становится ясно, что "простая" архитектура давно перестала быть таковой. Всё связано со всем: менеджеры зависят от других менеджеров, состояния ссылаются друг на друга, события триггерятся непредсказуемо. Каждая попытка улучшения начинает ломать другие системы, а чтобы просто изменить логику одного действия, приходится пересобирать зависимости половины проекта. И чем дольше всё это живёт без рефакторинга, тем страшнее становится подходить к коду. Что ещё хуже — в такой структуре сильно возрастает стоимость разработки новых фичей, которые вызывают конфликты, когда нельзя сказать, "что на что" повлияло и где сломается?

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

Рисунок N2 — 1

Рисунок N2 — 2

Архитектура "Cup of Mud" (Болото легаси) — это локализованные области беспорядка в коде, где отдельные функции, классы или модули представляют собой области хаоса внутри относительно упорядоченной системы. Такие участки кода обычно возникают в результате временных решений, которые так и не были переработаны, или попыток быстро исправить критические ошибки. Функция может содержать десятки параметров, множество вложенных условий и смешанную логику разных уровней абстракции. Хотя масштаб проблемы меньше, чем у "Big Ball of Mud", эти локальные очаги беспорядка становятся источником ошибок и замедляют разработку, поскольку разработчики избегают работы с такими участками кода.

Термин "Fancy Barrel" (Красивая обёртка) характеризует код, который имеет привлекательный внешний интерфейс или API, но внутри скрывает хаотичную и плохо организованную реализацию. Демонстрирует хорошую документацию, элегантные названия методов и современные паттерны проектирования на поверхности, но внутренняя архитектура остаётся запутанной и неструктурированной. Красивый фасад, который скрывает "бочку" технического долга и создаёт ложное впечатление о качестве, проблема проявляется при необходимости расширения функциональности или исправления ошибок, и тогда остаётся радоваться только красивому интерфейсу.

Термины "Dirty Feet" (дословно — грязные ноги, наследили) и "Pigsty" (свинарник) описывают код, который "наследил" в системе, оставив беспорядок и загрязнения в различных частях проекта. Характеризуется нарушением принципов инкапсуляции, когда изменения в одном модуле требуют модификации множества других, казалось бы, не связанных компонентов. В итоге те, кто с ним работает, вынуждены делать изменения в разных частях системы для реализации одной функции, что приводит к размыванию логики и созданию неявных зависимостей. В результате код трудно тестировать, ещё сложнее изолировать, поскольку каждый компонент тащит за собой множество побочных эффектов и требует сложной настройки.

Unreal Engine (Layered Architecture)

В 1991 году Тим Суини, основатель Epic Games, тогда всего лишь Epic MegaGames, начал создавать инструменты редактирования для своих первых игр. Всё началось с приключенческой игры-головоломки под названием ZZT с очень простой графикой (рис. 2.3).

Рисунок N2 — 3

Там надо было сражаться с различными существами и решать головоломки в лабиринто-подобных уровнях с видом сверху. Используя простые ASCII-символы для визуализации персонажей, врагов и окружения, ZZT работала в текстовом режиме DOS. В то время игра не считалась революционной с точки зрения графики или игрового процесса, но подход Тима к программированию и особенно встроенный редактор уровней ZZT-OOP заложил принципы модульности, которые впоследствии эволюционировали в Unreal Engine.

ZZT оказался успешным проектом, принося автору около 100 долл. в день за счёт покупок shareware-версии. Этого было достаточно, чтобы убедить его в возможности сделать разработку игр своей профессией. Наняв небольшую команду из участников конкурса по созданию уровней для ZZT, он вывел бизнес из дома родителей и команда из пяти человек начала работу над следующим проектом — Jill of the Jungle.

В 1992 году Epic выпустила Jill of the Jungle (рис. 2.4) — платформер для DOS, где появились более продвинутые инструменты вроде анимации спрайтов, физики движения и частиц. Но главным стал акцент на компонентном подходе: Тим использовал структуры данных на основе стандартных компонентов движка, что позволяло переопределять поведение объектов без переписывания всего кода. Можно было создавать новые типы врагов, изменять их AI или добавлять интерактивные элементы уровней через скрипты.

В то время как большинство студий писали код относительно "с нуля" для каждого проекта, подход Тима был в разделении игры на "движок" (низкоуровневые системы рендеринга, физики, звука), "контент" (ресурсы и базовая логика) и "скрипты" (файлы конфигурации и высокоуровневая логика). Впоследствии этот подход был реализован в Unreal Engine, анонсированном в 1998 году с игрой Unreal (рис. 2.5).

Самый первый движок-игра уже состоял из независимых компонентов: общая логика, рендер, поверх этого редактор уровня UnrealEd, и отдельно шёл скриптовый язык UnrealScript — объектно-ориентированный, с наследованием классов, что упрощало создание модов.

Рисунок N2 — 4

Рисунок N2 — 5

Другие особенности включали физику столкновений с динамическими объектами, 16-битовый цвет, динамическое освещение до трёх источников и запуск игры из редактора уровней. Игра стала огромным успехом, разойдясь тиражом более 1,5 миллиона копий. В 1999 году Epic выпускает свою вторую игру — Unreal Tournament, которая по факту была "работой над ошибками", добавив встроенную в движок поддержку сети.

Вторая версия Unreal Engine дебютировала в 2002 году с игрой America's Army — бесплатным многопользовательским шутером, созданным с целью повышения популярности службы. Это был первый случай, когда армия задействовала крупномасштабные игровые технологии не для внутреннего использования, игра даже получила несколько наград от игроков.

Хотя основным направлением Epic по-прежнему оставалась разработка игр для ПК, Суини и его команда снова увидели, куда движется рынок: в сторону консолей. Создание единого движка, который позволял бы разработчикам выпускать игры как на компьютерах, так и на Sony PlayStation 2, Nintendo GameCube и Microsoft Xbox, выглядело крайне привлекательно. Unreal Engine 2 также продвигал интерес Суини к модульности — вместо одного стабильного релиза это был постоянно развивающийся продукт, который после первого выпуска в 2002 году регулярно обновлялся и модифицировался.

Гибкость стала ещё одним ключевым элементом Unreal Engine 2. В то время как предыдущие движки от разных компаний в основном были "привязаны" к одному жанру — шутерам от первого лица — команда Epic поняла, что предоставление разработчикам свободы работать в разных стилях станет серьезным конкурентным преимуществом. Интеграция физического движка Karma, системы частиц и других новых возможностей быстро превратила UE2 в индустриальный стандарт. Он использовался в таких успешных играх, как BioShock и Thief: Deadly Shadows.

Unreal Engine 3 вышел в 2006 году, и его флагманским проектом стала первая часть Gears of War, к списку поддерживаемых платформ присоединились новые, и появилась возможность выпускать игры на устройствах iOS и Android.

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

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

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

По закону Конвея структура кода обычно повторяет структуру самой команды. В случае с разработкой Unreal это видно особенно хорошо: команда делится на небольшие группы: UI и ввод, программисты геймплея, инженеры AI (чтобы вы могли делать NPC, объекты и монстров) и крупная команда оптимизаторов движка. Такая организация напрямую переносится и на команды, которые делают уже сами игры. При этом отдельные разработчики могут брать на себя задачи из разных направлений или проходить стажировки в других группах — это часть общей политики компании.

Рисунок N2 — 6

Но люди остаются людьми, разработка на Unreal очень расслабляет, и бывает, что команды скатываются в "архитектуру по умолчанию", когда просто следуют шаблонам движка и принятым практиками без особого осмысления, зачем это всё надо. Хуже когда в проекте начинает появляться "унитарная архитектура" и разработчики просто "начинают кодировать" без чёткого плана. Какое-то время они неосознанно будут реализовать многоуровневый подход, который несёт движок, но без должной структуры и поддержки в итоге всё придёт к "Big Ball of Mud".

На 2023 год в Epic Games работает порядка 4 000 сотрудников по всему миру. Это команды, занимающиеся играми, издательской деятельностью, магазином и самим движком. По разным оценкам из открытых источников, над движком напрямую работают от 500 до 1000+ специалистов. Но сюда компания относит, помимо программистов, занимающихся графикой, физикой и оптимизацией (около 200 человек), также инженеров технической поддержки, которые поддерживают репозиторий на GitHub и принимают новые коммиты, технических писателей и инженеров курсов, разработчиков под платформы (VR/AR, мобилки) и большой отдел, который развивает направление Virtual Production, CAD-интеграцию и обеспечивает работу с крупными игровыми и киностудиями (ещё около 400 человек).

Автор — Сергей Кушниренко

Разработчик с более чем двадцатилетним опытом программирования и создания игр. Выпускник Национального исследовательского университета ИТМО. Начинал карьеру с разработки программного обеспечения для военно-морских тренажеров, навигационных систем и сетевых решений. Последние пятнадцать лет специализируется на разработке игр: в Electronic Arts занимался оптимизацией игр The Sims и SimCity BuildIt, в Gaijin Entertainment руководил переносом игр на платформы Nintendo Switch и Apple TV. Активно участвует в проектах с открытым исходным кодом, включая библиотеку ImSpinner и проект восстановления игры Pharaoh (1999).

Все части

Подписаться на рассылку
Хотите раз в месяц получать от нас подборку вышедших в этот период самых интересных статей и новостей? Подписывайтесь!
Популярные статьи по теме

Комментарии (0)

Следующие комментарии next comments
close comment form