Skip to main content
Version: 1.1

Dice Parser Interface

As mentioned in the config setup, Dice-Box requires a parser to do the fun TTRPGTable Top Role Playing Game things. Any roll notations that are more than the simple pattern {quantity}d{side}+/-{modifier} have to go through a parser to make sense of the notation. All the rolls supported are documented at Roll20 Dice Specification

note

Dice Parser Interface only works with the following dice types: d4, d6, d8, d10, d12, d20, d100, dfate.

dice-roller-parser

Rather than write my own parser from the ground up, I found one written by Ben Morton called dice_roller. While almost fully featured, the dice_roller project seems to have gone dormant. I forked that project into @3d-dice/dice-roller-parser, where I've been able to fix some bugs I've found as well as add features I need for Dice-Box. The important feature of dice_roller that made it different from other programmatic dice rollers like RPG Dice Roller is that it allows a custom random function as a constructor parameter. Instead of using a random function, I hijack this feature to pass in a function that contains all the roll results from Dice-Box. So instead of producing random numbers, it's just parsing the notation with the values I've delivered to it.

note

The documentation for @3d-dice/dice-roller-parser on GitHub is pretty robust so it is not reproduced here.

note

@3d-dice/dice-roller-parser is a dependency of @3d-dice/dice-parser-interface. You do not have to install it separately.

Parser Interface

The dice-parser-interface simply provides an interface between @3d-dice/dice-roller-parser and @3d-dice/dice-box. Since dice-roller-parser is pretty self contained, I did not want to include this interface in that package. The parser is available at @3d-dice/dice-parser-interface

Caveats

One thing this modules does not do is provide the interface for providing an input for the roll notation string or displaying the final results. It is expected that the developer will create their own inputs and outputs or a module such as Advanced Roller

Install

Install the library using:

npm install @3d-dice/dice-parser-interface

Setup

Then create a new instance of the parser

import DiceParser from '@3d-dice/dice-parser-interface'

const DP = new DiceParser()

The DP class instance now has methods to parse raw notations, process re-rolls and compute the final results from dice-box

<form id="dice-to-roll">
<input id="input--notation" class="input" placeholder="2d20" autocomplete="off" />
</form>
const form = document.getElementById("dice-to-roll")
const notationInput = document.getElementById("input--notation")

const submitForm = (e) => {
e.preventDefault();
const notation = DP.parseNotation(notationInput.value)
}

form.addEventListener("submit", submitForm)

Methods

MethodArgumentsDescription
parseNotationnotation :stringAccepts a dice string input, parses it and returns a JSON representation of the parsed input.
handleRerollsrollResults :arrayAccepts an array of dice roll results and returns a new array of dice objects that need to be re-rolled
parseFinalResultsrollResults :arraypass in a roll results object to get the computed results of the dice roll

parseNotation

Accepts a dice string input, parses it and returns a JSON representation of the parsed input.

Example: DP.parseNotation('4d6')

{
die: {
type: 'number',
value: 6
},
count: {
type: 'number',
value: 4
},
type: 'die',
mods: [],
root: true,
label: ''
}

See also: Just parse the value

handleRerolls

This method accepts an array of dice rolls (generated by parseNotation, updated by dice-box) and returns a new array of dice objects that need to be re-rolled. Examples of rolls that could generate rerolls include: exploding, penetrating, and compounding rolls (e.g.: 6d6!). Reroll and reroll-once notation is also supported (e.g.: 2d12r1).

rollResults Input

An example of what the input object should look like. This is what the final results look like from dice-box. See also: Dice Box: Common Objects Example 3d6r1 (roll 3 six sided dice, reroll dice that resulted in 1)

[
{
qty: 4,
sides: 6,
mods: [
{
type: "reroll",
target: {
type: "target",
mod: null,
value: {
type: "number",
value: 1
}
}
}
],
rolls: [
{
sides: 6,
groupId: 0,
rollId: 0,
theme: "diceOfRolling",
value: 1
},
{
sides: 6,
groupId: 0,
rollId: 1,
theme: "diceOfRolling",
value: 4
},
{
sides: 6,
groupId: 0,
rollId: 2,
theme: "diceOfRolling",
value: 3
},
{
sides: 6,
groupId: 0,
rollId: "0.1",
theme: "diceOfRolling",
value: 2
}
],
groupId: 0,
value: 10
}
]

Returned Dice Object:

Any dice that need a reroll are passed back in an array.

PropertyTypeDescription
groupIdintThe group the reroll target belongs to
rollIdint or stringThe roll id of the die being rerolled. This will be incremented by .1 for every reroll made
sideintThe number of sides the reroll die has
qtyintThe number of dice to be rolled. This will always be 1 on rerolls but is needed by dice-box

Example:

[
{
"groupId": 0,
"rollId": "2.1",
"sides": 6,
"qty": 1
},
{
"groupId": 0,
"rollId": "3.1",
"sides": 6,
"qty": 1
}
]

parseFinalResults

After all rolls and rerolls have completed, you can pass the results object to parseFinalResults to get the final results of the dice roll. This typically happens inside dice-box's onRollComplete callback method.

Example:

const results = DRP.parseFinalResults(results)

Example: 3d6r1

{
"count": {
"type": "number",
"value": 3,
"success": null,
"successes": 0,
"failures": 0,
"valid": true,
"order": 0
},
"die": {
"type": "number",
"value": 6,
"success": null,
"successes": 0,
"failures": 0,
"valid": true,
"order": 0
},
"rolls": [
{
"critical": null,
"die": 6,
"matched": false,
"order": 0,
"roll": 2,
"success": null,
"successes": 0,
"failures": 0,
"type": "roll",
"valid": true,
"value": 2
},
{
"critical": "failure",
"die": 6,
"matched": false,
"order": 1,
"roll": 1,
"success": null,
"successes": 0,
"failures": 0,
"type": "roll",
"valid": false,
"value": 1,
"reroll": true
},
{
"critical": "failure",
"die": 6,
"matched": false,
"order": 2,
"roll": 1,
"success": null,
"successes": 0,
"failures": 0,
"type": "roll",
"valid": false,
"value": 1,
"reroll": true
},
{
"critical": null,
"die": 6,
"matched": false,
"order": 3,
"roll": 3,
"success": null,
"successes": 0,
"failures": 0,
"type": "roll",
"valid": true,
"value": 3
},
{
"critical": "failure",
"die": 6,
"matched": false,
"order": 2,
"roll": 1,
"success": null,
"successes": 0,
"failures": 0,
"type": "roll",
"valid": false,
"value": 1,
"reroll": true
},
{
"critical": null,
"die": 6,
"matched": false,
"order": 5,
"roll": 5,
"success": null,
"successes": 0,
"failures": 0,
"type": "roll",
"valid": true,
"value": 5
}
],
"success": null,
"successes": 0,
"failures": 0,
"type": "die",
"valid": true,
"value": 10,
"order": 0,
"matched": false
}