ルールセットのシート

このページでは、ルールセットのキャラクターシートを設計します。能力値、スキル、フィールドとリスト、ライブステート、負傷トラック、ペナルティ、休息、Game Master向けの文章に加え、パーティーシートと進行クロックを扱います。ルールセットの作者向けのページです。始める前に、Game Modeのルールセットを作成するを読んでください。

シート

数値を読むものは値参照で指定します。これはconst、field、derived、abilityScore、abilityMod、abilityModFromField、skillMod、saveMod、listSum、livePool、liveTrack、itemStatのうちキーを厳密に1つだけ持つオブジェクトです。たとえば最大値に派生値を使うプールは"max": { "derived": "grit_max" }です。

未習熟時の判定。 キャラクターが習熟していない(段階が先頭の)スキルやセーヴは、ルールセットが別に定めない限り通常どおり振ります。別に定めるには、スキルやセーヴ、または所属するセクションにuntrainedを指定します(スキルやセーヴ自身の規則が優先します)。

"sections": [{ "id": "labour", "label": "Labour", "untrained": { "by": -1 } }],
"skills": [
  { "id": "dig", "label": "Dig", "ability": "sinew", "section": "labour", "untrained": "refuse" },
  { "id": "listen", "label": "Listen", "ability": "nerve", "untrained": "harder" }
]

能力値、スキル、セーヴのセクション指定と、あらゆる場所のuntrainedは、パッケージ形式のルールセットではCapability API 1.41です。

スキルやセーヴはcapを持てます。判定が到達できる最大値を示す値参照で、成長しても超えられない評価値や、判定を押さえ込むトラックを表します。GravewatchはSootheを、番人に残っているResolveで制限します("cap": { "livePool": "resolve" })。制限後の数値がシートに表示され、すべての判定が振る数値です。with=による入れ替えは制限前の数値で計算し、そのあと再び制限します。上限はスキルやセーヴの修正値を読めず、上限が読む派生値も、それより上で宣言した派生値も同様です。そのためシートは引き続き上から下へ1回で計算できます。Capability API 1.39です。

hideWhenは、別のフィールドの値によってフィールド、派生値、リスト、プール、普通のトラックを隠します。方法は厳密に3つのうち1つです。equalsは1つの値に一致する場合、notEqualsは1つの値に一致しない場合(フィールドがほかの値を持つときは常に隠れます。「この種類のキャラクター専用」を表す方法です)、inは値のリストに含まれる場合です。指定する値はすべてフィールドが持てる値でなければならず、そうでなければ規則は一致できません。値は1つずつ検査し、notEqualsとinでは数値フィールドの範囲とテキストフィールドの長さも検査します。規則はシートエディターが表示する値を読みます。未設定のフィールドは空白のシートの初期値、ルールセットが提供しなくなった列挙値はフィールドのデフォルトとして読みます。5eファイルはequalsで、呪文を使わないキャラクターの呪文スロットを隠します。Gravewatchは"hideWhen": { "field": "watch", "notEquals": "night" }で、夜番でないすべての番人のシートからランタンの油を除きます。レイヤーは、これらが比較する値を削除できません。負傷トラックは隠せません。シートの表示にかかわらず、ロールと戦闘が読むためです。notEqualsとinはCapability API 1.39です。

普通のトラックのmaxは数値の代わりに値参照にでき、キャラクターの評価値でトラックの長さを決められます。"max": { "field": "willpower_rating" }です。minとdefaultは数値のままです。名前付き段階を持つ負傷トラックのmaxは段階数と等しく、番号付きのマスのトラックの長さは自身のmaxです(後述の「名前付き段階の代わりに番号付きのマス」を参照)。alwaysShow: trueはデフォルト値でもGMのシートブロックにトラックを表示します。毎ターン重要な評価値のためのもので、これがなければデフォルト値のトラックは省略されます。0のままの死亡セーヴ3つは何も伝えないためです。この3つは、パッケージ形式のルールセットではCapability API 1.37です。

ライブステート: 形態、構え、明かり

列挙型フィールドはキャラクター作成時に選んだらそのままで、状態はオンかオフしかありません。ライブステートは、プレイ中に変わる、決まった集合の中の1つの値です。変身する者の形態、戦闘の構え、ランタンの明るさなどです。

"live": {
  "states": [
    {
      "id": "stance",
      "label": "Stance",
      "values": ["guarded", "steady", "reckless"],
      "valueLabels": { "guarded": "Guarded", "steady": "Steady", "reckless": "Reckless" },
      "default": "steady"
    }
  ]
}

連動する数値。 "op": "enumTable"の派生値は、列挙型フィールドやライブステートの各値に対応する数値を返します。

{
  "id": "stance_brawn",
  "label": "Stance on Brawn",
  "op": "enumTable",
  "from": { "liveState": "stance" },
  "table": { "guarded": -1, "reckless": 2 },
  "default": 0
}

ライブステート、enumTable、stateを指定する休息の処理は、パッケージ形式のルールセットではCapability API 1.42です。

負傷トラック: 数値でなくトラックとしての体力

HPを数えないシステムも多くあります。前より悪い段階のマスを縦に並べ、負傷時に印を付けます。live.tracks項目へkindsと、名前付きのlevelsか番号付きのboxes(後述)のどちらかを与えると、範囲上の数値からこの方式へ変わります。

システムに必要なのはどちらでしょうか。 プールは受けたダメージ量、トラックは各ダメージの量と種類を記録します。打撃、致死、加重といった種類があり、加重は治りにくい、吸収できない、最終的に死に至らせるなど、命中後も種類が重要なら、ロール後もそれを保持する場所が必要です。種類を保持できるのは印だけです。ポイントのプールは引かれた後は小さな数値でしかなく、どのポイントがどの種類だったかシートは記憶しません。体力がプールのルールセットでcombat.damageKindsを黙って無視せず拒否するのはそのためです。プールにもdamageTypesは使え、敵が抵抗や完全耐性を持つこともできます。それは負傷後の種類ではなく、1撃のどれだけが通るかに関する問題だからです。

{
  "id": "harm",
  "label": "Harm",
  "min": 0,
  "max": 4,
  "levels": [
    { "label": "Scuffed", "penalty": 0 },
    { "label": "Winded", "penalty": -1 },
    { "label": "Bleeding", "penalty": -3 },
    { "label": "Down", "penalty": -99 }
  ],
  "kinds": [
    { "id": "knock", "label": "K", "severity": 0 },
    { "id": "tear", "label": "T", "severity": 1 }
  ]
}

曖昧な理解では違うトラックになるため、規則を正確に示します。

プレイ中に印を付ける方法。 GMは[sheet: op="damage" track="harm" kind="knock" amount="1"]と書き、負のamountで回復します。マス単位で埋めるトラックでは、命中するマスを示すbox="3"を加えます。pool=を指定する従来のdamageは変わりません。単なる数値では新しい印の種類を示せないため、負傷トラックの通常のtrackコマンドは拒否されます。こうしたシステムが想定するように、プレイヤーもシートで手動で印を付けたり消したりできます。

戦闘でも印を付けられます。 combat.healthをプールでなくトラックに向けると、命中した1撃はcombat.damageKinds.marksで指定したマス数に、そのブロックがダメージ種別から対応付ける種類の印を付けます。トラックが満杯なら倒れ、死亡ルールがその状態を読みます。マス単位で埋めるトラックでは、per-pointのダメージは当たるマスを指定し、per-blowは最初のマスを狙います。どのマスにも入らない打撃はキャラクターを倒します。そのようなトラックを使うシステムでは、それが戦闘不能を意味するためです。回復は種類を問わず最も軽い印を1つ消します。一時ポイントを置くバッファーはないため、一時ポイントは拒否します。Engineはトラックを残り段階数として読むため、戦闘のほかの部分、倒れること、蘇生、ログ、要約は変わりません。

休息で負傷トラックを治せます。 "to"でトラックを指定する回復処理は、超過分も含め、印を指定個数まで減らします。負の"by"なら超過分から先に指定個数を消すため、"by": { "const": -2 }は2つ消します。kindも指定する処理はその種類の印だけを消します。Gravewatchの「Catch your breath」は{ "track": "harm", "kind": "knock", "to": "min" }で、knockの印を治し、tearの印は残します。休息は負傷を記録しないため、印を増やすことになる処理は何もしません。正の"by"もこれに含まれ、何も通知せずに省略されるので、マイナス記号を書いてください。

名前付き段階の代わりに番号付きのマス

トラックの長さがキャラクターのタフさに応じる場合は、levelsの代わりにboxesを与えます。マスの数は自身のmaxと同じで、シートが計算する値(ライブ状態を読むものは不可)を指定でき、最大64です。

{
  "id": "strain",
  "label": "Strain",
  "min": 0,
  "max": { "derived": "strain_boxes" },
  "boxes": {
    "penalty": {
      "by": "remaining",
      "table": [
        [0, -1],
        [1, 0]
      ]
    }
  },
  "kinds": [{ "id": "strain", "label": "S", "severity": 0 }],
  "fill": "indexed",
  "onFull": "refuse"
}

マス単位の記入と、拒否するトラック

リストが加える段階

名前付き段階を持つトラックに"extra": { "list": "scars", "countColumn": "levels", "penaltyColumn": "penalty" }を指定すると、シート上のリストでキャラクターごとにトラックを延ばせます。各行は順に、そのペナルティで指定数(最大16)の段階を加えます。挿入位置は、ペナルティがそれと同等以上に良い最後の段階の後です。ペナルティが一致すればその段階の名前を、そうでなければペナルティの値を名前にします。Gravewatchの傷跡はこの仕組みです。シートが隠すリストは何も加えず、印のある段階の行を削除した場合、収まらなくなった印は超過分として保持します。シートを編集しても負傷はなくなりません。

boxes、fill、onFull、extra、休息の処理のkindは、パッケージ形式のルールセットではCapability API 1.40です。

ロールへのペナルティ

resolution.penaltyFromは、このルールセットのすべての判定へペナルティを適用する負傷トラックを指定します。推測でなく明示宣言なので、省略したルールセットは負傷トラック導入前と同じように振ります。

ペナルティの作用は、シートの数値と同じく判定方式が決めます。

指定先は負傷トラックである必要があります。普通のトラックにはペナルティがなく、指定するとインポート時に拒否されます。結果に適用したペナルティが表示されるため、ダイスが減った理由を確認できます。GMのシートブロックにも段階とペナルティが表示されます。

シート由来の修正値

シートの数値には、関係するすべてのロールに付いて回るものがあります。登攀には重い荷物、忍び足には鎧のペナルティ、すべてに祝福などです。resolution.adjustは、どちらの方式でもこれを宣言します。

"adjust": [{ "value": { "derived": "burdened" }, "abilities": ["brawn"] }]

結果にはシートが加えた分が示されるため(記録のadjust="-2"と、ダイスカードの1行)、プレイヤーはロールの結果の理由を確認できます。パッケージ形式のルールセットではCapability API 1.38です。

休息

休息は回復処理と解除対象の一覧です。各処理は1つの対象(pool、poolGroup、listPools、track、state)を指定し、設定する("to": "max"、"to": "min"、または数値)か、増減する("by": { "const": 1 }または"by": { "fractionOfMax": 0.5 })かを定めます。負傷トラックを指定する処理は回復だけなので、byは負の値です。上記を参照してください。ライブステートを指定する処理は、"default"かその値の1つに設定するだけです。fractionOfMaxを持つpoolGroupの処理は、グループの各プールをそれぞれの割合で増減します。"shared": true(Capability API 1.77)を加えると、代わりにグループ全体の最大値で割合を計算し、シートが列挙する順にグループのプールへ、それぞれ不足分を上限として配ります。5eの大休憩で、ダイスの種類ごとに1つのプールに分けたヒット・ダイスを「キャラクターの総数の半分」回復する処理は、{ "poolGroup": "hit_dice", "by": { "fractionOfMax": 0.5, "round": "down", "min": 1 }, "shared": true }です。

Game Master向けの文章

"game-master"はすべての相手のターンをGame Masterに任せます。 Game MasterはEngineが提示する選択肢から選び、 応答しない場合はEngine自身の選択処理にフォールバックします。 プレイヤーがGame Masterによるボスの操作を許可したゲームでのみ適用され、 combatブロックのないルールセットのClassicやTacticalの戦闘を含む、 すべての戦闘スタイルに適用されます。 Fate、 Blades in the Dark、 Trophy、 Lasers & Feelingsなど、 相手側をダメージの合計ではなく物語として動かすナラティブシステムに使ってください。 "engine"を指定するか省略するとEngineの選択処理を維持し、 ボス(およびプレイヤーが求めた場合は、 名前付きの相手と天才的な思考の相手)をGame Masterに任せます。 このキーを使うルールセットにはCapability API 1.774が必要です。

GM向けの完全なルールリファレンス

任意のトップレベルのgmReferenceは、GM向けのルールセットの完全なルールリファレンスを最大16,000文字まで保持します。詳しい裁定ルールはここに書き、判定とリソースに関する短い指示はgm.checkGuidanceとgm.sheetGuidanceに残してください。それらのフィールドとgm.worldGuidanceの上限は引き続き1,500文字で、レイヤーのガイダンスも既存の上限のままです。

"gmReference": "When a journey crosses hostile country, judge supplies, shelter and exposure before the next leg. A failed navigation check costs time rather than silently moving the party to its destination."

リファレンスは、システムプロンプトの安定した部分にあるGame Master rules referenceの下に、リクエストごとに1回表示されます。ターンごとのリマインダーには決してコピーされません。ほかのプロンプトに安全な文章と同じく、1行で、制御文字、角括弧、マクロの波括弧({{と}})を含めてはいけません。通常の履歴と返信の予算を調整した後もリクエストがコンテキストの上限を超える場合は、中核の指示を削る前に、切り詰めた箇所に印を付けてリファレンスを短くします。既存のプロンプトのままにするには未設定にしてください。これを使うパッケージは、マニフェストでschemaVersion: 2と、capabilityApi: { "major": 1, "minor": 145 }以降を宣言する必要があります。

パーティーとシーンの進行クロック(clocks)

Capability API 1.143は、任意のトップレベルのclocksオブジェクトを追加します。クロックのコマンドを無効のままにするには省略してください。このオブジェクトは厳密で、次の3つのキーだけを受け付けます。

"clocks": {
  "sizes": [4, 6, 8],
  "max": 8,
  "text": "Create clocks for looming threats and long projects. Tick them when the fiction advances."
}

sizesは、それぞれ2~12の、重複しない区切り数の整数を1~6個指定します。デフォルトは[4, 6, 8]です。maxは同時に保持するクロックの最大数で、1~12、デフォルトは8です。任意のtextは、GMがクロックを作って進めるべきタイミングを説明する、最大400文字のプロンプトに安全な1行です。空のオブジェクトにするとデフォルト値で有効になります。

クロックはキャラクターではなく、パーティーとシーンのものです。GMへのリマインダーは毎ターン、クロックの名前と進み具合を列挙し、次のコマンドを教えます。

名前は1~100文字の1行で、二重引用符、角括弧、制御文字、マクロの波括弧は使えません。各タグが要求する操作はちょうど1つです。コマンドは返信内の順に適用するため、同じ返信でクロックを作って進められます。Engineは各タグをresult="ok" now="4/6"(またはnow="cleared")か、result="refused" reason="..."で書き換えます。モデルが書いた結果の属性は破棄します。不明なクロックや不正な要求は拒否され、1つの返信で適用するコマンドは最大40個です。

Game Modeでは、パーティーの状態の横に、区切られた円、名前、進み具合を表示します。タグは処理結果の記録として保存された返信に残り、語りからは隠されます。クロックは各ゲーム状態のスナップショットにrulesetClocksとして保存され、データがなければクロックはありません。再生成は直前のスナップショットから始まり、続きの生成は現在のスナップショットから始まります。スワイプやメッセージを選択または削除すると、そのスナップショットのほかの内容と一緒にクロックが戻ります。

パーティーシート: クルー、船、共有のStory Points

Capability API 1.144は、sheetと並ぶ任意のトップレベルのpartyを追加します。Bladesのクルー、Lasers & Feelingsの船、GenesysのStory Pointsのように、ゲームごとに1つの共有シートを持ちます。

"party": {
  "label": "Crew",
  "fields": [
    { "id": "heat", "label": "Heat", "type": "number", "min": 0, "max": 9, "default": 0 },
    { "id": "vault", "label": "Vault capacity", "type": "number", "min": 0, "max": 16, "default": 8 },
    { "id": "upgrades", "label": "Upgrades", "type": "text", "maxLength": 400 }
  ],
  "pools": [{ "id": "coin", "label": "Coin", "max": { "field": "vault" }, "start": "empty" }],
  "advancement": { "fields": ["heat", "vault", "upgrades"], "text": "Record heat after a score." },
  "text": "Coin belongs to the crew."
}

fieldsはsheet.fieldsと同じフィールドのスキーマを、poolsはstart、group、hideWhen、allowTempを含めてsheet.live.poolsと同じものを使います。少なくとも1つのフィールドかプールが必要で、IDはパーティーシート内で重複できません。キャラクターとパーティーのIDは同じでも構いません。このマイナーバージョンのパーティーシートには、セクション、リスト、能力値、派生値、キャラクターシートの移行はありません。プールのmaxは定数か、パーティーの数値フィールドを読みます。キャラクターの式はパーティーの値を読めず、パーティーの式はキャラクターの値を読めません。hideWhenもパーティーのフィールドだけを指定します。

advancement.fieldsは、GMが永続的に変更できる数値、テキスト、長文テキストのフィールドを指定します。advancement.textとtextは、それぞれ最大400文字のプロンプトに安全な1行です。任意のsummaryはgm.sheetSummaryの形を再利用します。そのfieldsはパーティーのフィールドを選び、derivedとlistsは空にする必要があります。要約がなければ、表示されているパーティーのフィールドをすべて表示します。プールは常に表示されます。

[sheet: sheet="party" op="restore" pool="coin" amount="3"]
[sheet: sheet="party" op="spend" pool="coin" amount="2"]
[sheet: sheet="party" op="advance" field="heat" by="2"]
[sheet: sheet="party" op="advance" field="upgrades" to="Hidden vault"]

sheet="party"は共有シートを選びます。whoは省略してください。既存のwho="party"は引き続きすべてのキャラクターに適用され、共有シートは変えません。このマイナーバージョンでパーティーシートに使えるのは、spend、restore、フィールドのadvanceです。不明なシート、未対応の操作、不足するプール、宣言されていない成長、無効な値は拒否され、Engineの結果で書き換えられます。パーティーのプールは、キャラクターのプールと同じ現在値と最大値の計算とデフォルトに従います。

GMは毎ターン、キャラクターシートのブロックの横に、パーティーのラベル、フィールド、プールを受け取ります。Game Modeは、キャラクターの肖像の横に、折りたためる読み取り専用のパーティーシートを、同じシートの表示形式で表示します。永続的な値は、チャットのメタデータ(gamePartySheet)にgameCharacterCardsと並んで1回だけ保存され、成長の記録を共有します。ライブのプールはrulesetLiveの予約済みの$party項目を使い、正規化したキャラクター名がそれと衝突することはありません。再生成は返信の前から始まり、スワイプの選択や削除は既存の履歴を通じて永続的な値とライブの値の両方を戻します。partyのないルールセットは既存の動作のままです。

パーティーの共同作成(Capability API 1.163)。 パーティーシートは、lists(キャラクターシートのリストと同じ書き方で最大12個)、独自のガイド付きのbuilder、fromMembersを持てます。これはパーティーのキャラクターから読む最大8個のパーティーの数値フィールドで、それぞれ{ "field", "count": true }(キャラクターの人数)か、{ "field", "sum": "<character number field>" }(Totemのドットのように、キャラクターの値の合計)です。メンバー由来のフィールドは共有シートを読むたびに現在のキャラクターから計算されるため、キャラクターの加入や離脱で即座に変わります。リストがある場合は、パーティーのsummary.listsでそれを指定できます。

ビルダーはキャラクターのものとまったく同じ書き方で(プール、ステップ、価格付きの行、消費の提示、プロファイル)、パーティー自身のフィールドとリストに対して同じ規則で検査されます。そのカタログと行コピーのステップは、パーティーのリストに供給するルールセットのカタログを読めます。Game Modeでは、どのプレイヤーも共有シートのEditを開いてガイド付きの設定を使い、パーティー全体のために保存できます。各保存は開いたときのリビジョンを示します(チャットのメタデータのgamePartySheetRevisionで、保存のたびと物語自体の変更で上がります)。ほかの人の保存が反映される前に開いた保存は拒否され、新しいシートが表示されます。プレイヤーの下書きは開いたまま残るため、もう一度保存すれば、置き換えることを自分で選んだことになります。

"party": {
  "label": "The Crew",
  "fields": [
    { "id": "tier", "label": "Tier", "type": "number", "min": 0, "max": 4, "default": 0 },
    { "id": "size", "label": "Crew size", "type": "number", "min": 0, "max": 12, "default": 0 }
  ],
  "lists": [{ "id": "upgrades", "label": "Upgrades", "columns": [{ "id": "name", "label": "Name", "type": "text" }] }],
  "builder": { "steps": [{ "id": "upgrades", "label": "Upgrades", "kind": "rows", "list": "upgrades" }] },
  "fromMembers": [{ "field": "size", "count": true }]
}