The dice language Contents

Rule systems

The dice language

The formulas behind every sentence: dice notation, values a roll can read, how a roll is read, with recipes for common mechanics.

One small language under every sentence

Every number in a rule system is either a plain number or a formula in one small language: the dice a check rolls, a target, a track's maximum, a stat's modifier, an enemy's health by tier, an amount on a rule card. You rarely need to write one: the sentence editor, the composer and Hob write them for you. The Advanced tab shows them all when you want to.

It is deliberately small. It is not a programming language: no loops, no reaching outside the values it's handed, nothing that can misbehave. A formula that doesn't make sense is refused when you save, in a sentence saying what's wrong.

Advanced: each check's roll and target, each track's maximum, each derived value's formula
Studio › Rules › Advanced: the formulas behind every sentence, each in its own field. Everything else the system holds is here too, as editable data.
The editor's footer: unsaved changes, one problem, written as a sentence
A broken formula is caught as you type, explained in words, and can't be saved.

Dice

WriteMeansExample
d20One twenty-sided die13
3d6Three six-sided dice, added4 + 2 + 6 = 12
2d20kh1Two d20s, keep the highest one (advantage)(7, 16) → 16
2d20kl1Keep the lowest one (disadvantage)(19, 7) → 7
4d6kh3Four d6s, keep the best three(5, 2, 6, 3) → 14
(@stat)d6As many dice as a value saysProwl 3 → 3d6
d(@dexterity)A die as big as a value says, for games where a stat is a dieDexterity 10 → d10
6d10>=6Count the dice at or over 6: the value is the count(2, 6, 9, 10, 1, 7) → 4
3d6!Exploding: a top face rolls another die(6, 2, 4) + 5 → 17
4dFFate dice: each −1, 0 or +1(+, 0, −, +) → +1
d100Percentile; d% is the same47
d100t(1)Percentile with a bonus tens die (keep the better tens); t(-1) a penalty die(4 or 7, 3) → 43
d12[Hope]A die with a name: shown with its name, and readable by rule cardsHope d12 (9)

Every face is kept in the roll's record, so the dice tray can replay it and the roll chip can show it. All dice roll from a seed: the same roll, rolled again for the same turn, gives the same faces.

Numbers and logic

Arithmetic
+ - * / and brackets: floor((@str - 10) / 2)
Comparisons
> >= < <= == !=, giving 1 or 0: @hp < 5
Logic
and, or, not: @cond.blessed > 0 and @nerve >= 3
Choices
if … then … else …: if @level >= 5 then 2 else 1. Only the branch taken is worked out, so only its dice are rolled.
Functions
floor ceil round abs min max clamp: clamp(@edge + @cond.edge, -1, 1)

Values a formula can read

WriteWhat it isWhere
@strA stat's value (by its id)Anywhere
@str.modA stat's modifier: its value when it has noneAnywhere
@statThe stat being rolled; @stat.mod its modifierA check's roll and target
@hpA track's current value; @hp.max its maximumAnywhere
@proficiencyA derived value (by its id)Anywhere
@levelThe character's level; @xp their xp. In an ability set to Scales with the level in a class, its own uses, cost, effects and modifiers read @level as their level in that class, while they hold itAnywhere
@class.hit_dieWhat their class says for a value (the system's default when it says nothing, worked out as that class's own; else 0). With several classes, each class's adds up: added together, the highest or their first class's, as the system setsAnywhere
@classlevel.wizardTheir level in a class (by its id), 0 when they don't hold itAnywhere
@classlevelTheir level in this class: 2 * @classlevel grows with each level in itA class's own values, and the system's class defaults
@classfirst1 for the class they took first, 0 for any other: what only the first class getsA class's own values, and the system's class defaults
@own.hit_dieThis class's own value of another name (its hit die), where @class.hit_die would read the added-up oneA class's own values, and the system's class defaults
@classesHow many classes they hold; @mastered how many are at their capAnywhere
@rankThis ability's rank: 1 when first taken, one more each time it is taken againAn ability's own cost, effects, uses and modifiers
@rank.toughenedAn ability's rank (by its id), 0 when they don't know itAnywhere
@difficultyThe number behind the word the storyteller picked for a label (Hard → 20). Every label is readable by its id: @edge, @position.A check's roll and target
@spend_push1 if the player paid that spend before the roll, else 0A check's roll
@cond.edgeWhat the sheet's conditions add up to as edge; @cond.mod as a bonus or penaltyA check's roll
@cond.poisonedA condition's level (0 when absent); @cond.poisoned.left its ticks leftAnywhere
@opp.insight.modThe opponent's stat or modifier, when a roll is aimed at someone present; @opp.tier their tierA check's opposed targets
@defenceThe defender's defenceThe attack check
@secondA value the blow reads beside its stat, by the name the system or the weapon gives it (What every attack reads, What its attack reads): the second die of a two-stat roll, or any other name (@accuracy, @weapon_die)The attack check and damage
@tierThe enemy's tier, 1 to 6Enemy templates
@thisThe stat itself; @linked the stat it leans onA stat's modifier
@group.Hope.highA named die's highest face; also .tops (top faces), .ones, .successes, .valueOutcomes and rule cards after a roll
@totalThe roll's total; also @target, @margin (total − target), @measureOutcomes and rule cards after a roll
@event.amountThe damage of the blow that set off the cardDamage cards
@roll.highThe highest die of the attack roll that landed the blow; @roll.low its lowest; @group.First.value a named die. @roll.high + 5 is a High Roll, with no dice of its ownDamage (weapons, abilities, enemies, the player's)
@thing.ship.hullA value on the character's first thing of a kindAnywhere

How a roll is read

A check has a roll and a way of reading it. The reading turns the dice into the outcome bands' measure:

ReadingMeasureOptions
Total against a targetA degree: −1 fumble, 0 failure, 1 success, 2 criticalsteps: beat the target by this much for a critical, miss by it for a fumble (PF2e: 10). naturals: a top or bottom face on the first die sets or shifts the degree.
Total into bandsThe total itselfBands by range: 10+, 7-9, 6- (PbtA).
Roll underA grade: −1 fumble, 0 failure, 1 success, 2 hard, 3 extremegrades (fractions of the target), what counts as a critical (a 1, rolling exactly the target, doubles), what fumbles, faces that always pass or fail, success levels instead of grades, or the roll's own tens die (roll under but high: higher is better).
Highest dieThe best face; several top faces count one higherForged in the Dark.
Count successesThe countPairs of a face as extra successes and a critical (tens in a d10 pool).

On top of any reading, a check can compare two named dice (Hope against Fear): which came up higher adds a word to the outcome and its own effects; equal dice can be a critical (or only from a face up, like doubles of 6 or more), and low equal dice a fumble (double 1s).

Recipes

Fifth-edition advantage, with conditions and exhaustion

(if @edge + clamp(@cond.edge + (if @exhaustion >= 1 then -1 else 0), -1, 1) > 0 then 2d20kh1
 else if @edge + clamp(@cond.edge + (if @exhaustion >= 1 then -1 else 0), -1, 1) < 0 then 2d20kl1
 else d20) + @stat.mod + @cond.mod

Classic d20's ability check: any number of disadvantages and advantages count once either way.

Pushing yourself for an extra die

if @stat + @spend_push <= 0 then 2d6kl1 else (@stat + @spend_push)d6

Forged in the Dark: zero dots rolls two and keeps the lower; paying the “push” spend (2 Stress) adds a die.

Hope, Fear, and a d6 if you spend Hope

d12[Hope] + d12[Fear] + @stat + (if @spend_hope > 0 then d6 else 0)

Two stat dice: a stat is a die

d(@stat)[First] + d(if @second_stat == 1 then @dexterity else @insight)[Second] + @cond.mod
read:  total against @difficulty; matching dice of 6 or more are a critical, double 1s a fumble

attack: d(@stat)[First] + d(@second)[Second]     reads: { "second": "@might" }

The composer's two stat dice engine: each stat is a die size (d6 to d12), and the second die is the stat a word the judge picks names. A stat shown as a die always reads as a real one: a +1 from gear leaves a d8 a d8, a +2 makes it a d10. A condition that moves a stat by steps is already in @stat: Dazed, one step down on Insight, rolls a d10 Insight as d8. See Conditions that move a stat. A blow's second die is @second, which every attack reads as the fighting stat; a staff whose reads say { "second": "willpower" } rolls WLP + WLP. See What its attack reads.

A number that grows with a class

"values": { "caster": "@classlevel", "kit": "2 * @classlevel", "hp": "5" }

A class's own values, under several classes: a caster level, 2 kit points a class level, and +5 Hit Points for holding it at all. Added together across their classes, a wizard 2 / cleric 3 has a caster level of 5. A heroic ability gated on mastery reads @classlevel.sentinel >= 10 or @mastered >= 1. See Numbers across classes.

Hit points by each class's die

"hit_points": "@classfirst * (floor(@own.hit_die / 2) - 1) + @classlevel * (floor(@own.hit_die / 2) + 1)"

Classic d20's class default, worked out once for each class they hold: the first class's whole die at its first level, the die's average every level after, and a later class's average from its first. A Fighter 1 / Wizard 1 gets 10 + 4. See A default worked out per class.

Percentile with bonus and penalty dice

d100t(@edge)                       read: roll under, target @stat.mod * @difficulty

A hunger pool: some dice are dangerous

(@stat - @hunger)d10>=6 + (@hunger)d10[Hunger]>=6

Count successes across both groups; then a rule card reads @group.Hunger.ones to turn a failure with a 1 on a Hunger die into something worse.

Degrees of success by ten

roll:  d20 + @stat.mod
read:  total against @difficulty, steps 10, naturals 20 / 1 shift the degree

An opposed lie

opposed: { "deception": "10 + @opp.insight.mod" }

A lie told to someone present is rolled against their passive Insight instead of a difficulty.