在线任务模式与内容编辑器
返回总览。本篇关注 FMMC、任务数据加载、启动大厅、通用任务执行与创建器;自由模式中的产业循环另见在线自由模式。
1. 内容定义、启动和执行分离#
FM_Mission_Creator.sc、FMMC_Launcher.sc 与 FM_Mission_Controller.sc 是三个不同职责,名称接近但不能互换。前者编辑/测试内容,launcher 管理进入活动及启动过程,controller 执行正式玩法。[S1][S2][S3]
2. FMMC 是规则与数据的运行容器#
Controller 拆出 Main、Entities、Peds、Peds_Brain、Objects、ObjectiveCompletion、Events、Bounds、Ending、HUD、Audio、Cutscene 等头文件。g_FMMC_STRUCT 持有任务选项、队伍/规则设置等内容定义,MC_serverBD 和 MC_playerBD 等保存网络运行状态。[S3][S4]
可见选项包括队伍和角色、回合/终局条件、可用武器、角色服装、载具限制、重生、时间、警察感知、室内环境等。不同模式通过配置和专属处理分支组合出行为;这比“每个竞赛都复制一个新脚本”更可扩展,但也让模式选项之间的组合测试成为重要工作。
不宜把 FMMC 宣称为能表达任意任务的无代码系统。目录中仍有大量专用流程、硬编码任务修正、抢劫和不同版本的扩展。通用解释器和特殊关卡逻辑共同存在。
3. 运行主循环的严格顺序#
FM_Mission_Controller.sc 初始化后进入主循环,源码注释明确要求这一阶段只有一个统一的等待点 MP_LOOP_WAIT_ZERO。紧接着先调用 CHECK_MISSION_BAIL_CONDITIONS,注释说明若不先检查退出,玩家已经不再是 participant 时可能越界。[S3,L2868]
之后初始化本地玩家数据、复位帧级状态、处理事件、维护场景/密度/控制覆盖,再执行相应玩法。这种顺序保证同一帧所用参与者身份尽量一致,也避免在深层 helper 中随意 WAIT 导致前半帧和后半帧使用不同网络身份。
这个约束针对该脚本的运行阶段,不表示整个 SanScript 项目禁止 helper 中 WAIT;初始化等待和单机任务有不同约定。
4. 启动大厅承载真实玩法状态#
Launcher 有 contact mission 和 heist strand 注册、任务入口 blip/corona 信息、邀请判断、不可加入原因、投票/选项状态、JIP 与 host gone 定时器等。[S2] 它负责把“玩家想参加”转成一组可以启动同一任务定义的参与者。
因此启动条件至少要协调内容是否加载、当前活动实例、玩家是否仍在参与、队伍/角色/车辆选择和主机状态。邀请成功不等于任务已开始;任务配置变动也需要同步,而不是只改本机菜单显示。
5. 云内容加载是异步状态机#
net_cloud_mission_loader.sc 持有 GET_UGC_CONTENT_STRUCT,按进度推进任务文件、内容 ID 对应 header 和抢劫规划数据下载。取消时重置加载变量并调用 UGC_CANCEL_QUERY;读取文件阶段另有安全超时处理。[S5]
这说明运行器消费的是经过加载过程得到的内容定义,而不是每个任务都必然编译成独立 .sc。同时,仓库中的脚本和加载器不能替代云端实际任务资源;本次未请求在线内容,也不能确认所有 mission data 都在本地齐备。
内容 ID、root ID、任务类型、实例 ID有不同用途:内容 ID定位定义,root 用于关联内容族/版本,实例 ID 区分会话内的一次运行。遇到“加载了错误任务”应追这条数据路径,不能只查脚本文件名。
6. 创建器和测试模式的往返#
Creator 具有 SAVE_LOCAL_DATA、放置数据加载、加载后设置、清理后进入测试、维护测试任务状态等路径。[S1] 编辑状态不是正式运行状态:进入测试需要撤销编辑器的世界占用并将定义交给运行器;返回后又要恢复编辑数据和菜单。
可复用的内容生产链是“配置—放置—校验—测试—回到编辑—保存/发布相关流程”。本次只静态确认本地保存和测试入口;不能凭创建器存在就声称已成功发布任何云内容。
7. 与较新通用内容框架的关系#
FMMC 强调任务定义、规则、实体和在线活动运行;Freemode_Content_Generics 强调自由世界任务的共享生命周期与覆写钩子。两者复用网络脚本、Native、公共实体/统计等能力,但并不是同一个文件换名,也不能断言后一套已经完全替代前一套。
新增内容应先判断它是独立活动、自由世界持续任务,还是现有模式的地点/规则变体,再选现有框架。优先增加可验证的数据差异;确实需要新行为时,再加清晰的状态和覆写入口,避免继续扩张一个无法枚举组合的巨型条件分支。
源码证据#
| 编号 | 位置 |
|---|---|
| [S1] | FM_Mission_Creator.sc L3848 测试清理;L3866 测试状态;L4217 加载后;L6110 保存 |
| [S2] | FMMC_Launcher.sc L1590/1631 内容注册;L1674/1727 入口;L2024 初始化;L3056 邀请 |
| [S3] | FM_Mission_Controller.sc L48 主机处理;L2836 预游戏;L2868 主循环 |
| [S4] | FM_Mission_Controller_Main.sch L802 服装;L877 角色;L2103 拾取;L2186 武器规则 |
| [S5] | net_cloud_mission_loader.sc L108 任务加载;L259 header;L396 抢劫;L433 超时 |
[S1]: <../../../GTAV Source/script/dev_ng/multiplayer/scripts/modes/freemode/FM_Mission_Creator/FM_Mission_Creator.sc> [S2]: <../../../GTAV Source/script/dev_ng/multiplayer/scripts/modes/freemode/FM_Mission_Creator/FMMC_Launcher.sc> [S3]: <../../../GTAV Source/script/dev_ng/multiplayer/scripts/modes/freemode/FM_Mission_Creator/FM_Mission_Controller/FM_Mission_Controller.sc> [S4]: <../../../GTAV Source/script/dev_ng/multiplayer/scripts/modes/freemode/FM_Mission_Creator/FM_Mission_Controller/FM_Mission_Controller_Main.sch> [S5]: <../../../GTAV Source/script/dev_ng/multiplayer/scripts/modes/freemode/net_cloud_mission_loader.sc>