# dice — TTRPG randomness pack

TTRPG randomness pack: parse and roll dice notation (3d6+2, 2d20, 1d100/d%, 4d6kh3, 2d20kl1) with keep/drop highest/lowest, multiple terms and modifiers; advantage/disadvantage rolls; ability-score...


A self-contained dice roller and tabletop random-helper adapter system. Pure JS, zero deps.

## What it is

Parse and roll standard dice notation, generate ability scores, flip coins, pick/shuffle,
draw from weighted loot tables, and roll up a simple RPG creature stat block. Every rolling
tool accepts an optional numeric `seed` for reproducible results (mulberry32); omit it for
`Math.random()`.

## Tools

| Tool | Args | Returns |
|---|---|---|
| `roll` | `{ notation, seed? }` | `{ total, rolls, notation, breakdown }` |
| `rollAdvantage` | `{ seed?, modifier? }` | 2d20 keep highest + modifier |
| `rollDisadvantage` | `{ seed?, modifier? }` | 2d20 keep lowest + modifier |
| `rollStats` | `{ method='4d6kh3', count=6, seed? }` | ability-score array + detail |
| `coinFlip` | `{ count=1, seed? }` | one flip or an array + heads/tails counts |
| `randomPick` | `{ items:[], count=1, seed? }` | sample without replacement |
| `shuffle` | `{ items:[], seed? }` | Fisher-Yates shuffled array |
| `lootTable` | `{ table:[{item,weight}], rolls=1, seed? }` | weighted random draw(s) |
| `statBlock` | `{ level?, seed? }` | a simple creature stat block |

## Notation

`roll` understands multiple terms, modifiers, percentile dice, and keep/drop:

- `3d6+2`, `2d20`, `1d100`, `d%` (== d100)
- `4d6kh3` — roll 4d6, keep highest 3 (classic ability score)
- `2d20kl1` — keep lowest 1 (disadvantage); `2d20kh1` is advantage
- `dh`/`dl` — drop highest / drop lowest
- `2d6+1d4+3` — any number of dice terms and flat modifiers

## Usage

```js
import dice from './index.js';

dice.adapters.roll({ notation: '3d6+2' });
// { total: 14, rolls: [4,5,3], notation: '3d6+2', breakdown: [...] }

dice.adapters.roll({ notation: '4d6kh3' });
// rolls 4 dice, keeps the highest 3

dice.adapters.lootTable({ table: [{ item: 'gold', weight: 10 }, { item: 'sword', weight: 1 }], rolls: 3 });
```

## DRY boundary

**dice owns randomness** for the ecosystem — random draws, shuffles, weighted picks, and dice.
The `array` pack stays deterministic (chunk/flatten/unique/rotate never randomize). If you need
a random shuffle or a weighted draw, call `dice`; reach for `array` only for structural transforms.


---
Source: shared/engines/adapters/domain/dice/README.md
Canonical: https://docs.leumas.tech/p/adapters/domain/dice
