На дворе 2025 год, а я всё ещё продолжаю делать видеоигры. Если верить archive.org, я начал заниматься этим двадцать лет назад! Достаточно долгий срок для одного увлечения...

Когда я рассказываю о том, над чем работаю, люди часто спрашивают меня, как я делаю игры, и их часто удивляет (а иногда и тревожит?), когда я говорю, что не пользуюсь коммерческими игровыми движками. Существует какой-то стереотип, что если ты делаешь игры не в популярном инструменте наподобие Unity или Unreal, это значит, что ты чуть ли не вручную пишешь ассемблерный код.
Я искренне считаю, что создание игр без огромного «многофункционального» движка может быть проще и интереснее, а часто и позволяет оптимальнее тратить вычислительные ресурсы. Я не делаю игру, в которой «есть всё», поэтому мне не нужны 90% фич, предоставляемых движками. Все мои игры обладают конкретным стилем и у меня есть конкретные способы работы с моими инструментами. Часто оказывается так, что используемым по умолчанию реализациям фич в крупных движках наподобие Unity не хватает столь многого, что мне всё равно приходится писать их самостоятельно. В конечном итоге, мои проекты по большей мере оказываются моими собственными инструментами и системами, а движок становится необходим лишь для создания удобного UI и части рендеринга...
Тут можно задаться вопросом, а зачем вообще использовать движок? Что он даёт? Зачем я позволяю инструменту потенциально препятствовать моей работе, когда его владельцы внезапно принимают неэтичные и ужасные бизнес-решения? Или выпускают обновление, которое требуется для запуска моей игры на консолях, но ломает всю систему в игре, заставляя переписывать её? Зачем я ежедневно борюсь с этим для работы с движком, пока я постепенно заменяю все его стандартные системы и он постепенно становится только загрузчиком ресурсов и фреймворком UI редактора?
Для меня ответ очевиден: просто не нужно использовать крупные игровые движки, и вместо них писать собственные маленькие инструменты для конкретных сценариев. Это интереснее, и к тому же мне нравится управлять своим стеком разработки. Когда что-то идёт не так, я могу найти проблему и устранить её, а не отправлять отчёт о баге, чтобы спустя три месяца получить ответ, что избавляться от него не будут. Мне нравится знать, что спустя ещё два десятка лет я всё ещё смогу скомпилировать свою игру без необходимости пиратить древнюю версию поломанного игрового движка.
Разумеется, это мои личные предпочтения, но уже долгое время я пишу инди-игры. Я несколько лет работал с движками наподобие Game Maker, и уже потом перешёл на более легковесные и специализированные процессы разработки. К тому же я работаю в очень маленьких командах, где легко создавать одноразовые инструменты для членов команды. Но я хочу развеять миф, что создание игр «с нуля» — это какая-то серьёзная и неподъёмная задача; особенно учитывая состояние опенсорсных фреймворков и библиотек в 2025 году. Множество популярных инди-игр было создано на фреймворках наподобие FNA, Love2D и SDL. Создание игр «без движка» не означает, что вам в буквальном смысле нужно открывать текстовый редактор и писать системные вызовы (хотя если хотите, можете поступить и так). Часто на изучение способов самостоятельной реализации таких систем тратится столько же времени, сколько и на изучение проприетарных процессов работы с самим движком.
С учётом всего вышесказанного, я думаю, было бы интересно рассказать о моём процессе работы и о том, что я использую при создании игр.
Языки программирования
Бóльшую часть времени я работал на C#, и за исключением кратковременного перехода на C++ несколько лет назад, я вернулся к современному процессу работы с C#.
Наверно, когда я говорю о C# разработчикам крупных игр, они вспоминают, как этот язык выглядел примерно в 2003 году — с закрытыми исходниками, интерпретируемый, многословный, со сборкой мусора. Должен сказать, что с тех пор язык существенно улучшился. C# 2025 года очень отличается от C# даже 2015 года, и многие из изменений были направлены на повышение производительности и улучшение синтаксиса языка. Теперь вы можете распределять в стеке массивы динамического размера ! C++
не может этого делать (хотя C99
может...).
Кроме того, разработчики dotnet реализовали в C# горячую перезагрузку (которая чаще всего работает), что потрясающе удобно для разработки игр. Можно запустить свой проект при помощи dotnet watch
, и изменения в коде будут применяться интерактивно. Это замечательно, если вам нужно поменять способ отрисовки или обновления противников.
К тому же C# оказался золотой серединой между высокой производительностью (которая нужна в видеоиграх) и простотой повседневной работы. Например, я работал над City of None с моим братом Лиамом, который в начале проекта почти не умел кодить. Но за прошлый год он постепенно освоил язык настолько, что теперь умеет самостоятельно писать бои с боссами. Вот настолько доступен C#; к тому же, выстрелить себе в ногу на нём довольно сложно. Для маленьких команд, где каждый выполняет разнообразные задачи, это очень хороший язык.

Наконец, у него есть встроенная рефлексия... И хотя я бы не использовал её в коде релизов, возможность рефлексии игровых объектов в инструментарии редактора очень удобна. Я с лёгкостью могу создавать инструменты для интерактивной проверки, показывающие состояния игровых объектов без необходимости метапрограммирования или данных рефлексии в игре. Потратив несколько лет на создание игр на C++, я очень рад, что у меня снова появилась эта возможность.

Окна... Ввод... Рендеринг... Звук?
Всё это важные аспекты при «создании игры с нуля», однако есть куча отличных библиотек, помогающих выводить всё на экран, от SDL, GLFW и Love2D до Raylib и так далее.
Я пользовался SDL3, потому что он выполняет всё необходимое в качестве кроссплатформенной абстракции поверх системы: работу с окнами, джойстиками и рендерингом. Он работает в Linux, Windows, Mac, Switch, PS4/5, Xbox и так далее. В версии SDL3 есть абстракция GPU, обрабатывающая рендеринг на DirectX, Vulkan и Metal. Всё просто работает без проблем, фреймворк опенсорсный и используется многими в нашей отрасли (например, Valve). Я начал работать с ним, потому что FNA, который использует Celeste на всех платформах, кроме Windows, применяет его в качестве абстракции платформы.
Я написал собственный слой C# поверх SDL для общих инструментов рендеринга и ввода, которые я применяют во всех проектах. У меня есть собственный способ структурирования моих игр, поэтому мне удобно взаимодействовать с этим тонким слоем. Он замечательно подходит для моих целей, но у него есть и полнофункциональные альтернативы, например, MoonWorks.
До выпуска SDL3 с абстракцией я писал собственные реализации OpenGL и DirectX, что было непросто! Но это многому меня научило, к тому же результат оказался не таким плохим, как я ожидал. Однако я всё равно очень благодарен за SDL GPU, потому что это очень прочный фундамент, который будет протестирован на миллионах устройств.
Для звука мы используем FMOD. Это последний проприетарный инструмент, оставшийся в наших процессах разработки, что мне не нравится (особенно когда что-то перестаёт работать и приходится патчить библиотеку вручную), но это лучший инструмент для этой задачи. Если вам нужно только воспроизводить звуки, то для этого есть более легковесные опенсорсные библиотеки, но я работаю с командами, которым требуется точный контроль над динамическим звуком, поэтому без инструментов наподобие FMOD не обойтись.
Ассеты
Про ассеты мне сказать особо нечего, потому что когда выкатываешь собственный движок, то просто загружаешь в него все нужные файлы и двигаешься дальше. Все мои игры с пиксель-артом загружаются полностью, и это нормально, потому что вся игра весит порядка двадцати мегабайтов. Когда я работал над Earthblade, где ассеты больше, я регистрировал их при запуске игры и загружал только по запросу, избавляясь от них при смене сцен. Мы выбрали простейшую реализацию, которая выполнила свою задачу.

Иногда нужно преобразовывать ассеты перед тем, как их сможет использовать игра; в этом случае я обычно пишу небольшой скрипт, который выполняется во время компиляции игры и выполняет всю необходимую обработку. Вот и всё.
Редакторы уровней, UI...
Когда-нибудь я напишу полностью процедурную игру, а пока мне нужны инструменты для проектирования внутриигровых пространств. Для этого есть множество потрясающих готовых инструментов, например, LDtk, Tiled, Trenchbroom и так далее. Я в той или иной степени пользовался всеми ими, они легко настраиваются и запускаются в проекте; достаточно лишь написать скрипт для получения сгенерированных ими данных и создания игровых объектов в среде исполнения.
Однако для своих проектов я обычно люблю писать собственные редакторы уровней. Мне нравится, когда все данные моей игры привязываются непосредственно в редакторе, и никогда не углубляюсь в создание сложных фич, потому что обычно необходимые нам возможности специфичны, но ограничены.

Но мне не нравится писать UI — кодинг текстовых полей и раскрывающихся списков меня не особо радует. Мне нужен простой способ создания полей и кнопок, как собственные утилиты редактора, которые пишут для движка Unity.
И здесь нам на помощь приходит Dear ImGui. Это легковесный кроссплатформенный движок GUI с immediate mode, который можно легко добавить в любой проект. На показанном выше скриншоте редактора он используется для всего, кроме режима сцены, которую мы сами создали для отрисовки уровня. Существуют более функциональные (и тяжёлые) альтернативы, но если он достаточно хорош для множества игр, в том числе и для Tears of the Kingdom, то хорош и для меня.
Благодаря ImGui становится крайне просто писать инструменты редактора. Мне нравится, когда мои инструменты подтягивают данные непосредственно из игры, а при использовании ImGui вместе с рефлексией C# это становится очень удобным. Я могу обойти в цикле все классы Actor в C# и сделать их доступными в редакторе, написав всего несколько строк кода! В случае более сложных инструментов написание собственной реализации оказывается слишком большой тратой ресурсов, поэтому для выполнения специфических задач я применяю уже готовые инструменты (например, Trenchbroom для проектирования 3D-окружений).
Портирование игр ... ?
Главной причиной изучения C++ несколько лет назад стали мои опасения о портируемости. В то время было сложно запускать код C# на консолях, потому что он компилировался «just in time», что допускают немногие платформы. В нашей игре Celeste использовался инструмент BRUTE для транспиляции IL (промежуточных двоичных файлов языка) C# на C++ и последующей рекомпиляции под целевую платформу. У Unity есть очень похожий инструмент, выполняющий ту же задачу. Это сработало, но мне казалось неидеальным. Я хотел, чтобы можно было просто компилировать наш код под целевую платформу, поэтому изучение C++ казалось единственным реальным вариантом.
Однако с тех пор в тулчейне Native-AOT C# произошёл невероятный прогресс (по сути, это означает, что весь код компилируется «заранее», как это происходит на C++ и Rust). Теперь можно компилировать код на C# для всех основных архитектур консолей, и это очень здорово. Проект FNA активно развивал это направление, что привело к выпуску игр, написанных на C#, для всех крупных платформ.

Кроме того, у SDL3 есть консольные порты для всех основных платформ. Если использовать их, как слой абстракции платформы (при аккуратной обработке системных вызовов) всё будет работать без проблем.
Прощай, Windows
Под конец скажу, что теперь для разработки игр я не пользуюсь Windows (за исключением тестирования). Мне кажется, это вполне соответствует моей философии использования опенсорсных кроссплатформенных инструментов и библиотек. Меня всё больше раздражала работа с Windows, отвращали бизнес-практики и общая нехватка возможностей операционной системы. Я рос на Windows, но примерно три года назад полностью перешёл на Linux. И, если откровенно, при программировании видеоигр я совершенно о ней не скучаю. Она не даёт мне ничего, чего я бы не мог делать быстрее и изящнее в Linux.
Разумеется, некоторые процессы и инструменты не работают в Linux; просто такова современная реальность. Я и не полностью избавился от продуктов Microsoft — я использую vscode, пишу игры на C# и храню проекты на github... Но чем больше людей ежедневно пользуются Linux, тем больше необходимость в его поддержке и тем больше появляется поддержки опенсорсных альтернатив.
(Забавно, что сегодня я в основном играю в свои игры на SteamDeck, то есть на PC, игровой консоли, веб-сервере и в телефоне всегда используется платформа Linux.)
Прочие мысли
А как насчёт Godot?
Если вам нужны возможности, которые предоставляют более крупные игровые движки, то я определённо считаю, что Godot — это лучший из вариантов. То, что он опенсорсный и поддерживается сообществом, избавляет от множества проблем, которые у меня были с проприетарными игровыми движками, но обычно он всё равно не подходит мне для создания игр. Я намереваюсь поэкспериментировать с ним в будущем, чтобы проверить некоторые свои идеи.-
А как насчёт 3D?
Я считаю, что использовать большие движки более уместно для 3D-игр, но даже для любого моего 3D-проекта я бы создал собственный маленький фреймворк. Я хочу создавать стилизованные игры, не требующие современных технологий, и выяснилось, что делать их достаточно просто (например, мы разработали Celeste 64, почти не имея никаких знаний в 3D, менее чем за две недели).Celeste 64 Для реализации моей идеи игры нужна только самая крутая технология
Тогда работайте в Unreal! В этом нет ничего плохого, просто моим проектам не требуются подобные фичи (и я считаю, что большинство того, что мне нужно, обычно можно достаточно быстро изучить).Вся моя команда знает [игровой движок XYZ]
Миграция всей команды на собственные движки может быть затратным и длительным процессом. Я поделился своим мнением исключительно с точки зрения маленькой команды/соло-разработчика. Тем не менее, судя по моему опыту, множество средних по размерам студий перешли на собственные движки, потому что потенциальный риск использования проприетарных движков показался им слишком большим, а затраты на миграцию и обучение себя оправдали. Думаю, крупным командам использовать собственные инструменты сегодня проще, чем в прошлом.-
Процессы разработки конкретных игр
Ассеты Aseprite загружаются автоматически Я загружаю файлы Aseprite, и движок City of None автоматически превращает их в игровые анимации, используя их встроенные тэги и тайминги кадров. Его формат на удивление прост. Если вы пишете собственные инструменты, добавлять в них подобные вещи очень просто!
Комментарии (12)
Mephi1984
21.05.2025 09:19Подтверждаю. Если раньше было влом писать кучу кода по загрузке ресурсов в форматах JPG, OBJ, подключение OpenAL и прочей рутины, то теперь можно навайбкодить всю второстепенную обвязку и сосредоточиться непосредственно на разработке игры.
Jijiki
21.05.2025 09:19надеюсь такой ИИ есть, мне модель не смогла слёту без ошибок сделать експорт/импорт из блендера/в блендер(там постоянно ошибки или експорт/импорт статики, а скелет не захватывает или не пишет) костной анимации
Mephi1984
21.05.2025 09:19У меня получилось написать с помощью ChatGPT скрипт на Питоне, который экспортировал скелет из Блендера + анимацию в текстовый файл. Получилось не с первого раза, но если с умом уточнить некоторые моменты, то ИИ напишет скрипт
Jijiki
21.05.2025 09:19ок то что она импортировала сеньор 3д дизайнер должен загружать в блендер, чтобы работать с моделькой исходной и с анимациями, которые прикреплены к родителю мешу по логической связи
тоесть проверкой служит хотябы фул перенос скелета с моделькой на диск/с диска в рамках блендера
(по пайплайну я делаю модельку, креплю скелет и анимирую, нужна возможность редактирования, чтобы выстраивалась последовательность из попыток у 3д дизайнера)
например клонирование родителя ради ввода кастомной анимации ну тоесть из Т позы(добавление одежды по размерам родителяс последующим мержем к анимациям либо через скрипт либо просто из нулевой точки через открывание редактирование ), но должна быть возможность открывания формата в блендере
ripandtear
21.05.2025 09:19Ох как же много плюсов. Что вынес для себя из опыта взаимодействия с Unreal Engine (не претендую на истину последней инстанции), и использования готовых движков в целом:
Минусы:
- Никакого контроля над тем, куда плывет этот огромный корабль - в новых релизах могут сломать то что у вас работало, добавить то что вам не надо, поменять API, лицензирование, и т.п.;
- Весомая часть навороченного функционала скорее всего будет простаивать;
- Бэкпортить нужные вам фиксы и новый функционал - отдельный тяжелый пласт работ сверху;
- Разбираться в чужой философии как использовать движок, и чужом коде;
- Скорее всего особо новых знаний вы не получите, т.к. большая часть вопросов (особенно базовых) должна закрываться существующим уже написанным функционалом;
Плюсы:
- Масштабируемые знания - в теории можно в дальнейшем работать по найму, если разобраться полностью как работает та или иная чужеродная технология и сделать ее "своей";
- Сложные вещи могут быть реализованы гораздо лучше, чем если вы будете пытаться их делать сами (особенно по части рендера).
Jec13
21.05.2025 09:19Большой плюс таких игр без движков, это Р А З М Е Р !!! Он получается компактным!!!
Jijiki
21.05.2025 09:19не получится изза костной анимации, хотя я сужу по ассимпу, если его как-то ухитриться собрать конечно то может быть
со своим форматом получится наверно(а свой формат дотягивает до инструментария например блендер, от которого будут зависеть прогеры скрипта - хотя это проще если уже есть спецификация собственного формата, потом если есть формат свой значит уже есть визуализатор модельки, ну его можно сделать впрок отдебажить в блендере например ))
SadOcean
21.05.2025 09:19Мысли конечно во многом верные, но не универсально полезные.
Чтобы так делать, нужно подсобрать граблей, кроме того, это не универсальный ответ для команд и серьезной разработки игр.
Время - деньги даже для себя лично, а уж для других людей в случае найма - и подавно.
Любую фичу можно сделать, но современное разнообразие и сложность инструментов и фич такова, что сделать с нуля весь тулсет (или даже собрать из кусков) требует огромного количества времени.
Движки же обеспечиваются стабильную основу, понятные правила, множество специалистов, с ними знакомых и готовые решения.
Если не нравятся платные движки - можно стать энтузиастами для опен сурсных.
Единственное, что страдает - чувство контроля, но проблема в том, что свой движок тоже не то чтобы дает это когда что-то в очередной раз ломается во внешних API.
Обьективные проблемы движков, которые вылезают при долговременном использовании большой командой могут быть не релевантны проблемам разработчика-одиночки.Jijiki
21.05.2025 09:19неизменная математика поидее,отрисовка текста, примитивов, и далее грабли - формат(статика, анимация), тулсет на блендер, и вот уже вы можете сделать игру, мерж террейна и разбиение виртуально на квадранты не совсем подподает под сложность как только поймём как генерить что нужно,
тогда стоит вопрос что добавляют и изменяют в движкаха кажись понял, у движка стоит задача пром масштаба по доступности, плюс реализация фишек, а у студии стоит вопрос написать своё решение если его пишут с нуля например
SADKO
Православненько!