ルールセットのレイヤー、翻訳、移行

このページでは、プレイヤーがあるゲームでオンにするバリエーションを用意する方法、ルールセットのテキストを翻訳する方法、シートが変わったときに保存済みの値を新しいIDへ移す方法を説明します。ルールセットの作者向けのページです。始める前に、Game Modeのルールセットを作成するを読んでください。

レイヤー: ルールセット自身のバリエーション

レイヤーはLow magic、Hard winter、より過酷な難易度など、ゲーム作成時にプレイヤーがオンにする名前付きのルールセット変種です。ルールセットファイル内の任意のlayers配列に置くため、一緒に移動し、使用したゲームから失われることはありません。ウィザードではルールセットの下にトグルとして表示し、ルールセット自身と同じく、そのゲームの存続中は選択を固定します。

"layers": [
  {
    "id": "hard_winter",
    "label": "Hard winter",
    "summary": "Cold, hunger and short days. Everything is harder.",
    "conflicts": ["mud_season"],
    "gm": {
      "guidance": "Hard winter is on. Let a failed check cost warmth, food or daylight as well as progress.",
      "worldGuidance": "Hard winter is on. Build a world of closed roads, thin stores and rationed settlements."
    },
    "fields": [{ "id": "calling", "removeValues": ["Sailor"], "default": "Hauler" }],
    "difficultyLadder": [{ "label": "Easy", "dc": 7 }],
    "catalogs": [{ "id": "knacks", "hide": { "filter": "grit", "above": 0 } }]
  },
  {
    "id": "mud_season",
    "label": "Mud season",
    "summary": "Thaw, flooded roads and slow going."
  }
]

レイヤーにできること。 リストは固定されており、各効果は何かを絞り込むか、文章を追加します。

"items": {
  "market": { "removeSellers": ["magic_dealer", "scribe"], "unsold": [{ "tag": "magical" }] },
  "lootTables": [{ "id": "treasure_low", "label": "Pocket treasure", "entries": [{ "coins": "sp", "weight": 1, "count": "4d6" }] }]
}

レイヤーにできないこと。 列挙値、フィールド、スキル、プール、休息、売り手、戦利品表の追加、解決方式の変更、ライブ状態や戦闘数値の変更、モデル呼び出しの追加はできません。レイヤーが_追加した_値は、シートを読むほかのすべての処理には未知となるため、値は除く方向だけです。このリストを超える変更は、ルールセット自身の変更か、別のルールセットになります。

競合。 conflictsは同時に有効にできないレイヤーを指定します。組の片方だけに書けば十分です。ウィザードは相手のトグルを無効にし、保存済みの選択になぜか両方がある場合は、後で宣言された方を削除します。そのため、同じ2つの選択からは常に同じルールが得られます。

除外された値をすでに持つシートは、その値を保ちます。 キャラクターを書き換えるものはありません。エディターはその値を選択肢として出さなくなり、すでに持つキャラクターにはそのまま表示します。新しいゲームでレイヤーをオフにすれば、再び選べます。隠したカタログ項目も同じです。選択画面からは消えますが、プレイヤーがすでに選んだ行はシートに残ります。レイヤーが除いた硬貨をすでに持っている場合は、袋に残ります。

制限。 ルールセットごとに12レイヤー、各レイヤーのガイダンスは2つの文字列を合わせて4000文字です。layersまたは基本のgm.worldGuidanceを宣言するパッケージ化されたルールセットにはCapability API 1.25が、硬貨を除くレイヤーを持つものには1.64が、itemsを変更するレイヤーを持つものには1.813が必要です。インポートするルールセットは読み取るEngineが検証するため、この宣言は不要です。

他者が書くレイヤー(自分が書いていないルールセット向けのLow Magicレイヤーを独立したファイルで配布するもの)は、今後の追加事項です。現在は、所属するルールセットの中で配布します。

翻訳

翻訳(Capability API 1.811)。ルールセットの表示文字列を別の言語に訳したものは、言語ごとに用意し、Engine自身の言語パックと同じく、その言語コードで名前を付けます(ru、pt-BR、zh-Hans)。公式エージェントカタログでは、それぞれがルールセットのファイルと並ぶ言語パックです(後述)。共有するルールセットパッケージファイルでは、代わりに内部に含めることもできます。ruleset.jsonと並べて言語ごとにlocales/<language>.jsonを置き、ほかのファイルと同じようにマニフェストに列挙します。どちらの場合も、それぞれがrulesetセクションを持つパッケージのローカライズカタログです。各キーはルールセットまたはそのカタログの表示文字列を英語のまま一字一句変えずに記したもので、値はその文字列をファイルの言語に訳したものです。

{
  "_meta": { "locale": "ru", "direction": "ltr" },
  "package": { "name": "5e (SRD 5.1)" },
  "ruleset": { "Prone": "Лежащий", "Fire Bolt": "Огненный снаряд", "Goblin": "Гоблин" }
}

_meta.localeはファイル名が示す言語でなければならず、ファイルには$schema、_meta、package、ruleset以外を含めず、値はすべてテキストにします。空のままの文字列は未翻訳で、英語で表示されます。rulesetセクションがないファイル(パッケージ自身の英語の紹介文であるlocales/en.json)は何も翻訳しません。翻訳は表示専用です。ルール、シートのコマンド、Game Masterに伝えられる内容はすべて、引き続き英語を読み取ります。戦闘画面(名前、状態、アクション、呪文、ログ、行動順)では、ルールセットの翻訳に文字列があればプレイヤーの言語で表示し、なければ英語で表示します。まずその言語自体のファイル、次にその基になる言語のファイル(pt-BRならpt)を参照します。「Goblin 2」は「Goblin」の翻訳にその番号を付けて表示します。翻訳を含むパッケージファイルにはCapability API 1.811が必要です。インポートすると、Engineに設定されている言語(またはその基になる言語)の翻訳だけを保持し、残りは破棄します。別の言語でルールセットを読むには、Engineの言語を切り替えてファイルを再度インポートしてください。保持されている翻訳が置き換わります。翻訳はバージョンに含まれないため、修正した翻訳を含む同じバージョンを再度インポートした場合も翻訳が置き換わり、翻訳のないファイルをインポートした場合は保持されている翻訳が残ります。

カタログのルールセットは、そのファイル内にlocales/<language>.jsonを含めません(含むものはダウンロード前に拒否されます)。その翻訳は言語パックです(Capability API 1.811)。言語ごとにJSONファイル<id>-<version>.<language>.jsonを用意し、<id>-<version>.ruleset.jsonと並べて公開します。内容はlocales/<language>.jsonとまったく同じです(_meta.localeはファイル名が示す言語で、rulesetセクションを持ちます)。カタログのエントリーは、artifactと並べてそれらを列挙します。

"locales": {
  "ru": {
    "url": "https://raw.githubusercontent.com/Pasta-Devs/Marinara-Agents/main/artifacts/ember-roads-1.0.0.ru.json",
    "sha256": "<64 hex>",
    "bytes": 812345,
    "name": "Угольные дороги",
    "description": "<the store card's description in Russian>"
  }
}

各パックは、成果物のURLと同じ形式のhttps URLで、バージョンと言語に応じた名前を付け、sha256とサイズ(8 MBまで)を持ちます。ルールセットが列挙できるパックは、40個までで、enは決して含めず(英語はルールセット自体です)、マニフェストにはCapability API 1.811を宣言します。nameとdescriptionはその言語でのストアカードの名前と説明なので、パックを取得しなくても、カードはEngineの言語で読めます。インストール時にはルールセットのファイルを取得し、続いてEngineに設定されている言語(またはその基になる言語)のパックだけを取得し、サイズ、チェックサム、言語を検証して、インストールしたバージョンとともに保持します。Engineの言語が変わると(およびその言語でページを開くたびに)、新しい言語のパックを列挙しているインストール済みの各カタログルールセットがそのパックを取得し、古い言語のパックは削除されます。パックを取得できない場合(オフライン、列挙されていない、カタログに列挙されたファイルと異なる場合)、ルールセットは英語のままになります。次のインストールまたは言語変更時に再試行します。アップデート時にはロールバック用に以前のバージョンを保持しますが、そのパックは保持しません。ロールバック後、次の言語変更時に、カタログが引き続きそのバージョンのパックを列挙していれば、再度取得します。

値を新しいIDへ移す: sheet.migrations

追加するだけなら何も要りません。新しい構成が値を別の場所へ移す場合(名前を変えたフィールド、クラスごとのレベルに分かれる1つのレベル、ダイスごとに分かれる1つのヒット・ダイスのプール)、その方法をsheet.migrations(Capability API 1.77)で示してください。そうすれば、古い構成で作ったすべてのキャラクターが、ライブラリー、ゲーム、古いセーブ、分岐、チェックポイント、インポートしたカードで、その数値を保ちます。

"migrations": [
  {
    "from": 3,
    "steps": [
      { "rename": "field", "from": "xp", "to": "experience" },
      {
        "route": "level",
        "by": "class",
        "cases": [
          { "words": ["fighter"], "to": "level_fighter" },
          { "words": ["wizard"], "to": "level_wizard" }
        ],
        "else": "level_other",
        "default": 1
      },
      {
        "routeLive": "pool",
        "from": "hit_dice",
        "cases": ["hit_dice_d6", "hit_dice_d8", "hit_dice_d10", "hit_dice_d12"],
        "else": "hit_dice_d8"
      }
    ]
  }
]