← 技术文档

追加剧本 MOD(自定义战役)

把几关自己编排的关卡串成一个战役:开局入队、关与关之间的场间、剧情中的选项分支和结局,打包成 .srw64mod 安装,存档与本篇分开。目前只能用原版的地图、人物、机体和台词。

更新于 2026-10-31

追加剧本是一个独立的小战役:几关按你定的顺序连起来,关与关之间照常进场间(改造、换乘、存档),可以用剧情中的选项分出不同结局。它装在 MOD 包里,从标题画面的「MOD → 追加剧本」进入,存档与本篇完全分开。

每一关就是一个迷你关卡:选一张原版地图,摆上单位,写开场、胜利和结束的事件脚本。战役只是在外面加一份关卡表,把它们连起来。

需要游戏 0.5.1 或更新。

现在能做什么

能做 还不能做
多关串联、选项分支、多个结局 新台词(对白只能引用原版已有的句子)
每关的地图、我方加入、敌人配置、增援、胜败条件 新地图(只能用原版的地图)
战役名、简介、每关标题三语分别写 新人物、新头像、新战斗台词
资金、剧情变量、关与关之间保留的部队

对白和选项都是引用原版台词的编号:游戏显示那句台词原本的说话人和头像,按玩家选的语言显示对应的译文。所以写剧情时要从原版台词里挑意思合适的句子来拼。

需要什么

  • 源代码仓库和 Python 3:编译关卡、打包。
  • 你自己的 ROM:放进仓库命名为 rom.z64,运行一次 make recomp-data。查人物、机体、地图编号,以及用原版的出击记录或事件做底板时都要用。
  • 想让 AI 边写边在游戏里试:按用 AI 智能体操作游戏(MCP)连上游戏。

交给 AI 做

能上网、能读写文件的 AI 智能体(Claude Code、Codex 等)可以照着说明做出整个战役。在仓库目录里打开它,复制下面这段话,把「剧情」那一段换成你的大纲:

请帮我给 Marchwind 64(《超级机器人大战64》的 PC 重编译版)做一个追加剧本 MOD(自定义战役),最后打包成可以直接安装的 .srw64mod 文件。

先读这些,严格按里面的格式、规则和编号做:
- https://srw64.dreamquest.club/zh/docs/mod-campaign.md(战役的格式、规则、找台词和打包)
- https://srw64.dreamquest.club/docs/mini-stage/llms.txt(每一关的格式和全部脚本指令)
- 仓库里的示例战役 config/recomp/campaigns/sample,照它的结构写

限制:
- 只用原版的地图、人物和机体;对白和选项只引用原版已有的文本号,不要编新台词
- 先在 content/dialogue/zh-Hans/story/ 里找意思合适的句子,把文本号、说话人和译文列给我确认,再写进关卡
- 每个事件以 3DD0 开头,不用主角路线标记;避开带 {HeroName}、{PartnerName} 的台词
- 战役自己的旗标只用变量 55–99 或 140–199

剧情:
(几关;每关用原版哪一话的地图、谁加入我方、敌人是谁、胜利和失败条件;哪里出选项、分几个结局)

做法:
1. 先给我关卡表和每关的设计,我确认后再写文件
2. 写完先编译整个战役检查,有错就改
3. 如果能用 MCP 连上我的游戏,每关单独加载试一遍,打到胜利再截图
4. 用 tools/mods/pack.py 打包,告诉我生成的文件在哪、怎么安装

几点经验:

  • **大纲越具体越好。**写到「第 2 关用原版第 5 话的地图,アムロ 和 カミーユ 出击,敌人 6 台,第 3 回合增援,全灭敌人胜利」这种程度。让 AI 自己挑地图和单位,编号很容易出错。
  • **一定要过目它挑的台词。**拼台词最容易出问题:借来的句子前后接不上,或者提到了你的剧情里没有的人和事。
  • **一关一关验证。**单关能进、能打赢、结束事件能接到下一关,再串起来玩一遍。

下面是给人看的完整说明,也是 AI 读的那份。

文件结构

my-campaign/
  mod.json                 包的信息
  campaign.json            关卡表、开局、标题
  stages/<关>.json         每一关,迷你关卡格式
  stages/<关>.meta.json    可选:本关情报页的内容
  status.json              可选:本关情报页的完成状态规则

mod.json 的写法见 MOD 包;game 写 ">=0.5.1"。打包时 campaign.json 和 stages/ 会被编译成包里的 campaign/campaign.json,源文件不进包。本关情报页的两个可选文件照示例战役里的抄。

campaign.json

{
  "schema": "srw64.campaign.v1",
  "id": "yourname.my-campaign",
  "name": {"zh-Hans": "我的战役", "en": "My Campaign", "ja": "マイキャンペーン"},
  "description": {"zh-Hans": "一句话简介。", "en": "One line about it.", "ja": "ひとことで紹介。"},
  "start": "first",
  "stages": {
    "first":  {"scene": 1, "file": "stages/first.json",
               "title": {"zh-Hans": "启程", "en": "Setting Out", "ja": "旅立ち"}},
    "second": {"scene": 2, "file": "stages/second.json",
               "title": {"zh-Hans": "岔路", "en": "Crossroads", "ja": "分かれ道"}}
  }
}
字段 说明
id 必须和 mod.json 的 id 一样。它也是战役存档文件夹的名字,发布后不要再改
name、description 追加剧本页上显示的名字和简介,可以是一个字符串,也可以按语言分别写(zh-Hans、zh-Hant、en、ja,以及语言包的语言)
start 第一关是 stages 里的哪一个
stages 每一关:scene 借用的场景号(见下),file 关卡文件,title 标题,显示在标题卡、场间和存档列表上。标题里不要写「第几话」:场间和存档列表会按已通关的关数自己在前面加上「第N话」

借场景号

游戏按「场景号」记录进度,战役的每一关都要借一个原版的场景号,游戏载入那个场景时换成你的关卡。存档里记的就是这个号,所以:

  • 每关借不同的号,范围 0–142;
  • 不能借 109–122(リンク 关卡)和 38、48、68、73、79、81、83、86、88、93、95、96、104、132(这些场景的场间菜单只有两项);
  • 关卡文件里自己写的 slot 不起作用,以 scene 为准。

借哪个号和用哪张地图无关,地图由关卡文件的 map 决定。

关与关怎么连

和原版一样,写在每一关的结束事件(类型 14)里:3D4B <下一关借的场景号>。分支就是在条件块里放不同的 3D4B:

{"name": "ending", "type": 14, "header": [0, 0, 0, 0], "commands": [
  {"op": "3DD0"},
  {"op": "3D3E", "args": [18401]},
  {"op": "3D44", "args": [0, 2, 18402]},
  {"op": "3E10"}, {"op": "3D47"}, {"op": "3D4B", "args": [3]}, {"op": "3E1D"},
  {"op": "3E11"}, {"op": "3D47"}, {"op": "3D4B", "args": [4]}, {"op": "3E1D"}
]}

3D44 0, 项数, 文本号 显示选项,3E10/3E11/3E12 分别是选了第 1/2/3 项,3E1D 结束条件块。也可以先用 3E13 变量, 值 记下选择,到后面的关里再用 3E03 判断。

最后一关的结束事件用 3D71 进入结局,结局播完回到标题。3D71 只能放在结束事件里,不要在战场上执行。

编译器会检查:每个 3D4B 都要指向本战役里某一关借的场景号(500 除外),start 要存在,场景号不能重复也不能借不允许的号。

每一关要有什么

  • 开场事件(类型 12):可以先在世界地图上演对白,然后 3D4D 切到战场,3D65 设定显示的胜败条件,3D45 组号 让单位登场,最后 3D48 关掉对白窗口,交给玩家。
  • 胜利:例如类型 7(某一方剩余单位 ≤ 某数)的事件里执行 3D4A。
  • 失败:3D4C 是 GAME OVER,玩家可以重试这一关。不要在开场事件中途执行,那时还没有重试用的快照。
  • 结束事件(类型 14):3D4A 胜利结算之后执行,在这里写过关对白和 3D4B。

每条指令、事件类型和出击记录字段见关卡脚本指令参考;仓库 config/recomp/mini-stages/ 有六十多个关卡可以参考。

开局与要避开的

  • 开局什么都没有:名册是空的,主角和搭档没有名字,也没有路线。我方用 3D5A 人物, 0, 机体, 500 登记(机体写 999 表示只登记驾驶员),或者在关卡里放我方的出击记录、用 3D45 登场,登场的我方单位会永久入队。资金用 3D5B n 加 n×1000。
  • 部队、资金、改造和变量会带到下一关,存档里也有。
  • 不用主角路线:每个事件以 3DD0 开头,不用 3DD1–3DD8;不要选带 {HeroName}、{PartnerName} 的台词,也不要用原创主角自己说的台词。
  • 剧情变量只有 0–3 四个值。每关开始时 100–114、128–139 会被置 3、54 置 1,0–54 原版剧本一直在读,战役自己的旗标放在 55–99 和 140–199。
  • 已知会崩溃的写法:3D49 时角色不在地图上;对还在地图上的单位执行 3D5A …, 4000(先 3D46 让它退场)。
  • 战役里的 リンク 菜单是禁用的。

找台词、地图和单位

台词在仓库的 content/dialogue/<语言>/story/scene-NNNN.txt(语言是 zh-Hans、zh-Hant、en,NNNN 是场景号):

@17464 万丈 · 万丈
> 「世のため人のため、ムゲゾルバドス
>  帝国の野望を打ち砕く
“为了世间,为了人们,粉碎穆格·佐尔巴多斯帝国野心的
---
……

@ 后面的数字就是文本号,填进对白指令 3D3E(3D3F–3D43 是其他显示方式),一条记录可以有好几页(--- 分页),整条一起显示。> 开头的是日文原文,下面是译文,# 开头的是注释。选项也是一条记录,每项一行 *,3D44 的项数要和行数一样。用全文搜索找意思合适的句子最快,比如在 zh-Hans/story 里搜「撤退」。

地图和单位在 make recomp-data 生成的 assets/original-data/records/ 里,每行一条 JSON:

文件 用途
scenarios.jsonl 每个场景(每一话)的标题
stage_maps.jsonl 场景号 → 地图号
stage_auxiliary.jsonl 某一话完整的出击记录,填进 deployments_from
stage_deployments.jsonl 单条出击记录,做 template 底板
actors.jsonl、units.jsonl 人物号、机体号

想用「原版第几话的那张图和那批敌人」,先在 scenarios 找到那一话的场景号,再从 stage_maps 和 stage_auxiliary 取地图号和出击记录。

编译、试玩、打包

检查整个战役(会列出每关借的场景号和它的 3D4B 通往哪里):

python3 tools/recomp/script_lab/mini_stage.py campaign my-campaign/campaign.json --out /tmp/check.json

单独试一关:在关卡文件里临时写上 "slot": <它借的场景号>,按迷你关卡的做法编译、用 srw64_mini_stage_load 加载。单关试玩是在本篇里进的,结束事件的 3D4B 会接到原版剧情,打到过关就停。关卡可能会存档,最好用 --user-dir 另开一套用户目录。

打包:

python3 tools/mods/pack.py my-campaign -o build/mods

生成 build/mods/<id>-<版本>.srw64mod,并自动用 tools/mods/validate.py 检查。

安装与游玩

  1. 把 .srw64mod 拖进游戏窗口安装(或放进 MOD 文件夹,见 MOD 包)。
  2. 在标题画面打开「MOD」,切到「追加剧本」页,点战役那一行的「进入」。
  3. 标题画面中间出现「开始战役」和战役名,从这里开始;之后在标题读档就是读这个战役的存档。
  4. 回本篇:同一页的「返回本篇」。切换只能在标题画面进行。

战役的存档在用户目录的 campaigns/<id>/saves/,和本篇互不影响。

分享

template、deployments_from、copy_from 会把你 ROM 里的原版数据复制进包里,这样的包只适合自己玩。想公开分享,出击记录要逐个字段自己写(group、x、y、actor、unit、faction、level_offset、upgrade 等),事件也全部自己写;文本号、地图号、人物号、机体号只是编号,可以用。其余照 MOD 包的版权要求。