Skip to content

Buff Metadata

A buff is a temporary (or conditional) change to a character. It can

  • modify an attribute — Strength +6, max HP +100%, Strength at least 18, speed at most 0;
  • change a roll — advantage on Con saves, +1d4 to attacks, attacks against you have disadvantage;
  • add or remove a trait or condition — you gain Cleave, you are Chilled, you are no longer Frightened;
  • change how damage lands — resist fire, immune to poison, vulnerable to iron, Absorb 50%;
  • say something only a GM can arbitrate — "this character is plagued by bad hair days".

A buff that hurts is still a buff here — a debuff is a buff with positivity: negative. Whatever applies Chilled to a target carries a buff whose effect is condition +chilled.

Buffs are declared in the frontmatter of the page that grants them, under buffs:. Every kind of page uses the same shape:

  • power actions (docs/play/actions/**) — the buffs the action applies when used;
  • powers and feats — passive buffs that hold while the trait is held, and triggered buffs the trait applies when something happens;
  • equipment — buffs that hold while the item is equipped, and triggered ones (activations, potions);
  • conditions — what the condition does while it lasts.

This lexicon is shaped to load straight into the platform's Buff (packages/shared/src/types/buff.ts): a name, a duration and a list of effects. Each effect string below says which platform effect kind it becomes, and which ones the platform does not evaluate yet.

Shape

buffs:
  - name: Blooded            # required
    trigger: your Bite hits  # optional — absent: passive (traits, items) or on use (actions)
    on: self                 # self | target | allies | area
    duration: Con ends       # absent: inherit
    uses: 1                  # optional — ends after this many uses
    ends: you use Self-Healing   # optional — any other way it ends, as prose
    minRank: 2               # optional — character rank this buff needs
    cost: 3                  # optional — points spent to choose this option
    choice: movement         # optional — buffs sharing a choice are alternatives
    positivity: negative     # optional — positive (default) | negative | neutral
    category: Magic          # optional — what cleansing ends it
    effects:                 # required — one string per effect
      - check.str advantage
      - hit-rating +(@rank)
      - hp.temp +(5 * @level)
      - speed.walk +6

Keep the field order above. Write only the fields that say something.

name

The buff's identity: the label on the token's chip and in the breakdown of a buffed number. Use the name the prose gives it (Blooded, Bark Skin); otherwise the action, power, feat or item name. Two buffs on one page need different names (Gossamer Wings, Gossamer Wings (Levitate)).

trigger

When the buff starts, if not "always" or "when used".

  • Absent on an action: the buff starts when the action resolves.
  • Absent on a power, feat or item: the buff is passive — it holds for as long as the trait is held or the item equipped. Large is passive.
  • Present: the buff is a template that starts when the trigger happens. Write the trigger as short prose: hit, crit, failed save, activate (swift), drink, your Bite hits, you drop to 0 HP.

An action whose buff depends on the outcome writes trigger: hit (or crit, failed save), so that a miss applies nothing.

on

Who receives it.

Value Meaning
self the user of the action, the bearer of the trait or item, the creature with the condition
target whatever the action targets — one creature, or every creature its area hits
allies the user's allies the action reaches (in range, or in its area)
area every creature in the action's area, friend or foe — usually for as long as it stands in it

Default: self. Always write on on an action's buffs, even when it is self.

On a passive trait or item, allies (or area) is an aura: it holds on whoever is in range for as long as the bearer has the trait. Give the radius in a note, and say whether the bearer benefits too ("note: emanation 5; you benefit too").

The creature that hits or attacks the bearer — the target of a retaliation — is target, with the trigger naming it (trigger: a creature hits you in melee).

duration

How long it lasts once started. Absent means inherit.

Value Meaning Platform BuffDuration
inherit as long as its source: an action's own duration:; an item while equipped; a power or feat while held; a condition while it lasts a trait buff (no duration), or effect linked to the action's effect (startBuff with parent)
1 round, 5 rounds, 1 turn, 10 minutes, 8 hours, 1 day, 2 weeks, 1 month, 1 year a fixed time timed
(@rank) rounds, (2 * @rank) days a time that scales: an expression, then the unit timed
concentration until the user's concentration ends concentration
sustained while the user sustains it effect
save ends the recipient's save ends it, the save the source names save ends
Str ends Dex ends Con ends Int ends Wis ends Cha ends the recipient's save of that ability ends it save ends
Str or Dex ends the recipient's choice of either save ends it save ends
encounter until the encounter ends effect, ended by hand
until end of turn until start of next turn until end of next turn the user's turns timed (1 round)
until short rest until long rest the next rest of that kind effect, ended by a rest
until dismissed until the user ends it (a free action unless the prose says otherwise) effect, ended by hand
permanent until something removes it (Remove Curse, a GM) effect, ended by hand

Rules:

  • A buff always ends when its source goes: the item is unequipped (unless it was consumed — a potion's buff outlives the bottle), the trait is lost, the condition ends.
  • An action with no duration: of its own has nothing to inherit. Its buffs must say how long they last. So must every buff with a trigger, since a trigger is not a duration.
  • A buff that ends on the first of several things takes the most mechanical one as duration and the rest as ends. "Concentration, or Wis ends" is duration: concentration with ends: Wis save.
  • A state that lasts "while X" — while focused, while mounted, while Blooded — is trigger: <X begins>, duration: permanent, ends: <X ends>.
  • When the prose gives no duration at all, prefer encounter for combat effects and until dismissed for ones the user controls, and never guess a number.

uses

uses: 1 — the buff ends after it has applied that many times: "advantage on your next attack roll" is uses: 1 with effects: [attack advantage]. It still needs a duration for the case where it is never used.

ends

Any other way the buff ends, as prose the GM applies: ends: you take damage, ends: you attack or cast a power.

minRank

The character rank this buff requires — the same field, with the same meaning, as an action's minRank:. A trait whose benefit grows at higher ranks writes one buff per rank step, each with its minRank.

cost and choice

For powers whose user spends points on a menu of options — Grace + Rank, Overload, Corruption, Vitae, extra energy, or an arcanist's raised DC:

  • cost: N — what this option costs, in whatever the power spends (an arcanist option that raises the DC by 4 is cost: 4).
  • choice: <label> — buffs that share a label are alternatives: pick at most one of them per use. Buffs without a choice combine freely, budget permitting.

A value that scales with the points spent (rather than a menu of options) uses the @points variable instead: str >= (16 + 2 * @points).

positivity

positive (the default), negative for a debuff, neutral for a change that is neither (a disguise, a polymorph's trade-offs). The platform colours the token's chip by it.

category

What the platform's cleansing (Dispel Magic, Remove Curse) ends: Magic, Curse, Poison, Disease, Physical, Mental. Optional; write it when the prose names how the buff can be removed ("requires Remove Curse").

Effects

Each effect is one string. The subject comes first, then what happens to it. Quote any string containing : or #, and quote every note.

Attribute effects

<target> <op><value> — a number on the character. Platform kind: attribute.

Form Op Example Reads as
<target> +N / -N add str +8, dex -2, reach +1 Strength +8
<target> +N% / -N% percent hp.max +100%, speed.walk -50% max HP doubled, speed halved
<target> = V set ac = (10 + @dex.mod) AC becomes …
<target> >= V floor str >= 18, speed.fly >= (@speed.walk) Strength at least 18
<target> <= V ceiling speed.walk <= 0 speed at most 0

V is a number, or an expression in parentheses that the system works out: +(@rank), = (16 + 2 * @points), +(5 * @level), +(max(@int.mod, @wis.mod, @cha.mod)). Expressions may use + - * /, parentheses, and min() / max(). Variables:

Variable Value Whose
@rank, @level character rank and level the user's
@points points spent on this use (Grace + Rank, Overload, extra energy) the user's
@prof proficiency bonus the user's
@str … @cha an ability score the recipient's
@str.mod … @cha.mod an ability modifier the recipient's
@hp.max, @speed.walk, any target that attribute's current value the recipient's
@user.<any of the above> the same, read from the user the user's

The rule of thumb: how strong a power is comes from its user, and what it does to a body comes from that body. Fly on an ally (speed.fly >= (@speed.walk)) uses the ally's speed; a hex that subtracts the witch's casting modifier writes -(@user.cha.mod). On a self buff the two are the same creature. The user's values are taken when the buff starts.

Choosing between the ops:

  • "Set Strength to 26" on an item, "Strength becomes 18", "your Strength is at least …" — >=. A set score never lowers a higher one.
  • "gain a Fly speed equal to your walking speed" — speed.fly >= (@speed.walk). Gaining a movement type is a floor on its speed.
  • "speed is reduced to 0", "can't move" — speed.walk <= 0 (or speed.* <= 0 for every movement type). A ceiling, so no bonus undoes it.
  • "+2 AC", "+6 movement" — +.
  • "double", "halve", "50% penalty" — %. Percents of one target add together before applying: two +100% make ×3.
  • = only for formulas that replace the way a number is worked out (an AC formula). The highest = wins.

Targets

Target Meaning
str dex con int wis cha ability scores
hp current hit points (a one-off change; prefer hp.temp for a buff)
hp.max maximum hit points
hp.temp temporary hit points
ac Armor Class
initiative Initiative
prof proficiency bonus
hit-rating hit-power crit-rating crit-power armor-penetration fortification haste dominance the combat attributes, named by their page
hardness ablation the damage-reduction traits
reach melee reach, in squares
size size category steps: size +1 is one size larger
speed.<type> a movement type's speed in squares: walk fly levitate hover glide climb swim burrow earth-glide jump teleport; speed.* is every one
sense.<type> a sense's range in squares: darkvision low-light blindsight tremorsense truesight
action.<type> actions available per turn: standard move swift immediate reaction; action.* is every one
mana mana.max mana and its maximum
spell-dc the DC of the bearer's powers
any roll target below a flat bonus to that roll: save.con +2, damage +2

Roll effects

<roll> advantage | disadvantage | fail | crit or <roll> +NdM — a change to a roll. Platform kind: roll (v0.118.0; until then, applied by hand).

Roll Meaning
attack every attack roll; attack.melee attack.ranged attack.spell narrow it, and attack.str … attack.cha to attacks made with one ability
check every ability check; check.str … check.cha narrow it to one ability, check.skill.<slug> to one skill (check.skill.stealth)
save every saving throw; save.str … save.cha narrow it
damage damage rolls; damage.melee damage.ranged damage.spell damage.str (damage from Strength attacks) narrow it
initiative, concentration those rolls
parry block dodge the active defenses
against.attack attack rolls made against the bearer; against.attack.melee against.attack.ranged narrow it
Verb Example
advantage / disadvantage check.str advantage, against.attack disadvantage
fail save.str fail — fails automatically
crit against.attack crit — hits are automatic critical hits
+NdM / -NdM attack +1d4

Condition and trait effects

condition +<id> / condition -<id> — the bearer has (or no longer has) a condition, by its page's file name. Platform kind: condition.

Conditions named in prose with no page yet still use condition +<id>, by the name the prose uses: restrained, grappled, prone, charmed, incapacitated, unconscious, petrified, invisible, nauseated, panicked, dying… The platform's own default conditions include several of them, and the validator lists the ones still without a page, so that they get one. Never restate a missing condition's mechanics as effects; when the prose spells out extra mechanics of its own, add those beside it.

trait +<id> / trait -<id> — the bearer gains (or loses) a feat, power or trait, by its page's file name: trait +cleave. Platform kind: trait (not yet evaluated).

Damage effects

Platform kind: damage (not yet evaluated).

Form Example
resist <type> [N%] resist fire (50%, the usual), resist slashing 90%, resist all 25%
immune <type or condition> immune poison, immune frightened, immune critical (hits are never critical) — the same as resist <type> 100%
vulnerable <type> vulnerable iron, vulnerable radiant
absorb N% [<types>] [limit <amount>] absorb 100% limit heavy, absorb 50% physical limit (@hp.max / 4)
concealment partial / concealment total attackers suffer the miss chance of concealment
ongoing <amount> <type> ongoing medium fire, ongoing 1d6 poison, ongoing (@rank) necrotic, ongoing light healing — at the start of each of the recipient's turns, for as long as the buff lasts. <amount> is a damage tier (light medium heavy), dice, a number, or an expression; healing heals instead (regeneration, fast healing)

<type> is a damage type (fire frost lightning sonic acid poison necrotic radiant psychic arcane force bludgeoning piercing slashing radiation), a group (physical, energy, all), a material (iron, silver, magic), or a source (falling, disease; and critical for immune).

Notes

note <text> — anything the lexicon cannot say, for the GM to arbitrate. Always quote it:

      - "note: suffer 10% of max HP as internal damage each round in direct sunlight"

The colon after note is optional; it reads better on the page. A buff may be nothing but notes — that is still worth declaring, because the token carries a chip that says it is running.

What not to write

  • Damage and healing. An attack's damage lives in damage:; an instant heal is not a buff. Temporary hit points that last are (hp.temp).
  • One-off movement. "Teleport 6 squares", "push the target 2 squares" — they happen and are over.
  • Summons, walls, zones as objects. The wall is not a buff; the creatures inside it may be (on: area).
  • Rules the action is. A power whose effect is "you may cast X" or "make an attack" grants nothing to carry.
  • Prose duplicates. Never rewrite the body to match. The prose stays the rules; buffs: is what the VTT can carry.

Examples

A monster power — passive attributes (Large):

buffs:
  - name: Large
    effects: [str +8, con +4, dex -2, reach +1, size +1]

An ancestry feat — a triggered state (Vampiric Nature):

buffs:
  - name: Blooded
    trigger: your Bite hits
    on: self
    duration: Con ends
    ends: you use Self-Healing
    effects:
      - check.str advantage
      - check.dex advantage
      - check.con advantage
      - hit-rating +(@rank)
      - hit-power +(@rank)
      - hp.temp +(5 * @level)
      - speed.walk +6
      - "note: the Con save is DC 10 + 5 per round Blooded"
      - "note: suffer 10% of max HP as internal damage each round in direct sunlight"
      - "note: Frightened on holy ground, or in a private residence uninvited"

Rank-gated movement (Grace of the Fair Folk):

buffs:
  - name: Gossamer Wings
    trigger: activate (free)
    duration: until dismissed
    effects: ["speed.glide >= (@speed.walk)"]
  - name: Gossamer Wings (Levitate)
    trigger: activate (free)
    duration: until dismissed
    minRank: 2
    effects: ["speed.levitate >= (@speed.walk)"]

A passive aura (Wind's Friend):

buffs:
  - name: Tailwind
    effects: ["speed.walk +(@rank)"]
  - name: Tailwind (allies)
    on: allies
    effects: ["speed.walk +(@rank)", "note: allies within 5 squares"]

An action that debuffs on hit (Frost Arrow):

buffs:
  - name: Chilled
    trigger: hit
    on: target
    duration: Con ends
    positivity: negative
    effects: [condition +chilled]

A concentration self-buff that scales (Grant Me Strength):

buffs:
  - name: Grant Me Strength
    on: self
    effects:
      - "str >= (16 + 2 * @points)"
      - "note: if Strength is already at least that, gain +2 Strength per point instead"

A menu of options (Levitation):

buffs:
  - name: Levitation (slow)
    on: self
    cost: 2
    choice: flight
    effects: [speed.levitate >= 2, "note: maximum height 2 squares"]
  - name: Levitation (flight)
    on: self
    cost: 4
    choice: flight
    effects: ["speed.fly >= (@speed.walk)", "note: must end each turn on solid ground or fall"]

An item — worn, so passive:

buffs:
  - name: Bold Ruby
    effects: [str >= 26]

A potion — consumed, so triggered with a duration of its own:

buffs:
  - name: Potion of Giant Strength
    trigger: drink
    duration: 10 minutes
    effects: [str >= 21]

A condition (Chilled):

buffs:
  - name: Chilled
    positivity: negative
    effects: [speed.* -50%]

Checking it

node scripts/validate-buffs.mjs            # every page; errors fail, warnings list unknown names
node scripts/validate-buffs.mjs --summary  # counts by page kind, target and duration