Skip to content

Result fields

A result reports each group of dice separately. A group is one run of dice with the same number of sides, so 1d8+1d4+3 comes back as two groups and a modifier.

{
"formula": "4d6kh3",
"dice": [
{
"sides": 6,
"sign": 1,
"results": [5, 4, 5, 3],
"kept": [5, 5, 4],
"keptFlags": [true, true, true, false],
"multiplier": 1,
"total": 14,
"naturalHigh": false,
"naturalLow": false
}
],
"modifier": 0,
"modifiers": [],
"total": 14,
"advantageState": "normal"
}
Field Type Meaning
formula string the formula as given, with whitespace trimmed
dice array one entry per group of dice
modifier integer the sum of the flat modifiers; dice are not counted here
modifiers array of integers each flat modifier separately, in the order written
total integer the answer
advantageState string normal, advantage or disadvantage
tag string, optional the trailing tag, when the formula carried one the request recognises

modifiers is a list rather than a single number so that +1 -6 can be shown as it was written. Their sum of -5 is true and says nothing about where the numbers came from.

tag is absent rather than null when there is no tag.

Field Type Meaning
sides integer how many faces these dice have
sign 1 or -1 whether the group adds to or subtracts from the total
results array of integers every die rolled, in the order rolled, dropped ones included
kept array of integers the values that counted towards the total
keptFlags array of booleans aligned to results: whether each entry counted
multiplier integer what the kept dice were multiplied by, 1 unless the formula said otherwise
total integer this group’s signed contribution to the total
naturalHigh boolean the one kept die showed its highest face
naturalLow boolean the one kept die came up 1

kept is in the order the dice were rolled, except when a keep rule sorted them: 4d6kh3 leaves them highest first, 2d6 leaves them as they fell.

keptFlags has the same length as results and the same order. kept does not: it holds values with no link back to the entries they came from. When you need to know which die was dropped rather than which values survived, read the flags.

Why every die comes back covers the reasoning, and Show the working in a UI renders it.

Normally 1 to sides. The one exception is penetrating dice: a penetrated 1 is recorded as 0, so 1d6!p can put a zero in results. Nothing else produces a value below 1.

A formula that sets a floor or a ceiling puts that bound in results too, as a value the dice competed against. 1d6min3 rolling a 1 comes back as results [1, 3] and kept [3]: the bound won, and the 1 it beat is still on the record. A bound can sit above sides where the formula asked for one, and it is the only entry in results that no die produced.

The formula grammar covers how the bound is placed and which entry wins a tie.

Both are set only when a group kept exactly one die. A top face among several kept dice does not set either, deliberately — see What Rollful does not know.

A group that kept a bound rather than a die sets neither. 1d20min20 counts as 20 on every roll, and a flag saying so would report a natural 20 that nobody rolled.

The same shape, with one difference: keptFlags is not a field. Call keptFlags(group) from the package instead. Result objects are created with Object.create(null), so they have no prototype — read the fields you need rather than calling hasOwnProperty on them.