ゲーム状態の設計
面白いワールドは、たいてい何かを記録しています。Battle Royale は 40 人の生徒と、そのうち誰が生き残っているかを記録しています。Sakura Season は 3 本の恋愛ルートを別々に記録しています。Wandering Diary は仲間の態度、持ち物、現在地の状態をまとめて記録しています。
変数の型、ビヘイビアルール、精密トラッキングの基本は 変数 を見てください。
何を記録するかを決める
何かを追加する前に、まず考えてみてください。プレイヤーが「本物だ」と感じるには、何が必要か?
サバイバルなら資源です。体力、空腹、弾薬。プレイヤーに足りなさを感じてもらう必要があります。恋愛ものなら関係の深さです。自分の選択が何かに積み上がっていると感じてもらう必要があります。ミステリーなら、何を知っているかのフラグです。捜査が絞り込まれていく感覚が必要です。
何でも変数にする必要はありません。物語の細かいところは AI が自分でうまく書きます。天気がしくみとして意味を持たないなら、current_weather の変数はいりません。記録するのは 選択と結果を動かすもの です。
目安はこうです。次に AI が書く内容に影響させたい値なら、変数にする。ただの味付けなら、AI のアドリブに任せる。
変数の一生
変数はキャンバスで 定義 します(型、初期値、範囲)。プレイヤーが新しいセッションを始めると、初期値で 初期化 されます。プレイ中に値が変わる道はいくつかあります。返信のたびに動く 精密トラッキング のアシスタント、AI の括弧の ディレクティブ(精密トラッキングがオフの変数の場合)、ビヘイビア、プレイヤー画面のボタン、ほかの変数から計算し直す 計算式 です。ゲームの状態全体は、毎ターンの終わりに 保存 されます。
もうプレイされているワールドに新しい変数を追加すると、既存のセーブは次に読み込んだときに自動で初期値が入ります。変数を削除すると、その値は何も言わずに取り除かれます。誰のセーブも壊さずに、変数の設計を何度でも作り直せます。
型を選ぶ
4 種類の型は 変数 で説明しています。キャンバスでの名前は数値、文字、スイッチ、リスト/表です(カードのデータ上は number、string、boolean、json)。設計で考えるのは どれをいつ使うか です。どの型を選ぶかで、AI とワールドのやりとりの仕方が変わります。
数値 は、値が少しずつ変わるとき、しきい値でイベントを起こしたいとき、変化の大きさに意味があるときに使います。数値は最小・最大をエンジンが守ってくれるので、「体力をゼロ未満にしないで」とプロンプトに書いて場所を使う必要はありません。
文字 は、値が量ではなくラベルのときに使います。現在地、気分、物語の段階など。決まった候補しかない場合(段階、気分など)は 選択肢 を設定すると、精密トラッキングがその中からだけ選ぶようになります。2 つの状態しかない値(施錠/解錠)には文字ではなくスイッチを使ってください。
スイッチ は、何かが起きたか起きていないかを表すときに使います。いちばん単純な型で、AI にとってもいちばん扱いやすく、条件ロアやビヘイビアの条件にぴったりです。
リスト/表 は、ひとつの変数に構造のあるデータを持たせたいときに使います。アイテムごとに情報を持つ持ち物、いくつもの関係を持つ勢力の一覧、進み具合が入れ子になったクエストの記録など。単純な値には使わないでください。[stats.health: -10] より [health: -10] のほうが確実です。この型では精密トラッキングが使えないので、AI がディレクティブで変えます。
ビヘイビアルールの書き方:4 つの質問
同じビヘイビアルールを、物語の AI が読みます。精密トラッキングがオンなら、トラッキング用のアシスタントが読みます。どちらの場合も、よいビヘイビアルールは 4 つの質問に答えています。
1. 値は何を意味するか? AI に凡例を渡します。数値なら、それぞれの範囲が物語の中でどんな状態かを書きます。文字なら、取りうる状態を並べます。スイッチなら、オンとオフが物語で何を意味するかを書きます。
2. 何で変わるか? 状況を具体的に書きます。関係の変数なら「やさしくすると好感度が上がる」で十分です。HP なら「物理ダメージで体力が減る」。例を多く挙げるほど、AI の動きがぶれなくなります。
3. どれだけ変わるか? ここに手をかけていないクリエイターがいちばん多いところです。変化量の範囲を書いてください。小さな出来事なら小さく、大きな出来事なら大きく変わるように。これがないと、AI は大げさに反応する(何をしても好感度 +20)か、反応が薄すぎる(死にかけても体力が 2 減るだけ)かのどちらかに寄りがちです。
4. 上限は? 1 ターンで変わる量に上限をつけます。没入感を壊すような急な振れを防げます。精密トラッキングがオンなら、1ターンの最大増加 と 1ターンの最大減少 を設定すれば、エンジンがそれを守ります。オフなら、ビヘイビアルールに「1 ターンで 15 を超えて変化させない」のように上限を書いておきます。
TIP
ふつうは 2〜4 文で足ります。ビヘイビアルールが短い段落より長くなったら、削りましょう。AI に渡すのは考え方と範囲で、ルールブックはいりません。
知っておくと役立つこと
delete 操作 は、JSON オブジェクトからキーを、JSON 配列から要素を取り除きます。ふつうの括弧の書き方で使えます。[npcs: delete "aria"](オブジェクトのキーは引用符付きの文字列)や [inventory: delete 0](配列の位置は数字)です。落とし穴がひとつあって、delete のあとには JSON の形をした値が必要です。[var: delete] のように何も付けないと暗黙の set として扱われ、変数に "delete" という文字列がそのまま書き込まれます。まず望んだ結果にはなりません。まとめて消したいときや、配列の要素を id で消したいときは、<UpdateVariable> の JSON Patch ブロック(AI ディレクティブとマクロ を参照)でも書けます。
公開ワールドで使われているパターン
関係の記録
Sakura Season は、ヒロインごとに別々の数値の変数を使い、ビヘイビアルールで変化量の範囲を決めています。いちばん単純なやり方で、キャラクターが 2〜5 人ならこれでうまくいきます。
もうひとつのやり方は、すべての関係をひとつの JSON オブジェクトに入れることです。
{
"aria": { "trust": 50, "romance": 0, "met": true },
"kael": { "trust": 30, "romance": 0, "met": false }
}キャラクターが多いときはこちらのほうがすっきりします。AI はドットパス([relationships.aria.trust: +10])で誰の値でも更新でき、新しいキャラクターはキーを merge で足せば増やせます。ただ、個別の数値の変数のほうが AI にとってわかりやすく、間違えにくく、精密トラッキングも使えます。
キャラクターが 2〜5 人で、確実さをいちばんに考えるなら 個別の変数。キャラクターが多い、あるいはあとから追加していく必要があるなら JSON オブジェクト を選びましょう。
持ち物のしくみ
いちばん単純な持ち物は、AI が append で書き足していく文字の変数です。Battle Royale は死亡者の名簿をこの方法で記録しています。アイテムごとに情報を持たせる本格的な持ち物なら、JSON 配列を使います。
[
{"id": "torch", "name": "Torch", "qty": 1},
{"id": "bread", "name": "Bread", "qty": 2}
]アイテムを足すには push、取り除くには位置を指定した delete を使います。どちらを使うかは、ビヘイビアルールで AI に伝えておきます。
アイテムを追加するときは、アイテムのオブジェクトをまるごと push する。取り除くときは、配列の位置を指定して delete する。持ち物の上限は 10 個。上限に達したら、先に何かを捨てる。
現在地と場面の状態
location という文字の変数(初期値は "starting village")があれば、たいてい足ります。プレイヤーが移動すると現在地が変わり(AI が [location: set "dark forest"] と書くか、精密トラッキングが選択肢から選ぶ)、location を条件にした条件ロアが、その場所に合った描写を AI に渡します。
場面のいくつもの面を記録する、もっと複雑なワールドなら JSON オブジェクトを使います。
{
"area": "castle",
"room": "throne-room",
"time": "night",
"alert-level": "high"
}AI は一部だけを更新できます。たとえば見張りをやり過ごしたあとに [scene.alert-level: set "low"] のように書きます。
9 つの操作すべて、省略記法の落とし穴、JSON 変数のドットパスの書き方など、ディレクティブの書き方の全体は AI ディレクティブとマクロ にまとめています。
よくあるミス
記録しすぎる。 何でも変数にする必要はありません。裏に数字がなくても AI が物語として扱えるなら、変数はいりません。変数が増えるほど、AI が読んで矛盾なく保たなければならない状態が増えます。よくできたワールドの多くは 5〜15 個を記録していて、50 個も必要なワールドはめったにありません。
ビヘイビアルールがあいまい。 「体力を記録する」では AI に何も伝わりません。「軽い打撃で 5〜15 減る、重い打撃で 15〜25 減る、0 なら死の場面」と書けば、必要なことはすべて伝わります。変数がちゃんと動くか無視されるかは、ビヘイビアルールで決まります。
単純な型で済むのに JSON を使う。 数字がひとつ欲しいだけなら、数値の変数を使いましょう。[health: -10] のほうが [stats.health: -10] より単純で確実です。JSON は本当に構造のあるデータのために取っておきます。
数値に最小・最大を付け忘れる。 範囲がないと、AI が体力を -47 にしたり、金貨を 999,999 にしたりしかねません。数値の変数にはすべて 範囲 を設定しておきましょう。エンジンが自動で範囲内に収めます。
変化量を試していない。 10 ターンほど遊んでみて、数字の動きが自然か確かめましょう。3 回のやりとりで好感度が 15 から 80 に跳ねたら、変化量の範囲が大きすぎます。20 ターンたってもほとんど動かないなら、狭すぎます。プレイテスト の このターン → それぞれの数値 で、どの値がなぜ動いたか、なぜ動かなかったかを確認できます。
AI にとって扱いにくい ID。 health、player-gold、aria-trust のように、短くて読みやすい ID を使いましょう(変数の ID は、その変数の設定の 詳細設定 にあります)。スペースや特殊文字、組み込みマクロとぶつかる名前(user、char、time、date)は避けてください。値を {{マクロ}} としてロアに書き込みたいなら、ハイフンではなくアンダースコアを使います(player_gold)。ハイフンを含む ID は、新しい変数に自動で付くランダムな ID も含めて、マクロとしては動きません。
関連ページ
- AI ディレクティブとマクロ — ディレクティブの書き方、9 つの操作、ドットパス、省略記法の落とし穴
- 優れたエントリの書き方 — 変数に反応する条件ロア
- ビヘイビアと自動化 — 変数がしきい値を越えたときに発動するビヘイビア
変数のスキーマの全体 → World Spec:変数
