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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@diegesis/dice-roll20-notation

v0.1.2

Published

Roll20 dice notation parser and serializer for the Diegesis dice IR — maps Roll20 sigils (kh, r, ro, !, !!, !p, d%, dF, @{attr}) to canonical modifier operations.

Readme

@diegesis/dice-roll20-notation

Roll20 dice notation parser and serializer for the Diegesis dice IR — maps Roll20 sigils (kh, r, ro, !, !!, !p, d%, dF, @{attr}) to canonical modifier operations.

@diegesis/dice-roll20-notation parses Roll20-style dice notation (including @{attribute} references) into the canonical @diegesis/dice-core RollExpr IR and serializes IR back to Roll20 sigils. The API shape mirrors @diegesis/dice-notation, plus an isFunctionName helper and an additional pipe token type.

Installation

npm install @diegesis/dice-roll20-notation

Quick start

import { fromFormula, toFormula } from '@diegesis/dice-roll20-notation';
import { evaluateRoll } from '@diegesis/dice-core';

const expr = fromFormula('5d10>6');
// bare comparison after a die -> implicit count-success:
// modifiers: [{ op: 'count-success', compare: { op: '>', value: 6 } }]

const result = evaluateRoll(expr, { seed: 'session-42' });
result.value; // number of dice above 6

toFormula(fromFormula('4d10cs>=8')); // '4d10>=8'

API

fromFormula(source)

Parses Roll20 dialect notation into a RollExpr. Throws Roll20NotationError (with position and input) on invalid syntax.

function fromFormula(source: string): RollExpr;

| Name | Type | Description | |------|------|-------------| | source | string | Roll20-style notation, e.g. '5d10>6'. |

fromFormula('2d6r<=2');  // reroll-recursive on <= 2
fromFormula('2d6ro<=2'); // reroll-once on <= 2

toFormula(expr)

Serializes a RollExpr back to Roll20 sigils.

function toFormula(expr: RollExpr): string;

Serialization rules: reroll-once -> ro, reroll-recursive -> r, explode -> !, explode-compound -> !!, explode-penetrating -> !p, count-failure -> f, sort-asc -> sa, sort-desc -> sd. count-success serializes as a bare comparison when it has exactly one, otherwise as cs.

tokenize(source) / isFunctionName(name)

function tokenize(source: string): Token[];
function isFunctionName(name: string): boolean;

type TokenType =
  | 'num' | 'word'
  | 'plus' | 'dash' | 'star' | 'slash' | 'percent'
  | 'lparen' | 'rparen' | 'lbrace' | 'rbrace'
  | 'comma' | 'colon' | 'question' | 'bang'
  | 'at' | 'dot' | 'pipe'
  | 'eq' | 'gt' | 'ge' | 'lt' | 'le'
  | 'eof';

interface Token {
  type: TokenType;
  text: string;
  value?: number;
  start: number;
  end: number;
}

The pipe token type supports Roll20's @{character|level} attribute syntax.

Constants

const MODIFIER_PATTERNS: readonly ModPattern[];
const CANONICAL_TO_SIGIL: Readonly<Record<string, string>>;
const FUNCTIONS: readonly string[]; // ['floor', 'ceil', 'round', 'abs', 'min', 'max', 'clamp']

Errors

interface Roll20NotationErrorOptions {
  position?: number;
  input?: string;
  cause?: unknown;
}

class Roll20NotationError extends Error {
  position?: number;
  input?: string;
  constructor(message: string, options?: Roll20NotationErrorOptions);
}

Sigil table

Parser (sigil to canonical op)

| Sigil | Canonical op | |-------|--------------| | !! | explode-compound | | !p | explode-penetrating | | ! | explode | | kh, k | keep-highest | | kl | keep-lowest | | dh | drop-highest | | dl, d | drop-lowest | | ro | reroll-once | | r | reroll-recursive (opposite of Foundry) | | cs | count-success | | cf, f | count-failure | | s, sa | sort-asc | | sd | sort-desc |

Dialect specifics

  • Faces: number, % percentile, F/fate (no coin).
  • Dynamic count and faces via expressions.
  • Bare comparison after a die implicitly inserts count-success: 5d10>6 counts dice > 6.
  • Implicit comparisons combine with modifiers: 5d10>7f<1 counts successes > 7 and failures < 1.
  • Explode accepts an optional numeric cap before the comparison: 2d6!3>5 explodes at most 3 times on > 5.
  • Attributes: @{strength} becomes { var: 'strength' }; @{character|level} becomes { var: 'character.level' } (pipe becomes a dot). The serializer prints @{path.with.dots}.
  • Comments: everything after # is ignored.
  • Not supported: min/max/clamp modifiers, margin-success, count-even, count-odd, deduct-failure, subtract-failure, explode-once.

Examples

fromFormula('@{character|level}');
// { var: 'character.level' }

fromFormula('5d10>7f<1');
// count-success on > 7 plus count-failure on < 1

import { fromFormula } from '@diegesis/dice-roll20-notation';
import { evaluateRoll } from '@diegesis/dice-core';

const expr = fromFormula('1d20 + @{strength}');
const result = evaluateRoll(expr, {
  rng: () => 0.95,
  scope: { strength: 4 },
});
result.value; // 24

Related packages

The IR flow: this parser produces the @diegesis/dice-core RollExpr IR, dice-core evaluates it deterministically, and toFormula prints it back as Roll20 sigils.


Part of diegesis-sdk. MIT.