UE5.8 平台认证与合规:老陈的 Lot Check 噩梦

📑 目录

老陈盯着屏幕上的红色标记,咖啡已经凉透。平台方刚发回的 Lot Check 报告里,第十七项被打上 Fail。游戏在 PS5 上连续运行了四小时十七分钟后,存档图标突然消失,再次读取时进度回退到三小时前。更糟的是,Trophy 列表里有一个成就的名字还挂着测试占位符字符串,像一面醒目的旗帜在风中飘扬。

这已经不是第一次。三个月前团队还觉得主机版只是 PC 的移植,把画面调低、按键图标换一换就能交货。现实给了响亮的一巴掌。主机平台认证是一套独立的游戏质量标准,和 PC 上那种能跑就行的逻辑完全不同。你糊弄它,它就加倍奉还。

本文从老陈踩过的坑出发,把 UE5.8 项目里必须面对的认证问题拆清楚。不讲空话,只谈实际会遇到的事。

主机平台认证概述

主机平台认证是索尼、微软、任天堂等厂商对上架游戏的技术与体验审核。游戏必须通过相应测试套件,才能获得发行许可。每个厂商的叫法不同,但核心目标一致:保证游戏在主机上稳定、安全、符合平台用户体验规范。

对 UE5.8 项目来说,认证工作通常从项目中期就要开始规划。因为很多问题不是最后两个月能补上的。存档系统的设计、在线服务集成、错误处理与恢复机制,这些都需要在架构阶段就预留接口。等到 Alpha 阶段再去改底层,牵一发而动全身。

主机平台对崩溃、卡死、帧率波动、加载时间、用户数据安全都有硬性指标。厂商会提供一份 Technical Requirements Checklist,也就是 TRC 或 TCR。开发者需要逐条自检,然后提交给平台方做 Lot Check。Lot Check 报告会列出 Pass、Fail、Warning 三种结果,任何一项 Fail 都可能导致游戏无法上架。

下面这张图大概能说明主机认证里各个模块的关系。游戏进程、平台 SDK、系统服务、在线后端,每一层都要对上接口。

flowchart TD
    subgraph platform ["平台服务层"]
        psn["PSN"]
        xbox["Xbox Live"]
        steam["Steamworks"]
    end
    subgraph os ["主机操作系统"]
        os_save["系统存档服务"]
        os_input["手柄输入服务"]
        os_ui["系统 UI 覆盖层"]
    end
    subgraph game ["游戏进程"]
    end

从图里能看出,游戏和平台的交互点非常多。任何一个接口没接好,都会成为认证路上的绊脚石。

TCR、TRC 与 Lot Check 的差异

老陈最初也没搞懂这三个词的区别,导致准备材料时漏掉了关键文档。后来他把概念写在白板上,每次开会都指着讲。

TCR 是 Technical Certification Requirements,索尼 PlayStation 使用这个叫法。它是一份详细的技术规范,规定了游戏在 PS 主机上必须满足的行为标准。TCR 条目涵盖启动流程、控制器支持、网络行为、保存数据、用户界面等多个方面。条目编号通常很长,比如 XS0013、FR0124,每个编号背后都是具体的测试方法。

TRC 是 Technical Requirements Checklist,微软 Xbox 使用这个叫法。作用和 TCR 类似,但条目编号、分类、测试方法不同。Xbox 的 TRC 对错误处理、成就、排行榜、多人联机有特别细的描述。比如 Xbox 要求任何网络错误都必须给出明确提示,不能静默失败。

Lot Check 是任天堂的术语,也常被泛化地指代平台方的最终审核流程。Lot Check 通常由平台方的测试团队执行,他们会用专门的测试套件和开发机运行游戏,记录所有异常。Lot Check 报告里的 Fail 项必须全部修复,否则拿不到发布批准。

三者关系见下图。

graph LR
    A["开发者自检"] --> B{TCR/TRC 考纲}
    B --> C["内部测试"]
    C --> D["修复问题"]
    D --> E["提交 Lot Check"]
    E --> F{平台测试团队}
    F -->|Pass| G["获得发布许可"]
    F -->|Fail| H["返回报告"]
    H --> I["修复问题"]
    I --> E

简单来说,TCR 和 TRC 是考纲,Lot Check 是考试。你按考纲准备,然后上考场。考纲告诉你考什么,考场决定你能不能毕业。

老陈的经验是:不要把 TCR/TRC 当成一份读完就扔的文档。要把相关条目转成测试用例,排进版本计划。比如索尼对崩溃报告有专门要求,微软对成就解锁时机有详细说明,这些都要变成代码和测试。

性能标准

老陈的项目在 PS5 性能模式下跑 4K60,宣传材料都发出去了。Lot Check 的自动化工具连续记录了一周帧率,发现 boss 战期间最低帧掉到了 47,而且掉帧集中在玩家输入最频繁的阶段。平台方给出的评语很直接:目标模式下必须稳定达到标称帧率,不能靠平均帧糊弄。

主机平台的性能测试不是看平均帧。核心指标是帧时间稳定性和最低帧。PS5 的 60 FPS 模式意味着每帧预算只有 16.67 毫秒。如果你的渲染线程、游戏线程、GPU 任何一个环节超时,就会掉帧。平台方通常要求实际帧时间 TactualT_{actual} 不超过目标帧时间 TframeT_{frame},且掉帧率低于规定阈值。

帧时间预算公式可以写成:

Tframe=1000FPStarget msT_{frame} = \frac{1000}{FPS_{target}} \text{ ms}

对于 60 FPS,Tframe16.67msT_{frame} \approx 16.67\text{ms}。掉帧率 DD 的定义是:

D=NdroppedNtotal×100%D = \frac{N_{dropped}}{N_{total}} \times 100\%

其中 NdroppedN_{dropped} 是超时的帧数,NtotalN_{total} 是总帧数。平台方通常要求 DD 低于 1%,某些严格场景甚至要求 0.5%。

UE5.8 在主机上的优化点和前几代有变化。Nanite 和 Lumen 默认开启时,GPU 压力比传统管线大。如果项目早期没有针对主机做预算分配,后期很难把帧率补回来。老陈的团队后来做了几件事:关闭非关键场景的 Lumen,改用烘焙光照;把阴影距离和粒子数量按平台设置 profile;用 stat unit 和 stat fps 持续监控;在 CI 里加入自动化性能捕获。

性能测试最好在开发机上做,而不是用编辑器。开发机的 OS 版本和零售机一致,能暴露更多问题。编辑器里跑 60 帧,不代表真机上能稳住。老陈吃过这个亏,后来每次提测前都先在 devkit 上跑满八小时。

存档规范

存档是老陈这次 Lot Check 失败的重灾区。主机平台对保存数据有严格规范:保存图标必须出现、保存过程不能卡死、保存数据不能损坏、云存档必须同步。

UE5.8 的 SaveGame 系统提供了 USaveGame 基类,可以直接序列化到平台提供的保存槽位。但默认行为并不完全符合平台规范。比如,保存时没有显示系统级保存图标,会被判为不合规。

老陈的代码里,保存逻辑大概长这样:

bool UMySaveManager::WriteCheckpoint(int32 SlotIndex)
{
    if (USaveGame* Save = UGameplayStatics::CreateSaveGameObject(UMySaveGame::StaticClass()))
    {
        UMySaveGame* MySave = Cast<UMySaveGame>(Save);
        MySave->PlayerProgress = CurrentProgress;
        MySave->Timestamp = FDateTime::Now();
        MySave->Checksum = ComputeChecksum(MySave);
        FString SlotName = FString::Printf(TEXT("Slot%d"), SlotIndex);
        return UGameplayStatics::SaveGameToSlot(MySave, SlotName, 0);
    }
    return false;
}

这段代码在 PC 上没问题,但上主机缺了几件事:没有处理保存失败重试;没有调用平台保存 UI 的显示接口;没有校验存档完整性;没有处理云存档冲突。

索尼要求保存图标必须在写入期间显示,且玩家不能误以为是游戏卡死。微软则对保存数据的大小和存储位置有明确限制。任天堂的 Lot Check 对存档损坏后的恢复流程有专门测试。他们会强制拔掉电源、模拟系统崩溃,检查游戏再次启动时能否正确恢复。

老陈后来加了一个保存状态机。流程是:请求保存、显示图标、异步写入、校验 checksum、隐藏图标、失败时回滚到上一份有效存档。这个流程让 Lot Check 的存档测试全部通过。他说,存档这玩意儿,宁可多花两秒,也不能让玩家丢进度。

成就与排行榜集成

成就和排行榜是平台在线服务的核心。每个平台的实现不同:PSN 用 Trophy,Xbox 用 Achievement,Switch 没有传统成就系统但有类似机制。如果项目要上多个平台,需要在 UE 里做一层抽象。

UE5.8 内置的 Online Subsystem 提供了跨平台接口。你可以用 IOnlineAchievements 和 IOnlineLeaderboards 来读写成就与排行榜。但这些接口在不同平台的具体行为有差异。

老陈遇到的问题是:成就触发时机不一致。PC 版触发成就是在任务完成瞬间,主机版必须在任务完成并且玩家回到安全状态后才触发。因为平台规范要求成就在玩家能看到明确反馈的时候解锁,不能在过场动画中间或加载画面里弹。老陈的代码最初在 boss 死亡动画播到一半就弹奖杯,结果被拒。

排行榜更麻烦。平台方会测试排行榜数据是否能在断网后正确提交、是否能在不同用户间隔离、是否能防止篡改。老陈的团队最初把排行榜分数存在本地,联机时再上传,结果被 Lot Check 判定为不安全。更好的做法是:关键分数在服务端计算,客户端只上传原始事件。平台 SDK 通常提供反作弊接口,可以验证上传数据的签名。

成就文本也是坑。占位符、测试字符串、英文未翻译,都是常见 Fail 项。老陈后来做了一套发布前扫描工具,自动检查所有成就 ID 对应的本地化文本是否完整。

用户隐私与合规

隐私合规这几年越来越严。主机平台本身有用户协议,但游戏还要面对 GDPR、CCPA 等法规。如果项目收集任何玩家数据,比如设备信息、游戏行为、崩溃日志,都需要明确告知玩家并获得同意。

UE5.8 默认会收集一些匿名遥测数据,比如编辑器使用情况。发布版本里这些通常已经关闭,但要注意 Analytics 插件和 Crash Reporter 的配置。Crash Reporter 会上传崩溃日志,其中可能包含用户 ID、IP 地址等敏感信息。如果你开启了自动上传,却没在隐私政策里写清楚,就可能踩线。

老陈的项目在隐私条款里写了我们可能会收集崩溃信息,但没有在游戏首次启动时弹出明确同意对话框。平台合规团队要求补上这个步骤。因为主机玩家可能包含未成年人,数据收集必须格外谨慎。同意对话框不能默认勾选,也不能藏在三层菜单之后。

另外,如果游戏支持跨平台联机,不同平台的数据共享策略也不同。Xbox 和 PlayStation 对跨平台好友、语音聊天、数据互通都有单独审核点。老陈的项目后来砍掉了跨平台语音,只为减少合规风险。这个决定让策划骂了一周,但认证团队松了口气。

常见认证失败项

老陈把历次 Lot Check 失败项整理成一张表,后来成了团队内部的避坑手册。这些项目看起来琐碎,但平台方会把每一项都测得很细。

常见失败项包括:启动时崩溃或黑屏超过规定时间;手柄断开重连后输入失效;游戏中出现平台禁止的按键图标;存档图标缺失或保存时卡死;成就或奖杯描述包含测试文本或占位符;多人模式断线后无法回到主菜单;帧率低于目标值且掉帧率超标;使用了未授权的第三方库或接口;用户协议或隐私政策缺失;错误提示使用英文而不是平台要求语言。

手柄重连测试尤其折磨人。测试人员会在游戏运行的不同时机拔掉手柄再插回去,检查输入恢复、UI 提示、暂停行为。如果你的 UMG 没有正确处理 Input Mode,就会挂。老陈的项目在商店界面拔手柄再插,焦点跑到屏幕外去了,玩家无法继续操作,这一项直接 Fail。

平台图标也是细节。PS5 游戏不能出现 Xbox 手柄的 ABXY 提示,反之亦然。如果你的项目是跨平台通用输入,记得根据当前平台动态替换图标资源。老陈的团队把图标资源做成了平台变体表,打包时按目标平台选择。

认证准备流程

老陈后来总结了一套准备流程,新项目都会按这个走。流程不复杂,贵在坚持。

阶段一:立项时读考纲。把 TCR/TRC 里和项目类型相关的条目挑出来,做成检查表。动作游戏和策略游戏关注的条目不一样,不要通读全文,要挑重点。老陈建议用电子表格维护检查表,每条目标注负责人、预计完成时间、当前状态。这样开会时不会遗漏,也能在提交前快速确认每个问题都有结果。

阶段二:开发中期做自测。每两周跑一次内部 Lot Check,重点测存档、输入、性能、网络。把发现的问题直接排进当前版本,不要拖到提交前。内部测试要模拟平台测试环境,包括拔掉网线、切换用户、长时间待机后恢复、手柄热插拔等边界场景。这些操作在编辑器里跑不出来,必须在 devkit 上反复做。

阶段三:提交前做完整自评。用平台提供的测试套件生成报告,所有 Fail 项必须清零。Warning 项能修也修,因为平台方可能把 Warning 升级成 Fail。自评报告要存档,方便和平台方返回的报告做对比,确认每个问题都回应过。

阶段四:正式提交后积极响应。平台方通常会给两周时间修 Bug,超时可能重新排队。回复报告时要逐条说明修复方案,不要含糊其辞。老陈的经验是,回复里最好附上验证视频或截图,让测试人员一眼看明白改动。模糊表述比如已修复或已优化,很容易被打回来要求补充说明。

整个流程可以用下图表示:

flowchart TD
    A["立项读考纲"] --> B["提取检查表"]
    B --> C["开发中期自测"]
    C --> D{发现 Fail}
    D -->|"是"| E["修复并回归"]
    E --> C
    D -->|"否"| F["提交前完整自评"]
    F --> G{仍有 Fail}
    G -->|"是"| H["集中修复"]
    H --> F
    G -->|"否"| I["提交 Lot Check"]
    I --> J["平台测试"]
    J --> K{结果}
    K -->|Pass| L["获准发布"]
    K -->|Fail| M["按报告修复"]
    M --> I

Lot Check 的反馈流程更像拉锯战。提交之后不是万事大吉,而是新一轮攻防的开始。下面这张序列图大致描绘了老陈经历的一次 Lot Check 循环。

sequenceDiagram
    participant Dev as "开发团队"
    participant Pub as "发行商"
    participant Plat as "平台方"
    participant Test as "测试团队"
    Dev->>Pub: 提交候选版本
    Pub->>Plat: 发起 Lot Check 申请
    Plat->>Test: 分配测试套件
    Test->>Test: 自动测试 + 人工测试
    Test-->>Plat: 生成测试报告
    Plat-->>Pub: 返回 Pass/Fail 报告
    Pub-->>Dev: 转发 Fail 项
    Dev->>Dev: 修复问题
    Dev->>Pub: 提交修复版本
    Pub->>Plat: 重新申请 Lot Check
    Test->>Test: 回归验证
    Test-->>Plat: 全部通过
    Plat-->>Pub: 授予发布许可
    Pub-->>Dev: 确认上架资格

老陈说,Lot Check 就像体检。你平时不注意的小毛病,到了体检全部暴露。与其临时抱佛脚,不如从项目早期就养成习惯。

写在最后

老陈的项目最终通过了 Lot Check,但代价是推迟了六周。他后来常在团队里讲,平台认证不是附加题,而是主游戏的一部分。如果 UE5.8 项目打算上主机,最好在写第一行战斗代码之前,就先搞清楚平台要你怎么存档、怎么报错、怎么弹成就。

认证这件事没有捷径。它不会因为你画面好就网开一面,也不会因为你剧情动人就降低标准。你能做的,就是把每一条规范都变成代码、变成测试、变成 checklist,然后在提交前把 Fail 项一个一个清零。

老陈现在每次路过那张贴满便利贴的白板,都会多看两眼。那些红叉和黄标,都是学费。交够了,路就顺了。