Arkusze zestawu zasad

Ta strona pomoże ci zaprojektować arkusz postaci zestawu zasad: atrybuty, umiejętności, pola i listy, stany bieżące, tory ran, kary, odpoczynki i tekst mistrza gry, a także arkusz drużyny i zegary postępu. Jest przeznaczona dla osób piszących zestawy zasad. Zanim zaczniesz, przeczytaj przewodnik Pisanie zestawów zasad Game Mode.

Arkusz

Wszystko, co odczytuje liczbę, nazywa ją odwołaniem do wartości: obiektem o dokładnie jednym kluczu const, field, derived, abilityScore, abilityMod, abilityModFromField, skillMod, saveMod, listSum, livePool, liveTrack lub itemStat. Przykład puli o maksimum będącym wartością pochodną: "max": { "derived": "grit_max" }.

Co robi test bez wyszkolenia. Umiejętność lub rzut obronny, w którym postać nie ma wyszkolenia (jej poziom wyszkolenia jest pierwszy), rzuca się normalnie, chyba że zestaw zasad stanowi inaczej przez untrained na umiejętności lub rzucie obronnym albo na sekcji, w której się znajdują (pierwszeństwo ma własna reguła umiejętności lub rzutu obronnego):

"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" }
]

Sekcje na atrybutach, umiejętnościach i rzutach obronnych oraz untrained w dowolnym miejscu wymagają Capability API 1.41 w zestawie dostarczanym jako pakiet.

Umiejętność lub rzut obronny może mieć cap, odwołanie do wartości będące najwyższą wartością, jaką może osiągnąć test: wartość, której nie da się przerosnąć, albo tor, który ją ogranicza. Gravewatch ogranicza Soothe do Resolve, które zostało strażnikowi: "cap": { "livePool": "resolve" }. Ograniczona liczba jest tą pokazywaną w arkuszu i używaną w każdym teście, a podmianę przez with= oblicza się na liczbie sprzed ograniczenia i potem ogranicza ponownie. Ograniczenie nie może odczytywać modyfikatora umiejętności ani rzutu obronnego; nie może tego również odczytywana przez nie wartość pochodna ani żadna wartość pochodna zadeklarowana nad nią, więc arkusz nadal oblicza się raz, od góry do dołu. Capability API 1.39.

hideWhen ukrywa pole, wartość pochodną, listę, pulę lub zwykły tor na podstawie wartości innego pola, na dokładnie jeden z trzech sposobów: equals jedna wartość, notEquals jedna wartość (ukryte, gdy pole zawiera cokolwiek innego; tak wyraża się "tylko dla tego rodzaju postaci") albo in lista wartości. Każda wskazana wartość musi być możliwa w tym polu, inaczej reguła nigdy by nie pasowała, i jest sprawdzana pojedynczo; dla notEquals i in obejmuje to zakres pola liczbowego i długość pola tekstowego. Reguła odczytuje wartość pokazywaną przez edytor arkusza: nieustawione pole ma wartość, od której zaczyna pusty arkusz, a wartość wyliczeniowa, której zestaw już nie oferuje, jest wartością domyślną pola. Plik 5e używa equals, aby ukryć komórki zaklęć u postaci nierzucających zaklęć; Gravewatch usuwa olej do latarni z arkusza każdego strażnika, który nie pełni nocnej warty, przez "hideWhen": { "field": "watch", "notEquals": "night" }. Warstwa nie może usunąć wartości, z którą porównuje któraś z tych reguł. Toru ran nie można ukryć, bo rzuty i walki odczytują go niezależnie od tego, co pokazuje arkusz. notEquals i in wymagają Capability API 1.39.

max zwykłego toru może być odwołaniem do wartości zamiast liczby, więc jego długość wyznacza wartość posiadana przez postać: "max": { "field": "willpower_rating" }. Jego min i default pozostają liczbami. Tor ran z nazwanymi poziomami ma max równe liczbie poziomów; tor z numerowanymi polami jest tak długi jak jego własne max (zobacz niżej Numerowane pola). alwaysShow: true wypisuje tor w bloku arkusza dla Game Master nawet przy wartości domyślnej, dla wartości ważnej w każdej turze; bez tego tor na wartości domyślnej jest pomijany, bo trzy rzuty przeciw śmierci na zerze niczego nie mówią. Te trzy wymagają Capability API 1.37 w zestawie dostarczanym jako pakiet.

Stany bieżące: forma, postawa, światło

Pole wyliczeniowe wybiera się przy tworzeniu postaci i ten wybór zostaje, a stan jest tylko włączony albo wyłączony. Stan bieżący to jedna wartość z zamkniętego zbioru, która zmienia się podczas gry: forma zmiennokształtnego, postawa w walce, jasność latarni.

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

Liczby, które za tym idą. Wartość pochodna z "op": "enumTable" daje liczbę dla każdej wartości pola wyliczeniowego lub stanu bieżącego:

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

Stany bieżące, enumTable i krok odpoczynku wskazujący state wymagają Capability API 1.42 w zestawie dostarczanym jako pakiet.

Tory ran: zdrowie jako tor zamiast liczby

Wiele systemów wcale nie liczy punktów życia. Mają kolumnę pól, każde gorsze od poprzedniego, i zaznacza się jedno po zranieniu. Dodaj do wpisu live.tracks kinds oraz nazwane levels albo numerowane boxes (niżej), aby zmienić liczbę na skali w taki tor:

Jakiej formy potrzebuje twój system? Pula zapisuje, ILE obrażeń zadano; tor zapisuje, ile ORAZ jakiego rodzaju była każda ich część. Jeśli twój system rozróżnia rany obuchowe, śmiertelne i spotęgowane, a rodzaj pozostaje ważny po ciosie, ponieważ spotęgowane goją się wolniej, nie mogą być pochłaniane albo ostatecznie zabijają, ten rodzaj musi gdzieś przetrwać po rzucie, a przechowuje go tylko znacznik. Pula punktów tego nie potrafi: po odjęciu obrażeń jest tylko mniejszą liczbą, a karta nie pamięta rodzaju poszczególnych punktów. Dlatego combat.damageKinds jest odrzucane w zestawie zasad ze zdrowiem jako pulą, zamiast być po cichu ignorowane. Pula nadal może mieć damageTypes, a przeciwnik może być na nie odporny lub niewrażliwy, ponieważ to kwestia wielkości otrzymanego ciosu, a nie rodzaju późniejszej rany.

{
  "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 }
  ]
}

Dokładne reguły, bo nieprecyzyjne odczytanie daje niepoprawny tor:

Zaznaczanie podczas gry. Game Master pisze [sheet: op="damage" track="harm" kind="knock" amount="1"] i leczy przez ujemne amount. Na torze zaznaczanym według pola dodaje box="3", czyli pole, w które trafia cios. Wariant damage wskazujący pool= nie zmienia się. Zwykła komenda track jest odrzucana dla toru ran: sama liczba nie określa nowych znaczników. Gracz może też ręcznie zaznaczać i czyścić pola arkusza, zgodnie z założeniami tych systemów.

Walka także może zaznaczać tor. Skieruj combat.health na tor zamiast puli. Trafiony cios zaznacza tyle pól, ile mówi combat.damageKinds.marks, rodzajem przypisanym przez ten blok typowi obrażeń. Postać z pełnym torem pada, co odczytuje reguła umierania. Na torze zaznaczanym według pola obrażenia per-point wskazują pole, w które trafiają, a per-blow celują w pierwsze, a cios, którego nie może przyjąć żadne pole, powala postać, bo tak w systemach z takim torem wygląda wyeliminowanie z walki. Leczenie usuwa jeden znacznik, najlżejszy, dowolnego rodzaju. Punkty tymczasowe są odrzucane, bo tor nie ma dla nich bufora. Engine odczytuje tor jako liczbę POZOSTAŁYCH poziomów, więc reszta walki, upadek, przywrócenie, dziennik i podsumowanie nie zmieniają się.

Odpoczynek może leczyć tor ran. Krok odnowienia z "to" czyści go do podanej liczby znaczników, wraz z nadmiarem; krok z UJEMNYM "by" usuwa tyle znaczników, zaczynając od nadmiaru, więc "by": { "const": -2 } usuwa dwa. Krok, który wskazuje także kind, usuwa tylko znaczniki tego rodzaju: "Catch your breath" z Gravewatch to { "track": "harm", "kind": "knock", "to": "min" }, co leczy stłuczenia i zostawia rozdarcia. Krok, który DODAŁBY znaczniki, nie robi nic, bo odpoczynek nie zadaje obrażeń; dotyczy to także dodatniego "by": jest pomijane bez słowa, więc pamiętaj o znaku minus.

Numerowane pola zamiast nazwanych poziomów

Gdy tor jest tak długi, jak wytrzymała jest postać, nadaj mu boxes zamiast levels. Ma tyle pól, ile wynosi jego własne max, które może być wartością obliczaną przez arkusz (nigdy odczytującą bieżący stan), najwyżej 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"
}

Zaznaczanie według pola i tory odrzucające znaczniki

Poziomy dodawane przez listę

"extra": { "list": "scars", "countColumn": "levels", "penaltyColumn": "penalty" } na torze z nazwanymi poziomami pozwala liście w arkuszu wydłużać go dla każdej postaci osobno. Każdy wiersz, po kolei, dodaje swoją liczbę poziomów (najwyżej 16) ze swoją karą, za ostatnim poziomem o karze co najmniej tak dobrej; poziomy te noszą nazwę tamtego poziomu, gdy kary są równe, a w przeciwnym razie nazwę od kary. Tak działają blizny w Gravewatch. Lista ukryta przez arkusz nic nie dodaje, a gdy usunięto wiersz, którego poziomy są zaznaczone, znaczniki, które już się nie mieszczą, zostają zachowane jako nadmiar: edycja arkusza nie cofa obrażeń.

boxes, fill, onFull, extra i kind w kroku odpoczynku wymagają Capability API 1.40 w zestawie dostarczanym jako pakiet.

Kara do rzutów

resolution.penaltyFrom wskazuje tor ran, którego kara dotyczy każdego testu zestawu. Jest deklarowana, nie domyślna: zestaw bez niej rzuca dokładnie tak jak przed wprowadzeniem torów ran.

DZIAŁANIE kary zależy od rodzaju rozstrzygania, tak samo jak znaczenie liczby z arkusza:

Wskazany tor musi być torem ran. Zwykły tor nie ma kary i wskazanie go jest odrzucane podczas importu. Wynik podaje zastosowaną karę, aby gracz rozumiał mniejszą liczbę kości, a blok arkusza dla Game Master pokazuje poziom i jego koszt.

Modyfikatory z arkusza

Niektóre liczby w arkuszu towarzyszą każdemu rzutowi, którego dotyczą: ciężki plecak przy każdej wspinaczce, kara za pancerz przy każdym skradaniu, błogosławieństwo przy wszystkim. resolution.adjust to określa, w obu rodzajach:

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

Wynik podaje, co dodał arkusz (adjust="-2" w zapisie i wiersz na karcie rzutu), aby gracz widział, dlaczego rzut wypadł tak, a nie inaczej. Wymaga Capability API 1.38 w zestawie dostarczanym jako pakiet.

Odpoczynki

Odpoczynek jest listą kroków odnowienia i rzeczy do wyczyszczenia. Każdy wskazuje jeden cel (pool, poolGroup, listPools, track lub state) i ustawia go ("to": "max", "to": "min" albo liczba) lub zmienia ("by": { "const": 1 } albo "by": { "fractionOfMax": 0.5 }). Krok wskazujący tor ran może go tylko leczyć, więc jego by jest ujemne; zobacz wyżej. Krok wskazujący stan bieżący tylko go ustawia, na "default" albo jedną z jego wartości. Krok poolGroup z fractionOfMax zmienia każdą pulę grupy o jej własny ułamek; dodaj "shared": true (Capability API 1.77), aby zamiast tego obliczyć ułamek od maksimum całej grupy i rozdzielić wynik między pule grupy w kolejności, w jakiej wymienia je arkusz, każdej najwyżej tyle, ile jej brakuje. Długi odpoczynek z 5e, "połowa całkowitej liczby" kości wytrzymałości postaci przechowywanych w osobnej puli dla każdego rodzaju kości, to { "poolGroup": "hit_dice", "by": { "fractionOfMax": 0.5, "round": "down", "min": 1 }, "shared": true }.

Tekst Game Master

Pełny opis zasad dla Game Master

Opcjonalne pole najwyższego poziomu gmReference zawiera pełny opis zasad zestawu dla Game Master, do 16 000 znaków. Umieść tu rozbudowane zasady rozstrzygania, a krótkie instrukcje dotyczące testów i zasobów zostaw w gm.checkGuidance i gm.sheetGuidance. Te pola oraz gm.worldGuidance nadal mają limit 1500 znaków; wskazówki warstw również zachowują dotychczasowe limity.

"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."

Opis pojawia się pod nagłówkiem Game Master rules reference (opis zasad dla Game Master) w stałym prompcie systemowym, raz na żądanie. Nigdy nie jest kopiowany do przypomnienia wysyłanego w każdej turze. Jak każdy inny tekst bezpieczny dla promptu musi być jedną linią, bez znaków sterujących, nawiasów kwadratowych i klamer makr ({{ i }}). Gdy żądanie nadal przekracza limit kontekstu po zwykłym dopasowaniu historii i budżetu odpowiedzi, opis jest skracany z oznaczonym miejscem cięcia, zanim zostaną przycięte podstawowe instrukcje. Pozostaw to pole nieustawione, aby zachować dotychczasowe prompty. Pakiet, który go używa, musi zadeklarować w manifeście schemaVersion: 2 i capabilityApi: { "major": 1, "minor": 145 } lub nowsze.

Zegary postępu drużyny i sceny (clocks)

Capability API 1.143 dodaje opcjonalny obiekt najwyższego poziomu clocks. Pomiń go, aby polecenia zegarów pozostały wyłączone. Obiekt jest ścisły: przyjmowane są tylko te trzy klucze.

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

sizes dopuszcza od jednej do sześciu różnych liczb całkowitych oznaczających liczbę segmentów, każdą od 2 do 12; domyślnie [4, 6, 8]. max to największa liczba zegarów przechowywanych naraz, od 1 do 12, domyślnie 8. Opcjonalny text to jedna bezpieczna dla promptu linia do 400 znaków, wyjaśniająca, kiedy Game Master ma tworzyć zegary i zaznaczać na nich segmenty. Pusty obiekt włącza wartości domyślne.

Zegary należą do drużyny lub sceny, nie do postaci. Przypomnienie dla Game Master w każdej turze wymienia ich nazwy i wypełnienie oraz uczy tych poleceń:

Nazwy to pojedyncze linie o długości od 1 do 100 znaków, bez cudzysłowów, nawiasów kwadratowych, znaków sterujących i klamer makr. Każdy znacznik żąda dokładnie jednej akcji. Polecenia są stosowane w kolejności odpowiedzi, więc zegar można utworzyć i przesunąć w tej samej odpowiedzi. Engine przepisuje każdy znacznik z result="ok" now="4/6" (lub now="cleared") albo z result="refused" reason="...". Pola wyniku podane przez model są odrzucane. Nieznane zegary i błędnie sformułowane żądania są odrzucane; w jednej odpowiedzi stosuje się najwyżej 40 poleceń.

Game Mode pokazuje obok stanu drużyny koło podzielone na segmenty, nazwę i wypełnienie. Znaczniki pozostają w zapisanej odpowiedzi jako potwierdzenia i są ukryte w narracji. Zegary są zapisywane w każdej migawce stanu gry jako rulesetClocks; brak danych oznacza brak zegarów. Ponowne generowanie zaczyna od poprzedniej migawki, kontynuacja od bieżącej, a wybranie lub usunięcie swipe'ów lub wiadomości przywraca zegary razem z resztą tej migawki.

Arkusz drużyny: załoga, statek lub wspólne Story Points

Capability API 1.144 dodaje obok sheet opcjonalne pole najwyższego poziomu party. Zawiera ono jeden wspólny arkusz na grę, np. załogę z Blades, statek z Lasers & Feelings albo Story Points z Genesys:

"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 używa tego samego schematu pól co sheet.fields; pools używa schematu sheet.live.pools, łącznie z start, group, hideWhen i allowTemp. Wymagane jest co najmniej jedno pole lub pula, a ich identyfikatory muszą być unikalne w obrębie arkusza drużyny. Identyfikatory postaci i drużyny mogą się pokrywać. Arkusze drużyny w tej wersji API nie mają sekcji, list, atrybutów, wartości pochodnych ani migracji arkusza postaci. max puli odczytuje stałą lub liczbowe pole drużyny. Formuły postaci nie mogą odczytywać wartości drużyny, a formuły drużyny – wartości postaci. hideWhen także wskazuje wyłącznie pola drużyny.

advancement.fields wskazuje pola typu number, text lub longtext, które Game Master może trwale zmieniać. advancement.text i text przyjmują po jednej bezpiecznej dla promptu linii do 400 znaków. Opcjonalne summary używa formatu gm.sheetSummary: jego fields wybierają pola drużyny; derived i lists muszą być puste. Bez podsumowania pokazywane są wszystkie widoczne pola drużyny. Pule pojawiają się zawsze.

[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" wybiera wspólny arkusz; pomiń who. Dotychczasowe who="party" nadal dotyczy każdej postaci i nigdy nie zmienia wspólnego arkusza. Ta wersja API dopuszcza na arkuszu drużyny spend, restore i advance pola. Nieznane arkusze, nieobsługiwane operacje, niewystarczające pule, niezadeklarowany rozwój i nieprawidłowe wartości są odrzucane i przepisywane z wynikiem Engine. Pule drużyny stosują tę samą arytmetykę wartości bieżącej i maksymalnej oraz te same wartości domyślne co pule postaci.

Game Master w każdej turze otrzymuje etykietę drużyny, pola i pule obok bloków arkuszy postaci. Game Mode oferuje obok portretów postaci zwijany arkusz drużyny tylko do odczytu, w tej samej prezentacji co arkusz postaci. Trwałe wartości są przechowywane raz, w metadanych czatu (gamePartySheet), obok gameCharacterCards, i współdzielą potwierdzenia rozwoju. Pule bieżące używają zarezerwowanego wpisu $party w rulesetLive; znormalizowane imiona postaci nie mogą z nim kolidować. Ponowne generowanie zaczyna od stanu sprzed odpowiedzi, a wybór lub usunięcie swipe'a przywraca zarówno trwałe, jak i bieżące wartości przez istniejącą historię. Zestawy bez party zachowują dotychczasowe działanie.

Wspólne tworzenie drużyny (Capability API 1.163). Arkusz drużyny może zawierać lists (do 12, zapisanych jak listy arkusza postaci), własny prowadzony builder i fromMembers: do 8 liczbowych pól drużyny odczytywanych z postaci drużyny, każde jako { "field", "count": true } (liczba postaci) albo { "field", "sum": "<character number field>" } (suma ich wartości, np. kropek Totem). Pola członków są obliczane z bieżącego stanu postaci przy każdym odczycie wspólnego arkusza, więc dołączenie lub odejście postaci od razu je zmienia. Jeśli drużyna ma listy, może je wskazywać jej summary.lists.

Kreator zapisuje się dokładnie tak jak kreator postaci (pule, kroki, wyceniane wiersze, oferty wydatków, profile) i podlega tym samym regułom względem własnych pól i list drużyny. Jego kroki katalogu i kopiowania wierszy mogą odczytywać katalogi zestawu zasilające listy drużyny. W Game Mode każdy gracz może otworzyć opcję Edit wspólnego arkusza, która oferuje prowadzoną konfigurację, i zapisać arkusz dla całej drużyny. Każdy zapis podaje wersję, na której go otwarto (gamePartySheetRevision w metadanych czatu, zwiększane przy każdym zapisie i przy zmianach wprowadzanych przez samą historię): zapis otwarty, zanim trafił zapis kogoś innego, jest odrzucany, pokazywany jest nowszy arkusz, a szkic gracza pozostaje otwarty, więc ponowny zapis to jego decyzja o zastąpieniu tamtego.

"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 }]
}