규칙 집합 레이어, 번역과 마이그레이션

이 페이지에서는 플레이어가 한 게임에 켜는 변형을 제공하고, 규칙 집합 텍스트를 번역하고, 시트가 바뀔 때 저장된 값을 새 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는 함께 켤 수 없는 레이어를 지정합니다. 쌍의 한쪽에만 지정하면 충분합니다. 마법사는 상대 토글을 비활성화합니다. 저장된 선택에 어떻게든 둘 다 있으면 나중에 선언된 쪽을 버리므로, 같은 두 선택은 항상 같은 규칙을 만듭니다.

제외된 값을 이미 가진 시트는 그대로 보존합니다. 캐릭터를 다시 쓰는 일은 없습니다. 편집기는 값을 더는 제공하지 않으며, 이미 가진 캐릭터는 원래 값을 표시합니다. 새 게임에서 레이어를 끄면 다시 제공됩니다. 숨겨진 카탈로그 항목도 같습니다. 선택기에서만 제외되며, 플레이어가 이미 고른 행은 시트에 남습니다. 레이어가 제외한 동전을 누군가 이미 지니고 있다면 그 동전은 가방에 남습니다.

제한. 규칙 집합당 레이어 12개이며, 레이어마다 두 문자열을 합해 지침 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). 언어별로 <id>-<version>.<language>.json이라는 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>"
  }
}

각 팩은 아티팩트와 같은 형식의 https URL이며, 버전과 언어에 따라 이름을 붙이고 sha256과 크기(최대 8 MB)를 함께 기재합니다. 규칙 집합은 최대 40개를 나열하며, en은 나열할 수 없고(영어는 규칙 집합 자체임), 매니페스트는 Capability API 1.811을 선언합니다. name과 description은 해당 언어의 스토어 카드 이름과 설명이므로, 팩을 가져오지 않아도 카드가 Engine의 언어로 표시됩니다. 설치할 때는 규칙 집합 파일을 가져온 다음 Engine에 설정된 언어(또는 그 상위 언어)의 팩만 가져와 크기, 체크섬, 언어를 검사하고 설치된 버전과 함께 보관합니다. Engine의 언어가 바뀔 때마다(그리고 그 언어로 페이지를 열 때마다), 새 언어의 팩을 나열한 설치된 각 카탈로그 규칙 집합은 해당 팩을 가져오고 이전 언어의 팩은 제거합니다. 팩을 가져올 수 없으면(오프라인이거나, 나열된 팩이 없거나, 카탈로그에 나열된 파일과 다르면) 규칙 집합은 영어로 남습니다. 다음 설치나 언어 변경 때 다시 시도합니다. 업데이트는 롤백을 위해 이전 버전을 팩 없이 보관합니다. 롤백 후 다음 언어 변경 때 카탈로그가 여전히 그 버전의 팩을 나열한다면 해당 팩을 다시 가져옵니다.

값을 새 ID로 옮기기: sheet.migrations

추가에는 더 필요한 것이 없습니다. 새 레이아웃이 값을 다른 곳으로 옮길 때(이름이 바뀐 필드, 클래스별 레벨이 된 레벨 하나, 주사위별 풀이 된 히트 다이스 풀 하나) 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"
      }
    ]
  }
]