Skip to content

Damage & Attacks

The expression parser supports several specialized expression types for combat.

Expressions fail with an error payload when they cannot be parsed.

Parse error at 1:13 - found token '+' ...
Lexing error at 1:5 - found token '$' ...

Returns a numeric value:

str + prof # Attack modifier
8 + prof + int # Spell save DC base
2 + 3 # Simple math

Includes dice rolls:

2d6 # Just dice
2d4 + str # Dice plus modifier
4d8 + 12 # Dice plus flat bonus

Includes damage type(s):

2d6 slashing # Single damage type
2d4 + str fire # Damage with modifier
2d6 fire + 1d8 cold # Multiple damage types
3d8 + con necrotic # Necrotic damage
4d10 + 5 necrotic or psychic # Choose one damage type when rolling

Defines a saving throw DC.

Format: DC <expression> <SAVE_TYPE>

DC 8 + prof + str STR # Strength save
DC 8 + prof + dex DEX # Dexterity save
DC 8 + prof + con CON # Constitution save
DC 8 + prof + int INT # Intelligence save
DC 8 + prof + wis WIS # Wisdom save
DC 8 + prof + cha CHA # Charisma save

Defines an attack roll bonus.

Format: Hit <expression>

Hit str + prof # Melee attack (Strength)
Hit dex + prof # Ranged attack (Dexterity)
Hit str + prof + 2 # Magic weapon (+2)
Type Description
acid Acid damage
bludgeoning Bludgeoning damage
cold Cold damage
fire Fire damage
force Force damage
lightning Lightning damage
necrotic Necrotic damage
piercing Piercing damage
poison Poison damage
psychic Psychic damage
radiant Radiant damage
slashing Slashing damage
thunder Thunder damage
hp Healing
thp Temporary hit points

You can combine multiple damage types in a single expression:

2d6 + str slashing + 2d6 fire

This creates a damage roll with:

  • 2d6 + STR modifier slashing damage
  • 2d6 fire damage

The parser tracks each damage type separately, allowing for proper resistance/immunity calculations.

Use or between damage types to offer a choice for the same roll:

{4d10 + 5 necrotic or psychic}
{2d6 fire or cold or lightning}

Clicking the rendered expression opens a damage-type selector. Choose one type and select Roll. The dice and modifier are rolled once, and the result and game log use only the chosen type. Canceling or closing the selector does not roll dice or consume a spell/power use.

or means one type, whereas + adds separate damage contributions. They can be combined:

{2d6 fire or cold + 1d8 force}

This rolls either fire or cold damage, plus the force damage. If an action contains several choices, select a type for each before any of its dice are rolled. Multi-target spell/power rolls use the selected types for all targets. Existing single-type rolls do not show a selector.

For parser consumers, unresolved alternatives are stored in the optional choices array on a kind: "damage" result, alongside the fixed damage map. Resolve every choice to an allowed damage type before generating random rolls; do not roll every alternative.

{
kind: "damage",
damage: {
fire: { avgResult: 7, dice: { d6: {...} } },
cold: { avgResult: 9, dice: { d8: {...} } }
}
}
{
kind: "save",
avgResult: 15, // The DC value
saveType: "DEX", // Which save
expression: "DC 8 + prof + int DEX"
}
{
kind: "hit",
avgResult: 7, // Attack bonus
dice: { d20: {...} }, // Always includes d20
expression: "Hit str + prof"
}