# Dice Parser Interface

As mentioned in the config setup, Dice-Box requires a parser to do the fun 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

## 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.

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

## 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

`@3d-dice/dice-roller-parser`

is a dependency of `@3d-dice/dice-parser-interface`

. You do not have to install it separately.

## 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)

### 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 use modules from @3d-dice/dice-ui

## Methods

Method | Arguments | Description |
---|---|---|

parseNotation | `notation` :string | Accepts a dice string input, parses it and returns a JSON representation of the parsed input. |

handleRerolls | `rollResults` :array | Accepts an array of dice roll results and returns a new array of dice objects that need to be re-rolled |

parseFinalResults | `rollResults` :array | pass 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.

Property | Type | Description |
---|---|---|

groupId | int | The group the reroll target belongs to |

rollId | int or string | The roll id of the die being rerolled. This will be incremented by `.1` for every reroll made |

side | int | The number of sides the reroll die has |

qty | int | The 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

}