目标架构:按事实、执行、投影与制品划分边界
自动关联目录:目标架构:按事实、执行、投影与制品划分边界
核心判断:复杂客户端的根问题不是管理器不够多,而是编辑事实、构建产物、运行状态和 UE 表示互相越权;目标架构必须让真相唯一,让投影可丢,让异步结果只能带证据提交。
一、从实际问题归纳根因
代码中的多个具体故障看似无关:运行时物理回写创作数据、Subsystem 在错误 World 阶段判断角色、异步回调把旧结果提交给新对象、跨世界数据随旧 World 销毁、Actor 快路径与命令路径可能分叉。共同根因都是边界缺失:对象同时承担事实、执行、生命周期和表现,调用方只能依靠当前指针、当前 World 或布尔标记猜测“这还是不是同一次”。
二、四层边界
flowchart LR
A[创作事实<br/>Description + ChangeSet] --> B[内容编译与验证]
B --> C[不可变制品<br/>Manifest + ArtifactRef]
C --> D[运行时权威与状态<br/>Command + Receipt + Snapshot]
D --> E[UE 投影<br/>Actor / Component / UI / Audio]
E -. 输入意图 .-> D
P[角色与平台适配器] --> B
P --> D
P --> E创作层保存用户意图和可撤销变更;构建层把意图编译成带身份、版本、能力和依赖摘要的不可变制品;运行层只消费制品,用命令、回执、快照和事件维护事实;表现层把事实投影为 Actor、动画、物理体、UI 和音频,随 World、距离、平台预算销毁重建。Client、DS、编辑器和平台差异通过外侧适配器进入,不能反向污染领域模型。
三、最小规范契约
| 契约 | 必须证明什么 | 禁止承载什么 |
|---|---|---|
ScopedIdentity | Session、World Generation、Entity、Revision | 裸进程指针 |
ChangeSet | 基线、操作、前置条件、作者意图 | 运行时 Actor 状态 |
ArtifactRef | Schema、平台、能力、依赖、摘要 | 可变编辑对象 |
Command/Receipt | 幂等身份、预期版本、权威结果 | 用广播代替结果 |
Snapshot/Event | 当前事实与一次性变化的区别 | 本地表现句柄 |
RuntimeScope | 取消树、角色、World 与会话所有权 | 进程静态开关 |
PresentationIntent | 语义动作与表现约束 | DS 业务权威 |
这些契约应是与 UE 类型解耦的值对象。领域层不依赖 Actor、Widget、NetMode 查询或具体 Subsystem;适配器依赖领域端口,而不是反向调用。
四、生命周期与提交权
生命周期不是一个 IsValid(),而是嵌套作用域:进程拥有会话,会话拥有 World 世代,World 拥有模拟域,模拟域拥有实体投影,实体拥有异步操作。父作用域结束时向下取消,但回调仍必须在 Game Thread 提交前复核完整身份。
CommitPermit permit = scope.Begin(entity, expectedRevision, operationKind);
AsyncPrepare(input).ThenOnGameThread([permit](Prepared value) {
if (!permit.Matches(CurrentScope(), CurrentRevision(value.entity)))
return Discard(StaleResult);
Commit(value);
});WeakObjectPtr 只防止访问已释放对象;CommitPermit 才证明结果属于当前会话、World、对象、槽位和请求。
五、迁移策略
这不是推倒重写。第一步从现有代码提取身份、命令、快照和能力契约;第二步把旧管理器包成端口适配器,先阻止新增直接依赖;第三步用运行时 Overlay 隔离试玩与创作事实;第四步建立 World 作用域实体库和投影索引;第五步把 Client/DS 差异收敛为角色上下文;最后用影子执行和摘要比较逐域替换 Actor、脚本、物理和表现路径。
每一步都必须有可回退的旧路径和删除条件。只增加新抽象、不删除旧入口,会得到两套真相而不是新架构。
六、收益、代价与验收
收益是故障域可定位:内容错误停在构建层,权威冲突停在运行层,表现丢失可以重建,World 切换能统一取消旧提交。代价是更多显式身份、值对象、适配器和契约测试,短期代码量会上升。
验收应针对根因:试玩不能污染创作基线;旧 World 的回调不能写入新 World;Client 与 DS 对同一命令序列得到相同领域摘要;表现投影销毁重建不改变事实;制品在错误平台或能力集上失败关闭;Actor 快路径与兼容路径语义一致。做到这些,架构才从“能跑”升级为“规模增大后仍能证明正确”。