Dagon 10 лет!

Проект стартовал 9 октября 2016 года, ровно 10 лет назад. Конечно, это не первая моя разработка в сфере геймдева, и я начал писать движок далеко не с полного нуля — к тому моменту у меня был DGL, набор классов, упрощающий работу с OpenGL в D (а до этого я работал с OpenGL и писал разнообразные сопутствующие библиотеки на C++). Однако именно Dagon стал наиболее успешным.

Создание игрового движка — наверное, одна из самых интересных и нетривиальных задач в программировании. Есть устойчивое убеждение, что свой движок писать вообще не нужно, и я как-то раз написал статью о том, почему это скорее миф. Существуют примеры успешных проектов как на лицензированных движках, так и на эксклюзивных, оба варианта имеют свои плюсы и минусы. На мой взгляд, главное преимущество собственной технологии — независимость от чужих лицензионных условий и архитектурных решений. В современном мире большинство проектов делается на Unity и UE, в результате чего игры слишком похожи друг на друга. Собственный движок — это ваш уникальный почерк. Понятно, конечно, что с UE конкурировать практически невозможно — продукты, в которые вложены миллионы долларов, будут всегда впереди. Но UE — это движок-монстр, все возможности которого нужны далеко не каждому. Если речь об инди, то нелепо, когда рантайм игры весит, как все ее ресурсы (если не больше), а системные требования — как у AAA. Должны же быть и маленькие движки! Ну и, наконец, психологический фактор: игра на чужом движке воспринимается как не совсем твоя.

Я начал интересоваться геймдевом еще в далеком 2005 году, когда открыл для себя Game Maker, Blitz3D и другие популярные любительские технологии того времени. Затем я пробовал работать с Irrlicht, OGRE, Blender Game Engine, но с точки зрения архитектуры меня очень впечатлила GLScene, графическая библиотека для Delphi. Мои собственные разработки во многом вдохновлены классами GLScene, хотя напрямую я оттуда ничего не копировал. Я вообще почти не заглядываю в исходники чужих движков — не знаю, хорошо это или плохо, но у меня свое понимание того, что удобно, а что нет. Боже упаси создавать клон Unity или что-то подобное. Не мыслите шаблонами индустрии, изобретайте свои технологии!

Я никогда не писал на DirectX, как-то почти сразу освоил OpenGL и всю жизнь сидел на нем. В нулевых это были версии 1.x-2.x, еще с фиксированным конвейером, где шейдеры были необязательной частью. Потом — короткий период 3.x, и, наконец, к концу десятых — 4.x. Я проследил практически всю эволюцию OpenGL и использовал его до последнего, когда стало уже очевидно, что пора двигаться дальше и осваивать эксплицитные API. Я, однако, не фанат чистого Vulkan. На нем не надо писать приложения напрямую по той же причине, по которой не пишут напрямую на ассемблере. Vulkan — это машинно-ориентированный бэкенд, поверх которого нужна абстракция, удобная для человека. Я терпеливо ждал появления таких абстракций, они появились, и вот теперь можно со спокойной душой уходить с OpenGL.

Что еще могу сказать на основе десятилетнего опыта? Разрабатывая большую систему, такую, как игровой движок, рано или поздно приходишь к идее неизбежности компромисса между двумя силами, тянущими проект в две разные стороны — абстракцией и специализацией. Абстракция — это сокрытие деталей под высокоуровневым интерфейсом. Абстракция повышает удобство на стороне пользователя, но снижает гибкость и возможности оптимизации. Специализация, напротив, подразумевает, что пользователь сам должен предоставить реализацию некоего интерфейса — то есть, углубиться в детали и интегрировать в движок свое решение специфической задачи. Это дает гибкость и возможности оптимизации, но снижает удобство. Хорошая система включает в себя и то, и другое. Дзен в балансе: нужно постоянно решать, в какой степени система должна быть абстрактной, и в какой — специализированной. Например, один из первых 3D-движков, с которыми я работал — Xtreme3D для Game Maker 6 — имел очевидный приоритет абстракции над специализацией: в нем были готовые декодеры разных форматов 3D-моделей, но полное отсутствие возможности создать свой собственный (то есть, собрать модель вручную из вершин и индексов). А вот встроенный 3D-рендер Game Maker, наоборот, не включал практически никаких абстракций и вынуждал программировать графику на низком уровне, составляя списки отрисовки из отдельных полигонов. В первом случае удобно, но не гибко, во втором — гибко, но неудобно. Учтя эти особенности, я решил делать движок, который охватывает оба сценария использования. Если вам нужно просто загрузить glTF, то это легко. А если вы хотите создать свой формат сцен, то это, пусть и с оговорками и требованиями, но реализуемо. Я всегда подчеркиваю, что Dagon — это фреймворк, то есть, каркас игрового приложения. Его ядро включает только создание окна и контекста OpenGL, управление таймером главного цикла и очередью событий. Рендер — это уже надстройка; в Dagon можно не использовать встроенный рендер и написать свой. То же касается абсолютного большинства всех подсистем — они не прибиты гвоздями. Принципиальной основой работы в Dagon является инверсия контроля, как и во всех фреймворках, но ядро минималистично — оно не отвечает за все процессы, и вы можете заменить почти все, что угодно, на самописные компоненты.

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