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 atrigger, since a trigger is not a duration. - A buff that ends on the first of several things takes the most mechanical one as
durationand the rest asends. "Concentration, or Wis ends" isduration: concentrationwithends: 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
encounterfor combat effects anduntil dismissedfor 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 iscost: 4).choice: <label>— buffs that share a label are alternatives: pick at most one of them per use. Buffs without achoicecombine 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(orspeed.* <= 0for 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