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

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

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

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

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

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

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

Ник Атамас: Для меня она делится на периоды до и после 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) непростой. Каждый элемент устроен комплексно, потому что с его помощью можно сделать или простую вещь, или очень-очень сложную.

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

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

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

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

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

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

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

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

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

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

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

Олег Чумаков: Недоумение при первом запуске 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, он только на клиенте существует (четыре базы по краям стола).

Про языки

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

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

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

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

Возьмём VR. Большинству пока непонятно, но в VR есть примерно 10 миллисекунд на каждый frame, а не 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 могут оказаться правильным выбором — думаю, один из них.

Про 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++, и это получается довольно быстро — одной кнопкой.

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

Олег Чумаков: Когда-то Oculus выдал свой самый-самый первый проект для VR, он был на UE и с открытыми источниками. Нас удивило, что весь код, те функции, которые в C++ написаны, чтобы их просто из Blueprint вызывали, просто игровая логика и так далее — всё разложено по 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 или при портировании адаптирует её под нужную платформу.

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

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

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

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

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

Про Vulcan

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

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

Нравится9
Комментарии (4)
B
i
u
Спойлер