34 KiB
Новый движок: выводы исследования UE, Godot и Unity
Название проекта — Faset Engine. Синхронизация решений: 18.09.2026. Каноническая архитектура — ARCHITECTURE.md, последовательность до и после MVP — PLAN.md. Этот отчёт сохраняет исследовательские аргументы и обновлённые принятые решения. Прежние альтернативы отмечены superseded; факты о чужих движках не означают, что соответствующие возможности реализованы в Faset.
Дата: 17 сентября 2026. Цель — новый движок для Linux и Windows, десктопных 2D/3D-игр, одинаково удобный при ручной работе и через MCP, с интеграцией как минимум с Blender. Это исследовательская основа реализации. На момент первоначального исследования код нового движка ещё не создавался; текущая реализация описана в журнале, ниже принятые архитектурные правила отделены от экспериментальных графических направлений и деталей будущих прототипов.
Уточнения после обсуждения исследования
Подтверждённый выбор пользователя: Box2D для 2D-физики, Box3D для 3D-физики. Под Box3D имеется в виду erincatto/box3d, анонсированный Erin Catto 30 июня 2026. Это отдельная 3D-библиотека с C API и реализацией на C17; репозиторий указывает поддержку Windows и Linux. Анонс, Box2D overview. На момент исследования версии ещё не выбирались и собственные физические тесты не выполнялись. Теперь версии закреплены в dependency lock, а результаты интеграции записаны в журнале реализации.
Принятый принцип интеграции: отдельные PhysicsWorld2D/PhysicsWorld3D, компоненты RigidBody2D/3D и Collider2D/3D, единые правила регистрации, идентичности, Inspector и диагностики. Миры 2D и 3D не сталкиваются автоматически друг с другом. Физика получает команды перед фиксированным шагом; после завершения шага движок переносит результаты и события в runtime. Для динамического тела физика владеет рассчитанным transform; runtime teleport и управление кинематическим телом — отдельные операции. События связываются с entity через проверяемые handles. Названия API в этом исследовательском описании предварительны; фактический API адаптеров и gameplay описан в Manual.
Решение от 18.09.2026: сначала ядро и игровая логика на C++, затем добавляем Lua отдельным модулем. Его будущая реализация принята, использование конкретной игрой необязательно. Игра на C++ не должна зависеть от Lua; точный Lua API и срок этапа уточняются по плану. Python и C# сохраняются в сравнении как ранее рассмотренные альтернативы. Каноническое решение записано в архитектуре.
Для C++ приняты отдельная сборочная цель игрового проекта и небольшой API движка. Gameplay статически включается в Player; редакторские plugins собираются как DLL/SO под точный SDK/toolchain. Первая версия: остановить Player → инкрементально собрать затронутые цели → запустить сцену в отдельном процессе, сохранив редакторскую сессию. Изменение заголовка может потребовать пересборки зависимых файлов; мгновенная пересборка не обещается. Inspector, сериализация и MCP используют метаданные компонентов. Горячая замена кода с сохранением состояния — отдельный этап: изменения layout объектов, callbacks и фоновые задачи требуют управления временем жизни. Например, UE Live Coding использует отдельную систему Object Reinstancing. UE Live Coding.
Короткий ответ: что именно объединять
От Godot — композицию сцен и короткий путь от изменения до запуска. От Unity — согласованные контракты Inspector, инструментов и расширений. От Unreal — способы строить масштабируемый renderer. От Blender — параметризованные команды и интерактивные инструменты с хорошей отменой.
Объединять это нужно через общую модель данных и действий. Иначе получится renderer уровня исследовательского проекта, несколько разных способов редактировать объекты и MCP, который ненадёжно нажимает кнопки. Принят небольшой независимый AuthoringService, над которым работают UI, CLI, MCP и плагины; из сохраняемых документов он строит runtime, где ECS и renderer получают удобное для исполнения представление.
Своя отличительная черта: движок умеет объяснить результат и показать изменения до их применения. Человек и MCP видят одну сцену, версии документов, источники значений, diagnostics и историю редакторских операций. Это принятый проектный ориентир, а не заявление, что другие движки совсем не имеют таких функций или что Faset уже реализован.
Карта материалов
- 07 — UE: графика по C++ и shader source: Nanite/GPU Scene, Lumen, MegaLights, VSM, VT, TSR, RDG, Substrate, glints; исходники, ограничения и отдельные прототипы.
- 08 — Godot: UX по исходникам: scene/resource composition, overrides, Inspector/Undo, запуск сцены, live editing, импорт и editor plugins.
- 09 — Unity: UX и расширяемость: serialized edits, UI binding, tools/overlays, importers, assembly/package boundaries, Play lifecycle.
- 10 — Blender: устройство редактора: operators, modal tools, undo, RNA metadata и поиск команд.
- 11 — ECS и удобство: нужен ли ECS, storage tradeoffs, authoring/runtime mapping, scripting façade, диагностика и критерии выбора реализации.
- 12 — MCP и обмен с Blender: единый command contract, transactions, асинхронные операции и устойчивый reimport моделей.
- 13 — Компиляция, экспорт и стек: code/shader compilation, asset cooking, packaging, варианты технологий и проверка на двух ОС.
Что проверено и чего исследование не доказывает
Unreal исследован в имеющемся локальном checkout 5.8.2, commit 16d75d84714512edfb744e1fd0a59e9c74d57873. Godot скачан полностью по исходному дереву с короткой Git-историей в ../../../godot: 4.8.0 dev, 9c776068d6ed23acd0c78bfe534272d1d2a3a619. Официальный UnityCsReference скачан в ../../../UnityCsReference: 6000.7.0a6, 6b50e5544f6efcca1f44dbace3d1778b465ac6d0. Blender загружен выборочно, shallow/sparse, в ../../../blender-source: 5.3.0 alpha, 28d47268bddcb9dc69143f0e2d9410969da16311.
Godot и Blender здесь — снимки разработки, Unity — alpha reference source. Это не рекомендация строить production на этих версиях. UnityCsReference открывает C#-слой и native bindings, но не полную native-реализацию. В отчётах явно разделены тело функции, декларация API и собственное предложение.
Проверены выбранные реальные C++/C#/shader тела и официальные документы. Редакторы не собирались и пользовательское тестирование не проводилось. Нет измеренных сравнений скорости движков или утверждения об объективном мировом рейтинге. Рассматриваются три выбранных ориентира и полезные механизмы; эффективность собственного сочетания предстоит доказать прототипом.
Семь принятых архитектурных решений
1. Сцена — документ, объект — стабильная идентичность
Authoring scene содержит понятную человеку композицию объектов и компонентов. Scene/prefab — одна базовая модель повторного использования. Приняты stable object/resource IDs, explicit C++ schema с TypeId/FieldId, JSON authoring с предсказуемым diff, binary cooked данные, типизированные asset references и явно видимые overrides.
Hierarchy, ownership и resource sharing — разные отношения. Пользователь должен видеть, меняет ли он общий материал, локальный экземпляр или временное состояние игры. Из Godot полезны remap локальных ресурсов и sparse overrides; из Unity — mixed selection и property-level revert. В MVP входят обычные и вложенные экземпляры без variant inheritance. Patch адресует instance chain/ObjectId/ComponentId/FieldId, проверяя TypeId; имя и transform path не заменяют ID. Reparent разрешён внутри экземпляра, перенос через nested boundary отклоняется; suppression и добавления сохраняются отдельным слоем. Удалённые targets и несовместимые поля требуют разрешения конфликта, без потери overrides. Revert входит в MVP; variants, Apply to template и поэлементное слияние массивов — после него. Предыдущее предложение раннего варианта superseded. Полные правила. Godot: сцены и overrides, Unity: изменение свойств.
2. Ручной интерфейс и MCP — два клиента одного сервиса
AuthoringService владеет открытыми документами, схемами свойств, validation, командами, транзакциями, undo и revisions. UI делает preview во время drag и один commit при завершении. MCP передаёт явные IDs и batch изменений с ожидаемой revision; один batch создаёт один понятный шаг истории.
Через общий сервис доступны: открыть/сохранить авторскую сцену, найти её объекты, изменить компоненты документа, импортировать ресурс, вызвать Play/Stop, получить editor diagnostics, снять editor viewport capture и собрать game build. MCP ограничен редактором/authoring/import/build/PlayStop/editor logs: он не инспектирует и не меняет runtime world. В Player и экспортированных играх MCP отсутствует. Не каждую UI-возможность нужно буквально экспортировать как tool: MCP нужны операции над намерением и данными, например «создать 20 экземпляров», без сотни mouse events.
В headless режиме работают документы, импорт, validation и build. Viewport capture требует render-capability; тест интерактивного окна требует соответствующей среды. Возможности следует обнаруживать явно, а не обещать, что отсутствие UI означает отсутствие GPU-зависимостей. Подробный протокол.
3. ECS скрывает устройство хранения, сохраняя понятность игры
Для runtime выбран EnTT; это не обязательная модель хранения каждой панели, ассета и пользовательского сценария. В редакторе остаются сцены и компоненты; compiler создаёт runtime representation и карту происхождения. Простая дверь использует удобный C++ gameplay API, позднее также Lua; массовое движение — типизированный batch query. Оба работают с одним runtime-состоянием.
Editor transaction отвечает за undo и авторские данные. Runtime command buffer отвечает за отложенное создание, удаление и изменение состава entity в безопасной фазе. Hot systems пишут выданные компоненты без редакторского журнала на каждое присваивание. GPU Scene из UE — ещё одно специализированное представление данных; она не заменяет игровой ECS. Решение по ECS.
4. Отдельный Player и snapshot редактируемой сцены
Play запускает отдельный Player process со snapshot текущей сцены или project entry point и статически собранным gameplay. Это изолирует сбой игры и задаёт ясный start/stop lifecycle. Авторский документ можно редактировать независимо; новая версия применяется к следующему запуску. Первый C++ цикл — Stop → incremental build → Play с сохранением контекста редактора.
Superseded для MVP: remote tree/property inspection как обязательный этап, пересылка всех authoring edits в игру и Apply выбранного runtime state в исходную сцену. MCP управляет Play/Stop через редактор, но не получает runtime query/mutation tools. Mapping authoring→runtime полезен внутренней диагностике и не означает такого доступа. Универсальная горячая замена C++ с сохранением состояния отложена.
Godot subprocess/debugger flow и Unity lifecycle остаются исследовательскими сравнениями. Godot Play, Unity lifecycle.
5. Инструменты регистрируются как пакеты возможностей
Плагин добавляет component schema, system, importer, Inspector drawer, viewport tool, menu command и diagnostics через typed registries. Runtime и Editor code — разные модули. В Player игровой код линкуется статически; C++ editor plugins — DLL/SO с точным соответствием версии SDK, compiler/ABI profile. Универсальная двоичная совместимость между версиями SDK не обещается. У каждой регистрации есть владелец plugin scope; отключение снимает callbacks и UI. Опциональная Blender-интеграция не должна становиться обязательной зависимостью игрового Player. В v1 editor DLL/SO загружаются при старте Editor; обновление, отключение и повторное включение требуют его перезапуска. Hot-unload editor plugins не поддерживается. Данные неизвестных компонентов сохраняются в документе с diagnostic, а после включения пакета восстанавливается их редактирование. Проверка disable → restart Editor → re-enable → restart Editor должна проходить без потери данных и поздних callbacks.
Один параметризованный command обслуживает menu, hotkey, palette и MCP. Интерактивная часть получает mouse/keyboard events и делает preview; headless execute принимает готовые параметры. Это сочетает operator model Blender с расширениями Godot/Unity. Важны tool lifecycle, cancellation и причина disabled state, а не копирование всей системы окон.
6. Blender — источник, импортируемая модель — производный артефакт
Используется обычный официальный Blender без модификации исходников. Стандартный glTF/GLB импорт работает самостоятельно, без add-on. Необязательное Python-дополнение добавляет IDs частей, manifest и удобную кнопку экспорта согласованного профиля. Engine importer создаёт mesh/material/animation artifacts; .blend остаётся исходником геометрии/rig/animation, а игра использует cooked данные без установленного Blender. Требование обязательного add-on superseded.
Повторный импорт должен сохранять ссылки на объект и настройки уровня, а конфликтующие изменения объяснять. Имя mesh или индекс узла не должны быть единственной идентичностью. Без устойчивых source IDs нельзя гарантировать matching внутренних частей после rename/reorder; неоднозначность требует явного remap. Gameplay, physics settings и overrides принадлежат Faset и не перезаписываются экспортом Blender. Поддержку материала и анимации следует зафиксировать как профиль: произвольный Blender node graph, modifiers и симуляции не превращаются автоматически в эквивалент нашего renderer.
После MVP — live link с выбором, переходом к исходнику, запросом экспорта и статусом reimport. Геометрию лучше передавать asset-артефактом, а команды и manifest — по управляющему соединению. Roundtrip и проверки.
7. Экспорт игры проектируется вместе с редактором
Build — общий сервис, доступный кнопкой, CLI и MCP: проверить проект → определить зависимости → скомпилировать код/шейдеры → подготовить assets → собрать manifest → упаковать Player → проверить артефакт. Каждая стадия имеет входы, версии инструментов, кэшируемые результаты, structured log, progress и cancellation.
Игровой build не зависит от editor modules, source checkout или Blender и не содержит MCP. MCP доступен только в редакторе, который может заказать сборку или запустить отдельный Player. Linux/Windows получают свои целевые runtime и native libraries. «Разработка на Linux» не равна «проверенная Windows-сборка»: реальная проверка должна происходить на обеих ОС.
Исходные финалисты исследования — C++ + SDL3 + Vulkan + Lua и C#/.NET + native renderer/physics — сохраняются в сравнении стеков как история рассмотренных вариантов. 18.09.2026 принят порядок: сначала C++ для ядра и gameplay, затем добавление Lua отдельным модулем; его использование конкретной игрой необязательно. Box2D и Box3D также выбраны. Дополнительно приняты SDL3, Vulkan 1.3, собственный renderer/RenderGraph и Slang, собственный retained C++ editor UI с декларативными layout/styles и тёмной темой по умолчанию (ImGui — debug tools), CMake + Ninja, Clang на Linux и clang-cl на Windows. Прежний статус открытого выбора этих частей superseded. Проверка сквозным прототипом должна подтвердить реализацию выбранного стека, а не заново выбрать язык.
Какой advanced renderer имеет смысл строить
Первое MVP ограничено базовым 2D-путём, PBR и обычными тенями для 3D; сложные технологии ниже — после MVP. Для выбранного Vulkan 1.3 renderer нужно зафиксировать конкретный capability profile: базовый renderer должен запускать простую 2D/3D игру без RT/mesh shaders; advanced paths включаются после проверки возможностей и имеют явный fallback или diagnostic. Поддержка Linux/Windows сама по себе не гарантирует одинаковых GPU features.
Основа MVP: собственный RenderGraph, GPU timestamps/captures и управление ресурсами. Расширение после MVP: stable GPU instance IDs, indirect rendering, depth pyramid, motion vectors, two-pass HZB по идеям Nanite и контроль доверия к истории по идеям TSR. Это создаёт базу для дальнейших экспериментов без обязательного полного виртуализированного renderer.
Далее выбрать ветку по демонстрационной игре:
- Много геометрии: cluster LOD и согласованные переходы, затем residency/streaming, visibility buffer/material bins, позже hybrid software/hardware raster.
- Свет и атмосфера сцены: screen/world hybrid tracing, radiance probes/cache, budgeted updates и специализированный denoiser; затем выборочная оценка lights по идеям MegaLights.
- Большие тени: cached atlas, page table/requests, VSM для одного directional light, invalidation и только затем расширение.
Для относительно локального визуального эксперимента glints интереснее попытки немедленно повторить Substrate целиком. Материальные тайлы simple/complex также можно применить независимо от произвольного графа физических слоёв. VT имеет смысл при доказанном давлении на texture memory или дорогом повторном shading ландшафта.
Важная связь с удобством: каждый cache должен иметь debug view актуальности и причины обновления; каждый проход — измерение. Локальные графические инструменты должны помогать выяснить причину артефакта или задержки. MCP получает editor diagnostics и результаты authoring/import/build, но не читает runtime world или данные Player через диагностический обходной путь. Все алгоритмы, источники и проверочные сцены подробно разобраны в UE-исследовании.
Что может стать нашим собственным преимуществом
- Inspector происхождения. Рядом со значением видно: asset/template default, instance override, scene edit. Можно перейти к источнику и вернуть нижележащее значение. Animation/runtime writers относятся к отдельным будущим debug tools, без runtime MCP.
- Предварительный просмотр пакетной правки. MCP или инструмент предлагает изменить сцену; editor показывает затронутые объекты и diff. Применение проверяет revision. Повтор в пределах срока хранения журнала с тем же idempotency key и payload возвращает сохранённый результат authoring-транзакции.
- Объяснение результата. «Почему объект не виден?» проходит через disabled/layer/camera/culling/material/pass diagnostics. «Почему модель не обновилась?» показывает source hash, export/import status и зависимости.
- Одинаковые сценарии из UI и headless. Игра, созданная через MCP, редактируется вручную без особого формата. Ручная сессия воспроизводится как высокоуровневые команды, где это допускает контракт, без записи движений мыши.
- Понятный reimport diff. Новые, исчезнувшие и изменённые mesh/material/animation outputs видны до публикации, а overrides имеют известного владельца.
Эти идеи не заменяют базовую usability. Сначала должны хорошо работать выбор объекта, поиск, ввод чисел, Undo, сохранение, запуск и сообщения об ошибках.
Вертикальные прототипы и критерии выбора
A. Редактор и MCP делают одну и ту же сцену
Создать дверь, collider, light, script и два экземпляра; изменить свойство, multi-edit и override, отменить drag, сохранить/открыть. Повторить через MCP с явными IDs. Сравнить канонические документы. Структура и семантика одинаковы; UI показывает результат MCP сразу; конфликтующая revision не приводит к частично применённому batch.
B. Полный круг Blender
Создать модель, импортировать, расставить несколько instances, изменить mesh и переэкспортировать. Ссылки и local overrides сохраняются. После удаления mesh output появляется конкретный конфликт. Сломанный экспорт не заменяет последнюю рабочую модель наполовину записанными файлами.
C. Игра и ECS
Простая 2D-аркада и маленькая 3D-сцена используют одинаковые save/import/Play/MCP workflows. Отдельная массовая сцена проверяет ECS, structural changes и render extraction. Удобство простой игры оценивается отдельно от throughput массового теста.
D. Самостоятельный build
Одинаковый проект собирается из UI, CLI и MCP. Артефакты проверяются в Linux и Windows без редактора и Blender. Изменение одного texture source не пересобирает весь код, изменение gameplay-кода не переимпортирует всю графику. Build failure возвращает привязанный к стадии diagnostic.
E. После MVP: одна передовая графическая технология
Демонстрационная сцена с измеряемой целью: GPU culling на множестве объектов либо гибридное освещение. Есть baseline, фиксированный camera path, p50/p95 frame time, VRAM и сравнение качества в движении. Не засчитывать количество реализованных именованных технологий как успех.
Порядок реализации после утверждения
- Формализовать принятые identity/schema, documents/transactions, EnTT façade, Player snapshot, asset/reimport, SDK и build contracts в тестируемых интерфейсах.
- Провести выбранный стек через вертикаль «окно → viewport → свойство → Undo → editor MCP → JSON → Player» на Linux и Windows.
- Довести маленькие 2D- и 3D-демо до самостоятельного экспорта: базовые rendering/physics, glTF/GLB import, шаблоны/overrides, editor UX, build/cook. Baseline PBR/тени достаточны для первого MVP.
- После MVP реализовать обязательный Lua-модуль, затем наращивать графику и инструменты по измерениям; расширять Blender roundtrip, scene variants и plugins согласно PLAN.md.
Первоначальные материалы 01–06 сохраняют сравнительный контекст. Исторические привязки к другому проекту, Flecs, C# или ранее существовавшим demo не считаются ограничениями Faset; при разночтениях действуют ARCHITECTURE.md и PLAN.md. Принятие решения не является отметкой о завершённой реализации, а исследовательская проверка исходников не заменяет будущих сборок и приёмочных тестов.