Framework in codice
Schemi dei Framework
Dichiara input, azioni, valori derivati, Frame, contenuti e Framework figli per un tipo di Elemento.
Un file Framework
Ogni file in schemas/ dichiara un Framework. Le pagine di riferimento fanno crescere il Keeper dell'avvio rapido. Ora ha una scelta Calling, un valore derivato Guard, un preset già pronto, una sezione e un Lamp figlio.
manifest/project.json
schemas/keeper.json
schemas/lamp.json
rules/keeper.ts
rules/lamp.ts
rules/hurt.ts
rules/heal.ts
rules/guard.ts
layouts/keeper.json
layouts/lamp.json
scenarios/new-keeper.json
scenarios/heal.json
scenarios/new-lamp.jsonCampi principali
| Campo | Obbligatorio | Significato |
|---|---|---|
| id | Sì | L'id univoco del Framework. Lo usano il manifest e gli scenari. |
| name | Sì | Il nome mostrato. |
| elementType | Sì | Cosa costruisce: character per i personaggi giocabili, item per gli oggetti, spell per gli incantesimi. Sono ammessi tipi personalizzati. |
| constructor | Sì | Il percorso del file di regole che costruisce un nuovo Elemento. |
| inputs | No | Cosa inserisce il giocatore quando crea un Elemento. Ogni chiave corrisponde a un parametro del constructor. |
| actions | No | Cose che un Elemento può fare. Ognuna ha un id, un nome e un file di regole. |
| ledgerFunctions | No | Valori derivati. Ognuno punta a un campo memorizzato e ha un file di regole. |
| frames | Sì | Da uno a sedici Frame. Esattamente uno ha default impostato su true. |
| sections | No | Raggruppa gli input in passaggi della procedura guidata di creazione. |
| content | No | Preset già pronti. Ognuno ha un id, un nome e dei valori di input. |
| childFrameworks | No | Collega il nome di uno slot figlio a un altro Framework dello stesso gioco. |
In un GAME, il Framework di ingresso nel manifest deve essere un personaggio giocabile.
The entry framework must be a character constructor.Input
Un input personalizza un parametro del constructor e la sua chiave deve corrispondere al nome del parametro. La maggior parte degli input ha bisogno solo di una label. Le altre chiavi restringono ciò che un giocatore può inserire.
"inputs": {
"name": { "label": "Name" },
"max_hp": {
"label": "Maximum HP",
"description": "How much damage a Keeper can take.",
"defaultValue": 10,
"min": 1,
"max": 40
},
"calling": {
"label": "Calling",
"options": ["Guard", "Scout"],
"defaultValue": "Guard"
},
"lamp": { "label": "Lamp", "defaultValue": "lamp", "hidden": true }
},- Righe 8-14 min e max limitano un numero. Uno scenario o un preset fuori dai limiti fallisce.
- Righe 15-19 options dà un elenco fisso di scelte. Il valore predefinito deve essere una di esse.
- Riga 20 Un input hidden contiene un valore che il giocatore non vede mai. Qui collega la Lamp figlia.
schemas/keeper.json
{
"id": "keeper",
"name": "Keeper",
"elementType": "character",
"constructor": "rules/keeper.ts",
"inputs": {
"name": { "label": "Name" },
"max_hp": {
"label": "Maximum HP",
"description": "How much damage a Keeper can take.",
"defaultValue": 10,
"min": 1,
"max": 40
},
"calling": {
"label": "Calling",
"options": ["Guard", "Scout"],
"defaultValue": "Guard"
},
"lamp": { "label": "Lamp", "defaultValue": "lamp", "hidden": true }
},
"childFrameworks": { "lamp": "lamp" },
"sections": [
{
"id": "basics",
"title": "Basics",
"inputs": ["name", "max_hp", "calling", "lamp"]
}
],
"actions": [
{ "id": "hurt", "name": "Take damage", "source": "rules/hurt.ts" },
{ "id": "heal", "name": "Heal", "source": "rules/heal.ts" }
],
"ledgerFunctions": [
{
"id": "guard",
"name": "Guard",
"field": "guard",
"source": "rules/guard.ts"
}
],
"frames": [
{ "id": "sheet", "source": "layouts/keeper.json", "default": true }
],
"content": [
{
"id": "mira-scout",
"name": "Mira the Scout",
"parameters": {
"name": "Mira",
"max_hp": 8,
"calling": "Scout",
"lamp": "lamp"
}
}
]
}| Chiave | Significato |
|---|---|
| label | Il testo mostrato al giocatore. |
| description | Testo di aiuto, fino a 1024 caratteri. |
| defaultValue | Il valore usato quando il giocatore non tocca l'input. |
| options | Un elenco fisso da 2 a 128 scelte di testo, ognuna fino a 128 caratteri. Il valore predefinito deve essere una di esse. |
| optionLabels | Etichette mostrate al giocatore per le opzioni. Il valore memorizzato resta l'opzione. |
| min, max | Limiti per un numero. min non deve superare max. |
| minLength, maxLength | Limiti per la lunghezza di un testo. |
| required | Imposta su false per lasciare che il giocatore lasci l'input vuoto. |
| hidden | Tiene l'input fuori dalla procedura guidata. Un input nascosto ha bisogno di un defaultValue. |
| visibleWhen | Mostra l'input solo finché vale una condizione su altri input. |
Un valore predefinito che non è tra le opzioni viene rifiutato.
{
"calling": {
"label": "Calling",
"options": ["Guard", "Scout"],
"defaultValue": "Mage"
}
}Default for calling must be one of its options ("Guard", "Scout").Anche scenari e preset devono rispettare i limiti.
Parameter max_hp 99 is not between 1 and 40.Un input nascosto senza valore predefinito fallisce con:
Input name is hidden, so it must declare a defaultValue.Azioni e funzioni del registro
Ogni azione ha un id, un nome e un file sorgente. Ogni funzione del registro ha gli stessi, più un campo. Il campo è il valore memorizzato che la funzione ricava e deve essere un campo scalare restituito dal constructor. Una funzione del registro legge i valori e restituisce quello derivato. Non scrive mai.
"ledgerFunctions": [
{
"id": "guard",
"name": "Guard",
"field": "guard",
"source": "rules/guard.ts"
}
],- Righe 36-39 id e name identificano la funzione, field è il valore salvato che ricava e source è il suo file di regole.
function 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);
}- Righe 1-3 Una funzione di supporto. Non ha export e la funzione del registro la chiama per nome.
- Riga 5 Una funzione del registro riceve il suo valore attuale e l'Elemento.
- Riga 6 Leggi i valori salvati con element.var.
- Riga 7 Restituisci il valore derivato.
Ledger function must target an existing scalar field.Gli id devono essere unici all'interno di un Framework. Azioni e funzioni del registro condividono un unico insieme di id.
Duplicate semantic identity or source path.Due funzioni del registro possono condividere un file sorgente. Un'azione e una funzione del registro no:
action source does not match its owner contractInput delle azioni
Gli input di un'azione sono i parametri della sua funzione. La firma li dichiara e lo schema può aggiungere una voce per ciascuno. Ogni input è un numero, un testo o un valore vero/falso.
Al giocatore viene chiesto ogni input in una finestra quando usa il pulsante. La finestra indica un input con il nome del suo parametro, a meno che la voce non gli dia un'etichetta. Una voce può anche dare una descrizione e un valore predefinito. Un input numerico può avere un minimo e un massimo. Un input di testo può avere un elenco di opzioni o opzioni da una tabella. La finestra mostra tutto, e il server rifiuta un valore fuori dai limiti o dalle opzioni. Un pulsante non può fornire un valore. Dai a ogni parametro un nome che il giocatore possa leggere: roll, non r.
{
"id": "check_lore",
"name": "Lore check",
"source": "rules/check-lore.ts",
"inputs": { "roll": { "label": "Roll", "min": 1, "max": 100 } }
}- Riga 24 La voce dell'input del tiro. La finestra mostra l'etichetta e il server applica minimo e massimo.
Un minimo e un massimo non impediscono un numero con decimali. Se la regola richiede un numero intero, lo controlla da sé, e un passo dello scenario lo dimostra. Un passo dello scenario fuori dai limiti viene rifiutato.
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.
Un input di testo può invece offrire un elenco di scelte da una tabella del regolamento. La pagina Tabelle del regolamento mostra come.
Un input di testo può invece scegliere per nome uno dei campi memorizzati del Framework, con un elenco fields. La pagina Scrivere le regole mostra un'azione che lo usa.
Un input numerico può chiedere al server di tirarlo. Aggiungi una chiave roll con un'espressione di dadi, come "roll": "1d100" o "roll": "2d6+1". La finestra mostra allora un pulsante Tira al posto di un campo da digitare. Il server tira e la finestra mostra il totale, che il giocatore non può cambiare. Solo un parametro numerico può essere tirato. Il compilatore rifiuta un roll insieme a un defaultValue e rifiuta un'espressione di dadi che il server non accetta.
Un input tirato si spende una sola volta: l'azione prende il tiro quando viene eseguita, e un nuovo tiro annulla i precedenti non spesi di quell'input. Un tiro è legato alla sua campagna e scade dopo 15 minuti. La pagina Layout e schede mostra cosa vede il tavolo.
Riga di registro di un'azione
Un'azione può pubblicare una riga di risultato nel registro del tavolo. Aggiungi un modello di registro alla voce dell'azione nello schema, per esempio "log": "{name} takes {amount} damage, defense {defense}". Il server riempie ogni segnaposto {name} come testo semplice dopo il salvataggio dell'azione. Un browser non invia mai la riga.
Un segnaposto può indicare un input dell'azione, o un campo numerico, di testo o vero/falso dello stesso Framework. Il compilatore rifiuta un input nascosto, un campo di salute (hp, current_hp, hit_points, temp_hp, current_health, max_health, hitPoints, e i campi di salute e di condizione del blocco di combattimento), un nome che non esiste, un modello di più di 200 caratteri, più di 16 segnaposto, una graffa isolata e un carattere di controllo. Quando un input e un campo hanno lo stesso nome, vince l'input. I valori sono quelli dopo l'azione, quindi un campo scritto dall'azione mostra il suo nuovo valore. Un campo calcolato non viene ricalcolato, quindi mostra il valore che aveva prima dell'azione.
Un giocatore che agisce sul proprio personaggio vede la riga allo stesso pubblico dei suoi tiri di dado: tutti, solo lui, oppure lui e i GM. In ogni altro caso, compreso un GM che agisce su qualsiasi personaggio, la riga arriva solo ai membri della campagna che possono leggere quel personaggio. Se il pubblico è tutti ma un membro non può leggere il personaggio, la riga va come messaggio privato ai membri che possono. Il tavolo mostra la riga con l'etichetta Gioco, così nessuno la scambia per il messaggio di un giocatore.
Preset di contenuto
Un preset è un insieme di valori di input con un nome, come un personaggio già pronto. Fabled controlla ogni preset come uno scenario, quindi ogni valore deve rispettare il suo input. Un gioco può contenere fino a 512 preset per Framework.
"content": [
{
"id": "mira-scout",
"name": "Mira the Scout",
"parameters": {
"name": "Mira",
"max_hp": 8,
"calling": "Scout",
"lamp": "lamp"
}
}
]- Righe 47-48 Un preset ha un id e un name.
- Righe 49-54 I valori di input che il preset compila. Devono rispettare i limiti degli input.
Sezioni
Le sezioni raggruppano gli input in passaggi della procedura guidata di creazione. Quando un Framework dichiara sezioni, ogni input deve essere elencato in una di esse, compresi gli input nascosti.
"sections": [
{
"id": "basics",
"title": "Basics",
"inputs": ["name", "max_hp", "calling", "lamp"]
}
],- Righe 25-27 Una sezione ha un id, un title e gli input che mostra. Ogni input deve stare in una sezione.
Input lamp is not assigned to any section.Framework figli
Un Framework figlio è una parte di un Elemento più grande, come il Lamp che porta un Keeper. Il figlio ha il proprio schema, constructor, Frame e scenario.
"childFrameworks": { "lamp": "lamp" },- Riga 22 Collega lo slot figlio lamp al Framework con l'id lamp.
{
"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 }]
}- Righe 6-9 Gli input del figlio. Anche un figlio ha bisogno di un name.
- Riga 10 Il figlio ha un suo Frame.
Il genitore collega il nome di uno slot a un id di Framework in childFrameworks. Un input nascosto contiene il riferimento. Il constructor restituisce gli input del figlio accanto ai propri valori.
export 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 } } },
};
}- Riga 5 lamp è un FrameworkRef. La piattaforma trasforma in uno di questi l'id del Framework preso dall'input.
- Righe 6-9 Il tipo di ritorno elenca i valori salvati e gli slot figlio.
- Riga 11 I valori iniziali del Keeper.
- Riga 12 Lo slot figlio: quale Framework costruire e gli input da dargli.
Ogni Framework, figli compresi, deve restituire un nome.
must define the required 'name' value, normally as a string constructor field.Uno slot che punta a un Framework fuori dal gioco fallisce con:
Invalid child Framework constraint: lamp.Campi avanzati
| Campo | Scopo |
|---|---|
| lists | Contenuti che un personaggio ottiene durante il gioco. |
| contentChoices | Punti di scelta in cui il giocatore sceglie una voce di un Framework di contenuti. |
| slots | Selettori per scelte ripetibili. |
| pools | Riserve condivise da cui attingono gli input numerici. |
| modifiers | Numeri che la piattaforma ricava dagli effetti dei contenuti. |
| effects | Come un Framework di contenuti indica un modificatore e una quantità. |
| levelling | Far salire o scendere un personaggio di un livello dopo la creazione. |
| rebuild | Cosa fa una ricostruzione allo stato di gioco, come un cambio di livello. |
| combat | I ruoli che gli strumenti di combattimento del tavolo leggono. |
| catalogue | Record di contenuti tenuti fuori dal sorgente e aggiunti a blocchi. |
| tables | Tabelle di dati condivise. |
| playReads | Valori derivati che il tavolo legge dagli attributi salvati. |
| rulesAttacks | Attacchi che ogni personaggio possiede. |
| optionsFrom | Prende le opzioni di un input da un'altra fonte. |
| rich, richText | Segna un input di testo come testo formattato. |

