Files
XCEngine/docs/blueprint.md

1097 lines
41 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.
# XCEngine 蓝图
本文按当前工作树整理,快照时间为 `2026-04-04`。如果源码、测试、`CMakeLists.txt` 或项目布局继续演进,这份蓝图也必须同步更新。
---
# SYSTEM_META
```yaml
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
```yaml
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
```yaml
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
```yaml
- 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
```yaml
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
```yaml
- 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
```yaml
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/` 误写成可忽略目录。"
```