Karty a balíčky
Úvod · Index funkcií · Ťahák
Balíček je pomenovaná zásoba kariet. Karta je kus príbehu — text, {set}, volania, možnosti — s lícom (meno, ilustrácia, popis) a s podmienkou. Na mieste, ktoré si autor zvolí, príbeh rozdá z balíčka ruku; čitateľ si jednu alebo viac vyberie; každá vybraná karta sa zahrá presne ako tunel a príbeh pokračuje tam, kde bol.
Karta bez balíčka je staršia predstava storyletu: obsah, ktorý zobudí svet, nie obsah, ktorý rozdá balíček. Je to tá istá deklarácia, a preto majú obe jednu stránku.
Deklarácia balíčka
{define deck roles play="consumed", face="down"}Pomenovaná zásoba kariet s predvolbami, ktoré dedia jej karty aj miesta ťahania: rozsah, politika návratu, koľko sa rozdáva a či čitateľ vidí líca.
Balíček je líce a súbor predvolieb, takže je nepárový — jeden príkaz, žiadne begin:
{define deck roles name="Karty rolí", back="assets/cards/card-role-background.webp",
scope="group", play="consumed", face="down"}| Atribút balíčka | Význam | Predvolené |
|---|---|---|
name, back, description | Líce samotného balíčka (názov, rub) | — |
scope | reader (kópia pre každého) alebo group (jeden balíček pre celú kooperatívnu reláciu) | reader |
play | Čo sa stane so zahranou kartou: reusable (späť do balíčka), exhausted (odložená, kým ju niekto nevráti), consumed (preč pre toto čítanie) | reusable |
deal, pick, face, optional | Predvolby pre príkazy {draw} / {play}, ktoré tento balíček používajú | all, 1, up, false |
reclaim | Sekundy po odpojení držiteľa, kým sa jeho karta vráti do balíčka; never ju necháva držanú (len scope="group") | odkladová lehota platformy |
Deklarácia karty
{define card king deck="roles" when … begin} … {end card}Karta je líce plus telo. Priorita, váha, ochladenie, štítky a klauzula when riadia výber; deck= ju zaraďuje do balíčka a karta bez balíčka je to, čomu sa kedysi hovorilo storylet.
Karta má telo — to, čo sa zahrá, keď je aktivovaná — takže je párová a zatvára sa vlastným druhom:
{define card king deck="roles", name="Kráľ", image="assets/cards/card-role-king.webp",
role="king" begin}
Zobudíš sa v kráľovskej spálni. Okenice už niekto otvoril.
* [Zvolaj radu] -> council_chamber
* [Prejdi sa po hradbách sám]
Kameň je studený a stráže predstierajú, že ťa nevidia.
{end card}Karta vstupuje do balíčka tým, že ho pomenuje, nie tým, že v ňom sedí — rovnako ako vstupuje do sady kariet. Hierarchia žije v dátach, takže karta otvorená uprostred súboru stále hovorí, kam patrí.
Karta berie deck=, atribúty líca, ktoré berie každá definícia karty (name, image, description a vlastnosti zvolené autorom), vlastné play= prekrývajúce balíček a výberové atribúty nižšie. Jej použiteľnosť je koncová klauzula when v hlavičke.
| Atribút | Popis |
|---|---|
when … | Podmienka, ktorá musí platiť, aby bola karta použiteľná |
priority= | Karty s vyššou prioritou sa rozdávajú skôr (predvolene 0) |
repeatable= | true povoľuje opakované ťahanie, false je jednorazová karta (predvolené) |
cooldown= | Najmenší počet ťahov, kým sa karta môže znovu objaviť |
weight= | Relatívna pravdepodobnosť, keď je použiteľných viac kariet |
tags= | Kategorizácia na filtrovanie |
trigger= | Druh vstupu z reálneho sveta, ktorý kartu zobudí (pozri Spúšťané karty) |
match= | Nepovinný regulárny výraz (bez ohľadu na veľkosť písmen), ktorému musí hodnota vstupu vyhovieť |
Tri atribúty niečo robia, nie opisujú:
| Atribút správania | Účinok |
|---|---|
role="king" | Ťahanie karty postaví čitateľa do tejto roly — takto sa priraďuje context.group.role |
mandatory=true | Rozdá sa vždy, keď je použiteľná, bez ohľadu na strop deal |
alone=true | Keď je použiteľná, rozdá sa sama a vytlačí z ruky všetky ostatné karty |
when je podmienka typu kedykoľvek, vyhodnocovaná v čase výberu — vždy, keď engine rozdáva, a nikdy medzitým. Balíček preto nikdy nespustí senzor: when čítajúce context.location sa zodpovie z polohy, ktorú platforma naposledy dodala, a ak polohu nikto nesleduje, odpoveď je unknown a karta jednoducho nie je použiteľná. Príbeh, ktorý chce, aby engine ďalej sledoval, píše {wait} — to je sloveso until a spustí, čo potrebuje.
Čo je na karte vytlačené
{face vertical="60%" begin} **1 gold** {end face}To, čo je na karte vytlačené — na rozdiel od tela, ktoré sa prehrá. Blok, nie atribút, takže unesie tučné písmo, kurzívu, odkazy aj nápovedy; vertical= ho umiestni ako percento výšky karty a horizontal= ako percento jej šírky, čím sa z pásu textu stane štítok na konkrétnom mieste obrázka. Tri mince, ktoré vyzerajú rovnako a majú hodnotu 1, 2 a 5, sa líšia iba tu.
Líce karty je to, čo je na karte vytlačené; jej telo je to, čo sa zahrá, keď sa karta zahrá. Tri mince, ktoré vyzerajú rovnako a majú hodnotu 1, 2 a 5, sa líšia iba lícom.
{define card coin_gold deck="purse", image="assets/cards/coin.webp" begin}
{face vertical="15%" begin}**Zlatá**{end face}
{face vertical="60%" begin}hodnota **5**{end face}
{earn gold=5}
Vsunieš si mincu do dlane.
{end card}{face} je blok, nie atribút, pretože jeho obsah je bohatý: tučné písmo, kurzíva, odkazy aj nápovedy fungujú cez ten istý riadkový parser ako próza. Hodnota atribútu nesúca markdown je pasca na úvodzovky.
| Atribút | Popis |
|---|---|
vertical= | Kde text sedí, ako percento výšky karty zhora, orezané na 0 %–100 %. Ak chýba, zostane v predvolenom páse vykresľovača, pod obrázkom |
horizontal= | Kde sedí naprieč kartou, ako percento jej šírky zľava, orezané na 0 %–100 %. Ak chýba, líce zostane pásom cez celú šírku; ak je uvedené, líce je štítok vycentrovaný na tomto bode |
Karta môže deklarovať viac líc, každé s vlastnou pozíciou, pretože nadpis na 15 % a hodnota na 60 % sú jedna karta, nie dve. Pozície sa volajú vertical a horizontal, pretože kartu píše autor: x je súradnica, ktorú programátor pozná na prvý pohľad a pisateľa ju treba naučiť. Zástupné symboly {variable} v líci sa vyhodnocujú voči živému stavu príbehu presne ako v name a description, takže {face begin}{story.purse} zlata{end face} je živé.
horizontal= je to, čo položí číslo na symbol namiesto do vlastného riadka — 5 na štíte a 7 na meči. Meria sa zľava obrázka v každom smere čítania, pretože pozícia na kresbe je tam, kde je kresba.
{face} mimo definície karty sa nahlási a zahodí a pozícia, ktorá nie je percento, sa nahlási a ignoruje — text sa aj tak vytlačí, v predvolenom páse.
Obrázky navrstvené na karte
{layer image="assets/shield.webp", vertical="20%", horizontal="80%", width="18%"}Obrázok navrstvený na kresbu karty. Viac vrstiev aj text líca tvoria jednu kartu: otáčajú sa, zväčšujú a animujú spolu. Pozície sú percentá karty, takže prekrytie padne na to isté miesto na náhľade aj na celej obrazovke; ako je vrstva krycia, patrí obrázku, a klauzula when je to, čo prekrytie zapne — štít sa objaví, keď ho čitateľ má.
Kresba karty je jeden obrázok; vrstva je ďalší, vytlačený nad ním. Jedno prekrytie so symbolmi zdieľa šesťdesiat kariet, z ktorých každá má vlastný portrét, takže sa deklarujú oddelene a kreslia sa ako jedna karta.
{define traveller mercenary deck="travellers", image="assets/cards/mercenary.webp", guard=5, blade=7 begin}
{layer image="assets/cards/symbols.webp"}
{layer image="assets/cards/crown.webp", vertical="20%", horizontal="80%", width="18%" when story.crowned}
{face vertical="19%", horizontal="17%" begin}**{story.card.mercenary.guard}**{end face}
{face vertical="19%", horizontal="82%" begin}**{story.card.mercenary.blade}**{end face}
{end define}{layer} je nepárový: obrázok nemá obsah, takže všetko, čo hovorí, je v jednom riadku.
| Atribút | Popis |
|---|---|
image= | Cesta k obrázku relatívna k archívu, rovnako ako image= v hlavičke karty. Povinný — vrstva bez neho sa nahlási a zahodí |
vertical= | Stred vrstvy zhora nadol, ako percento výšky karty. Ak chýba, znamená stred |
horizontal= | Stred vrstvy naprieč kartou, ako percento jej šírky. Ak chýba, znamená stred |
width= | Šírka vrstvy ako percento šírky karty; výška ide podľa obrázka. Ak chýba, znamená celú kartu |
when | Vrstva sa kreslí, len kým klauzula platí; vyhodnocuje sa voči živému stavu príbehu ako každá iná podmienka |
Vrstvy sa kreslia v poradí deklarácie, nad kresbou a pod textom líca. Vrstva bez pozície pokryje celú kartu, čo je presne to, čo chce prekrytie kreslené vo veľkosti karty; vrstva so width= je vycentrovaná na svojom bode.
Ako je vrstva krycia, sa tu nepíše: polopriehľadné prekrytie je polopriehľadný obrázok. Druhé miesto, kde to povedať, by bola druhá odpoveď na tú istú otázku, a tie dve si odporujú vždy len v príbehu, ktorý sa zabudol zopakovať.
Karta je jeden objekt, nech je zložená z akéhokoľvek počtu obrázkov: kresba, jej vrstvy aj líca sú v tom istom rámci, takže sa otáčajú spolu pri prevrátení karty, spolu sa zmenšujú na náhľade a čitateľ nikdy neuvidí kartu rozpadnutú.
Klauzula when je spôsob, ako príbeh prekrytie zapne. Odpovedá sa na ňu raz, tam, kde sa karta vyhodnocuje, takže každá plocha, ktorá kartu kreslí — ruka, Taška, Zbierka aj náhľad v editore — kreslí tú istú kartu.
{layer} mimo definície karty sa nahlási a zahodí, presne ako zatúlané {face}.
Čo je napísané na rube
{detail begin} … {end detail}To, čo čitateľ nájde na rube karty: autorova próza o nej, taká dlhá, ako treba. Nie jednoriadkový description, ktorý ukazuje zoznam — tu si čitateľ prečíta o Rytierovi bez toho, aby opustil príbeh. Bežný obsah, a nikdy nie súčasť tela, takže otočenie karty ju nikdy nezahrá.
Detail karty je to, čo čitateľ nájde, keď ju otočí: autorova vlastná próza o karte, taká dlhá, ako treba.
{define card knight deck="roles", name="Rytier" begin}
{face vertical="12%" begin}**RYTIER**{end face}
{detail begin}
**Rytier** dostal povinnosť a kus ocele, v tomto poradí.
Povinnosť bola prvá a nikdy nebola odvolaná.
{end detail}
Vyrážaš skôr, než sa ostatní zobudia.
{end card}Detail nie je description: to je jeden riadok, ktorý zoznam ukáže vedľa karty. Detail je miesto, kde si čitateľ prečíta o karte — kto je Rytier, čo stojí Koruna — bez toho, aby opustil príbeh. Berie bežný obsah, takže odseky, zvýraznenie, odkazy aj nápovedy fungujú.
Karta, ktorá detail nedeklaruje, sa jednoducho otočí na rub. {detail} mimo definície karty sa nahlási a zahodí a neuzavretý sa automaticky zatvorí na konci súboru ako každý iný blok.
Detail nie je súčasť tela: otočením karty sa ukáže, čo je na nej napísané, a karta sa nikdy nezahrá.
Ťahanie a zahranie
{draw deck="basic"} · {play deck="basic", deal=3 begin}{draw} vezme kartu do Vaku, {play} jednu hneď aktivuje a {return card=…} ju vráti späť. Oba majú blokovú formu s výzvou a náhradou {empty}.
{draw} získava, {play} aktivuje.
{draw deck="basic"} {comment vezmi kartu do Kapsy; zahrá sa neskôr}
{play deck="basic"} {comment vyber kartu z balíčka a zahraj ju hneď}
{play card="king"} {comment príbeh vynúti jednu konkrétnu kartu}
{return card="king"} {comment vráť kartu do jej balíčka}Oba príkazy majú blokovú formu pre chvíľu, ktorá potrebuje výzvu alebo náhradu:
{play deck="basic", deal=3, pick=1 begin}
Trh sa rozprestrie. Čo si vezmeš?
{empty begin}
Stánky sú prázdne; sezóna sa skončila.
{end empty}
{end play}| Atribút príkazu | Význam | Predvolené |
|---|---|---|
deck / card | Z čoho ťahať alebo ktorú kartu zahrať | — |
count | Koľko kariet | 1 |
deal | Koľko sa vyloží na výber | z balíčka, inak všetky použiteľné |
pick | Koľko si čitateľ vezme | 1 |
face | up (vyberá čitateľ) alebo down (náhodne) | z balíčka, inak up |
optional | Smie si čitateľ nevziať nič | z balíčka, inak false |
Ruka s face="down" sa zamieša a berie sa zvrchu: rozdanie, ktoré čitateľ nevidí, nie je voľba, takže sa nič nepredkladá. {empty} sa spustí, keď v balíčku nie je nič použiteľné — balíček sa musí dať vyčerpať a vyčerpaný balíček musí mať kam ísť.
{return card="…"} sa píše s atribútom, pretože {return VÝRAZ} sa už vracia z funkcie. Jedno sloveso, dve úlohy, a kartová forma je tá, ktorá pomenúva svoj predmet — presne ako {draw} a {play}.
Čítanie stavu balíčka
{if drawn("king") begin} {comment potiahol ju tento čitateľ}
Stále cítiš ťarchu koruny.
{end if}
{if held("king") begin} {comment má ju práve teraz v ruke}
Karta je ešte teplá.
{end if}
Zostáva {story.deck.basic.remaining} zo {story.deck.basic.size} kariet.
{for part.card in eligible("basic") begin} {comment ruka ako dáta, vyložená ručne}
- {part.card}
{end for}Počítadlo sa predvolene ukazuje, lebo skrytá veľkosť balíčka je práve to, čo čitatelia čítajú ako podvod. eligible() vráti zásobu bez rozdania, takže autor, ktorý chce rozloženie, aké vstavaná ruka nedáva, si karty vykreslí sám — výber zostáva engine, prezentácia zostáva autorovi.
Karty v balíku
Karta je text v Rea a súbor je len jedno z miest, kde môže žiť. Balík môže niesť adresár deck/, ktorého podadresáre sú balíčky a súbory .rea v nich sú karty:
project.reast
├── manifest.json
├── story/0001-the-silence.rea ← usporiadané časti, bez zmeny
├── deck/roles/deck.rea ← {define deck roles …}
├── deck/roles/king.rea ← jedna karta na súbor
└── deck/basic/coin.reaManifest uvádza adresáre na načítanie, nie balíčky — "decks": ["deck/roles", "deck/basic"] — pretože čo balíček je, hovorí {define deck}, a balíček pomenovaný na oboch miestach by bol jednou vecou s dvoma zdrojmi pravdy. Súbor karty, ktorý nedeklaruje deck=, vstupuje do balíčka pomenovaného podľa svojho adresára, takže pridať kartu znamená pridať súbor a nikdy nie upraviť manifest. Karty napísané priamo v časti fungujú ďalej a jednoducho deklarujú deck=.
Spúšťané karty
trigger=scan · match="^REAST-.*"Storylet, ktorý rozdáva svet namiesto balíčka; prehrá sa ako vedľajšia cesta a vráti sa presne tam, kde čitateľ prestal. Ktoré druhy spúšťačov skutočne fungujú, závisí od čitateľskej aplikácie a od funkcií, ktoré sú ešte vo vývoji.
Kartu s trigger= a bez balíčka zobudí svet namiesto rozdania: takmer v ktorejkoľvek chvíli čítania môže vstup z reálneho sveta — naskenovanie QR nálepky na lavičke, vyslovená fráza, priloženie NFC štítka — prerušiť hlavný príbeh, zahrať kartu ako vedľajšiu cestu a vrátiť čitateľa presne tam, kde skončil:
{define card bench_secret trigger=scan, match="^REAST-BENCH-.*", weight=2 when story.act >= 2 begin}
Kód na lavičke ožije. Hlas zašepká: „Našiel si ma."
* [Nasleduj šepot]
-> bench_alley
* [Nevšímaj si to]
{end card}
{define card magic_word trigger=listen, match=abracadabra begin}
Slovo zostane visieť vo vzduchu — a stena odpovie.
{end card}trigger=pomenúva druh vstupu. Množina je otvorená — čitateľská aplikácia rozhoduje, ktoré druhy fyzicky zachytí. Bežné druhy:scan(obsah QR/čiarového kódu),listen(rozpoznaný prepis reči),text,vision,nfc,shake,locationmatch=je regulárny výraz bez ohľadu na veľkosť písmen, testovaný proti hodnote vstupu (obsah QR kódu, prepis). Vynechaj ho, ak stačí ľubovoľný vstup daného druhu- Karta v balíčku sa rozdáva, nikdy nezobúdza. Balíček rozhoduje, kedy jeho karty vyjdú, takže
trigger=patrí karte bezdeck= - Výber sa riadi bežnými pravidlami kariet: medzi kartami, ktorým sedí druh a
match=, sa rešpektujú podmienkywhen, stav potiahnutia,cooldown=apriority=, a potom sa jedna vyberie váženým náhodným výberom. Jeden vstup zobudí presne jednu kartu - Vnútri tela sprístupňujú
event.kindaevent.valuespúšťací vstup podmienkam aj textu (sú viditeľné aj prewhenpočas výberu), takže naskenovaný obsah alebo vyslovené slová sa dajú citovať späť:Na štítku stojí {event.value}.
Prerušenie a návrat
Spúšťaná karta sa zahrá ako autorský tunel (->->): engine si zapamätá pozíciu v hlavnom príbehu — vrátane čakajúcej, nezodpovedanej skupiny možností — zahrá kartu a obnoví hlavný príbeh presne tam, kde bol, keď karta skončí (posledným riadkom alebo výslovnou odbočkou von). Zmeny stavu vnútri ({set}, {give}, mince) pretrvajú do hlavného príbehu. Uloženie počas karty sa obnoví do karty aj s návratovou pozíciou. Nový spúšťač sa ignoruje, kým beží iná spúšťaná karta — vedľajšie cesty sa nikdy nevnárajú.
Keď vstup nezodpovedá ničomu — žiadna použiteľná karta, žiadna čakajúca možnosť prieskumnej ponuky — čitateľská aplikácia dá jemnú spätnú väzbu („to zatiaľ nič neurobilo") namiesto chyby, takže skenovať náhodné kódy je vždy bezpečné. Keď na ten istý vstup môže odpovedať aj čakajúca prieskumná ponuka aj spúšťaná karta, vyhráva ponuka — pozri Priorita pri spúšťačoch storyletov.
Ohradenie prerušení
Niektoré úseky príbehu sa nesmú prerušiť — filmová scéna, odpočítavanie, výjav, ktorého podstatou je načasovanie. {triggers off} ohradu zatvorí, {triggers on} ju znova otvorí:
* [Otvor dvere]
{triggers off}
Chodba pohltí zvuk za tebou. Nič, čo teraz urobíš, nikto nepočuje.
- Chodba sa končí.
* [Vyjdi von]
{triggers on}
Hluk mesta sa vráti naraz.Kým je ohrada zatvorená, vstup z reálneho sveta nezobudí nič a karta, ktorú čitateľ zahrá z tašky, je odmietnutá. Je to zámerne jedno pravidlo, nie dve: spúšťaná karta a karta zahraná z tašky sú ten istý čin — niečo vstupuje do príbehu medzi dvoma jeho vlastnými krokmi — takže autor ohradí oboje jedným riadkom. Súčasťou toho istého pravidla je aj bežiace prerušenie: vedľajšie cesty sa nikdy nevnárajú, nech ohrada hovorí čokoľvek.
Ohrada putuje s uložením. Uloženie spravené v ohradenom úseku sa v ňom aj obnoví a uloženie spravené pred ním sa doň nikdy nevráti.
Pozri aj
- Udalosti kariet — čo karta robí, keď je získaná, stratená alebo použitá, napísané ako plochá obsluha
{on}. - Priorita pri spúšťačoch storyletov — arbitráž medzi čakajúcou prieskumnou ponukou a spúšťačom karty pre ten istý vstup, v časti Prieskumné ponuky.
- Priorita: prieskumné ponuky vs. spúšťače storyletov — to isté pravidlo arbitráže, zopakované v časti Interakcie s reálnym svetom.