Этот проект я начал 11 лет назад и вложил в него все свои навыки и опыт работы в геймдеве. Я делаю игры уже 15+ лет, и в своем движке я постарался дать разработчику то что считаю нужным: удобство и простоту, при этом оставляя его производительным и гибким. Я работаю в основном с мобильными играми, так что движок скорее нацелен на мобилки. Однако нет препятствий использовать его для десктопа и под веб.

Я все еще дорабатываю его, но он уже вполне стабилен и я делаю игры на нем. Сейчас это ближе к бета‑версии, и я думаю пора представить его публике:

https://github.com/o2-engine/o2

Движок предназначен для 2D/3D игр, работает на C++ и JS, есть крутой редактор «всё в одном» и поддерживается пачка платформ:

  • iOS, Android, Windows, macOS, Linux, Web

Он компактный (всего несколько мегабайт), производительный, позволяет писать логику игры как на C++, так и на JavaScript, и на него легко пересесть с Unity3D/Godot и тому подобное

Движок октрытый и бесплатный. Это ключевое решение для движка, нижу чуть подробнее об этом


На мой взгляд лучше всего рассказать про технологию — показать демо и рассказать как все устроено внутри.

Ниже по ссылке можно пощупать редактор в сендбокс‑окружении под веб. Внутри простая демка игры, с JavaScript и шейдерами. При наличии ключика gemini можно так же поэкспериментировать с ИИ

https://o2editor.zenkovich.space/

В статье я расскажу какие идеи заложены в o2, как он устроен внутри и в чём я постарался сделать его лучше, чем Unity3D/Godot/Cocos и др. движки.

Идея

Если коротко, o2 в себе совмещает преимущества Unity3D и кастомных C++ движков:

  • в нём есть удобный редактор, понятная и продуманная архитектура, чтобы делать игры быстро и прототипировать

  • из него можно выжать максимум производительности, так как внутри C++ и игровую логику так же можно писать на C++. Можно залезть настолько глубоко, насколько этого требует оптимизация

  • опенсорс. Код открыт, можно узнать как что работает и в случае необходимости модифицировать

  • JavaScript как скриптовый язык — для нетребовательных к перформансу частей игры: UI, бизнес‑логика. Писать быстро, а хотрелоад экономит кучу времени

  • мультиплатформенность. Пишешь игру на C++ и JS под все платформы сразу

  • маленький размер. Минимальный hello world движка — менее 3 МБ, отлично подходит для мобилок и под web

То есть, наверное, то, чего все C++ разработчики хотели от Unity3D: сохраняя все его плюсы, добавить в него ПЛЮСЫ, при этом имея открытый код и более компактный размер.

А еще o2 можно встроить в уже готовые игры

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

Решением может стать o2: он может встроиться в рендер и игровой цикл другого движка, а так же обернуть другой движок в редактор o2. Тогда в старом проекте мгновенно станут доступны Unity3D‑like инструменты: редактор, сцена, UI, анимации, и все это в старой игре без переписывания с нуля.

Например, здесь я попробовал интегрировать o2 в довольно популярный, но старый движок — cocos2d‑x. Он уже не поддерживается несколько лет, но на нем еще работает куча игр и даже делаются новые. Ниже по ссылке демо: в редакторе o2 можно посмотреть стандартный тестовый набор сцен cocos. Даже пощупать иерархию и посмотреть параметры нод

http://cocoso2.zenkovich.space/

Что внутри

Внутри несколько мегабайт кода. И это немного для того, что o2 умеет: 2D/3D, анимации, партиклы, UI, скриптинг, звуки, видео, обработку инпута, физика, сеть.

Всё можно разделить на три абстрактных уровня: утилитарный, низкий и высокий.

Утилитарный слой

Пачка базовых подсистем, на которых всё держится:

  • менеджмент памяти. Собственные умные указатели, GC в режиме отладки. Максимальная эффективность и безопасность работы с памятью в C++. GC в режиме отладки — вишенка на торте, позволяет прямо из движка найти утечки, зацикленные ссылки и посмотреть, куда сколько памяти уходит

  • рефлексия. Через неё работают сериализация, биндинги, анимации, события и строится редактор. Работает через метаинформацию о типах, генерируемую отдельной утилитой

  • математика. Всё, что нужно для геймдева: vec2/3, matrix, quaternion, spline и так далее

  • файловая система. Кроссплатформенные обёртки над работой с файлами, удобные API для итерации по папкам и тому подобное

  • удобные обёртки над std. Более «сахарные» vector/map, в которых есть удобные функции для удаления, итерирования и агрегирования

  • системные обёртки. Для вызова системных окон, работы с буфером обмена и тому подобное

  • properties. C#‑like обёртки над set/get, с минимальными издержками, дающие удобство работы со сложными полями. Например, вместо obj.SetPosition(obj.GetPosition() + XXX) можно написать просто obj.position += XXX;

  • система тасок и корутины. Для отложенного вызова, асинхронной логики (оченнь полезно при взаимодейсвтии с сервером)

Здесь есть всё, что делает работу с движком удобной. Добавлены некоторые фичи в C++, которые делают синтаксис проще и сахарнее, без потери производительности.

Например, есть свой аналог std::function — o2::Function, который может хранить в себе не только одну функцию, а целую пачку. Очень удобно для паттерна подписчика: на единый коллбек может подписаться множество слушателей. Под капотом оптимизировано, и неважно, один там коллбек или несколько.

Низкий слой

Здесь набор низкоуровневых подсистем, которые можно было бы назвать скорее фреймворком, чем полноценным движком:

  • приложение. Входная точка и управление всем жизненным циклом игры. Единая обвязка под все платформы. Достаточно работать с ней, чтобы управлять поведением игры на всех платформах

  • ассеты. Инициализация и оперирование ассетами в игре, система сборки ассетов

  • рендер. Всё, что касается 2D/3D‑отрисовки, материалов и шейдеров. Настраиваемые рендер‑пайплайны, можно управлять буквально всем процессом рендеринга вручную

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

  • скриптинг. Скриптовый движок и C++ обёртки над JS‑примитивами. Автобиндинг через рефлексию. Поддержка нескольких JS‑движков, в частности, под WASM используется биндинг на нативный движок браузера, где запускается игра

  • анимации. Внутренний формат, который биндится через рефлексию и позволяет анимировать буквально любую property или поле объекта

  • звуки. Простой плеер звуков с базовыми настройками и поддержкой пространственных звуков

  • физика. Интегрированы Box2D / Box3D (дада, мистер Эрин сделал 3D версию), обернуты базовые примитивы коллайдеров и джоинтов

  • работа с сетью. Сокеты и http запросы — джентельменский набор для клиент‑сверного взаимодействия

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

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

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

Высокий слой

Как я писал выше, это надстройка над низким уровнем, преимущественно нацеленная на ускорение разработки и удобство. Сюда входят:

  • иерархическая сцена. Акторы, их наследники, компоненты, префабы — все, что образует игровую логику на сцене. Классический подход Unity3D. Удобный для 90% случаев

  • UI. Это надстройка над сценой — примитивы для вёрстки интерфейса, с адаптивной вёрсткой и группировками. Очень похоже на UnityGUI, за исключением того, что оперирует наследниками от Actor, а не компонентами. В какой‑то степени это более гибко и удобно: логика работает с кнопками и виджетами, а не нодами и компонентами

  • out of box компоненты:

    • система частиц

    • анимации и стейт‑граф

    • 2D/3D примитывы

    • физика

    • звуки

    • видео

    • скриптинг‑компоненты

Редактор

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

Для редактора нужен хороший и гибкий UI, и в движке тоже. Я решил убить двух зайцев одновременно и сделал редактор на своей движковой системе UI. Даже писал об этом тут на хабре: https://habr.com/ru/articles/521306/. Это позволило мне сделать максимально гибкий и удобный UX редактора, при этом завести пачку красивостей в виде плавных анимаций

В редакторе можно запускать игру, редактировать сцену и префабы, настраивать ассеты. Внутри есть редактор анимаций (а так же стейт‑граф анимаций), редактор частиц, редактор UI. Все что умеет движок — все можно сделать в редакторе.

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

Редактор работает под windows, mac, linux, и я хочу сделать удобное решение под веб. Чтобы можно было отдать его дизайнеру, не запаривая его с билдами, скачиванием и настройкой.

Тесты и CI

В движке уже больше 2000 тестов, и их становится больше. Я долгое время не писал тесты, но с появлением ИИ грех этого не делать. Весь движок был покрыт тестами, причем не просто для галочки, а именно тестами реальных кейсов. Любой баг, любая доработка, любой новый функционал, в т.ч. в редакторе — по умолчанию покрываются тестами.

Это позволяет движку не деградировать, и становиться только стабильнее. Тесты покрывают все слои движка. Отдельно могу отметить архитектуру и тесты редактора: все что меняет ассеты или сцену в редакторе происхходит через систему действий. Действия умеют выполняться и отменяться, что обеспечивает работу Ctrl + Z / Cmd + Z.

На основной ветке настроены сборки через github actions, с помощью них я слежу за стабильностью движка на всех поддерживаемых платформах

Интеграция с ИИ

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

Недавно навайбкодил игру на хакатон на o2: https://habr.com/ru/articles/1065796/

Интеграция JS для скриптов значительно ускоряет итерации ИИ, он может без перекомпиляции или перезапуска работать над игрой.

Так же в движок встроены утилиты для того, чтобы ИИ понимал, что происходит внутри, и мог с ним взаимодействовать в рантайме: снимать скриншоты, делать клики, смотреть в сцену и тому подобное. Совместно с JS‑скриптингом буквально может сам итерироваться и проверять свою работу.

В планах у меня добавить в движок генерацию арта. Это всегда было краеугольным камнем для инди‑разработчиков, и сейчас ИМХО лучшее время для них. У меня есть прототип нодового генератора контента — https://assetsline.app/, и я думаю встроить это прямо в редактор. Можно будет генерировать спрайты, звуки, текст и видео. А затем использовать в игре

Здесь небольшая пачка игр, сделанных с ИИ на o2: https://games.zenkovich.space/

Как начать пользоваться o2?

Самое простое — сделать форк проекта‑шаблона и на его основе делать игру. Или же по образу его и подобию создать свой проект и подключить o2 как сабмодуль.

https://github.com/o2-engine/o2-Template

Для сборки нужны CMake и IDE для локальной разработки на C++, в зависимости от платформы: VS Code, CLion, MSVS, Xcode, Android Studio.

Конфигурация проекта — либо через IDE, либо вручную через CMake, либо через внутреннюю тулзу GenerateProject.

Внутри шаблонного проекта есть несколько таргетов. Они делятся на 2 категории: проект и редактор. Проект просто запускает игру в виде standalone‑приложения, локально или на девайсе. Редактор соответственно запускает редактор, как в Unity3D: можно редактировать сцену, ассеты и локально запускать игру.

Документация

Она лежит прямо в репозитории в виде markdown. На мой взгляд лучшее место и формат как для человека, так и ИИ.

https://github.com/o2-engine/o2/blob/master/Docs/ru/Architecture/architecture.md


Больше о разработке o2 и о разработке в целом в моем телеграм‑канале.

Там менее формально, и вдруг если вас заинтересует движок, могу что‑нибудь подсказать по нему