可玩就绪:Decode 成功不是首帧 Ready

自动关联目录:可玩就绪:Decode 成功不是首帧 Ready

核心判断:加载完成必须按玩家承诺定义。场景能解码、Actor 已生成、资源已绑定、角色可控制和世界完整同步是不同里程碑,任何一个都不能代替 Playable。

一、业务冲突:更早关加载界面,可能只是更早暴露半成品

玩家需要尽快进入,但进入后必须至少能看见本地角色、获得有效相机、接收权威状态并与出生区域交互。若加载界面只等场景 Decode,可能出现黑帧、无角色、相机未接管或关键对象仍是空组件;若等待全地图全部资产,又会让远处内容拖慢进入。

因此首屏优化不是把同一个 Loaded 提前,而是定义比“全量完成”更小、比“Decode 成功”更强的可玩集合。

二、实际实现:已经从百分比迁移到多阶段闸门

工程里有独立的场景构建就绪状态、初始资源请求计数、空间常驻区域完成信号和客户端会话状态机。加载层只有在角色/控制器、活动相机和关键场景要求满足后才隐藏;端到端时间线还区分 Playable 与后续完整同步。

这说明实践已经承认:进度条数值只是呈现,Ready 必须由事实驱动。代码中也出现过典型反例:在错误的 World/NetMode 启动加载状态机,等待一个永远不会到来的联机事件,最终卡在接近完成的位置。根因不是进度算法,而是闸门缺少适用上下文。

三、值得保留:命名里程碑比一个完成回调更可靠

  • 会话 ID 和单调起点跨 Editor、Client、DS 传播,能把多进程阶段放进同一时间线。
  • Playable 与 FullSync 分离,既允许关键路径前移,也不丢失后台收敛指标。
  • 初始资源以请求集合完成,而不是以“已经发起请求”完成。
  • 加载遮罩关闭后再次检查其状态,能把呈现失败纳入会话失败而不是静默继续。
  • World、NetMode 和会话所有权参与闸门判断,避免把独立世界当成联网客户端。

四、结构性缺陷:闸门仍可能由多个系统分别宣布完成

空间流式关注对象是否进入需求集合,资源队列关注异步工作是否排空,Actor 管理关注实体是否存在,角色系统关注首个有效姿态,相机系统关注活动 ViewTarget。若每个模块都能直接推进总进度或关闭遮罩,就会发生“较弱事实覆盖较强承诺”。

另一个问题是条件只有布尔值,没有版本。场景重载、角色重建或相机换代后,旧一代的 Ready 回调可能误满足新会话。简单地把计数清零也不够,迟到回调仍会写入新计数器。

五、目标设计:显式 Readiness DAG

将可玩条件建成带代次的有向无环图,每个 Requirement 声明所有者、强度和失败策略。加载 UI 只观察根节点,不直接理解资产或角色细节。

ReadinessGraph graph(sessionId, worldGeneration);
graph.Require("scene.identity");
graph.Require("local.character.actor", {"scene.identity"});
graph.Require("local.character.pose", {"local.character.actor"});
graph.Require("camera.view", {"local.character.actor"});
graph.Require("spawn.gameplay", {"scene.identity"});
graph.DefineGate("playable", {
    "local.character.pose", "camera.view", "spawn.gameplay"
});

每个完成事件携带 SessionId + WorldGeneration + RequirementRevision;失败分为阻断、允许降级和后台重试。远处纹理或高阶 LOD 不属于 Playable,只影响 PresentationComplete。DS 的 Gate 则不要求相机、UI、音频和视觉资源,只要求权威脚本、碰撞和复制入口可用。

六、验证:优化的是关键路径,不是进度条

应记录 T_decode、T_actor、T_local_pose、T_camera、T_spawn_gameplay、T_playable 和 T_fullsync,并保存每个 Gate 的最后阻塞项。关键指标是:

Tplayable=max⁡(Ti∣i∈Rplayable)T_{playable}=\max(T_i\mid i\in R_{playable})

合成示例:远处代理晚 300 ms 到达,但不在可玩集合中,则不能拖慢 T_playable;本地相机晚 30 ms,即使总资产已完成,也必须继续阻塞。示例只用于说明 Gate 语义。

最终决策规则:只有直接影响首个可靠交互的事实进入 Playable;每个 Ready 都必须绑定会话、世界和代次。