npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dice-note

v0.0.1

Published

Dice notation interpreter

Downloads

2

Readme

Dice Note

Dice notation interpreter, for all your digital dice rolling needs (except the actual rolling).

Installation

Install any way you normally get node packages onto your computer. I tend to use:

npm i dice-note

What even is this?

Dice Note is fundamentally a string parser, designed to abstract away needing to think too hard about the outcomes of dice rolls when making games or applications that require such things. Think: table-top role-play games, but online.

What does it do

DN accepts a string representation of a dice roll, eg. d6, 4d8+4 or 2d20kH+3.

These can be quite complex at times, given various games require semantics like "roll with advantage" or "drop lowest n values", etc.

As output, the initial prepare() function will provide a list of dice your application needs to "roll" (by whatever mechanism you care to use), and a result() function into which those raw dice results can be put, which will then itself return the final numeric result(s).

It will also validate a string for you—tell you whether or not it's valid notation.

What doesn't it do

Specifically, DN does not roll dice for you. That's left to the application's discretion, because you may want to use a random number generator, a THREE.js dice roller, or fudge the numbers in any given circumstance.

How does it work?

Less tell, more show:

import { prepare } from 'dice-note'

// A simple example to start: two d6 die
const { dice, result } = prepare('2d6')
// dice = [ "d6", "d6" ]

// Let's fudge those numbers, but we could use RNG to get this result.

// Remember that it's important that the INDEX of the result matches that of
// the dice from the `dice` array
const weRolled = [ 2, 6 ]

const outcome = result(weRolled)
// outcome = [ 8 ]

Dice Note expects the following constraints on the array input into the result function:

  • all array elements are numbers
  • the length of the array matches that of dice, given from the prepare function
  • each element in the roll results array (weRolled, above) must positionally match the die for which it was rolled, ie. their index in the array must be the same

You may notice that the "preparation step" and the "execution step" have been separated. This is on purpose, one of the benefits of which is that you can run the same roll more than once without having to redo the execution-plan step.

To that end, if certain rolls are going to be executed frequently, for performance it would be beneficial for your application to cache the execution plan, rather than recompute it every time.

More complex examples

Selective results

Dropping or keeping certain results within a roll is common (eg. to roll with advantage or disadvantage). While supporting every possible variant notation isn't possible, the following quasi-standard notations should provide enough flexibility to support most scenarios.

To drop dice, the following notations are supported:

  • -(n)H (eg. 4d6-2H) - drop the highest 2 results
  • -(n)L (eg. 4d6-L) - drop the lowest 1 (implied) result
  • dL(n) (eg. 4d6dL2) - drop the lowest 2 results (n can be omitted if 1)
  • dH(n) (eg. 4d6dH1) - drop the highest 1 result (n can be omitted if 1)

To keep dice, the following notations are supported:

  • +(n)L (eg. 4d6+2L) - keep the lowest 2 results
  • +(n)H (eg. 4d6+H) - keep the highest 1 (implied) result
  • kH(n) (eg. 4d6kH2) - keep the highest 2 (n can be omitted if 1)
  • kL(n) (eg. 4d6kL1) - keep the lowest 1 (n can be omitted if 1)
import { prepare } from 'dice-note'

const rollWithDisadvantage = '2d20dH'
const rollWithAdvantage = '2d20+H'

const dis = prepare(rollWithDisadvantage)
const adv = prepare(rollWithAdvantage)
// dis.dice = adv.dice = [ "d20", "d20" ]

const roll = [ 19, 4 ]

const disOutcome = dis.result(roll)
// disOutcome = [ 4 ]

const advOutcome = adv.result(roll)
// advOutcome = [ 19 ]

Player's choice

In some games, the player can choose which value they want to apply, rather than sum the results. For Dice Note, this is represented with a suffix of 'c' on the dice notation, eg. 2d20c.

Using the choice option should be used sparingly, and on not-too-complicated rolls; the more complicated a roll, the more likely players will wonder how the results they got were derived, and whether or not your application is cheating.

Note that it is not possible with Dice Note to combine 'c' with 'k' or 'd'.

import { prepare } from 'dice-note'

const { dice, result } = prepare('2d20c+4')
// dice = [ "d20", "d20" ]

const outcome = result([ 17, 3 ])
// if there were no 'c' term, the 17 and 3 would be summed; instead, the +4 is
// applied to each roll before being included in the output
// outcome = [ 21, 7 ]

This feature can also be used to emulate situations such as Dungeons & Dragons' "Magic Bullet" spell, where 3 or more dice are rolled, but all the dice values are used separately:

import { prepare } from 'dice-note'

const { dice, result } = prepare('3d4c+1') // magic bullet cast at level 1
// dice = [ "d4", "d4", "d4" ]

const outcome = result([ 4, 2, 3 ])
// outcome = [ 5, 3, 4 ]

Arithmetic

Dice Note supports basic addition and substraction of modifiers. Multiplication and division are not supported.

Adding a modifier

import { prepare } from 'dice-note'

const { dice, result } = prepare('d20+7')
// dice = [ "d20" ]

const outcome = result([ 11 ])
// outcome = [ 18 ]

Adding a multiplier

1d6x5 or 5xd6 means "roll one 6-sided die, and multiply the result by 5."

import { prepare } from 'dice-note'

const { dice, result } = prepare('2d20x7')
// dice = [ "d20", "d20" ]

const outcome = result([ 4, 3 ])
// the 4 and 3 are summed, and then multiplied by 7 (ie. 7*7)
// outcome = [ 49 ]

Validation

The validate function is intended as a lightweight (as in, per-keystroke) means to prevent invalid notations hitting the more complex— and thus slower—logic.

import { validate } from 'dice-note'

const valid = validate('4+2d20-2')
// valid = true

Licence

MIT

Bugs and Issues

Please use GitHub's issue tracker to report bugs.