ルールセットのカタログ

このページでは、シートエディターが選択画面に表示する用意済みのエントリー(呪文、装備、クラス特性)をルールセットに同梱する方法を説明します。これにより、プレイヤーが長いリストを手で入力せずに済みます。カタログのヘッダー、エントリー、ルールセットが保持する値、シートコマンド、使用コマンドを扱います。ルールセットの作者向けのページです。始める前に、Game Modeのルールセットを作成するを読んでください。

長い呪文リストや装備表を行ごとに入力すると時間がかかります。カタログはルールセットに同梱する、名前付きの既製項目集です。供給先の各リストでシート編集画面が選択肢として表示し、1つ選ぶと行を埋めます。

カタログは任意で、最大12個です。Engineはそれぞれが何についてのカタログか知りません。ID、列、フィルター、用語はすべてファイルから来ます。

ヘッダー

ヘッダーはファイルのトップレベルで、gmと並ぶcatalogsに入れます。

"catalogs": [
  {
    "id": "knacks",
    "label": "Knacks",
    "feeds": ["knacks", "tricks"],
    "filters": [
      { "id": "grit", "label": "Grit cost", "type": "number" },
      { "id": "road", "label": "Road", "type": "text" },
      { "id": "callings", "label": "Calling", "type": "tags", "startFrom": { "field": "calling" } }
    ],
    "units": { "distance": { "label": "paces", "perCell": 2 } },
    "entries": []
  }
]

項目

{
  "id": "road-sense",
  "label": "Road Sense",
  "summary": "You read a road the way other people read a face.",
  "filters": { "grit": 0, "road": "Ash Flats", "callings": ["Scout", "Courier"] },
  "rows": [
    {
      "list": "knacks",
      "values": { "name": "Road Sense", "notes": "Sneak to notice where a road turns bad." }
    }
  ]
}

各値を対象リストの列と照合するため、列名の誤字や列の範囲外の値は、出所の項目とともに報告します。ルールセット内に書いた項目はセット読込時、インポートファイルならインポート時に検査します。パッケージの独立したカタログファイルは選択画面が最初に要求した時に検査し、誤りがあれば項目の代わりに理由を表示します。

一つのエントリーから複数のリストへ

回数制限のある特性は、特性本体と使用回数カウンターの2行をシートに持ちます。それでも選ぶのは1項目です。

{
  "id": "last-ember",
  "label": "Last Ember",
  "rows": [
    {
      "list": "knacks",
      "values": { "name": "Last Ember", "notes": "Spend 1 Grit to give a downed friend 3 Grit back." }
    },
    { "list": "tricks", "values": { "name": "Last Ember", "uses": 1, "recharge": "camp" } }
  ]
}

ルールセットが更新を保つ値

選んだ行の数値はプレイヤーのものになります。ただし、能力値と等しい使用回数や、レベルに応じて増えるクラスリソースなど、キャラクターに連動する最大値は例外にする価値があります。行はscaledマップに自身の数値列を最大4つ指定でき、シート編集画面がその値を更新します。

{
  "list": "tricks",
  "values": { "name": "Last Ember", "uses": 1, "recharge": "camp" },
  "scaled": { "uses": { "from": { "abilityScore": "heart" } } }
}

値は編集時に計算し、読取時には計算しません。保存行は常に記述どおりの数値です。格納先列のminとmaxに制限し、整数列では切り捨てます。上の例ではHeart 3なら3回、Heartが0以下なら0回です。行は使用回数0のまま残り、最大0のカウンターはプールではないため、プレイ中に消費できるものはありません。

パッケージ形式の連動列はCapability API 1.23です。コミュニティのインポートは読み取るEngineが検証するため、別の指定は不要です。

選んだ行はコピー

選んだ各行はシートにコピーし、追加キー_catalogへ<catalog id>/<entry id>を入れます。列IDは必ず英字で始まるため、このキーが自作の列と衝突することはありません。

コピーはキャラクターに属します。プレイヤーは後からどの内容でも編集でき、ルールセットが未インストールでもシートは動作し、新版の公開が誰かのキャラクターを書き換えることもありません。選択画面はこの印から取得済みの項目を示し、下記のRefreshもこれを読みます。

ルールセットから更新する

選んだ行は印を保つため、シート編集画面はルールセットの新しい文章と保存行との差を通知できます。リストの下に更新のある行数が表示され、Review(確認)でシートの内容とルールセットの内容を並べ、各行のチェック欄を表示します。Update selected(選択項目を更新)を押すまでは何も書かず、チェックした行の差のある列だけを更新します。印も含め、ほかの内容は維持されます。

比較範囲は意図的に狭くしています。

したがって、表現や名前の変更は、プレイヤーが承認すれば取得済みのキャラクターにも反映できます。数値の意味の変更は反映できず、行を取得した後の数値列はプレイヤーのものです。

シートコマンド: 永続的な成長

ルールセットはsheet.advancementで、永続的なビルドの変更を受け入れられます。

"advancement": {
  "fields": ["xp", "level", "humanity", "discipline"],
  "abilities": true,
  "skills": true,
  "saves": true,
  "text": "Award XP at the end of a session; change other values only when earned."
}

シートが数値かテキスト(textまたはlongtext)として宣言するフィールドIDだけを、最大24個含めてください。真偽値は、それぞれすべての能力値、スキル、セーヴを許可します。省略するかfalseなら許可しません。空の許可、不明なフィールド、未対応のフィールド型、不明なキーはインポート時に拒否されます。textは、プロンプトに安全な最大400文字の任意のガイダンスです。advancementがなければ、既存のコマンドは以前と同じく動作し、すべてのadvance要求は拒否されます。

[sheet: op="advance" field="xp" by="250" who="party"]
[sheet: op="advance" field="xp" to="1200"]
[sheet: op="advance" field="humanity" by="-1"]
[sheet: op="advance" field="discipline" to="Auspex"]
[sheet: op="advance" ability="str" by="1"]
[sheet: op="advance" ability="str" to="16"]
[sheet: op="advance" skill="stealth" tier="expert"]
[sheet: op="advance" save="will" tier="trained"]

対象をちょうど1つ指定してください。フィールドと能力値はbyかtoのちょうど1つを取り、テキストはtoだけを取ります。名前と段階は、大文字と小文字を区別せずにIDかラベルに一致させます。スキルとセーヴはresolution.proficiencyTiersで宣言した任意の段階を受け付けます。数値フィールドはinteger、min、maxに従い、能力値は整数の範囲に従い、テキストはmaxLengthに従います。無効な値は黙って範囲に収めず、範囲を示すbad-amountの理由とともに拒否されます。成長が無効な場合、許可されていない対象、不明な名前、不明な段階も拒否されます。書き換えたタグはresultと、nowに新しい値を持ちます。プレイヤーにはwhoを省略し、曖昧さのないすべてのパーティーカードにはwho="party"を使います。一部が拒否された場合は、どのカードが成長できなかったかを示します。

Engineは、プレイヤーの編集と同じメタデータの保存先を通じてゲームのカードにビルドを保存し、シートのバージョンを保ち、新しいビルドから派生値を再計算します。ライブラリーのカードは変わりません。ライブのコマンドと同じく、別のスワイプや再生成した返信は、置き換わる返信の変更より前から始まります。各返信は、成長のない返信も含め、終了時のビルドを記録します。スワイプを選ぶとそのスナップショットを復元し、最新の返信を削除すると直前のスナップショットが現れます。古い返信を削除しても、後のスナップショットはその後の返信が取り除かれるまで有効なままです。続きの生成は同じ返信のスナップショットを更新します。取り消しは、記録された結果とまだ一致する値だけを変えるため、後のプレイヤーの編集は残り、無関係な編集があってもXPの付与を取り消せます。

useコマンド: 指定した価格をGame Masterに支払わせる

GMは描写しながら[sheet: ...]でシートを更新します。spend、restore(healも同義)、damage、temp、track、condition、note、restです。カタログを持つルールセットでは、さらに1つ加わります。

[sheet: who="Mira" op="use" name="Fireball"]
[sheet: who="Mira" op="use" name="Fireball" pool="3rd-level slots"]

op="cast"はop="use"、spell=はname=と同じ意味です。形式に「呪文」という概念を組み込まなくても、GMが使いやすい言葉で動作します。

名前は、キャラクターシートのカタログ由来の行に、大小文字を区別せず照合します。行はGMに見せた名前(そのリストのsheetSummary名前列、次にpools.nameColumn、最後に最初のテキスト列)と、元項目のlabelの両方に応じるため、改名しても使えます。該当しない名前と、異なる2項目に該当する名前はどちらも拒否します。

消費するものは次のとおりです。

pool=は上位発動です。同じ単一の価格を、同グループの別プールから払います。コストが厳密に1要素で、指定プールがそのグループに属するか、そのグループの支払いを引き受ける場合だけ受け付けます。それ以外は解釈し直さず拒否します。

ほかのグループの支払いを引き受けるプール(Capability API 1.171)。ライブのプールのpaysは、そのコストも支払えるほかのグループを最大4つ指定します。支払いは自身の段階(そのlevelか、自身のグループ内の位置)で行い、自身より高い段階のコストは支払いません。5eのパクト・スロットは、マルチクラスのウォーロックと同じく、呪文スロットでコストを定めた呪文を支払えます。

{
  "id": "pact_slots",
  "label": "Pact Slots",
  "group": "pact",
  "max": { "field": "pact_slot_count" },
  "level": { "field": "pact_slot_level" },
  "pays": ["slots"]
}

戦闘は、このようなプールを、呪文自身のグループの上位プールと並べて提示し、そこからの支払いは、その段階が呪文の段階を上回る分だけ呪文を段階的に強化します。3レベルのパクト・スロットは、3レベルのスロットと同じくMagic Missileを支払います。自身のプールが空の使用も、上位のプールかその支払いを引き受けるプールからだけ支払う形で提示されるため、1レベルのスロットがなくなった後は、1レベルの呪文を2レベルのスロットで発動できます。項目のmechanicsのtargetsPerCostStep(1.171、1~10)は、上位に支払った1段階ごとにその数の標的を加え、最大20です。Hold Personは"targetCount": 1, "targetsPerCostStep": 1です。

一括で成否を決めます。どれか1つでも払えなければ全コマンドを拒否し、何も変えずプレイヤーへ通知します。初級呪文や常時特性など、コストがまったくない項目は受け付け、何も変更しません。

インラインか独立ファイルか

小さなカタログはruleset.jsonのヘッダーのentries内に置きます。長いものは別ファイルに置き、ヘッダーは代わりにassetで指定します。厳密に片方だけが必要です。

{ "id": "knacks", "label": "Knacks", "feeds": ["knacks"], "asset": "catalogs/knacks.json" }

パスは常にcatalogs/<the catalog's id>.jsonです。ファイルの形は次のとおりです。

{ "schemaVersion": 1, "catalog": "knacks", "entries": [] }

独立したカタログファイルはパッケージで提供します。公式カタログを通じて公開するパッケージか、自分でインポートするルールセットのパッケージファイルです(ルールセットの共有を参照)。パッケージはcontributions.assets.pathsでruleset.jsonとともにファイルを宣言し、Capability API 1.21が必要です。クリーチャーのカタログはインラインでも別ファイルでもCapability API 1.27、アイテムのカタログにはCapability API 1.49が必要です。単一ファイルでインポートする、またはGitHubリポジトリーで共有するルールセットはカタログをインラインで持つため、ルールセットファイル全体の上限(512 KB)以内に収めます。短いエントリーなら数百件入ります。

上限はルールセットごとに12カタログ、どちらの形式も1カタログ2,000項目、独立カタログ1ファイル2 MBです。ruleset.jsonが256 KBを超えるか、1 MBを超えるカタログファイルを持つパッケージには、両方の上限を引き上げたCapability API 1.340が必要です。