Fantastic Dice Parser
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
__F__antastic __D__ice __P__arser, or FDP for short, 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/fdp
@3d-dice/dice-roller-parser
is a dependency of @3d-dice/fdp
. You do not have to install it separately.
Install
Install the library using:
npm install @3d-dice/fdp
Setup
Then create a new instance of the parser
import DiceParser from '@3d-dice/fdp'
const DRP = new DiceParser()
The DRP 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 = DRP.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/fui
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: DRP.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
}