Zum Hauptinhalt springen

Code-Frameworks

Layouts und Bögen

Zeichne einen Bogen mit einem Frame, binde ihn an deine Felder und verbinde seine Schaltflächen mit Aktionen.

Eine Frame-Datei

Ein Frame ist eine JSON-Datei in layouts/. Ein Framework listet ihn in frames auf. Das ist der Keeper-Bogen.

layouts/keeper.json
  "dataContract": {
    "requiredBindings": [
      { "binding": "element.attributes.name", "expectedType": "string" },
      { "binding": "element.attributes.hp", "expectedType": "number" },
      { "binding": "element.attributes.max_hp", "expectedType": "number" }
    ],
    "optionalBindings": [],
    "actions": [
      { "name": "hurt", "functionRef": "hurt" },
      { "name": "heal", "functionRef": "heal" }
    ],
    "regions": []
  },
  1. Zeilen 11-15 requiredBindings listet jedes Feld auf, das der Text nutzt, mit seinem Typ.
  2. Zeilen 17-20 Aktions-Aliase: ein Name, den Schaltflächen nutzen, und die id der Aktion, die er aufruft.
layouts/keeper.json
layouts/keeper.json
{
  "version": "1.0",
  "metadata": {
    "name": "Keeper sheet",
    "bindingMode": "bound",
    "frameworkRef": "keeper",
    "context": "BLADE",
    "template": "standard-blade"
  },
  "dataContract": {
    "requiredBindings": [
      { "binding": "element.attributes.name", "expectedType": "string" },
      { "binding": "element.attributes.hp", "expectedType": "number" },
      { "binding": "element.attributes.max_hp", "expectedType": "number" }
    ],
    "optionalBindings": [],
    "actions": [
      { "name": "hurt", "functionRef": "hurt" },
      { "name": "heal", "functionRef": "heal" }
    ],
    "regions": []
  },
  "layout": {
    "kind": "container",
    "children": [
      { "kind": "text", "text": "{{element.attributes.name}}" },
      {
        "kind": "text",
        "text": "HP: {{element.attributes.hp}} / {{element.attributes.max_hp}}"
      },
      { "kind": "button", "label": "Take damage", "actionRef": "hurt" },
      { "kind": "button", "label": "Heal", "actionRef": "heal" }
    ]
  }
}
TeilWas er enthält
versionDie Version des Frame-Formats. Nutze 1.0 oder 2.0 für einen Frame, der eine Liste zeichnet.
metadataDen Namen, bindingMode bound und frameworkRef, die ID des Frameworks, zu dem der Frame gehört. Lass context und template wie im Beispiel.
dataContractDie Felder, die der Frame liest, und die Aktionen, die seine Schaltflächen aufrufen dürfen.
layoutEin Baum aus Knoten. Das Beispiel nutzt container-, text- und button-Knoten.

Ein container nimmt Layout-Einstellungen in einem layout-Objekt neben kind. Ein text-Knoten nimmt Stil-Einstellungen wie fontSize und fontWeight. Ein Frame enthält keinen Code, keine Event-Handler und kein rohes HTML.

layouts/keeper.json
    "kind": "container",
    "layout": { "direction": "column", "gap": 12, "padding": 16 },
    "children": [
  1. Zeile 25 Die Art des Knotens.
  2. Zeile 26 Die Layout-Einstellungen: Richtung, Abstand und Innenabstand.
  3. Zeile 27 Die Knoten im Container.

Bindungen

Text zeigt einen gespeicherten Wert mit {{element.attributes.field}}. Liste jedes Feld, das du nutzt, mit seinem Typ in requiredBindings auf. Eine Bindung an ein Feld, das nicht existiert, wird abgelehnt.

{
  "kind": "text",
  "text": "HP: {{element.attributes.hp}} / {{element.attributes.mana}}"
}
FRAME_BINDING_UNKNOWN: element.attributes.mana

Schaltflächen und Aktionen

Der dataContract listet Aktions-Aliase auf. Jeder Alias hat einen name und eine functionRef, die eine Aktions-ID desselben Frameworks ist. Eine Schaltfläche nennt einen Alias in actionRef.

layouts/keeper.json
  "layout": {
    "kind": "container",
    "children": [
      { "kind": "text", "text": "{{element.attributes.name}}" },
      {
        "kind": "text",
        "text": "HP: {{element.attributes.hp}} / {{element.attributes.max_hp}}"
      },
      { "kind": "button", "label": "Take damage", "actionRef": "hurt" },
      { "kind": "button", "label": "Heal", "actionRef": "heal" }
    ]
  }
  1. Zeilen 26-30 Textknoten zeigen Felder mit doppelten geschweiften Klammern.
  2. Zeilen 31-32 Schaltflächen nennen in actionRef einen Alias aus dataContract.actions.
{ "kind": "button", "label": "Take damage", "actionRef": "mend" }
ACTION_MISSING: Action "mend" not found in framework's actionFunctions/ledgerFunctions

Würfel im Text

Schreibe einen Würfelwurf in einen Text, zum Beispiel [[1d20+{{element.attributes.guard}}]]. Der Spieler würfelt mit den üblichen Würfel-Steuerungen von Fabled. Eine gebundene Zahl muss ein deklariertes Feld sein und in requiredBindings stehen.

layouts/keeper.json
        "text": "Defend: [[1d20+{{element.attributes.guard}}]]"
  1. Zeile 39 Eine Würfel-Annotation steht in doppelten eckigen Klammern. Das Feld muss in requiredBindings stehen.

Wie ein Wurf eine Aktion erreicht

Eine Würfel-Annotation zeigt ein Würfel-Abzeichen. Klickt ein Spieler darauf, würfelt Fabled und zeigt das Ergebnis im Würfelprotokoll und im Chat des Tisches. Der Wurf schreibt nicht ins Ledger und füllt keine Aktions-Eingabe. Eine Eingabe mit dem Schlüssel roll würfelt dagegen der Server, wie unten beschrieben.

Auch eine Schaltfläche kann keinen Wert und keinen Wurf halten. Nutzt ein Spieler die Schaltfläche einer Aktion mit Eingaben, öffnet Fabled einen Dialog und fragt nach jeder Eingabe. Die Schritte sind also: würfeln, die Zahl ablesen, die Schaltfläche der Aktion nutzen und die Zahl tippen.

Schreibe diese Schritte auf den Bogen, damit die Spieler sie kennen. Die Regel muss die Zahl prüfen, denn der Dialog begrenzt sie nicht.

Damit Fabled für den Spieler würfelt, gib der Aktionseingabe einen Schlüssel roll, wie die Seite zu Framework-Schemas zeigt. Der Dialog zeigt dann eine Schaltfläche Würfeln statt eines Feldes. Der Server würfelt, und der Dialog trägt die Summe in ein Feld ein, das der Spieler nicht bearbeiten kann. Der Spieler kann erneut würfeln, und die neue Summe ersetzt die alte.

Ein Wurf wird nur einmal verbraucht. Beim Ausführen nimmt die Aktion den Wurf, den der Server gespeichert hat, sodass eine Zahl weder getippt noch zweimal verwendet werden kann. Ein neuer Wurf macht frühere unverbrauchte Würfe dieser Eingabe ungültig. Ein Wurf ist an die Kampagne gebunden, in der er gemacht wurde, und läuft nach 15 Minuten ab. Danach würfelt der Spieler erneut.

Der Wurf wird für ein Publikum im Tischprotokoll veröffentlicht. Nennt die Aktion keine Empfänger, geht er an das Wurf-Publikum des Spielers, dieselbe Einstellung wie bei seinen anderen Würfelwürfen. Alle ist ein öffentlicher Wurf, nur er ist ein Flüstern an sich selbst, und er und die SL ist ein Flüstern an sich selbst und die SL.

Eine Aktion kann mit einer Log-Vorlage eine Ergebniszeile in das Tischprotokoll schreiben. Der Abschnitt Protokollzeile einer Aktion auf der Seite Framework-Schemas zeigt, wie. Ein Wurf auf dem Bogen schreibt nur seinen eigenen Würfelwurf. Protokollzeilen werden gerade eingeführt und sind möglicherweise noch nicht in jedem Spiel verfügbar.

Ein Frame für jedes Framework

Jedes Framework hat eigene Frames. Das untergeordnete Lamp hat eine eigene Karte, die an die Lamp-Felder gebunden ist.

Weiter