# Ecosystem Overview

RANDSUM is a monorepo with three layers: a dice engine (with built-in notation parsing), and game-specific packages. Every package is TypeScript-first, ships ESM with full type declarations, and is published to npm under `@randsum`.

## Dependency diagram

```
@randsum/roller              (zero dependencies — includes notation)
  |
  +-- @randsum/games         (TTRPG game packages)
  |     +-- /blades            (Blades in the Dark)
  |     +-- /daggerheart       (Daggerheart)
  |     +-- /fifth             (D&D 5e)
  |     +-- /pbta              (Powered by the Apocalypse)
  |     +-- /root-rpg          (Root RPG)
  |     +-- /salvageunion      (Salvage Union)
```

Every package depends only on packages above it in the tree. Game packages never depend on each other.

## Packages by layer

### Core: Roller
**@randsum/roller**
The zero-dependency dice rolling engine with built-in notation parsing and validation. Accepts numbers, notation strings, or options objects and returns typed roll results with full modifier support. Includes `isDiceNotation`, `notation`, `validateNotation`, `notationToOptions`, `optionsToNotation`, `tokenize`, and more — most projects only need this package.

    [Learn more](https://randsum.dev/roller/introduction/)

### Game packages
**@randsum/games**
Code-generated TTRPG game packages, each available as a subpath export. Every game wraps `@randsum/roller` with game-specific dice pools, modifiers, and outcome interpretation -- generated from `.randsum.json` specs.

    [Learn more](https://randsum.dev/games/introduction/)

Currently supported games: **Blades in the Dark**, **D&D 5e**, **Daggerheart**, **Powered by the Apocalypse**, **Root RPG**, and **Salvage Union**.

### Tools
**Discord Bot**
Roll dice directly in Discord with slash commands. Supports all game packages with rich embeds.

    [Learn more](https://randsum.dev/tools/discord-bot/)

## Where to start

Pick the package that matches your use case:

| Use case | Install | Start here |
|---|---|---|
| **Roll dice in any JS/TS project** | `bun add @randsum/roller` | [Roller Getting Started](https://randsum.dev/roller/getting-started/) |
| **Parse or validate notation strings** | `bun add @randsum/roller` | [Roller Getting Started](https://randsum.dev/roller/getting-started/) |
| **Build a TTRPG app with game-specific mechanics** | `bun add @randsum/games` | [Games Getting Started](https://randsum.dev/games/getting-started/) |

Most developers should start with `@randsum/roller`. It includes the full notation parser and validator along with all rolling functionality and types, so most projects only need one install. Notation functions like `isDiceNotation`, `validateNotation`, `notationToOptions`, `optionsToNotation`, `tokenize`, and others are all exported directly from `@randsum/roller`.

## Design principles

- **RDN conformant** -- `@randsum/roller` implements the complete [RANDSUM Dice Notation (RDN) Specification](https://notation.randsum.dev) at Level 4 (Full) conformance, the formal standard for dice notation syntax in tabletop RPGs
- **Zero core dependencies** -- `@randsum/roller` has no runtime dependencies and includes the full notation parser and validator
- **Throws on invalid input** -- `roll()` throws typed errors on bad input (`ValidationError`, `ModifierError`, or `NotationParseError`); validate user-provided strings with `isDiceNotation()` or `validateNotation()` before rolling
- **Game packages are code-generated** -- every game is defined as a `.randsum.json` spec and transformed into TypeScript by an internal codegen pipeline
- **Strict TypeScript** -- `isolatedDeclarations`, `exactOptionalPropertyTypes`, `noUncheckedIndexedAccess`, no `any`
- **Bundle size enforced** -- roller 20KB (includes notation), game packages under 15KB each (35KB for salvageunion)