CD Code Digest Hub /GTA V

存档统计与进度

8 分钟阅读 7 个章节 1 张图

返回总览。持久化横跨单机保存结构、在线角色/账号统计、任务表现、成就与完成度。它们共享部分事件和数值,但具有不同生命周期。

1. 四类状态#

状态例子主要职责
临时运行实体句柄、当前摄像机、局部进度当前脚本/活动
单机长期保存剧情 strand、抢劫选择、收集和人物状态g_savedGlobals 与 SaveLoad
在线长期状态角色槽数据、账号统计、奖项/拥有关系stats wrapper、原生 Stats、在线服务
单次任务指标命中率、爆头、耗时、评级mission_stat_watcher 与结算界面

2. 单机保存是显式登记#

Standard_global_reg.sc 先初始化结构,再 START_SAVE_DATA(g_savedGlobals, SIZE_OF(...), TRUE),登记 save version,按模块调用 Flow、Heist、Shop、Ambient、Player、Respawn、Friends 等 Register 函数。调试分支验证登记尺寸。[S1]

这是一套结构化保存契约,不是自动序列化所有全局变量。新增长期字段应同时确认初值、登记、版本/迁移、恢复后的运行对象重建,以及重玩环境是否需要临时覆盖。

initial.sc 的恢复校验检查保存 strand 的命令位置能否与当前定义对应,说明内容定义变化可能影响已有进度恢复。[S2] 存档保存执行位置不等于保存所有资源和世界实体。

3. 自动保存是有准入规则的状态机#

autosave_controller 维护 request、performing、in-progress、complete 和 queued requests,完成后消费队列并复位相关标志。[S3]

源码明确区分“延迟”和“取消”:在线模式、非正常剧情等可能取消这类 SP 自动保存;玩家死亡、角色尚在切换等可延迟。动物和导演身份也有专门检查。不能把发出 autosave 请求当作存储已经完成。

另一个阅读细节是:定义的 AUTOSAVE_DELAY_TIME=1000 对应的早期时间检查在当前文件中被注释,部分 on-mission 判断也被注释。本文只据有效分支描述门槛,不把历史检查写成仍然生效的保证。

4. 在线统计区分账号与角色槽#

net_stat_system.sch 有 MPPLY player stats 和 MP character stats,GET_SLOT_NUMBER 决定角色槽。高频统计 setter 同时调用 STAT_SET_INT 并更新脚本缓存。[S4]

这意味着不能只改缓存,也不能只调用底层 Native 却让上层缓存保持旧值。角色选择变化时,同一个语义统计也可能对应不同槽位;账号级统计则不应随角色槽复制。

原生 commands_stats.cpp 对统计是否允许脚本修改、类型、云文件是否仍加载/加载失败、是否由原生代码负责等进行检查,并提供 save pending 查询。[S5] 有字段 hash 不表示任何时刻都可以安全写入。在线保存、交易库存与脚本广播也不能互相替代。

5. 任务评分是独立观察器#

mission_stat_watcher.sc 跟踪准确率、伤害、爆头、无辜者死亡等事件,形成结算数据并上传到 Scaleform/相关排行榜接口。[S6] 它把任务核心推进和表现评价分离:任务通过是一种结果,达到金牌指标是另一种结果。

stats_controller 监测玩家能力/车辆表现等变化并发 UI 反馈;CompletionPercentage_controller 汇总各类长期指标和 presence 条件;achievement_controller 处理成就相关推进。[S7][S8][S9]

100% 完成度不应理解为“所有计数求和再除一个常数”,必须追其各内容类别与条件。也不要把脚本成就触发与平台最终授予成功视为同一个同步事件。

6. 数据演进与验证方向#

保存注册表、统计枚举、packed 数据和生成工具共同形成数据模式。位索引与枚举变化可能影响已有数据语义,尤其不能在插入内容时随意重排已保存的 bitset 含义。需要检查默认值、旧数据恢复、重复奖励、重玩隔离、云保存失败及 UI 等待反馈。

本次只做静态分析,没有读写实际玩家存档、云统计或平台成就,也未验证所有历史保存版本。

源码证据#

[S1] Standard_global_reg.sc L103–186;[S2] initial.sc L389–438;[S3] autosave_controller.sc L115–249;[S4] net_stat_system.sch L17、L134–155、L466、L698;[S5] commands_stats.cpp L2751–2811、L10068;[S6] L412、L578、L920、L1707;[S7] L327、L484;[S8] L1185 起聚合检查;[S9] 成就控制入口。

[S1]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/startup_reg/Standard_global_reg.sc> [S2]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/main/initial.sc> [S3]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/savegame/autosave_controller.sc> [S4]: <../../../GTAV Source/script/dev_ng/multiplayer/include/public/net_stat_system.sch> [S5]: <../../../GTAV Source/src/dev_ng/game/script/commands_stats.cpp> [S6]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/missionstats/mission_stat_watcher.sc> [S7]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/stats/stats_controller.sc> [S8]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/stats/CompletionPercentage_controller.sc> [S9]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/stats/achievement_controller.sc>