Notation Spec

FlowDice uses an AnyDice-inspired notation extended with crit modifiers, percentile pair support, Flows, Named Parameters, and reroll operators. All input methods (calculator buttons, text field) produce and parse the same notation.

Core Dice

NotationDescriptionExample
NdXRoll N dice with X faces (1–X)3d6
dXRoll 1 die with X faces (implied 1)d20
d{a,b,...}Explicit Custom Face Valuesd{1,3,5,7}
d[a..b]Range of face values (inclusive)d[0..5]
d%Percentile Pair (tens + units, 00+0=100)d%
d100Flat 1–100 (single die, no pair logic)d100

Reroll Operator (Phase 2)

NotationDescriptionExample
RReroll indefinitely on specified valued6R[1..2], d20R
rReroll once on specified valued20r, d6r[1]

See Reroll Mechanic for full documentation and binding order.

Modifiers

NotationDescriptionExample
+N / -NAdd or subtract flat valued20+5
khNKeep highest N dice (default 1)2d20kh
klNKeep lowest N dice (default 1)2d20kl
cNormal Crit: double dice count2d6c
CPerkins Crit: max one set + roll again2d6C

Implied Defaults

When a count or keep value is omitted, it defaults to 1:

  • d20 = 1d20
  • 2d20kh = 2d20kh1

The app accepts either form and displays the shorter form.

d% vs d100

These are distinct die types:

  • d100 — A single flat die producing 1–100. 2d100kl rolls two independent d100s and keeps the lowest full result.
  • d% — A Percentile Pair (tens die + units die). The 00+0=100 rule applies. 2d%kl rolls an extra tens die and keeps the lowest tens digit; the units die stays fixed (Call of Cthulhu bonus die).

Crit Mechanics

The c and C suffixes transform dice expressions into critical hit rolls. They are mutually exclusive.

  • Normal Crit (c): Doubles the number of dice. 2d6c → 4d6. Modifier applied once after.
  • Perkins Crit (C): Maxes one set and rolls again. 2d6C → 12 + 2d6. Guarantees at least max single-roll damage.

Crit scope is controlled by parenthesized grouping. (d8(<smite>?+2d8))(n20?c)+3 crits both the weapon die and smite dice together, while the +3 stays unaffected.

Flows (Phase 1 Stretch)

See Flows for full documentation.

The -> operator chains rolls. Conditional expressions resolve based on triggers:

attack_expr -> damage_expr (trigger ? result_expr [: next_cond])

Named Parameters (Phase 1 Stretch)

See Named Parameters for full documentation.

<n> triggers are user-toggled booleans. s<n> inherits from a prior flow box.

Formal Grammar

program     := expression ['->' flow_expr]
expression  := term (('+' | '-') term)*
term        := dice_expr | number
dice_expr   := [count] die_type [reroll] [keep] [crit]
count       := number
die_type    := 'd' number          — standard die (d6, d20)
            |  'd{' values '}'     — explicit face set
            |  'd[' range ']'      — face range
            |  'd%'                — percentile pair
reroll      := ('R' | 'r') ['[' values ']']              — Phase 2 reserved
keep        := 'kh' [number] | 'kl' [number]         — defaults to 1
crit        := 'c' | 'C'
number      := [0-9]+
values      := number (',' number)*
range       := number '..' number

— Flow extensions (Phase 1 stretch) —
flow_expr   := expression [cond]
cond        := '(' trigger '?' expr [':' cond] ')'
trigger     := ('n' | 't') value | '<' name '>' | 's<' name '>'
value       := number | '{' values '}' | '[' range ']'
name        := [a-zA-Z][a-zA-Z0-9_]*

Operator precedence and binding order: dice operations bind tighter than arithmetic. 2d6+4 is (2d6)+4, not 2d(6+4). For Reroll Mechanic, binding order is die definition (including reroll) → keep → crit → modifier → flow.