追加シナリオは独立した小さなキャンペーンです。決めた順にステージをつなぎ、ステージの間はいつもどおりインターミッション(改造・乗り換え・セーブ)に入り、選択肢でエンディングを分けることもできます。MOD パッケージに入れて配り、タイトル画面の「MOD → 追加シナリオ」から始めます。セーブは本編と完全に別です。
各ステージはミニステージそのものです。元のマップを選び、ユニットを置き、オープニング・勝利・終了のイベントスクリプトを書きます。キャンペーンはその上にステージ表を足して、ステージ同士をつなぐだけです。
バージョン 0.5.1 以降が必要です。
今できること
| できる | まだできない |
|---|---|
| 複数ステージの連結、選択肢による分岐、複数のエンディング | 新しい台詞(会話は元の台詞の引用だけ) |
| 各ステージのマップ、味方の加入、敵の配置、増援、勝敗条件 | 新しいマップ(元のマップだけ) |
| キャンペーン名・説明・各ステージのタイトルを言語ごとに | 新キャラクター、新しい顔グラフィック、新しい戦闘台詞 |
| 資金、シナリオ変数、ステージをまたいで引き継ぐ部隊 |
会話と選択肢は元の台詞を番号で引用します。ゲームはその台詞本来の話者と顔グラフィックを、プレイヤーが選んだ言語で表示します。シナリオを書くときは、言いたいことに合う台詞を元の中から選んでつなぎます。
必要なもの
- ソースリポジトリと Python 3(ステージのコンパイルとパッケージ作成に使います)。
- 自分の ROM。リポジトリに
rom.z64として置き、make recomp-dataを一度実行します。キャラクター・ユニット・マップの番号を調べるときと、元の出撃レコードやイベントを下敷きにするときに必要です。 - AI に書きながらゲームで試させたい場合は、AI エージェントでゲームを操作する(MCP)のとおりにゲームとつなぎます。
AI に任せる
Web を読めてファイルを書ける AI エージェント(Claude Code、Codex など)なら、説明どおりにキャンペーンを丸ごと作れます。リポジトリのフォルダーで起動し、下の文をコピーして、「シナリオ」の部分を自分のあらすじに書き換えてください。
Marchwind 64(『スーパーロボット大戦64』の PC 向けリコンパイル版)の追加シナリオ MOD(オリジナルキャンペーン)を作り、そのままインストールできる .srw64mod ファイルにまとめてください。
まず次を読み、書式・ルール・番号をそのとおりに守ってください:
- https://srw64.dreamquest.club/ja/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 に任せると番号を間違えやすくなります。
- **選んだ台詞は必ず自分で読む。**台詞をつなぐところがいちばん失敗しやすく、前後がつながらなかったり、自分のシナリオにいない人物や出来事に触れていたりします。
- **1 ステージずつ確かめる。**単独で入れて、勝てて、終了イベントで次のステージにつながることを確かめてから、通しで遊びます。
ここから下は人向けの完全な説明で、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 にコンパイルされ、元のファイルはパッケージに入りません。ステージ情報の 2 ファイルはサンプルキャンペーンのものをまねてください。
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 |
追加シナリオページに出る名前と説明。文字列 1 つか、言語ごと(zh-Hans・zh-Hant・en・ja、言語パッケージの言語) |
start |
stages のどれが最初のステージか |
stages |
各ステージ:scene は借りるシナリオ番号(後述)、file はステージファイル、title はタイトルカード・インターミッション・セーブ一覧に出るタイトル。「第何話」はタイトルに入れないでください(インターミッションとセーブ一覧が、クリアした話数から「第N話」を自動で前に付けます) |
シナリオ番号を借りる
ゲームは進行を「シナリオ番号」で記録します。キャンペーンの各ステージは元のシナリオ番号を 1 つずつ借り、ゲームがそのシナリオを読み込むときに自分のステージに差し替わります。セーブにもこの番号が記録されるので:
- ステージごとに違う番号を、0〜142 から借ります。
- 109〜122(リンクステージ)と 38、48、68、73、79、81、83、86、88、93、95、96、104、132(インターミッションのメニューが 2 項目しかない)は借りられません。
- ステージファイルに書いた
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/ には参考になるステージが 60 以上あります。
始まりの状態と避けること
- 最初は何もありません:部隊は空で、主人公とパートナーには名前もルートもありません。味方は
3D5A キャラクター, 0, ユニット, 500で登録する(ユニット 999 はパイロットだけを登録)か、ステージに味方の出撃レコードを置いて3D45で登場させます。こうして登場した味方ユニットはそのまま加入します。資金は3D5B nで n×1000 増えます。 - 部隊・資金・改造・変数は次のステージに引き継がれ、セーブにも残ります。
- 主人公ルートは使わない:どのイベントも
3DD0で始め、3DD1〜3DD8 は使いません。{HeroName}・{PartnerName}を含む台詞や、オリジナル主人公本人の台詞は選ばないでください。 - シナリオ変数は 0〜3 の 4 値だけです。各ステージの開始時に 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 は表示方法違い)に入れます。1 つのエントリーは複数ページ(--- で区切り)でもよく、まとめて表示されます。> で始まる行が日本語の原文、その下が翻訳、# で始まる行はコメントです。選択肢も 1 つのエントリーで、項目ごとに * の行が 1 行あり、3D44 の項目数と一致させます。合う台詞を探すには全文検索がいちばん早く、たとえば zh-Hans/story で「撤退」を検索します。
マップとユニットは make recomp-data が作る assets/original-data/records/ にあり、1 行に 1 つの JSON です。
| ファイル | 用途 |
|---|---|
scenarios.jsonl |
各シナリオ(各話)のタイトル |
stage_maps.jsonl |
シナリオ番号 → マップ番号 |
stage_auxiliary.jsonl |
ある話の出撃レコード一式(deployments_from に) |
stage_deployments.jsonl |
出撃レコード 1 件ずつ(template の下敷きに) |
actors.jsonl・units.jsonl |
キャラクター番号・ユニット番号 |
「元の第 N 話のマップと敵」を使いたいときは、scenarios でその話のシナリオ番号を探し、stage_maps と stage_auxiliary からマップ番号と出撃レコードを取ります。
コンパイル・試遊・パッケージ作成
キャンペーン全体を確認します(各ステージが借りた番号と、その 3D4B の行き先が表示されます)。
python3 tools/recomp/script_lab/mini_stage.py campaign my-campaign/campaign.json --out /tmp/check.json
1 ステージだけ試すには、ステージファイルに一時的に "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 で自動的にチェックされます。
インストールと遊び方
.srw64modをゲームのウィンドウにドラッグしてインストールします(MOD フォルダーに入れても可。MOD パッケージ参照)。- タイトル画面で「MOD」を開き、「追加シナリオ」ページでキャンペーンの行の「プレイ」を押します。
- タイトル画面の中央に「キャンペーン開始」とキャンペーン名が出るので、そこから始めます。以後タイトルでのロードはこのキャンペーンのセーブになります。
- 本編に戻るには、同じページの「本編に戻る」。切り替えはタイトル画面でだけできます。
キャンペーンのセーブはユーザーディレクトリの campaigns/<id>/saves/ にあり、本編とは別です。
公開するとき
template・deployments_from・copy_from は ROM の元データをパッケージにコピーします。そうして作ったパッケージは自分で遊ぶためだけのものです。公開するなら、出撃レコードを項目ごとに自分で書き(group・x・y・actor・unit・faction・level_offset・upgrade など)、イベントもすべて自分で書いてください。テキスト・マップ・キャラクター・ユニットの番号はただの番号なので使えます。そのほかは MOD パッケージの著作権のとおりです。