Pular para o conteúdo principal

Code frameworks

Receita: rolar contra uma perícia

Confira uma rolagem percentual contra o valor de uma perícia e informe uma faixa de sucesso.

Objetivo

Deixe um jogador rolar um d100 contra uma perícia Lore e ver uma faixa: Flawless, Strong, Pass ou Miss. Uma rolagem menor é melhor.

Como a rolagem entra

As regras não rolam dados. O jogador rola na ficha e digita o número em uma ação. A regra valida o número e o escreve. O ciclo de jogo tem quatro passos.

  1. Clique no emblema do dado

    A ficha mostra Roll: [[1d100]]. Um clique rola um d100.

  2. Leia a rolagem no registro

    O resultado aparece no registro de dados da mesa e no chat. Nada é escrito no personagem ainda.

  3. Execute a ação e digite a rolagem

    Use o botão Lore check. O Fabled pede a rolagem em uma caixa de diálogo. Digite o número do registro.

  4. A faixa é atualizada

    A regra escreve a rolagem e o alvo. A função de ledger deriva a faixa, e a ficha a mostra.

A mudança

Adicione ao schema uma entrada Lore, a ação e a função de ledger. Uma entrada de constructor pode ter limites.

schemas/keeper.json
    "lore": {
      "label": "Lore",
      "description": "The percentile a Lore check must roll under.",
      "defaultValue": 40,
      "min": 1,
      "max": 99
    }
  1. Linhas 13-14 Estes limites valem quando um personagem é criado. Eles não valem para a rolagem.
schemas/keeper.json
    {
      "id": "check_lore",
      "name": "Lore check",
      "source": "rules/check-lore.ts",
      "inputs": { "roll": { "label": "Roll", "min": 1, "max": 100 } }
    }
  1. Linhas 21-23 A ação de teste de Lore e o seu arquivo de regras.
  2. Linha 24 A entrada Roll: um rótulo e limites. O diálogo os mostra e o servidor os impõe.
schemas/keeper.json
  "ledgerFunctions": [
    {
      "id": "last_band",
      "name": "Last band",
      "field": "last_band",
      "source": "rules/band.ts"
    }
  ]
  1. Linhas 32-35 A função de ledger deriva last_band dos dois campos que a ação escreve.

O constructor devolve os novos campos com valores provisórios. A função de ledger substitui last_band quando o Element é criado.

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. Linhas 10-12 Os campos que a ação escreve e a função de ledger lê.
  2. Linhas 19-21 Valores iniciais: ainda sem rolagem.

Os limites da entrada mantêm a rolagem entre 1 e 100. A ação ignora um número com casas decimais e, caso contrário, escreve a rolagem e o alvo.

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. Linha 1 A rolagem é uma entrada que o jogador digita.
  2. Linha 2 Ignore um número com casas decimais. Os limites da entrada já o mantêm entre 1 e 100.
  3. Linhas 4-5 Escreva o alvo e a rolagem. A faixa vem deles.

Uma função de ledger os transforma em uma faixa. Toda perícia pode usá-la, porque toda ação de perícia escreve os mesmos dois campos.

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. Linhas 2-3 Leia os dois campos que a ação escreveu.
  2. Linhas 4-6 Antes de qualquer rolagem, diga isso.
  3. Linhas 7-15 Uma rolagem menor é melhor. Cada faixa é uma parte do alvo.
  4. Linha 16 Acima do alvo é um Miss.

Para outra perícia, copie check-lore.ts e mude o nome da função e o campo na chamada element.var. Cada perícia precisa da sua própria ação, porque o nome de um campo é escrito por extenso no código.

Mostre os dados, a faixa e um botão na ficha. Liste a faixa em requiredBindings e a ação nos aliases.

layouts/keeper.json
      { "binding": "element.attributes.last_band", "expectedType": "string" }
  1. Linha 15 A faixa é texto.
layouts/keeper.json
      { "name": "check_lore", "functionRef": "check_lore" }
  1. Linha 21 O alias que o botão usa.
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. Linha 35 O selo de dados. Um clique rola e mostra o resultado no registro de dados.
  2. Linhas 36-39 A faixa que a função de ledger derivou.
  3. Linha 40 O botão que abre a caixa de diálogo da rolagem.

Teste

Teste cada faixa, e uma rolagem fora do intervalo. Cada passo lista as duas escritas. expectedValuesAfter confere a faixa depois da ação.

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. Linha 17 O número que o jogador digitou.
  2. Linhas 18-21 As duas escritas, em ordem.
  3. Linha 22 A faixa derivada depois da ação.

O último passo é uma rolagem de 40,5. Não escreve nada, então a proteção contra decimais fica comprovada. Uma rolagem de 500 não pode ser um passo: está fora dos limites da entrada e o cenário é recusado.

scenarios/lore.json
    {
      "action": "check_lore",
      "parameters": { "roll": 40.5 },
      "expectedWrites": [],
      "expectedValuesAfter": { "last_band": "Miss" }
    }
  1. Linha 53 Um número com casas decimais.
  2. Linha 54 Nenhuma escrita.
  3. Linha 55 A faixa fica como o passo anterior a deixou.

Liste o arquivo de cenário no manifesto. Adicione os novos campos aos valores esperados dos outros cenários.

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. Linha 12 O novo arquivo de cenário.

Próximo