CD Code Digest Hub /GTA V

单机任务流与任务启动

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

返回总览。本篇讨论剧情图的推进、任务可用性和启动仲裁;具体任务内部编排见剧情任务与抢劫。

1. 四层职责#

任务系统不是一个巨大的主线任务 switch。它至少分为剧情流、任务描述/触发器、候选仲裁、运行中的任务脚本四层。[S1][S2][S3]

这种划分使同一个任务可以由地图入口、角色切换、重玩等不同路径进入,同时仍接受全局的冲突管理。任务“已解锁”“已显示”“已触发”“已取得运行资格”“脚本已运行”是五种不同状态。

2. Flow 是脚本中的小型命令解释器#

flow_controller.sc 从 g_flowUnsaved.flowCommands 取命令和数据索引,按 FLOW_COMMAND_IDS 分发。可见命令包括激活/终止 strand、等待激活、标签和跳转、存储 flag/int/bitset、条件跳转。命令返回下一跳标签,既可以顺序前进,也可以停留等待。[S1]

每条 strand 的 thisCommandPos 和 saved bitflags 保存在 g_savedGlobals.sFlow.strandSavedVars;命令表、上下界等运行数据位于 g_flowUnsaved。这是“保存剧情执行位置,重新装配运行定义”的设计,而不是把整个世界或所有脚本调用栈保存成快照。

UPDATE_STRAND 校验指令位置上下界,跳过未激活或已终止的 strand。标签可以立即跳过;fast-track 模式允许同帧持续运行到阻塞命令。MAINTAIN_MISSION_FLOW 支持只处理锁定 strand、下一帧处理全部 strand、按 MAX_STRANDS_TO_PROCESS_PER_FRAME 配额处理三种策略。正常扫描索引跨帧保留,因此剧情检查成本可控,又能在关键时刻加速同步。

核心控制器通过 flow_controller_GAME.sch 扩展游戏专属命令。这种“通用解释器 + GTA 命令处理 + 各剧情 strand 初始化”的结构,使主线、抢劫准备、电话提示等不必都写入同一个任务入口。[S4][S5]

3. 任务数据和入口场景#

Flow_Mission_Data_GTA5.sch 集中初始化任务数据和 blip;mission_control_public.sch 提供基本触发器、场景触发器、切换触发器的注册与注销接口,分别带 mission ID、strand、候选类型和角色标志。[S2][S6]

mission_triggerer_A.sc 并不实现所有任务:它持有局部状态和 SETUP_SET_A_TRIGGER_SCENE 函数指针,把工作交给 MISSION_TRIGGERER_MAIN_UPDATE。文件明确限定 A 版本不应运行到 Trevor1 完成以后。A/B/C/D 是内容阶段拆分的触发器集合,不能简单理解成四个玩家槽位。[S3]

触发场景的作用不只是在地上画圈:它在任务真正运行前维护环境、演员和入口条件,并对死亡/被捕、SP→MP、重玩等执行不同清理。任务位置附近存在可见的人物与对白,是“入口场景”和“正式任务”协作的结果。

4. Candidate 是共享玩法占用仲裁#

candidate_controller 等候候选列表数量在相邻帧稳定,再做裁决;检查任务类型是否能与当前类型共存,排除撤回项,通过候选类型枚举的顺序进行优先级比较,最终写入当前候选 ID、绑定线程和 g_OnMissionState。[S7]

这里应注意三个细节:

  • 列表稳定等待是同一轮候选收集的缓冲,并非承诺全局公平排队。
  • 枚举顺序参与优先级计算;增加候选类型可能改变仲裁语义。
  • 绑定线程死亡会触发 Mission_Over,避免内容脚本异常结束后长期占着任务资格。该机制不等于所有世界修改都会自动撤销。

从 off-mission 进入任务及返回时,控制器还调用 COPY_BANK_TRANSLOGS。任务边界同时是经济检查点边界,说明候选仲裁与保存/恢复并非完全独立。

5. 三种“重放”不要混在一起#

概念作用关键入口
任务内检查点重试回到当前任务的已登记阶段任务脚本的 replay stage、失败屏幕
已完成任务重玩临时准备适合历史任务的角色、剧情、抢劫条件mission_repeat_controller
游戏影像录制/编辑保存和呈现游戏录像内容replay Native、导演模式与编辑器相关脚本

mission_repeat_controller 有 Setup、Launch、Run、Passed、Failed、Exit 流程;配套 private 头文件包含武器解锁、角色能力、房屋、RC、剧情跳转、抢劫规划板等准备接口。[S8][S9] 可重玩性需要重新构造任务前提,不是从菜单直接启动一个 .sc 就能获得。

6. 内容扩展和维护要点#

新增任务要同时考虑任务 ID 和描述、strand 解锁条件、入口场景、候选类型、实际脚本、成功/失败回报、重玩环境和统计。遗漏其中一环可能造成“地图上有点但不启动”“任务完成但下一条剧情不开放”“首次正常但重玩异常”。这些是架构推导的排查方向,并非本次运行确认的故障。

在数据流上应保持:任务内容只报告自己的结果;任务流负责长期解锁;候选系统负责当前占用;保存系统负责长期持久化。通过已存在接口完成这些操作,比由具体任务直接重置整个剧情流更容易维护。

源码证据#

编号位置
[S1]flow_controller.sc L80 命令分发;L354 strand;L427 配额调度
[S2]mission_control_public.sch L112/311/490 触发器;L882 安全检查
[S3]mission_triggerer_A.sc L19 职责说明;L38 回调;L60 阶段限制
[S4]flow_controller_GAME.sch L1 游戏命令扩展
[S5]Strands:各剧情线的初始化定义
[S6]Flow_Mission_Data_GTA5.sch L24、L263
[S7]candidate_controller.sc L80、L98、L143、L191
[S8]mission_repeat_controller.sc L377、L691、L844
[S9]mission_repeat_private.sch L48、L918、L966、L1583

[S1]: <../../../GTAV Source/script/dev_ng/core/common/flow/flow_controller.sc> [S2]: <../../../GTAV Source/script/dev_ng/singleplayer/include/public/mission_control_public.sch> [S3]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/missionlauncher/mission_triggerer_A.sc> [S4]: <../../../GTAV Source/script/dev_ng/core/game/flow/flow_controller_GAME.sch> [S5]: <../../../GTAV Source/script/dev_ng/singleplayer/include/private/Mission_Flow/Strands> [S6]: <../../../GTAV Source/script/dev_ng/singleplayer/include/private/Mission_Flow/Flow_Mission_Data_GTA5.sch> [S7]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/missionlauncher/candidate_controller.sc> [S8]: <../../../GTAV Source/script/dev_ng/singleplayer/scripts/missionlauncher/mission_repeat_controller.sc> [S9]: <../../../GTAV Source/script/dev_ng/singleplayer/include/private/mission_repeat_private.sch>