Files
Faset_Engine/docs/studies/14-engine-blueprint.md
T

151 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Новый движок: выводы исследования UE, Godot и Unity
**Название проекта — Faset Engine. Синхронизация решений: 18.09.2026.** Каноническая архитектура — [ARCHITECTURE.md](../ARCHITECTURE.md), последовательность до и после MVP — [PLAN.md](../../PLAN.md). Этот отчёт сохраняет исследовательские аргументы и обновлённые принятые решения. Прежние альтернативы отмечены **superseded**; факты о чужих движках не означают, что соответствующие возможности реализованы в Faset.
Дата: 17 сентября 2026. Цель — новый движок для **Linux и Windows, десктопных 2D/3D-игр**, одинаково удобный при ручной работе и через **MCP**, с интеграцией как минимум с **Blender**. Это исследовательская основа реализации. На момент первоначального исследования код нового движка ещё не создавался; текущая реализация описана в [журнале](../IMPLEMENTATION.md), ниже принятые архитектурные правила отделены от экспериментальных графических направлений и деталей будущих прототипов.
## Уточнения после обсуждения исследования
**Подтверждённый выбор пользователя: Box2D для 2D-физики, Box3D для 3D-физики.** Под Box3D имеется в виду [erincatto/box3d](https://github.com/erincatto/box3d), анонсированный Erin Catto 30 июня 2026. Это отдельная 3D-библиотека с C API и реализацией на C17; репозиторий указывает поддержку Windows и Linux. [Анонс](https://box2d.org/posts/2026/06/announcing-box3d/), [Box2D overview](https://box2d.org/documentation/). На момент исследования версии ещё не выбирались и собственные физические тесты не выполнялись. Теперь версии закреплены в [dependency lock](../../dependencies.lock.json), а результаты интеграции записаны в [журнале реализации](../IMPLEMENTATION.md).
Принятый принцип интеграции: отдельные PhysicsWorld2D/PhysicsWorld3D, компоненты RigidBody2D/3D и Collider2D/3D, единые правила регистрации, идентичности, Inspector и диагностики. Миры 2D и 3D не сталкиваются автоматически друг с другом. Физика получает команды перед фиксированным шагом; после завершения шага движок переносит результаты и события в runtime. Для динамического тела физика владеет рассчитанным transform; runtime teleport и управление кинематическим телом — отдельные операции. События связываются с entity через проверяемые handles. Названия API в этом исследовательском описании предварительны; фактический API адаптеров и gameplay описан в [Manual](../manual/scripting/api.md).
**Решение от 18.09.2026: сначала ядро и игровая логика на C++, затем добавляем Lua отдельным модулем. Его будущая реализация принята, использование конкретной игрой необязательно.** Игра на C++ не должна зависеть от Lua; точный Lua API и срок этапа уточняются по [плану](../../PLAN.md). Python и C# сохраняются в сравнении как ранее рассмотренные альтернативы. Каноническое решение записано в [архитектуре](../ARCHITECTURE.md).
Для C++ приняты отдельная сборочная цель игрового проекта и небольшой API движка. Gameplay статически включается в Player; редакторские plugins собираются как DLL/SO под точный SDK/toolchain. Первая версия: остановить Player → инкрементально собрать затронутые цели → запустить сцену в отдельном процессе, сохранив редакторскую сессию. Изменение заголовка может потребовать пересборки зависимых файлов; мгновенная пересборка не обещается. Inspector, сериализация и MCP используют метаданные компонентов. Горячая замена кода с сохранением состояния — отдельный этап: изменения layout объектов, callbacks и фоновые задачи требуют управления временем жизни. Например, UE Live Coding использует отдельную систему Object Reinstancing. [UE Live Coding](https://dev.epicgames.com/documentation/unreal-engine/using-live-coding-to-recompile-unreal-engine-applications-at-runtime).
## Короткий ответ: что именно объединять
**От Godot — композицию сцен и короткий путь от изменения до запуска. От Unity — согласованные контракты Inspector, инструментов и расширений. От Unreal — способы строить масштабируемый renderer. От Blender — параметризованные команды и интерактивные инструменты с хорошей отменой.**
Объединять это нужно через общую модель данных и действий. Иначе получится renderer уровня исследовательского проекта, несколько разных способов редактировать объекты и MCP, который ненадёжно нажимает кнопки. Принят небольшой независимый **AuthoringService**, над которым работают UI, CLI, MCP и плагины; из сохраняемых документов он строит runtime, где ECS и renderer получают удобное для исполнения представление.
Своя отличительная черта: **движок умеет объяснить результат и показать изменения до их применения**. Человек и MCP видят одну сцену, версии документов, источники значений, diagnostics и историю редакторских операций. Это принятый проектный ориентир, а не заявление, что другие движки совсем не имеют таких функций или что Faset уже реализован.
## Карта материалов
- [07 — UE: графика по C++ и shader source](./07-unreal-graphics-source-study.md): Nanite/GPU Scene, Lumen, MegaLights, VSM, VT, TSR, RDG, Substrate, glints; исходники, ограничения и отдельные прототипы.
- [08 — Godot: UX по исходникам](./08-godot-ux-source-study.md): scene/resource composition, overrides, Inspector/Undo, запуск сцены, live editing, импорт и editor plugins.
- [09 — Unity: UX и расширяемость](./09-unity-ux-extensibility-study.md): serialized edits, UI binding, tools/overlays, importers, assembly/package boundaries, Play lifecycle.
- [10 — Blender: устройство редактора](./10-blender-editor-patterns.md): operators, modal tools, undo, RNA metadata и поиск команд.
- [11 — ECS и удобство](./11-ecs-and-ergonomics.md): нужен ли ECS, storage tradeoffs, authoring/runtime mapping, scripting façade, диагностика и критерии выбора реализации.
- [12 — MCP и обмен с Blender](./12-mcp-and-blender-integration.md): единый command contract, transactions, асинхронные операции и устойчивый reimport моделей.
- [13 — Компиляция, экспорт и стек](./13-build-pipeline-and-stack.md): 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**. [Полные правила](01-architecture.md). [Godot: сцены и overrides](./08-godot-ux-source-study.md), [Unity: изменение свойств](./09-unity-ux-extensibility-study.md).
### 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-зависимостей. [Подробный протокол](./12-mcp-and-blender-integration.md).
### 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](./11-ecs-and-ergonomics.md).
### 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](./08-godot-ux-source-study.md), [Unity lifecycle](./09-unity-ux-extensibility-study.md).
### 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 и проверки](./12-mcp-and-blender-integration.md).
### 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** — сохраняются в [сравнении стеков](./13-build-pipeline-and-stack.md) как история рассмотренных вариантов. **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-исследовании](./07-unreal-graphics-source-study.md).
## Что может стать нашим собственным преимуществом
1. **Inspector происхождения.** Рядом со значением видно: asset/template default, instance override, scene edit. Можно перейти к источнику и вернуть нижележащее значение. Animation/runtime writers относятся к отдельным будущим debug tools, без runtime MCP.
2. **Предварительный просмотр пакетной правки.** MCP или инструмент предлагает изменить сцену; editor показывает затронутые объекты и diff. Применение проверяет revision. Повтор в пределах срока хранения журнала с тем же idempotency key и payload возвращает сохранённый результат authoring-транзакции.
3. **Объяснение результата.** «Почему объект не виден?» проходит через disabled/layer/camera/culling/material/pass diagnostics. «Почему модель не обновилась?» показывает source hash, export/import status и зависимости.
4. **Одинаковые сценарии из UI и headless.** Игра, созданная через MCP, редактируется вручную без особого формата. Ручная сессия воспроизводится как высокоуровневые команды, где это допускает контракт, без записи движений мыши.
5. **Понятный 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 и сравнение качества в движении. Не засчитывать количество реализованных именованных технологий как успех.
## Порядок реализации после утверждения
1. Формализовать принятые identity/schema, documents/transactions, EnTT façade, Player snapshot, asset/reimport, SDK и build contracts в тестируемых интерфейсах.
2. Провести выбранный стек через вертикаль «окно → viewport → свойство → Undo → editor MCP → JSON → Player» на Linux и Windows.
3. Довести маленькие 2D- и 3D-демо до самостоятельного экспорта: базовые rendering/physics, glTF/GLB import, шаблоны/overrides, editor UX, build/cook. Baseline PBR/тени достаточны для первого MVP.
4. После MVP реализовать обязательный Lua-модуль, затем наращивать графику и инструменты по измерениям; расширять Blender roundtrip, scene variants и plugins согласно [PLAN.md](../../PLAN.md).
Первоначальные материалы 01–06 сохраняют сравнительный контекст. Исторические привязки к другому проекту, Flecs, C# или ранее существовавшим demo не считаются ограничениями Faset; при разночтениях действуют [ARCHITECTURE.md](../ARCHITECTURE.md) и [PLAN.md](../../PLAN.md). Принятие решения не является отметкой о завершённой реализации, а исследовательская проверка исходников не заменяет будущих сборок и приёмочных тестов.