Salta al contenuto principale

Framework in codice

Ricetta: tiro contro un'abilità

Controlla un tiro percentuale contro il valore di un'abilità e indica una fascia di successo.

Obiettivo

Fai tirare un d100 a un giocatore contro l'abilità Lore e fagli vedere una fascia: Flawless, Strong, Pass o Miss. Un tiro più basso è meglio.

Come entra il tiro

Le regole non possono tirare i dadi. Il giocatore tira sulla scheda e scrive il numero in un'azione. La regola controlla il numero e lo scrive. Il ciclo di gioco ha quattro passi.

  1. Clicca il badge dei dadi

    La scheda mostra Roll: [[1d100]]. Un clic tira un d100.

  2. Leggi il tiro nel registro

    Il risultato appare nel registro dei dadi del tavolo e nella chat. Per ora non viene scritto nulla sul personaggio.

  3. Esegui l'azione e scrivi il tiro

    Usa il pulsante Lore check. Fabled chiede il tiro in una finestra di dialogo. Scrivi il numero letto nel registro.

  4. La fascia si aggiorna

    La regola scrive il tiro e il bersaglio. La funzione del registro ricava la fascia e la scheda la mostra.

La modifica

Aggiungi allo schema un input Lore, l'azione e la funzione del registro. Un input del costruttore può avere dei limiti.

schemas/keeper.json
    "lore": {
      "label": "Lore",
      "description": "The percentile a Lore check must roll under.",
      "defaultValue": 40,
      "min": 1,
      "max": 99
    }
  1. Righe 13-14 Questi limiti valgono quando si crea un personaggio. Non valgono per il tiro.
schemas/keeper.json
    {
      "id": "check_lore",
      "name": "Lore check",
      "source": "rules/check-lore.ts",
      "inputs": { "roll": { "label": "Roll", "min": 1, "max": 100 } }
    }
  1. Righe 21-23 L'azione Lore check e il suo file di regole.
  2. Riga 24 L'input Roll: un'etichetta e dei limiti. La finestra li mostra e il server li applica.
schemas/keeper.json
  "ledgerFunctions": [
    {
      "id": "last_band",
      "name": "Last band",
      "field": "last_band",
      "source": "rules/band.ts"
    }
  ]
  1. Righe 32-35 La funzione del registro ricava last_band dai due campi che l'azione scrive.

Il costruttore restituisce i nuovi campi con dei segnaposto. La funzione del registro sostituisce last_band quando l'Elemento viene costruito.

rules/keeper.ts
export function construct(
  name: string,
  max_hp: number,
  lore: number,
): {
  name: string;
  max_hp: number;
  hp: number;
  lore: number;
  last_roll: number;
  last_target: number;
  last_band: string;
} {
  return {
    name: name,
    max_hp: max_hp,
    hp: max_hp,
    lore: lore,
    last_roll: 0,
    last_target: 0,
    last_band: "",
  };
}
  1. Righe 10-12 I campi che l'azione scrive e la funzione del registro legge.
  2. Righe 19-21 Valori iniziali: nessun tiro ancora.

I limiti dell'input tengono il tiro tra 1 e 100. L'azione ignora un numero con decimali e altrimenti scrive il tiro e il bersaglio.

rules/check-lore.ts
export function check_lore(self: ElementRef, roll: number): void {
  if (math.floor(roll) === roll) {
    const lore: number = element.var(self, "lore") as number;
    ledger.set(self, "last_target", lore);
    ledger.set(self, "last_roll", roll);
  }
}
  1. Riga 1 Il tiro è un input che il giocatore scrive.
  2. Riga 2 Ignora un numero con decimali. I limiti dell'input lo tengono già tra 1 e 100.
  3. Righe 4-5 Scrivi il bersaglio e il tiro. La fascia ne deriva.

Una funzione del registro li trasforma in una fascia. Ogni abilità può usarla, perché ogni azione di abilità scrive gli stessi due campi.

rules/band.ts
export function last_band(currentValue: string, self: ElementRef): string {
  const roll: number = element.var(self, "last_roll") as number;
  const target: number = element.var(self, "last_target") as number;
  if (roll === 0) {
    return "No roll yet";
  }
  if (roll <= math.floor(target / 5)) {
    return "Flawless";
  }
  if (roll <= math.floor(target / 2)) {
    return "Strong";
  }
  if (roll <= target) {
    return "Pass";
  }
  return "Miss";
}
  1. Righe 2-3 Leggi i due campi scritti dall'azione.
  2. Righe 4-6 Prima di ogni tiro, dillo.
  3. Righe 7-15 Un tiro più basso è meglio. Ogni fascia è una parte del bersaglio.
  4. Riga 16 Sopra il bersaglio è un Miss.

Per un'altra abilità, copia check-lore.ts e cambia il nome della funzione e il campo nella chiamata element.var. Ogni abilità ha bisogno della propria azione, perché il nome di un campo è scritto per esteso nel codice.

Mostra sulla scheda i dadi, la fascia e un pulsante. Elenca la fascia in requiredBindings e l'azione negli alias.

layouts/keeper.json
      { "binding": "element.attributes.last_band", "expectedType": "string" }
  1. Riga 15 La fascia è testo.
layouts/keeper.json
      { "name": "check_lore", "functionRef": "check_lore" }
  1. Riga 21 L'alias che usa il pulsante.
layouts/keeper.json
      { "kind": "text", "text": "Roll: [[1d100]]" },
      {
        "kind": "text",
        "text": "Last check: {{element.attributes.last_band}}"
      },
      { "kind": "button", "label": "Lore check", "actionRef": "check_lore" }
  1. Riga 35 Il badge dei dadi. Un clic tira e mostra il risultato nel registro dei dadi.
  2. Righe 36-39 La fascia ricavata dalla funzione del registro.
  3. Riga 40 Il pulsante che apre la finestra di dialogo per il tiro.

Provalo

Prova ogni fascia e un tiro fuori intervallo. Ogni passo elenca le due scritture. expectedValuesAfter controlla la fascia dopo l'azione.

scenarios/lore.json
    {
      "action": "check_lore",
      "parameters": { "roll": 6 },
      "expectedWrites": [
        { "op": "ledger.set", "key": "last_target", "value": 40 },
        { "op": "ledger.set", "key": "last_roll", "value": 6 }
      ],
      "expectedValuesAfter": { "last_band": "Flawless" }
    },
  1. Riga 17 Il numero che il giocatore ha scritto.
  2. Righe 18-21 Le due scritture, in ordine.
  3. Riga 22 La fascia derivata dopo l'azione.

L'ultimo passo è un tiro di 40,5. Non scrive nulla, quindi la protezione dai decimali è dimostrata. Un tiro di 500 non può essere un passo: è fuori dai limiti dell'input e lo scenario viene rifiutato.

scenarios/lore.json
    {
      "action": "check_lore",
      "parameters": { "roll": 40.5 },
      "expectedWrites": [],
      "expectedValuesAfter": { "last_band": "Miss" }
    }
  1. Riga 53 Un numero con decimali.
  2. Riga 54 Nessuna scrittura.
  3. Riga 55 La fascia resta come l'ha lasciata il passo precedente.

Elenca il file di scenario nel manifest. Aggiungi i nuovi campi ai valori attesi degli altri scenari.

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"],
  "scenarios": [
    "scenarios/new-keeper.json",
    "scenarios/heal.json",
    "scenarios/lore.json"
  ]
}
  1. Riga 12 Il nuovo file di scenario.

Avanti