Подкаст «Как Делают Игры»: программисты об Unreal Engine

Старший программист Epic и CEO Luden.io о настоящем и будущем движка.

9 февраля вышел 172 выпуск подкаста «Как Делают Игры». В этот раз ведущие Сергей Галёнкин и Михаил Кузьмин поговорили с гостями об особенностях игрового движка Unreal Engine 4.

Гости выпуска:

— Ник Атамас — Senior engine programmer, Epic;

— Олег Чумаков — CEO Luden.io.

DTF публикует избранные моменты беседы.

Подкаст «Как Делают Игры»: программисты об Unreal Engine

Про историю движка

Ник Атамас: Для меня она делится на периоды до и после Unreal Engine 3 (UE3).

На UE 1 были сделаны игры Unreal и Unreal Tournament, я играл в них ребёнком. Тогда все говорили: вот — отличный редактор! Но когда я его попробовал — оказалось, что нет, не отличный. Он был непонятен, устроен не как остальные программы — 3ds Max, Maya или даже Windows Explorer. Unreal Engine 2 стал просто его эволюцией. А настоящие изменения пришли с UE3.

Я начал работать в Epic в 2008 году — тогда разрабатывалась Gears of War 2. После этого мы сделали браузер контента (content browser) — первую часть будущего UE4.

Основная разработка UE4 началась после Gears of War 3. В команде было три человека — Тим Суини (Tim Sweeney), Эндрю Шайдекер (Andrew Scheidecker) и я. У каждого — свой проект. Мы хотели сделать движок, лучше работающий на Mac OS, Linux и Windows, с более понятным интерфейсом редактора. Конечно, он должен был выдавать отличную графику, такую, какой никогда ещё не было.

В тот момент мы думали сделать это на Larrabee. Не знаю, помнит ли кто, но тогда Intel планировала выпустить Larrabee-видеокарту, которая бы использовала x86, у неё было бы, скажем, 64-128 процессоров, каждый из которых — примерно как Pentium-60. Многопоточная система. Тим разрабатывал свой язык программирования, «Пи», который позволил бы всё параллелизировать.

Эндрю Шайдекер работал над идеей рендеринга в стиле Pixar. Это когда берёшь меш (mesh), делишь на микротреугольники, каждый размером примерно с пиксель. После применяется аналитический антиалиасинг (analytical antialiasing) и порядко-независимая прозрачность (order-independent transparency).

Я же собирался сделать систему UI, которая бы работала на всех платформах. Мою часть оставили в UE4, остальные были слишком умными и как-то не пошли.

Мой проект теперь называется Slate. Это был первый код в UE4. За шесть месяцев, используя Slate, мы полностью переписали редактор, и он начал работать на всех платформах. К нему начали разрабатывать инструментарий.

Во время работы UE делает много разных вещей. В нём есть Blueprint, как в Visual Studio (не такой сложный, но всё же). Непростой редактор систем частиц (particle system editor). Каждый элемент устроен комплексно, потому что с его помощью можно сделать или простую вещь, или очень-очень сложную.

Подкаст «Как Делают Игры»: программисты об Unreal Engine

Олег Чумаков: Сейчас программисты часто пишут model view controller. Такие каркасы все себе писали, потому что индустрия, по крайней мере в России, последние годы работала на Unity. А в Unreal тебе сразу дают player, pawn controller, и нужно всё это самому разбивать между ними. В разработках компании это как-то разбивается ещё на подсистемы, или вы придерживаетесь только базового каркаса?

Ник Атамас: В компании разработки начинаются с того, как сделать игру интересной, чтобы человек хотел играть и не останавливаться. Этим обычно занимаются геймдизайнеры или художники, но не программисты. Мы бываем нужны, чтобы добавлять абсолютно новые системы, например, чтобы анимация взаимодействовала с физикой. Тогда — да, программист будет помогать.

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

Создание UI идёт более структурированно, потому что есть модель: кнопки, слайдеры, меню, то есть очевидный дизайн-словарь, с ним можно использовать MVC, MVVM. А когда делаешь игру — откуда ты знаешь, что понадобится, а что нет.

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

Как вы обычно делаете — остаётесь в рамках фреймворка, который предоставляет UE, или нет?

Ник Атамас: Инженеры, конечно, хотят сделать всё структурированно. Но обычно есть расписание, в котором указано, что всё должно было быть закончено месяц тому назад, и пора начинать «кранч». Нет времени переписывать — просто сделай так, чтобы оно работало.

В этот момент нужны талант и опыт, чтобы решить — переписывать всё, или оставить и исправить отдельные ошибки.

Если MVC, MVVM подходят — их используют. Думаю, главное в них не гениальный дизайн (который не всегда подходит), а в контексте. Ты получаешь «словарь», который сразу можешь использовать, чтобы дойти до того, как что-то реализовать.

Все понимают, что делать отдельные «M», «V» и «С» — не всегда умно, обычно делят так: «M» и «VC». Используется даже набор понятий, вышедший из Next и Apple.

А MVVM — вообще новая вещь, которая не всегда подходит. Зачем делать три класса, когда очень часто можно сделать один, быстро написать, и всё заработает?

Подкаст «Как Делают Игры»: программисты об Unreal Engine

Олег Чумаков: Недоумение при первом запуске Unreal вытекает из того, что многие в российской индустрии сидели на Unity. Там чистый entity-component: всё, что тебе даёт движок — это базовый класс, и обращайся к базовому API, условно говоря, Static API самого движка. Типа «input, скажи, сколько времени ты потратил на последний кадр» и всё такое. Вокруг этого каждый крутил систему, которая ему была нужна — естественно, MVC чаще всего.

Посмотрим на другие движки, даже на Javascript frameworks. Там почти всегда, когда вы создаёте новое приложение — автоматически генерируется фреймворк, чтобы программист не навёл архитектурный ад и кошмар. В UE4 как раз такой случай. Движок создаёт базовый каркас. Если игра начинается с дизайнерской мысли — у дизайнеров меньше шансов промахнуться и потом, когда скажут, что уже месяц «кранч» — напороться на то, что всё разложено как попало и не там.

Ник Атамас: Когда я писал свой первый движок — я всё сделал неправильно. Но это было нужно, чтобы понять, как их писать.

Не всегда легко понять, почему UE делает именно то, что он делает. Я бы даже сказал, что всё снова изменилось пора думать, как это нужно реализовывать для VR. У нас есть понятие «game controller» — именно физический контроллер: геймпад или мышка. А есть «pawn» — это как пешка в мире, которую игрок контролирует через контроллер. Но если подумать об этом сейчас — в VR этот контроллер и есть «pawn» в мире игры. Можно снова задаться вопросом — MVC уже более 30 лет, может, он уже не подходит?

Олег Чумаков: Мы всю жизнь занимались стратегиями или CCG, и в итоге поняли, как разобраться в архитектуре Unreal. Нужно выписать себе, как маппится pawn controller, game state, player state и так далее на примере мультиплеерного шутера. Рядом выписываем параметры нашей игры, например — Hearthstone. И пытаемся свести параллели — что бы было, если бы это был шутер, и как правильно «раскидывать» компоненты.

Ник Атамас: Я думаю, так и нужно делать, это правильно.

Олег Чумаков: Мы пришли к этому муками. Где-то на форуме UE есть заведённая нами тема. Там расписывали пользователи, где держат код для логики, а где — для синхронизирующихся с сервером переменных и так далее. Мы выкладывали скриншот Hearthstone, на котором стрелочками показано: по аналогии с шутером вот эта карта — pawn, а это — просто независимый actor, он только на клиенте существует (четыре базы по краям стола).

Подкаст «Как Делают Игры»: программисты об Unreal Engine

Про языки

Олег Чумаков: В UE официально есть поддержка Blueprint (синтетический язык, который можно превращать в C++) и самого C++. Почему вы не добавили какой-то скриптовый язык, который имеет текстовую репрезентацию?

Ник Атамас: Думаю, в будущем могут появиться  C#, Python или что-нибудь в этом роде. Мы уже говорили — MVC, MVVM, зачем к вопросу «как должна быть устроена архитектура?» добавлять «мне использовать Python, C# или Blueprint, или C++?». 

Может быть, логику удобнее писать на C#, визуализацию на Python, а сетевую часть в Blueprint? Теперь попробуйте через всё это сделать дебаг. Зачем такая головная боль? 

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

Возьмём VR. Большинству пока непонятно, но в VR есть примерно 10 миллисекунд на каждый фрейм, а не 16 или не 30. Это очень мало. Если  garbage collection вызывает задержку, и игра пропускает 2-3 фрейма, человеку может стать тошно. Может, C# — это неправильный выбор, контролировать garbage collection в нём может быть очень непросто. Или начинаешь писать на C# без использования оператора New, и это превращается вообще непонятно во что.

Это серьёзные вопросы — ответы на них неочевидны, и дискуссия пока идёт. 

Сергей Галёнкин: Как я понимаю, проблема в том, что программисты хотели бы разрешить геймдизайнерам писать на скриптовом языке, который они понимают. Есть плагины почти для всех скриптовых языков в Unreal Engine. Если кому-то прямо хочется, можно их поставить.

Олег Чумаков: Поясню с позиции разработчика. Плагины есть, их даже грантами поддерживали. Но когда я захожу в них — список платформ всегда неполон. Не дай бог у меня игра хочет работать на Mac OS, Windows, Linux — всё, нет ни одного плагина. Или если выходит новая версия API движка — мне нужно либо самому его «пробрасывать» в Javascript, либо ждать, когда будет выходной у того, кто поддерживает плагин, чтобы он это сделал.

Ник Атамас: А как насчёт iOS, Android, PS4, Switch? Единственный язык, который работает на всех платформах — это C++. Если мы выберем один язык — нужно сделать так, чтобы он отлично работал всюду. Думаю, ни одна компания в мире не обеспечит хорошую поддержку двух языков — слишком много работы. Сейчас Python, C# и JS могут оказаться правильным выбором — думаю, один из них.

Подкаст «Как Делают Игры»: программисты об Unreal Engine

Про Blueprint

Ник Атамас: Мы сделали Blueprint после Kismet. В UE3 было три используемых системы — C++, Unreal Script и Kismet. С++ пользовались разработчики движка. US использовали программисты, которые делают геймплей. И с Kismet работали дизайнеры уровней, например, если дверь должна открываться после убийства врагов. 

Некоторые дизайнеры уровней использовали хитрости. Один человек, Ли Перри, используя Kismet, сделал для UT3 робота-треногу из «Войны миров». Потом её взяли программисты, перевели в US и C++, и эту машину можно было водить в UT3. 

Мы на это посмотрели и сказали: «Хорошо, давайте больше возможностей из US перейдут в Kismet, US должен исчезнуть». Программисты будут заниматься движком, а остальные разработчики начнут работать в Kismet 2. Потом его переименовали в Blueprint. 

Мы полностью перевели имплементацию. У US была виртуальная машина, которая интерпретировала код, а теперь она интерпретировала US-код, который генерировался Blueprint. Я разрабатывал сам редактор, Джеймс Голдвин (James Goldwin) — систему компиляторов. Мы внедряли его до тех пор, пока не перевели на него всю компанию. Тогда стало понятно, что его можно добавить в UE4. 

Сейчас, используя Blueprint, можно почти полностью сделать игру и не писать ни одной строчки кода C++. Я думаю, главная его сила в скорости итерации. С того момента, как ты что-то изменил и нажал кнопку «play», проходит полсекунды-секунда и ты проверяешь, что изменил. Из-за хорошей интеграции с движком возрастает скорость разработки. Если нужно что-то найти — просто заходишь в браузер контента, перетаскиваешь — и всё работает. 

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

Михаил Кузьмин: А есть какие-то ограничения, например, для клиент-серверных игр, или он может всё?

Ник Атамас: Blueprint может всё. Я бы не делал на нём тяжёлую математику, свой алгоритм сортинга. Например, на Robo Recall мы переводим Blueprint в C++, и это получается довольно быстро — одной кнопкой.

Подкаст «Как Делают Игры»: программисты об Unreal Engine

Про библиотеки

Олег Чумаков: Когда-то Oculus выдал свой самый-самый первый проект для VR, он был на UE и с открытыми источниками. Нас удивило, что весь код, те функции, которые в C++ написаны, игровая логика и так далее — всё разложено по C++ файлам .dll, отдельным библиотекам. Игровой код подключался в движок, как плагины. У нас были гипотезы, почему так — библиотека компилируется быстрее, художники ничего не компилируют, а им можно просто отдавать библиотеки и так далее. Вы «разбиваете» C++, или он лежит в проекте?

Ник Атамас: Это очень зависит от состава команды. Например, у Robo Recall в ней 4-5 дизайнеров, некоторые умеют писать на C++, но в основном делают всё в Blueprint из-за скорости итераций. Думаю, над Oculus трудятся заядлые C++ инженеры, и им гораздо приятнее работать в нём: они разбивают логику на плагины, а когда плагин маленький — итерацию можно получить за две-три секунды.

Я тоже люблю всё делать в C++. Жмёшь кнопку «compile» или «module reload» (это более «спрятанная» функция в Unreal) и перезапускаешь .dll, не останавливая движок. Бонусы очевидны — отлично работают дебаггер, поиск и рефакторинг, есть достаточное разделение (merging) между людьми.

Но обычно дизайнеры говорят программистам, как всё должно работать, а те просто как робот говорят «хорошо, сделаю». 

О мобильной разработке

Ник Атамас: Весь контент никогда в билд не помещался. У нас есть процесс «cook» — «запекание» проекта. Он похож на «garbage collection». Мы начинаем с рута (root) — это список специальных пакетов, которые всегда используются в игре, например — картинки для UI всегда хранятся в памяти. Мы смотрим на рут и делаем «garbage collection pass»: находим всё из этого рута, на что стрелочки показывают, все референсы. Остальное выбрасываем.

У нас есть понятие DDC — «Derived Data Cache». Например, мы компрессируем текстуру в формат, который лучше всего подходит платформе. Это часть «запекания». Во время работы Unreal пишет все версии текстур, мешей и анимаций в DDC, приготовленный для платформы. Потом «запекание» или берёт Derived Data или при портировании адаптирует её под нужную платформу.

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

Подкаст «Как Делают Игры»: программисты об Unreal Engine

Работа со звуком

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

Сейчас с нами работает композитор — Аарон МакЛарен (Aaron McLaren). Он гений, очень любит музыку, сам пишет её по выходным. Он полностью переписал миксер (mixer), который смешивает звуки в игре, и его мы используем в Robo Recall. Он также добавил в систему синтез, и делает API для его. Живёт в Сиэтле, мы с ним часто говорим о том, как устроить UI, чтобы он был более доступным для работавших в музыкальных программах.

В Robo Recall у нас есть второй человек, молодой инженер, который очень серьёзно занимается музыкой — он написал часть саундтрека и звуков для проекта. Думаю, это лучший звук, который мы делали в Epic. Новые опции из этой сферы появятся в UE, думаю, их покажут на GDC.

Про Vulkan

Ник Атамас: Я думаю, наши ребята уже с ним работают. Vulkan и DirectX 12 дают программисту больше возможностей, но с ними гораздо легче сделать ошибку, влияющую на производительность. 

Программисты, которые занимаются только графикой день и ночь, скорее всего, этих ошибок делать не будут. Или если мы сделаем их — они их найдут. Это много даст движку. Но для человека, который хочет написать мобильную игру или что-то вроде этого, Vulkan — хуже. Старый добрый Open GL лучше походит простым играм.

2222
16 комментариев

Отличное интервью, спасибо, и из него полностью очевидно почему инди и маленькие разработчики преподчитают юнити )

3

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

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

Не думаю, что это серьезно. У них на доске в трелло такой задачи нет, потому что и смысла в ней особо не видно. А перевод блюпринтов в C++ в прошлом году был реализован.

Насчет того, что UE1(2) был непонятен я в корне несогласен. Тогда популярным движком для разработки был Квейк, а это Radiant или QuArK (Quake Army Knife) - кто в них работал, тот знает, какой это адский геморрой. UE по скорости работы покрыл их как бык овцу, но платой за это был перелом в методологии построения уровня - вместо добавления мешей "твердой" геометрии в "пустоту", надо было работать булевыми операциями на "твердым" изначально пространством. Но компилирование уровня (bsp + лайтмапы) занимал в десятки раз меньше времени, чем в Кваке. И про С тогда особо не думали - на скриптах и триггерах можно было собрать черта лысого.