Files
XCEngine/docs/blueprint.md

41 KiB
Raw Permalink Blame History

XCEngine 蓝图

本文按当前工作树整理,快照时间为 2026-04-04。如果源码、测试、CMakeLists.txt 或项目布局继续演进,这份蓝图也必须同步更新。


SYSTEM_META

name: XCEngine
version: 0.1.0
type: editor-first-game-engine-workspace
description: "Windows 优先、编辑器优先的模块化 C++17 游戏引擎工作区,当前已经形成 RHI、Rendering、AssetDatabase/Library、Mono Scripting 与 Editor Viewport 的可运行闭环。"
target_runtime: "C++17 + .NET Framework 4.7.2 + Mono"
snapshot_date: 2026-04-04
primary_platform: Windows 10/11
workspace_roots: [engine, editor, managed, project, tests]

SYSTEM_STRUCTURE

root: XCEngineWorkspace

subsystems:
  - name: Core
    responsibilities:
      - "提供基础类型、事件、Layer/LayerStack、容器、数学和资源路径等通用基础设施。"
      - "为上层 Memory、Threading、Resources、Rendering、Scene 和 Editor 提供共享工具。"
    provides: [Types, Event, LayerStack, Containers, Math, ResourcePath]
    depends_on: []
    boundary:
      inputs: []
      outputs: [基础类型, 通用容器, 几何与路径工具]

  - name: Memory
    responsibilities:
      - "提供 Allocator、LinearAllocator、PoolAllocator、ProxyAllocator 和全局 MemoryManager。"
      - "为资源缓存、RHI 资源和长期对象生命周期管理提供分配策略。"
    provides: [Allocator, LinearAllocator, PoolAllocator, ProxyAllocator, MemoryManager]
    depends_on: [Core]
    boundary:
      inputs: [分配请求]
      outputs: [内存块, 内存统计]

  - name: Threading
    responsibilities:
      - "提供 Thread、Mutex、SpinLock、ReadWriteLock、TaskSystem、TaskGroup。"
      - "支撑资源异步加载、后台导入和部分并行测试场景。"
    provides: [Thread, Mutex, ReadWriteLock, TaskSystem, TaskGroup]
    depends_on: [Core]
    boundary:
      inputs: [任务函数, 同步请求]
      outputs: [调度结果, 同步原语]

  - name: Debug
    responsibilities:
      - "提供 Logger、ILogSink、Profiler、RenderDocCapture 等诊断能力。"
      - "为 engine、editor 和 tests 提供统一日志与性能分析入口。"
    provides: [Logger, ILogSink, Profiler, RenderDocCapture]
    depends_on: [Core, Threading]
    boundary:
      inputs: [日志消息, profile 样本]
      outputs: [控制台输出, 文件输出, profile 数据]

  - name: Input
    responsibilities:
      - "维护 InputManager、InputModule、InputEvent、InputAxis 和键鼠状态抽象。"
      - "为 runtime 与 editor viewport 导航提供统一输入层。"
    provides: [InputManager, InputModule, InputEvent, InputAxis]
    depends_on: [Core]
    boundary:
      inputs: [平台输入事件]
      outputs: [输入状态, 输入事件流]

  - name: Project
    responsibilities:
      - "承载 `Project.xcproject`、`Assets/`、`.meta`、`Library/` 的工程数据布局。"
      - "作为 editor、resources、managed、scripting 共享的项目根目录边界。"
    provides: [ProjectDescriptor, AssetSourceTree, AssetMetaFiles, ProjectLibrary, StartupScene]
    depends_on: []
    boundary:
      inputs: [用户资源, 用户脚本, 编辑器操作, 构建产物]
      outputs: [Project.xcproject, Assets, Library]

  - name: Resources
    responsibilities:
      - "维护 AssetDatabase、AssetImportService、ProjectAssetIndex、ResourceManager 和 ResourceCache。"
      - "把 `Assets/ + .meta` 导入为 `Library/SourceAssetDB`、`Library/ArtifactDB`、`Library/Artifacts`。"
      - "统一运行时资源查找、Artifact 解析、ResourceHandle 与异步加载。"
    provides: [AssetDatabase, AssetImportService, ProjectAssetIndex, ResourceManager, ResourceHandle, AsyncLoader]
    depends_on: [Core, Memory, Threading, Debug, Project]
    boundary:
      inputs: [projectRoot, assetPath, AssetRef, importer settings]
      outputs: [IResource, ArtifactRecord, AssetRef, import status]

  - name: RHI
    responsibilities:
      - "提供 RHIDevice、RHICommandList、RHISwapChain、RHITexture、RHIBuffer 等抽象接口。"
      - "维护 D3D12、OpenGL、Vulkan 三后端及 RHIFactory 选择逻辑。"
      - "为 Rendering 和 editor host 提供统一 GPU 资源与提交契约。"
    provides: [RHIFactory, RHIDevice, RHICommandList, RHISwapChain, RHITexture, RHIBuffer]
    depends_on: [Core, Debug]
    boundary:
      inputs: [RHIType, 渲染命令, 资源描述]
      outputs: [后端设备, GPU 资源, 提交结果]

  - name: Rendering
    responsibilities:
      - "维护 `SceneRenderer -> CameraRenderer -> RenderPipeline` 正式主链。"
      - "提供 RenderSurface、RenderContext、RenderSceneExtractor、RenderResourceCache 和 builtin passes。"
      - "支撑 Scene/Game viewport 离屏渲染、ObjectId picking、Outline、InfiniteGrid 和 overlay passes。"
    provides: [SceneRenderer, CameraRenderer, RenderPipeline, RenderSurface, RenderContext, BuiltinPasses]
    depends_on: [Core, Debug, Resources, RHI, Components, Scene]
    boundary:
      inputs: [Scene, CameraRenderRequest, RenderSurface]
      outputs: [离屏颜色/深度目标, ObjectId, overlay draw results]

  - name: Components
    responsibilities:
      - "提供 GameObject、Component、ComponentFactoryRegistry 和内建组件集合。"
      - "维护 Transform、Camera、Light、Mesh、Audio 等组件级数据。"
    provides: [GameObject, Component, TransformComponent, CameraComponent, LightComponent, MeshFilterComponent, MeshRendererComponent, AudioComponents]
    depends_on: [Core, Resources, Audio]
    boundary:
      inputs: [场景编辑操作, 资源引用]
      outputs: [组件树, 运行时组件状态]

  - name: Scene
    responsibilities:
      - "维护 Scene、SceneManager、SceneRuntime、RuntimeLoop 和场景序列化。"
      - "负责 `.xc` 场景文档的读写、运行时更新与层级查询。"
    provides: [Scene, SceneManager, SceneRuntime, RuntimeLoop]
    depends_on: [Core, Components]
    boundary:
      inputs: [场景文件, 编辑器命令, deltaTime]
      outputs: [场景树, 保存后的场景文档, 生命周期事件]

  - name: Scripting
    responsibilities:
      - "维护 ScriptComponent、ScriptEngine、ScriptFieldStorage、IScriptRuntime 与 MonoScriptRuntime。"
      - "加载 `Library/ScriptAssemblies/` 中的 `XCEngine.ScriptCore.dll`、`GameScripts.dll` 和 `mscorlib.dll`。"
      - "提供脚本类发现、字段元数据、默认值、override 和运行时字段同步。"
    provides: [ScriptComponent, ScriptEngine, ScriptFieldStorage, IScriptRuntime, MonoScriptRuntime]
    depends_on: [Core, Components, Scene, Project]
    boundary:
      inputs: [程序集路径, Scene, ScriptComponent field writes]
      outputs: [脚本实例, 字段快照, 生命周期回调]

  - name: Audio
    responsibilities:
      - "提供 AudioSystem、AudioMixer、IAudioBackend 和 WindowsAudioBackend。"
      - "为 AudioSource / AudioListener 组件提供基础音频运行时支持。"
    provides: [AudioSystem, AudioMixer, IAudioBackend, WindowsAudioBackend]
    depends_on: [Core]
    boundary:
      inputs: [音频配置, 场景音频源]
      outputs: [混音结果, 平台音频提交]

  - name: Editor
    responsibilities:
      - "维护 `XCEditor` 桌面宿主、项目根解析、SceneManager、ProjectManager、Undo/Selection 和各类面板。"
      - "通过 `ViewportHostService` 把引擎 Rendering + RHI 离屏结果接入 ImGui。"
      - "当前 Scene View 主链按 `SceneViewportChrome -> SceneViewportInteractionFrame -> SceneViewportNavigation -> SceneViewportTransformGizmoCoordinator -> ViewportHostService` 编排。"
    provides: [XCEditor, EditorContext, SceneManager, ProjectManager, ViewportHostService, SceneViewportHelpers]
    depends_on: [Core, Debug, Input, Project, Resources, Rendering, Scene, Scripting, RHI]
    boundary:
      inputs: [用户交互, 项目路径, viewport host window]
      outputs: [编辑器 UI, 场景编辑命令, project workflow, script build trigger]

  - name: Managed
    responsibilities:
      - "编译 `managed/XCEngine.ScriptCore/` 与 `managed/GameScripts/`。"
      - "扫描 `project/Assets/**/*.cs`,生成项目脚本程序集。"
      - "把产物复制到 `project/Library/ScriptAssemblies/` 和 tests 专用输出目录。"
    provides: [ScriptCoreAssembly, GameScriptsAssembly, ProjectGameScriptsAssembly, MonoCorlibCopy]
    depends_on: [Project, Scripting]
    boundary:
      inputs: [managed C# source files, project C# source files, Mono corlib]
      outputs: [XCEngine.ScriptCore.dll, GameScripts.dll, mscorlib.dll]

  - name: Tests
    responsibilities:
      - "维护 `tests/` 下对 Core、Resources、RHI、Rendering、Editor、Scripting 等主线模块的回归覆盖。"
      - "维持 `rhi_all_tests`、`rendering_all_tests`、`editor_tests`、`scripting_tests` 等聚合 target。"
      - "验证资源导入、viewport helper 链、脚本程序集输出和 backend 分层边界。"
    provides: [CTestTargets, RegressionSpecs, IntegrationScenes]
    depends_on: [Core, Memory, Threading, Debug, Input, Project, Resources, RHI, Rendering, Components, Scene, Scripting, Editor, Managed]
    boundary:
      inputs: [build targets, test assets, project fixtures]
      outputs: [测试结果, 回归信号]

modules:
  - name: Event
    parent_subsystem: Core
    responsibility: "提供线程安全的订阅、退订和事件广播能力。"
    public_api:
      - fn: Subscribe
        params:
          - name: callback
            type: std::function<void(Args...)>
        returns:
          type: uint32
      - fn: Unsubscribe
        params:
          - name: id
            type: uint32
        returns:
          type: void
      - fn: Invoke
        params:
          - name: args
            type: Args...
        returns:
          type: void

  - name: AssetDatabase
    parent_subsystem: Resources
    responsibility: "维护源资产记录、artifact 记录、.meta 生成和按需重导入。"
    public_api:
      - fn: Initialize
        params:
          - name: projectRoot
            type: const Containers::String&
        returns:
          type: void
      - fn: Refresh
        params: []
        returns:
          type: MaintenanceStats
      - fn: EnsureArtifact
        params:
          - name: requestPath
            type: const Containers::String&
          - name: requestedType
            type: ResourceType
          - name: outAsset
            type: ResolvedAsset&
        returns:
          type: bool
      - fn: TryGetAssetRef
        params:
          - name: requestPath
            type: const Containers::String&
          - name: resourceType
            type: ResourceType
          - name: outRef
            type: AssetRef&
        returns:
          type: bool

  - name: ResourceManager
    parent_subsystem: Resources
    responsibility: "负责统一资源加载、缓存、AssetRef 解析、项目资源刷新和 Library 重建入口。"
    public_api:
      - fn: Initialize
        params: []
        returns:
          type: void
      - fn: Load
        params:
          - name: path
            type: const Containers::String&
          - name: settings
            type: ImportSettings*
        returns:
          type: ResourceHandle<T>
      - fn: RefreshProjectAssets
        params: []
        returns:
          type: void
      - fn: RebuildProjectAssetCache
        params: []
        returns:
          type: bool
      - fn: GetProjectAssetImportStatus
        params: []
        returns:
          type: AssetImportService::ImportStatusSnapshot

  - name: RHIFactory
    parent_subsystem: RHI
    responsibility: "根据后端类型创建 RHIDevice实现抽象层到具体后端的选择。"
    public_api:
      - fn: CreateRHIDevice
        params:
          - name: type
            type: RHIType
        returns:
          type: RHIDevice*
      - fn: CreateRHIDevice
        params:
          - name: typeName
            type: const std::string&
        returns:
          type: RHIDevice*

  - name: SceneRenderer
    parent_subsystem: Rendering
    responsibility: "构建 CameraRenderRequest 并驱动 CameraRenderer / RenderPipeline 完成场景渲染。"
    public_api:
      - fn: BuildRenderRequests
        params:
          - name: scene
            type: const Components::Scene&
          - name: overrideCamera
            type: Components::CameraComponent*
          - name: context
            type: const RenderContext&
          - name: surface
            type: const RenderSurface&
        returns:
          type: std::vector<CameraRenderRequest>
      - fn: Render
        params:
          - name: requests
            type: const std::vector<CameraRenderRequest>&
        returns:
          type: bool

  - name: Scene
    parent_subsystem: Scene
    responsibility: "负责 GameObject 层级管理、场景更新和 `.xc` 文档读写。"
    public_api:
      - fn: CreateGameObject
        params:
          - name: name
            type: const std::string&
          - name: parent
            type: GameObject*
        returns:
          type: GameObject*
      - fn: Update
        params:
          - name: deltaTime
            type: float
        returns:
          type: void
      - fn: Save
        params:
          - name: filePath
            type: const std::string&
        returns:
          type: void
      - fn: Load
        params:
          - name: filePath
            type: const std::string&
        returns:
          type: void

  - name: ScriptEngine
    parent_subsystem: Scripting
    responsibility: "管理 ScriptComponent 生命周期、程序集类发现、字段读写和运行时同步。"
    public_api:
      - fn: SetRuntime
        params:
          - name: runtime
            type: IScriptRuntime*
        returns:
          type: void
      - fn: OnRuntimeStart
        params:
          - name: scene
            type: Components::Scene*
        returns:
          type: void
      - fn: TryGetAvailableScriptClasses
        params:
          - name: outClasses
            type: std::vector<ScriptClassDescriptor>&
          - name: assemblyName
            type: const std::string&
        returns:
          type: bool
      - fn: ApplyScriptFieldWrites
        params:
          - name: component
            type: ScriptComponent*
          - name: requests
            type: const std::vector<ScriptFieldWriteRequest>&
          - name: outResults
            type: std::vector<ScriptFieldWriteResult>&
        returns:
          type: bool
      - fn: TryGetScriptFieldModel
        params:
          - name: component
            type: const ScriptComponent*
          - name: outModel
            type: ScriptFieldModel&
        returns:
          type: bool

  - name: ScriptFieldStorage
    parent_subsystem: Scripting
    responsibility: "保存脚本字段 override并提供字符串序列化 / 反序列化。"
    public_api:
      - fn: SetFieldValue
        params:
          - name: fieldName
            type: const std::string&
          - name: type
            type: ScriptFieldType
          - name: value
            type: const ScriptFieldValue&
        returns:
          type: bool
      - fn: Remove
        params:
          - name: fieldName
            type: const std::string&
        returns:
          type: bool
      - fn: SerializeToString
        params: []
        returns:
          type: std::string
      - fn: DeserializeFromString
        params:
          - name: data
            type: const std::string&
        returns:
          type: void

  - name: ISceneManager
    parent_subsystem: Editor
    responsibility: "为 editor 提供场景创建、加载、保存、脏标记、复制粘贴与 snapshot 恢复接口。"
    public_api:
      - fn: LoadScene
        params:
          - name: filePath
            type: const std::string&
        returns:
          type: bool
      - fn: SaveSceneAs
        params:
          - name: filePath
            type: const std::string&
        returns:
          type: bool
      - fn: GetScene
        params: []
        returns:
          type: Components::Scene*
      - fn: CaptureSceneSnapshot
        params: []
        returns:
          type: SceneSnapshot

  - name: SceneViewportChrome
    parent_subsystem: Editor
    responsibility: "负责 Scene View 顶栏工具条、工具切换 overlay 和对应命令构建。"
    public_api:
      - fn: RenderSceneViewportTopBar
        params:
          - name: pivotMode
            type: SceneViewportPivotMode&
          - name: transformSpaceMode
            type: SceneViewportTransformSpaceMode&
        returns:
          type: void
      - fn: RenderSceneViewportToolOverlay
        params:
          - name: content
            type: const ViewportPanelContentResult&
          - name: activeTool
            type: SceneViewportToolMode
        returns:
          type: SceneViewportToolOverlayResult
      - fn: BuildSceneViewportToolCommand
        params:
          - name: overlayResult
            type: const SceneViewportToolOverlayResult&
          - name: shortcutAction
            type: const SceneViewportToolShortcutAction&
        returns:
          type: SceneViewportToolCommand

  - name: SceneViewportInteractionFrame
    parent_subsystem: Editor
    responsibility: "整合 viewport frame geometry、overlay 数据、gizmo frame 和 presentation 刷新。"
    public_api:
      - fn: BuildSceneViewportToolState
        params:
          - name: toolMode
            type: SceneViewportToolMode
          - name: pivotMode
            type: SceneViewportPivotMode
          - name: transformSpaceMode
            type: SceneViewportTransformSpaceMode
        returns:
          type: SceneViewportToolState
      - fn: BuildSceneViewportFrameGeometry
        params:
          - name: viewportSize
            type: const ImVec2&
          - name: viewportMin
            type: const ImVec2&
          - name: absoluteMousePosition
            type: const ImVec2&
        returns:
          type: SceneViewportFrameGeometry
      - fn: BuildSceneViewportInteractionFrameState
        params:
          - name: context
            type: IEditorContext&
          - name: viewportHostService
            type: IViewportHostService&
          - name: hasInteractiveViewport
            type: bool
          - name: geometry
            type: const SceneViewportFrameGeometry&
          - name: gizmoFrameOptions
            type: const SceneViewportTransformGizmoFrameOptions&
          - name: moveGizmo
            type: SceneViewportMoveGizmo&
          - name: rotateGizmo
            type: SceneViewportRotateGizmo&
          - name: scaleGizmo
            type: SceneViewportScaleGizmo&
          - name: emptyOverlayFrameData
            type: const SceneViewportOverlayFrameData&
        returns:
          type: SceneViewportInteractionFrameState

  - name: EditorScriptAssemblyBuilder
    parent_subsystem: Editor
    responsibility: "从 editor 侧触发项目脚本程序集重建。"
    public_api:
      - fn: RebuildProjectAssemblies
        params:
          - name: projectPath
            type: const std::string&
        returns:
          type: EditorScriptAssemblyBuildResult

  - name: ProjectFileUtils
    parent_subsystem: Editor
    responsibility: "读写 `Project.xcproject`,并在 project root 与相对路径之间做转换。"
    public_api:
      - fn: SaveProjectDescriptor
        params:
          - name: projectRoot
            type: const std::string&
          - name: descriptor
            type: const ProjectDescriptor&
        returns:
          type: bool
      - fn: LoadProjectDescriptor
        params:
          - name: projectRoot
            type: const std::string&
        returns:
          type: std::optional<ProjectDescriptor>
      - fn: ResolveProjectPath
        params:
          - name: projectRoot
            type: const std::string&
          - name: pathValue
            type: const std::string&
        returns:
          type: std::string

EVOLUTION_MODE

mode: evolve
description: "当前工作重点是在已经成型的 editor-first 主链上继续收口,而不是重新设计另一套全新架构。"
context: |
  XCEngine 已经不再是“若干独立 sample + 早期渲染实验”的状态。
  当前真实主线已经包含:
  - D3D12 / OpenGL / Vulkan 三后端 RHI
  - SceneRenderer -> CameraRenderer -> RenderPipeline 渲染链
  - Assets/ + .meta + Library/ 的项目与资源导入链
  - Mono C# scripting runtime 与 ScriptComponent 字段编辑链
  - 通过 Rendering + RHI 接入 ImGui 的 editor Scene/Game viewport

  当前演进不是从零构建 build也不是只做零碎 bugfix maintain而是
  - 把旧时期残留入口继续收口到当前正式链路
  - 把 project、managed、editor、tests 的边界写实化
  - 在不破坏现有 workflow 的前提下推进 backend parity、viewport helper 正式化、脚本字段持久化和 Library 生命周期工具化

  仍需明确的现实约束:
  - editor 目前仍是 D3D12 宿主应用
  - Vulkan SDK 当前是配置阶段硬依赖
  - Mono scripting 需要额外外部依赖,但相关代码与构建链已经落地
  - 部分 builtin render pass 仍存在 D3D12-first 假设,需要逐步跨后端收口

REQUIREMENTS

- id: REQ-001
  title: "Editor 必须能加载工程并打开启动场景"
  description: "桌面编辑器必须能够识别 project root、读取 `Project.xcproject`,并加载 `startup_scene` 指向的 `.xc` 场景。"
  source: user
  type: functional
  acceptance_criteria:
    - "`editor/bin/<Config>/XCEngine.exe` 默认可把仓库内 `project/` 识别为工程根。"
    - "支持通过 `--project <path>` 覆盖工程根。"
    - "`startup_scene=Assets/Scenes/Main.xc` 这类相对路径可被 editor 正确解析并载入。"
  priority: P0

- id: REQ-002
  title: "项目资源必须通过 Assets/.meta/Library 闭环管理"
  description: "资源系统必须维护 `.meta`、源资产数据库、artifact 数据库和 artifact 输出目录,而不是只做裸路径加载。"
  source: constraint
  type: functional
  acceptance_criteria:
    - "`AssetDatabase` 能扫描 `Assets/` 并为缺失资源生成 `.meta`。"
    - "工程目录下存在 `Library/SourceAssetDB/assets.db` 与 `Library/ArtifactDB/artifacts.db` 两套持久化记录。"
    - "`ResourceManager` 能通过路径或 `AssetRef` 解析 artifact 并触发必要的重导入。"
  priority: P0

- id: REQ-003
  title: "Viewport 渲染必须走引擎 Rendering + RHI 主链"
  description: "Scene/Game viewport 不能退化成 editor 私有渲染器,必须继续使用离屏 RenderSurface、CameraRenderRequest 和 builtin passes。"
  source: constraint
  type: functional
  acceptance_criteria:
    - "Scene/Game viewport 能从引擎离屏颜色目标接入 ImGui。"
    - "`ObjectId` picking、outline、grid 和 overlay pass 仍通过 Rendering 合约接入。"
    - "Scene View helper 链保持 `Chrome -> InteractionFrame -> Navigation -> TransformGizmoCoordinator -> ViewportHostService` 口径。"
  priority: P0

- id: REQ-004
  title: "脚本程序集必须能从 project/Library/ScriptAssemblies 被发现和加载"
  description: "脚本系统必须同时支持 ScriptCore、示例 GameScripts 和项目 `Assets/**/*.cs` 编译结果。"
  source: user
  type: functional
  acceptance_criteria:
    - "`xcengine_managed_assemblies` 能生成 `XCEngine.ScriptCore.dll`、`GameScripts.dll` 和 `mscorlib.dll`。"
    - "`xcengine_project_managed_assemblies` 能把项目程序集输出到 `project/Library/ScriptAssemblies/`。"
    - "`ScriptEngine` / `MonoScriptRuntime` 能发现脚本类并让 Inspector 读取字段元数据。"
  priority: P0

- id: REQ-005
  title: "场景与组件必须可编辑、可保存、可恢复"
  description: "Scene、GameObject 和内建组件必须支持编辑器中的创建、层级调整、复制粘贴、保存与重新加载。"
  source: user
  type: functional
  acceptance_criteria:
    - "`ISceneManager` 提供 New/Load/Save/SaveAs、Copy/Paste/Duplicate、snapshot 恢复。"
    - "`.xc` 场景文件能保留 GameObject 层级、Transform、Mesh、Light、ScriptComponent 等数据。"
    - "重新载入场景后Inspector 与 viewport 仍能解析对应实体和组件。"
  priority: P0

- id: REQ-006
  title: "RHI 抽象层必须维持三后端并保持测试分层"
  description: "公共 RHI 抽象与 D3D12/OpenGL/Vulkan 后端必须继续分层,不能通过测试反向污染抽象层。"
  source: constraint
  type: non-functional
  acceptance_criteria:
    - "`RHIFactory` 继续支持 D3D12、OpenGL、Vulkan 三后端创建。"
    - "`tests/RHI/unit/` 与 `tests/RHI/integration/` 不直接依赖后端私有实现。"
    - "`rhi_all_tests` 仍可作为统一聚合入口。"
  priority: P1

- id: REQ-007
  title: "主线测试 target 必须持续可用"
  description: "工程需要保留跨模块聚合 target用于快速验证 Rendering、Editor、Scripting 和 RHI 主线。"
  source: constraint
  type: non-functional
  acceptance_criteria:
    - "`rendering_all_tests`、`rendering_phase_regression`、`editor_tests`、`scripting_tests`、`rhi_all_tests` 仍存在。"
    - "`tests/Editor/` 覆盖 Scene View helper 新链路。"
    - "资源导入和项目脚本程序集输出存在对应 tests。"
  priority: P1

- id: REQ-008
  title: "构建入口必须真实反映当前外部依赖门槛"
  description: "文档和蓝图必须明确 Vulkan、Mono、ImGui、googletest 等依赖的实际门槛,不能继续保留旧时期的过时描述。"
  source: constraint
  type: non-functional
  acceptance_criteria:
    - "配置阶段明确 Vulkan SDK 是当前硬依赖。"
    - "Mono scripting 可通过 `XCENGINE_ENABLE_MONO_SCRIPTING=OFF` 关闭。"
    - "首次配置 editor/tests 时需要考虑 `FetchContent` 的 ImGui 与 googletest。"
  priority: P1

MVS_DEFINITION

mvs_solutions:
  - id: MVS-001
    name: "Editor 宿主与 Scene View 渲染闭环"
    goal: "确保 editor 能以 D3D12 宿主身份启动,并通过 Rendering + RHI 离屏结果驱动 Scene/Game viewport。"
    verification_criteria:
      - "构建 `XCEditor` 后可打开 `project/Assets/Scenes/Main.xc`。"
      - "Scene/Game viewport 能显示离屏渲染结果,而不是空白宿主窗口。"
      - "`tests/Editor/` 中与 viewport helper 链相关的测试保持通过。"
    scope:
      - subsystem: Editor
        components: [Application, ViewportHostService, SceneViewPanel, SceneViewportChrome, SceneViewportInteractionFrame]
      - subsystem: Rendering
        components: [SceneRenderer, CameraRenderer, RenderPipeline, RenderSurface]
      - subsystem: RHI
        components: [RHIFactory, RHIDevice, RHITexture]
      - external: [Win32, ImGui, D3D12]
    code_structure:
      - file: editor/src/Application.cpp
        purpose: "初始化 editor 宿主、project root、script runtime status 和 application 生命周期。"
        contains:
          - "project root 解析"
          - "Library/ScriptAssemblies wiring"
          - "editor runtime lifecycle"
        standalone: false
      - file: editor/src/Viewport/ViewportHostService.h
        purpose: "把 Scene View 与引擎 Rendering/RHI 输出连接起来。"
        contains:
          - "offscreen render target ownership"
          - "overlay data access"
          - "viewport render flow"
        standalone: false
      - file: engine/include/XCEngine/Rendering/SceneRenderer.h
        purpose: "构建并执行场景渲染请求。"
        contains:
          - "CameraRenderRequest build"
          - "render dispatch"
        standalone: false
    integration_plan:
      - step: "由 editor 解析工程根并创建 viewport host。"
      - step: "由 Rendering 根据当前 scene 与 camera 构建 render requests。"
      - step: "把离屏颜色目标交回 editor并由 ImGui 面板展示。"
    status: completed

  - id: MVS-002
    name: "Assets/.meta/Library 资源导入与运行时加载闭环"
    goal: "确保工程资源从 `Assets/` 到 `Library/Artifacts/` 的导入、记录和运行时解析已经形成统一链路。"
    verification_criteria:
      - "首次扫描工程时能补 `.meta` 并建立 `assets.db` / `artifacts.db`。"
      - "`ResourceManager` 能按路径和 `AssetRef` 成功定位 artifact。"
      - "材质、网格、shader 等资源的 artifact 重导入路径保持一致。"
    scope:
      - subsystem: Project
        components: [Assets, AssetMetaFiles, ProjectLibrary]
      - subsystem: Resources
        components: [AssetDatabase, AssetImportService, ProjectAssetIndex, ResourceManager]
      - subsystem: Tests
        components: [asset_tests, material_tests, mesh_tests, shader_tests, texture_tests]
    code_structure:
      - file: engine/include/XCEngine/Core/Asset/AssetDatabase.h
        purpose: "定义源资产记录、artifact 记录和导入维护接口。"
        contains:
          - "SourceAssetRecord"
          - "ArtifactRecord"
          - "EnsureArtifact / Refresh"
        standalone: false
      - file: engine/include/XCEngine/Core/Asset/ResourceManager.h
        purpose: "统一运行时加载、项目资源刷新和 Library 重建入口。"
        contains:
          - "Load / LoadAsync"
          - "RefreshProjectAssets"
          - "RebuildProjectAssetCache"
        standalone: false
      - file: project/Library/
        purpose: "承载 SourceAssetDB、ArtifactDB、Artifacts、ScriptAssemblies 等工程级缓存。"
        contains:
          - "SourceAssetDB/assets.db"
          - "ArtifactDB/artifacts.db"
          - "Artifacts/<shard>/<artifactKey>"
        standalone: false
    integration_plan:
      - step: "扫描 `Assets/` 并生成缺失 `.meta`。"
      - step: "写入源资产与 artifact 数据库。"
      - step: "通过 `ResourceManager` 暴露统一的运行时解析入口。"
    status: completed

  - id: MVS-003
    name: "Mono 脚本程序集与 ScriptComponent 闭环"
    goal: "确保 C# API、示例脚本和项目脚本可构建、可发现、可在 Inspector 与运行时之间同步字段。"
    verification_criteria:
      - "`xcengine_managed_assemblies` 与 `xcengine_project_managed_assemblies` 产物齐全。"
      - "`ScriptEngine` 能发现可用脚本类并生成字段模型。"
      - "Inspector 中对 ScriptComponent 字段的编辑能写回存储并在运行时同步。"
    scope:
      - subsystem: Managed
        components: [XCEngine.ScriptCore, GameScripts, project asset assemblies]
      - subsystem: Scripting
        components: [ScriptEngine, ScriptFieldStorage, MonoScriptRuntime, ScriptComponent]
      - subsystem: Editor
        components: [EditorScriptAssemblyBuilder, ScriptComponentEditor]
      - external: [dotnet, Mono]
    code_structure:
      - file: managed/CMakeLists.txt
        purpose: "定义 ScriptCore、示例脚本、项目脚本与 tests 专用程序集输出。"
        contains:
          - "xcengine_managed_assemblies"
          - "xcengine_project_managed_assemblies"
          - "xcengine_test_project_managed_assemblies"
        standalone: false
      - file: engine/include/XCEngine/Scripting/ScriptEngine.h
        purpose: "管理脚本生命周期、脚本类发现和字段同步。"
        contains:
          - "TryGetAvailableScriptClasses"
          - "ApplyScriptFieldWrites"
          - "TryGetScriptFieldModel"
        standalone: false
      - file: editor/src/Scripting/EditorScriptAssemblyBuilder.h
        purpose: "从 editor 触发项目脚本程序集重建。"
        contains:
          - "RebuildProjectAssemblies"
        standalone: false
      - file: project/Library/ScriptAssemblies/
        purpose: "承载 editor 与 runtime 实际加载的程序集目录。"
        contains:
          - "XCEngine.ScriptCore.dll"
          - "GameScripts.dll"
          - "mscorlib.dll"
        standalone: false
    integration_plan:
      - step: "先构建 ScriptCore 与示例脚本程序集。"
      - step: "扫描 `project/Assets/**/*.cs` 并生成项目脚本程序集。"
      - step: "由 editor/runtime 从 `Library/ScriptAssemblies/` 装载程序集并驱动 ScriptComponent。"
    status: completed

DATA_MODELS

- name: ProjectDescriptor
  description: "`Project.xcproject` 的键值对格式工程描述。"
  fields:
    - name: version
      type: int
      default: 1
      constraints: required
    - name: name
      type: string
      default: project root folder name
      constraints: required
    - name: startup_scene
      type: string
      default: Assets/Scenes/Main.xc
      constraints: required

- name: SceneDocument
  description: "`.xc` 场景文件;文件头记录 scene 名称和 active 状态,随后以 `gameobject_begin/end` 块序列化实体及组件。"
  fields:
    - name: scene
      type: string
      default: Untitled Scene
      constraints: required
    - name: active
      type: bool
      default: true
      constraints: required
    - name: gameObjects
      type: list<GameObjectRecord>
      default: []
      constraints: required

- name: AssetMetaFile
  description: "与每个工程资源并存的 `.meta` 文件,保存 guid 与 importer 信息。"
  fields:
    - name: fileFormatVersion
      type: int
      default: 1
      constraints: required
    - name: guid
      type: AssetGUID
      default: generated
      constraints: required
    - name: folderAsset
      type: bool
      default: false
      constraints: required
    - name: importer
      type: string
      default: DefaultImporter
      constraints: required
    - name: importerVersion
      type: int
      default: 5
      constraints: required

- name: SourceAssetRecord
  description: "`AssetDatabase` 中对源资产的持久化记录,对应 `Library/SourceAssetDB/assets.db`。"
  fields:
    - name: guid
      type: AssetGUID
      default: generated
      constraints: required
    - name: relativePath
      type: string
      default: ""
      constraints: required
    - name: metaPath
      type: string
      default: ""
      constraints: required
    - name: isFolder
      type: bool
      default: false
      constraints: required
    - name: importerName
      type: string
      default: DefaultImporter
      constraints: required
    - name: importerVersion
      type: uint32
      default: 5
      constraints: required
    - name: metaHash
      type: string
      default: ""
      constraints: required
    - name: sourceHash
      type: string
      default: ""
      constraints: required
    - name: lastKnownArtifactKey
      type: string
      default: ""
      constraints: optional

- name: ArtifactRecord
  description: "`AssetDatabase` 对 artifact 的持久化记录,对应 `Library/ArtifactDB/artifacts.db`。"
  fields:
    - name: artifactKey
      type: string
      default: ""
      constraints: required
    - name: assetGuid
      type: AssetGUID
      default: generated
      constraints: required
    - name: importerName
      type: string
      default: ""
      constraints: required
    - name: importerVersion
      type: uint32
      default: 0
      constraints: required
    - name: resourceType
      type: ResourceType
      default: Unknown
      constraints: required
    - name: artifactDirectory
      type: string
      default: ""
      constraints: required
    - name: mainArtifactPath
      type: string
      default: ""
      constraints: required
    - name: dependencies
      type: list<ArtifactDependencyRecord>
      default: []
      constraints: optional

- name: ScriptFieldStorageModel
  description: "`ScriptFieldStorage` 的字段 override 存储模型,可序列化为字符串并挂在 ScriptComponent 上。"
  fields:
    - name: fields
      type: map<string, StoredScriptField>
      default: {}
      constraints: required
    - name: StoredScriptField.type
      type: ScriptFieldType
      default: None
      constraints: required
    - name: StoredScriptField.value
      type: ScriptFieldValue
      default: null
      constraints: required

- name: ScriptAssemblySet
  description: "`project/Library/ScriptAssemblies/` 中 editor/runtime 解析的一组程序集。"
  fields:
    - name: outputDirectory
      type: path
      default: project/Library/ScriptAssemblies
      constraints: required
    - name: coreAssembly
      type: path
      default: XCEngine.ScriptCore.dll
      constraints: required
    - name: gameAssembly
      type: path
      default: GameScripts.dll
      constraints: required
    - name: corlib
      type: path
      default: mscorlib.dll
      constraints: required

- name: MaterialArtifactHeader
  description: "材质 artifact 文件头,对应 `XCMAT02` 和 schema v2。"
  fields:
    - name: magic
      type: char[8]
      default: XCMAT02
      constraints: required
    - name: schemaVersion
      type: uint32
      default: 2
      constraints: required
    - name: renderQueue
      type: int32
      default: Geometry
      constraints: required
    - name: textureBindingCount
      type: uint32
      default: 0
      constraints: required

EVOLUTION_PLAN

fix_plan:
  - issue_id: BUG-001
    description: "工作树中的 `project/Library/ScriptAssemblies/` 快照可能落后于目标构建产物,容易让 editor 脚本类发现与真实构建状态脱节。"
    root_cause: "脚本程序集同时存在 managed 输出、project 输出和 tests 专用输出三处目录,单看仓库快照容易误判。"
    minimal_change:
      - file: managed/CMakeLists.txt
      - file: editor/src/Scripting/EditorScriptAssemblyBuilder.cpp
      - file: tests/Scripting/test_project_script_assembly.cpp
    verification: "执行 `cmake --build build --config Debug --target xcengine_project_managed_assemblies scripting_tests`,确认 editor 与 tests 都从正确输出目录装载程序集。"

  - issue_id: BUG-002
    description: "Scene View 新交互如果绕过 helper 链直接写回旧 world overlay 路径,会导致实现和 `tests/Editor/` 的行为漂移。"
    root_cause: "旧入口仍可访问,容易跳过 `SceneViewportChrome -> SceneViewportInteractionFrame -> SceneViewportNavigation -> SceneViewportTransformGizmoCoordinator` 的新编排。"
    minimal_change:
      - file: editor/src/Viewport/SceneViewportChrome.h
      - file: editor/src/Viewport/SceneViewportInteractionFrame.h
      - file: editor/src/panels/SceneViewPanel.cpp
      - file: tests/Editor/test_scene_viewport_chrome.cpp
    verification: "执行 `cmake --build build --config Debug --target editor_tests`,确认 helper 链相关测试继续通过。"

refactor_plan:
  - target: "继续把 editor 侧 viewport 行为收口到 Rendering overlay pass 与 helper 链"
    constraints:
      - "不要把新逻辑重新堆回 `SceneViewPanel.cpp` 或 panel 层临时拼的 immediate draw 路径。"
      - "保持 `tests/Editor/` 对 helper 的独立覆盖。"
      - "Editor 仍然是宿主层,渲染问题优先回到 Rendering / RHI contract 排查。"
    steps:
      - "优先扩展 `SceneViewportInteractionFrame`、`SceneViewportNavigation`、`SceneViewportTransformGizmoCoordinator`。"
      - "世界空间 overlay 优先经 `CameraRenderRequest::overlayPasses` 和 `SceneViewportEditorOverlayPass` 接入。"
      - "helper 链变化时同步维护 editor README、AGENT 和 API 页面。"

  - target: "统一 `Assets/.meta/Library` 导入链与运行时解析链的契约"
    constraints:
      - "不要把 `project/Library/` 当作无关垃圾目录。"
      - "不要在局部代码路径里绕开 `AssetDatabase` / `ProjectAssetIndex` / `ResourceManager`。"
      - "artifact schema 变更必须同步 tests 与文档。"
    steps:
      - "继续把资产定位、artifact 生成、AssetRef 解析集中在 `AssetDatabase`、`ProjectAssetIndex`、`ResourceManager`。"
      - "保持 `Project.xcproject`、`.meta`、`assets.db`、`artifacts.db` 和 `Artifacts/` 之间的一致性。"
      - "对材质、网格、shader artifact 的契约修改补齐 `tests/Resources/`。"

feature_plan:
  - feature_id: FEAT-001
    name: "Builtin pass 跨后端收口"
    addition: "逐步降低 Rendering 内置 pass 对 D3D12 的硬编码假设使离屏渲染、ObjectId 和 outline contract 更接近真正的 backend-agnostic。"
    integration_point: "engine/src/Rendering/Passes/, engine/src/RHI/, tests/Rendering/, tests/RHI/"
    steps:
      - "梳理 `BuiltinInfiniteGridPass`、`BuiltinObjectIdPass`、`BuiltinObjectIdOutlinePass` 的 backend gating。"
      - "把必须留在 D3D12-host 层的逻辑与真正属于 Rendering 的逻辑继续拆开。"
      - "为跨后端 contract 补齐单测和场景回归。"

  - feature_id: FEAT-002
    name: "脚本字段持久化与编辑器回写深化"
    addition: "继续增强 `ScriptFieldStorage`、Inspector 字段编辑与运行时字段同步的一致性。"
    integration_point: "engine/src/Scripting/, editor/src/ComponentEditors/, project/Assets/Scripts/, tests/Scripting/, tests/Editor/"
    steps:
      - "扩展字段类型覆盖与默认值解析。"
      - "校验默认值、stored override 与 runtime 值三态同步。"
      - "保持 scene 保存、重新载入和 play mode 之间的字段一致性。"

  - feature_id: FEAT-003
    name: "Project Library 生命周期工具化"
    addition: "在不破坏现有 workflow 的前提下增强 Library 清理、重建与状态可视化。"
    integration_point: "engine/include/XCEngine/Core/Asset/ResourceManager.h, editor/src/Managers/ProjectManager.cpp, editor/src/Application.cpp"
    steps:
      - "把清理与重建入口继续收束到 `ResourceManager` 和 editor commands。"
      - "为 `SourceAssetDB`、`ArtifactDB`、`Artifacts`、`ScriptAssemblies` 提供更明确的状态反馈。"
      - "补对应 tests 和用户文档,避免再次把 `Library/` 误写成可忽略目录。"