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.
- Clicca il badge dei dadi
La scheda mostra Roll: [[1d100]]. Un clic tira un d100.
- 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.
- 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.
- 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.
"lore": {
"label": "Lore",
"description": "The percentile a Lore check must roll under.",
"defaultValue": 40,
"min": 1,
"max": 99
}- Righe 13-14 Questi limiti valgono quando si crea un personaggio. Non valgono per il tiro.
{
"id": "check_lore",
"name": "Lore check",
"source": "rules/check-lore.ts",
"inputs": { "roll": { "label": "Roll", "min": 1, "max": 100 } }
}- Righe 21-23 L'azione Lore check e il suo file di regole.
- Riga 24 L'input Roll: un'etichetta e dei limiti. La finestra li mostra e il server li applica.
"ledgerFunctions": [
{
"id": "last_band",
"name": "Last band",
"field": "last_band",
"source": "rules/band.ts"
}
]- 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.
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: "",
};
}- Righe 10-12 I campi che l'azione scrive e la funzione del registro legge.
- 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.
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);
}
}- Riga 1 Il tiro è un input che il giocatore scrive.
- Riga 2 Ignora un numero con decimali. I limiti dell'input lo tengono già tra 1 e 100.
- 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.
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";
}- Righe 2-3 Leggi i due campi scritti dall'azione.
- Righe 4-6 Prima di ogni tiro, dillo.
- Righe 7-15 Un tiro più basso è meglio. Ogni fascia è una parte del bersaglio.
- 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.
{ "binding": "element.attributes.last_band", "expectedType": "string" }- Riga 15 La fascia è testo.
{ "name": "check_lore", "functionRef": "check_lore" }- Riga 21 L'alias che usa il pulsante.
{ "kind": "text", "text": "Roll: [[1d100]]" },
{
"kind": "text",
"text": "Last check: {{element.attributes.last_band}}"
},
{ "kind": "button", "label": "Lore check", "actionRef": "check_lore" }- Riga 35 Il badge dei dadi. Un clic tira e mostra il risultato nel registro dei dadi.
- Righe 36-39 La fascia ricavata dalla funzione del registro.
- 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.
{
"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" }
},- Riga 17 Il numero che il giocatore ha scritto.
- Righe 18-21 Le due scritture, in ordine.
- 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.
{
"action": "check_lore",
"parameters": { "roll": 40.5 },
"expectedWrites": [],
"expectedValuesAfter": { "last_band": "Miss" }
}- Riga 53 Un numero con decimali.
- Riga 54 Nessuna scrittura.
- 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.
{
"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"
]
}- Riga 12 Il nuovo file di scenario.

