Frameworki kodowe
Rozwiń Lantern w prawdziwą grę
Dodaj do gry z szybkiego startu wybór, wartość pochodną, podrzędny framework i listę, a każdy krok potwierdź scenariuszem.
Zanim zaczniesz
Zacznij od projektu zbudowanego w szybkim starcie. Każdy krok wymienia każdy plik do utworzenia lub zmiany. Fragment pokazuje część, która się zmienia, a możesz go rozwinąć, aby zobaczyć cały plik. Po każdym kroku wybierz Sprawdź i wyświetl.
Cztery kroki
- Dodaj wybór
Dodaj dane wejściowe Calling z dwiema opcjami.
schemas/keeper.json"calling": { "label": "Calling", "options": ["Guard", "Scout"], "defaultValue": "Guard" }- Wiersz 11 Stała lista wyborów. Wartość domyślna musi być jednym z nich.
Konstruktor odbiera nowe dane wejściowe i zwraca je jako zapisane pole.
rules/keeper.tsexport function construct( name: string, max_hp: number, calling: string, ): { name: string; max_hp: number; hp: number; calling: string } { return { name: name, max_hp: max_hp, hp: max_hp, calling: calling }; }- Wiersz 4 Nowe dane wejściowe.
- Wiersze 5-6 calling jest teraz zapisanym polem.
Oba scenariusze potrzebują nowej wartości, w parameters i w expectedValues. Zacznij od new-keeper.json.
scenarios/new-keeper.json{ "id": "new-keeper", "framework": "keeper", "parameters": { "name": "Mira", "max_hp": 10, "calling": "Guard" }, "expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10, "calling": "Guard" } }- Wiersz 4 Dane wejściowe, które podajesz.
- Wiersz 9 Zapisana wartość, której oczekujesz.
Potem wprowadź te same dwie zmiany w heal.json.
scenarios/heal.json"parameters": { "name": "Mira", "max_hp": 10, "calling": "Guard" }, "expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10, "calling": "Guard" },- Wiersz 4 Te same dane wejściowe.
- Wiersz 9 Ta sama zapisana wartość.
Wybierz Sprawdź i wyświetl. Sprawdzenie powinno przejść, zanim ruszysz dalej.
Projekt zawiera teraz te pliki. Rozwiń dowolny fragment powyżej, aby zobaczyć cały plik.
manifest/project.json schemas/keeper.json rules/heal.ts rules/hurt.ts rules/keeper.ts layouts/keeper.json scenarios/heal.json scenarios/new-keeper.json - Wylicz wartość
Funkcja ledgera wylicza Guard z calling. Zadeklaruj ją w schemacie.
schemas/keeper.json"ledgerFunctions": [ { "id": "guard", "name": "Guard", "field": "guard", "source": "rules/guard.ts" } ]- Wiersze 24-27 id i name wskazują funkcję, field to zapisana wartość, którą wypełnia, a source to jej plik reguł.
Utwórz rules/guard.ts.
rules/guard.tsfunction base_guard(calling: string): number { return calling === "Guard" ? 3 : 1; } export function guard(currentValue: number, self: ElementRef): number { const calling: string = element.var(self, "calling") as string; return base_guard(calling); }- Wiersze 1-3 Funkcja pomocnicza bez export.
- Wiersze 5-7 Funkcja ledgera odczytuje calling i zwraca wyliczoną wartość.
Konstruktor zwraca też pole guard z wartością początkową 0. Funkcja ledgera wpisuje prawdziwą wartość.
rules/keeper.tsexport function construct( name: string, max_hp: number, calling: string, ): { name: string; max_hp: number; hp: number; calling: string; guard: number } { return { name: name, max_hp: max_hp, hp: max_hp, calling: calling, guard: 0 }; }- Wiersze 5-6 guard jest częścią zwracanej wartości i zaczyna od 0.
Scenariusz sprawdza tę funkcję. Dodaj guard do oczekiwanych wartości w new-keeper.json oraz linię ledgera, która wywołuje funkcję.
scenarios/new-keeper.json{ "id": "new-keeper", "framework": "keeper", "parameters": { "name": "Mira", "max_hp": 10, "calling": "Guard" }, "expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10, "calling": "Guard", "guard": 3 }, "ledger": [{ "function": "guard", "currentValue": 0, "expected": 3 }] }- Wiersz 10 Wyliczona wartość, po uruchomieniu funkcji ledgera.
- Wiersz 12 Wywołuje funkcję guard z bieżącą wartością 0 i oczekuje 3.
Dodaj tę samą oczekiwaną wartość do heal.json.
scenarios/heal.json"parameters": { "name": "Mira", "max_hp": 10, "calling": "Guard" }, "expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10, "calling": "Guard", "guard": 3 },- Wiersz 10 Wyliczona wartość w tym scenariuszu też zostaje 3.
Aby pokazać Guard na karcie, wpisz go w requiredBindings i dodaj węzeł tekstowy, który go używa.
layouts/keeper.json{ "binding": "element.attributes.guard", "expectedType": "number" }- Wiersz 15 Powiązanie dla nowego pola.
layouts/keeper.json{ "kind": "text", "text": "Guard: {{element.attributes.guard}}" },- Wiersz 32 Węzeł tekstowy, który pokazuje wartość.
Wybierz Sprawdź i wyświetl. Sprawdzenie powinno przejść, zanim ruszysz dalej.
Projekt zawiera teraz te pliki. Rozwiń dowolny fragment powyżej, aby zobaczyć cały plik.
manifest/project.json schemas/keeper.json rules/guard.ts rules/heal.ts rules/hurt.ts rules/keeper.ts layouts/keeper.json scenarios/heal.json scenarios/new-keeper.json - Dodaj podrzędny framework
Keeper nosi Lamp. Lamp to drugi framework z własnym schematem, konstruktorem, ramką i scenariuszem. Wpisz jego schemat i scenariusz w manifeście.
manifest/project.json{ "formatVersion": "fabled.game-project/v1", "projectId": "game-your-game-id", "projectKind": "GAME", "compilerProfile": "native-game-v1", "name": "Lantern Keepers", "entryFramework": "keeper", "frameworks": ["schemas/keeper.json", "schemas/lamp.json"], "scenarios": [ "scenarios/new-keeper.json", "scenarios/heal.json", "scenarios/new-lamp.json" ] }- Wiersz 8 Schemat Lamp dołącza do schematu Keeper.
- Wiersze 9-13 Scenariusz Lamp dołącza do scenariuszy Keepera.
Utwórz schemat Lamp.
schemas/lamp.json{ "id": "lamp", "name": "Lamp", "elementType": "item", "constructor": "rules/lamp.ts", "inputs": { "name": { "label": "Name" }, "oil": { "label": "Oil", "defaultValue": 5 } }, "frames": [{ "id": "card", "source": "layouts/lamp.json", "default": true }] }- Wiersze 6-9 Dane wejściowe elementu podrzędnego. On też potrzebuje name.
- Wiersz 10 Element podrzędny ma własną ramkę.
Utwórz jego konstruktor, ramkę i scenariusz.
rules/lamp.tsexport function construct(name: string, oil: number): { name: string; oil: number } { return { name: name, oil: oil }; }- Wiersz 1 Konstruktor zwraca dane wejściowe jako zapisane wartości.
layouts/lamp.json{ "version": "1.0", "metadata": { "name": "Lamp card", "bindingMode": "bound", "frameworkRef": "lamp", "context": "BLADE", "template": "standard-blade" }, "dataContract": { "requiredBindings": [ { "binding": "element.attributes.name", "expectedType": "string" }, { "binding": "element.attributes.oil", "expectedType": "number" } ], "optionalBindings": [], "actions": [], "regions": [] }, "layout": { "kind": "container", "children": [ { "kind": "text", "text": "{{element.attributes.name}}" }, { "kind": "text", "text": "Oil: {{element.attributes.oil}}" } ] } }- Wiersze 11-14 Każde pole, które pokazuje ramka, jest wymienione jako powiązanie.
scenarios/new-lamp.json{ "id": "new-lamp", "framework": "lamp", "parameters": { "name": "Lantern", "oil": 5 }, "expectedValues": { "name": "Lantern", "oil": 5 } }- Wiersz 4 Buduje samodzielnie Lamp i sprawdza jego wartości.
W Keeperze ukryte dane wejściowe przechowują odwołanie do frameworka, a childFrameworks przypisuje miejsce do frameworka.
schemas/keeper.json"lamp": { "label": "Lamp", "defaultValue": "lamp", "hidden": true }- Wiersz 14 Ukryte dane wejściowe nigdy nie pojawiają się w kreatorze.
schemas/keeper.json"childFrameworks": { "lamp": "lamp" }- Wiersz 31 Przypisuje miejsce lamp do frameworka o id lamp.
Konstruktor zwraca dane wejściowe Lamp obok własnych wartości.
rules/keeper.tsexport function construct( name: string, max_hp: number, calling: string, lamp: FrameworkRef, ): { values: { name: string; max_hp: number; hp: number; calling: string; guard: number }; children: { lamp: { framework: FrameworkRef; params: { name: string; oil: number } } }; } { return { values: { name: name, max_hp: max_hp, hp: max_hp, calling: calling, guard: 0 }, children: { lamp: { framework: lamp, params: { name: "Lantern", oil: 5 } } }, }; }- Wiersz 5 lamp to FrameworkRef. Platforma zamienia na niego id frameworka z danych wejściowych.
- Wiersze 6-9 Typ zwracany wymienia zapisane wartości i miejsca podrzędne.
- Wiersz 12 Miejsce podrzędne: który framework zbudować i jakie dane wejściowe mu dać.
Dodaj do scenariuszy Keepera dane wejściowe lamp i oczekuj Lamp, który buduje konstruktor.
scenarios/new-keeper.json{ "id": "new-keeper", "framework": "keeper", "parameters": { "name": "Mira", "max_hp": 10, "calling": "Guard", "lamp": "lamp" }, "expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10, "calling": "Guard", "guard": 3 }, "ledger": [{ "function": "guard", "currentValue": 0, "expected": 3 }], "expectedChildren": { "lamp": { "name": "Lantern", "oil": 5 } } }- Wiersz 8 Ukryte dane wejściowe.
- Wiersz 18 Element podrzędny, który buduje konstruktor, razem z jego wartościami.
scenarios/heal.json"parameters": { "name": "Mira", "max_hp": 10, "calling": "Guard", "lamp": "lamp" }, "expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10, "calling": "Guard", "guard": 3 },- Wiersz 8 Ukryte dane wejściowe w heal.json.
scenarios/heal.json"expectedChildren": { "lamp": { "name": "Lantern", "oil": 5 } }- Wiersz 30 Oczekiwany element podrzędny w heal.json.
Wybierz Sprawdź i wyświetl. Sprawdzenie powinno przejść, zanim ruszysz dalej.
Projekt zawiera teraz te pliki. Rozwiń dowolny fragment powyżej, aby zobaczyć cały plik.
manifest/project.json schemas/keeper.json schemas/lamp.json rules/guard.ts rules/heal.ts rules/hurt.ts rules/keeper.ts rules/lamp.ts layouts/keeper.json layouts/lamp.json scenarios/heal.json scenarios/new-keeper.json scenarios/new-lamp.json - Dodaj listę i odrzuconą akcję
Lista przechowuje treści, które postać zdobywa w grze. Pack przechowuje Trinket, czyli drugi framework, którego presety są treścią. Wpisz jego schemat i dwa scenariusze w manifeście.
manifest/project.json{ "formatVersion": "fabled.game-project/v1", "projectId": "game-your-game-id", "projectKind": "GAME", "compilerProfile": "native-game-v1", "name": "Lantern Keepers", "entryFramework": "keeper", "frameworks": [ "schemas/keeper.json", "schemas/lamp.json", "schemas/trinket.json" ], "scenarios": [ "scenarios/new-keeper.json", "scenarios/heal.json", "scenarios/new-lamp.json", "scenarios/new-trinket.json", "scenarios/pack.json" ] }- Wiersze 8-12 Schemat Trinket dołącza do pozostałych dwóch.
- Wiersze 17-18 Scenariusz Trinket i scenariusz pack.
Utwórz schemat Trinket. Jego ramka potrzebuje id, którego nie używa żadna inna ramka w grze.
schemas/trinket.json{ "id": "trinket", "name": "Trinket", "elementType": "item", "constructor": "rules/trinket.ts", "inputs": { "name": { "label": "Name" }, "weight": { "label": "Weight", "defaultValue": 1, "min": 0, "max": 5 } }, "frames": [ { "id": "trinket-card", "source": "layouts/trinket.json", "default": true } ], "content": [ { "id": "rope", "name": "Rope", "parameters": { "name": "Rope", "weight": 2 } }, { "id": "anvil", "name": "Anvil", "parameters": { "name": "Anvil", "weight": 5 } } ] }- Wiersz 8 Waga z ograniczeniami. Oferta ją odczytuje.
- Wiersze 10-16 Trinket ma własną ramkę.
- Wiersze 17-28 Presety, które gracz może spakować. Scenariusz wybiera je po id.
Utwórz jego konstruktor, ramkę i scenariusz.
rules/trinket.tsexport function construct( name: string, weight: number, ): { name: string; weight: number } { return { name: name, weight: weight }; }- Wiersz 5 Zwraca dwie zapisane wartości.
layouts/trinket.json{ "version": "1.0", "metadata": { "name": "Trinket card", "bindingMode": "bound", "frameworkRef": "trinket", "context": "BLADE", "template": "standard-blade" }, "dataContract": { "requiredBindings": [ { "binding": "element.attributes.name", "expectedType": "string" }, { "binding": "element.attributes.weight", "expectedType": "number" } ], "optionalBindings": [], "actions": [], "regions": [] }, "layout": { "kind": "container", "children": [ { "kind": "text", "text": "{{element.attributes.name}}" }, { "kind": "text", "text": "Weight: {{element.attributes.weight}}" } ] } }- Wiersze 22-23 Pokazuje nazwę i wagę.
scenarios/new-trinket.json{ "id": "new-trinket", "framework": "trinket", "parameters": { "name": "Rope", "weight": 2 }, "expectedValues": { "name": "Rope", "weight": 2 } }- Wiersz 4 Buduje samodzielnie Trinket i sprawdza jego wartości.
Zadeklaruj akcję i listę w schemacie Keeper.
schemas/keeper.json"actions": [ { "id": "hurt", "name": "Take damage", "source": "rules/hurt.ts" }, { "id": "heal", "name": "Heal", "source": "rules/heal.ts" }, { "id": "pack_trinket", "name": "Pack a trinket", "source": "rules/pack-trinket.ts" } ],- Wiersze 19-23 Nowa akcja.
schemas/keeper.json"lists": { "pack": { "label": "Pack", "of": "trinket", "max": 4 } }- Wiersz 37 Lista Pack: jej etykieta, framework treści, który przechowuje, i jej rozmiar.
Utwórz plik reguł akcji.
rules/pack-trinket.tsexport function pack_trinket(self: ElementRef, trinket: ContentRef): void { list.add(self, "pack", trinket, offer.where({ weight: { lte: 3 } })); }- Wiersz 1 Wybrany trinket przychodzi jako ContentRef.
- Wiersz 2 Oferta decyduje, co można spakować. Tylko trinkety ważące 3 lub mniej.
Oferta może odmówić, więc przetestuj oba wyniki. Utwórz scenarios/pack.json.
scenarios/pack.json{ "id": "pack-trinkets", "framework": "keeper", "parameters": { "name": "Mira", "max_hp": 10, "calling": "Guard", "lamp": "lamp" }, "expectedValues": { "name": "Mira", "max_hp": 10, "hp": 10, "calling": "Guard", "guard": 3 }, "expectedChildren": { "lamp": { "name": "Lantern", "oil": 5 } }, "actions": [ { "action": "pack_trinket", "parameters": {}, "choose": { "trinket": "rope" }, "expectedWrites": [{ "op": "list.add", "key": "pack", "value": "rope" }] }, { "action": "pack_trinket", "parameters": {}, "choose": { "trinket": "anvil" }, "expectedRefusal": "NOT_OFFERED", "expectedWrites": [] } ], "expectedLists": { "pack": ["rope"] } }- Wiersze 19-24 Przyjęty: lina jest dość lekka, więc zostaje dodana.
- Wiersze 25-31 Odrzucony: kowadło jest za ciężkie. Krok oczekuje odmowy NOT_OFFERED i braku zapisów.
- Wiersz 33 Po ostatnim kroku Pack zawiera tylko linę.
Ramka, która pokazuje listę, używa version 2.0. Zmień wersję, zadeklaruj akcję i region w dataContract oraz narysuj przycisk i region.
layouts/keeper.json"version": "2.0",- Wiersz 2 Ramki z listą używają version 2.0.
layouts/keeper.json"actions": [ { "name": "hurt", "functionRef": "hurt" }, { "name": "heal", "functionRef": "heal" }, { "name": "pack_trinket", "functionRef": "pack_trinket" } ], "regions": [{ "name": "pack", "listBinding": "element.lists.pack" }]- Wiersz 21 Alias nowej akcji.
- Wiersz 23 Deklaruje region listy.
layouts/keeper.json{ "kind": "button", "label": "Pack a trinket", "actionRef": "pack_trinket" }, { "kind": "region", "id": "pack_list", "listBinding": "{{element.lists.pack}}", "emptyText": "Your pack is empty." }- Wiersze 37-39 Przycisk, który uruchamia akcję.
- Wiersz 42 Region rysuje listę.
- Wiersz 44 Lista do narysowania.
- Wiersz 45 Pokazywane, gdy lista jest pusta.
Wybierz Sprawdź i wyświetl. Sprawdzenie powinno przejść, zanim ruszysz dalej.
Projekt zawiera teraz te pliki. Rozwiń dowolny fragment powyżej, aby zobaczyć cały plik.
manifest/project.json schemas/keeper.json schemas/lamp.json schemas/trinket.json rules/guard.ts rules/heal.ts rules/hurt.ts rules/keeper.ts rules/lamp.ts rules/pack-trinket.ts rules/trinket.ts layouts/keeper.json layouts/lamp.json layouts/trinket.json scenarios/heal.json scenarios/new-keeper.json scenarios/new-lamp.json scenarios/new-trinket.json scenarios/pack.json
Co zbudowałeś
Twój Keeper ma teraz wybór, wartość pochodną, podrzędny framework, listę z odrzuconą akcją i scenariusze, które potwierdzają każdą z tych rzeczy. Przepisy pokazują mniejsze zmiany osobno.

