跨关卡引用:共享层不能反向依赖私有层

自动关联目录:跨关卡引用:共享层不能反向依赖私有层

核心判断:公共层可以独立存在,因此不能引用只在某一关卡存在的私有对象;关卡私有对象可以引用公共层。引用方向必须与生命周期包含关系一致。

一、业务问题:拆文件之前必须先拆生命周期

把单一场景拆成公共片段与多个关卡片段,看似只是减少单文件大小。真正困难的是对象引用:公共规则对象若指向关卡 A 的机关,切到关卡 B 后该引用指向什么?如果继续保留旧对象,关卡就没有真正卸载;如果返回空,又会让公共逻辑在运行时随机失效。

因此“哪些对象放公共层”不能只按目录或创作者选择决定,还要服从引用方向。

二、实际实现:Merge 时验证完整引用图

现有拆分/合并逻辑会为公共层和活动关卡分别建立 ID 集合,拒绝重复对象号、缺失父节点和悬空对象引用。最关键的一条是:公共对象引用集合中不能出现关卡私有 ID;关卡对象则可以引用公共对象和同关卡对象。

它还验证公共根只能属于公共层,关卡父节点必须在合并集合内,并用顺序账本重建确定性对象顺序。旧格式没有顺序账本时保留兼容路径,但重新封存必须证明投影等价。

这些规则把“公共层”从文件分类提升成了生命周期契约,这是多关卡设计中最值得保留的部分。

三、缺口:扫描 _type=ObjectRef 仍依赖序列化约定

当前引用校验通过递归扫描带类型标记的 JSON 值收集对象号。只要某个新字段用裸整数或另一种包装表达引用,校验器就看不见它。相反,字符串脚本里出现的逻辑引用也不能靠 JSON 递归可靠分析。

目标模型应让引用成为 Schema 的一等类型:

Ref<T> {
    targetContentId
    scope = Common | SameLevel | ExplicitLevel
    policy = Required | Optional | LateBound
}

编译器根据字段 Schema 构建引用图,再验证生命周期:

Common -> Common          allowed
LevelA -> Common          allowed
LevelA -> LevelA          allowed
Common -> LevelA          rejected
LevelA -> LevelB          explicit handoff/late-bound only

跨关卡引用若业务确实需要,应引用一个稳定服务、事件通道或可迟绑定句柄,而不是直接持有目标对象的运行时 ID。

四、验证结论

测试应覆盖嵌套数组与对象中的引用、删除目标、移动对象到公共层、复制关卡导致的 ID 冲突、旧格式顺序恢复,以及新增引用字段未注册 Schema 时构建失败。运行时还要测试切关后旧引用不能意外命中新关卡的同号对象。

多关卡的核心不是“把场景切成几个 JSON”,而是让依赖方向与对象生命周期一致。只要公共层还能反向抓住私有对象,分层就只是文件布局。