# Roller API Reference

Everything exported from `@randsum/roller`. All functions and types below are exported directly from roller — notation parsing is built in with no separate package required.

## Functions

### `roll(...args)`

Roll dice. Accepts numbers, notation strings, options objects, or any combination. An optional `RollConfig` object can be passed as the last argument to customize the random function.

<CodeExample code={`roll(20)                    // number: 1d20
roll('4d6L')                // notation string
roll({ sides: 6, quantity: 4, modifiers: { drop: { lowest: 1 } } })
roll('1d20+5', '2d6+3')    // multiple groups
roll('2d6', { randomFn: () => 0.5 })  // custom RNG
roll('5d6W')                // D6 System wild die
roll('g6')                  // geometric die
roll('3DD6')                // draw die
roll('4d6Lx6')              // repeat operator
roll('2d6+3[fire]')         // annotation`} />

**Signature:**

```typescript
function roll<T = string>(
  ...args: [...RollArgument<T>[], RollConfig]
): RollerRollResult<T>
```

### `validateNotation(notation)`

Validate a dice notation string and return a detailed result with parsed structure or error.

<CodeExample code={`const result = validateNotation('4d6L')
if (result.valid) {
  console.log(result.notation)  // ['4d6L'] — array of DiceNotation
  console.log(result.options)   // [{ sides: 6, quantity: 4, ... }] — array of ParsedNotationOptions
} else {
  console.log(result.error)     // { message: '...', argument: '...' }
}`} />

**Signature:**

```typescript
function validateNotation(notation: string): ValidationResult
```

### `isDiceNotation(value)`

Type guard that checks whether a string is valid dice notation.

<CodeExample code={`if (isDiceNotation(userInput)) {
  // userInput is now typed as DiceNotation
  const result = roll(userInput)
}`} />

**Signature:**

```typescript
function isDiceNotation(value: string): value is DiceNotation
```

### `notation(value)`

Assert a string is valid dice notation or throw `NotationParseError`.

**Signature:**

```typescript
function notation(value: string): DiceNotation
```

### Validation helpers

Validators for numeric input. Used by the roller engine and game packages. Each throws `ValidationError` on failure.

| Function | Description |
|---|---|
| `validateInteger(value, name)` | Asserts value is an integer |
| `validateRange(value, min, max, name)` | Asserts value is within [min, max] |
| `validateNonNegative(value, name)` | Asserts value is >= 0 |
| `validateFinite(value, name)` | Asserts value is finite |

## Error classes

`RandsumError` extends `Error` and adds a `code` property. `ValidationError`, `ModifierError`, and `RollError` all extend `RandsumError`. `NotationParseError` extends `Error` directly and is part of `@randsum/roller`.

| Class | Extends | Code | Thrown when |
|---|---|---|---|
| `RandsumError` | `Error` | (varies) | Base class for roller errors |
| `ValidationError` | `RandsumError` | `VALIDATION_ERROR` | Invalid input (zero sides, negative quantity, etc.) |
| `ModifierError` | `RandsumError` | `MODIFIER_ERROR` | Modifier produces invalid state (e.g. dropping all dice) |
| `RollError` | `RandsumError` | `ROLL_ERROR` | General roll execution failure |
| `NotationParseError` | `Error` | `INVALID_NOTATION` | Invalid dice notation string |

### `ERROR_CODES`

Constant object with all error code strings:

```typescript
const ERROR_CODES = {
  INVALID_NOTATION: 'INVALID_NOTATION',
  MODIFIER_ERROR: 'MODIFIER_ERROR',
  VALIDATION_ERROR: 'VALIDATION_ERROR',
  ROLL_ERROR: 'ROLL_ERROR'
} as const
```

## Result types

### `RollerRollResult<T>`

Return type of `roll()`. Extends `RollResult`.

| Property | Type | Description |
|---|---|---|
| `total` | `number` | Combined total of all roll groups |
| `values` | `T[]` | Aggregate result values (defaults to `string[]`) |
| `rolls` | `RollRecord<T>[]` | Full record for each roll group |

### `RollRecord<T>`

Detailed record of a single roll group.

| Property | Type | Description |
|---|---|---|
| `argument` | `RollArgument<T>` | Original input for this group |
| `notation` | `DiceNotation` | Dice notation string |
| `description` | `string[]` | Human-readable descriptions |
| `parameters` | `RollParams<T>` | Fully resolved roll parameters |
| `rolls` | `number[]` | Die values after modifiers |
| `initialRolls` | `number[]` | Die values before modifiers |
| `modifierLogs` | `ModifierLog[]` | Log of each modifier application |
| `appliedTotal` | `number` | Total including arithmetic modifiers |
| `total` | `number` | Final total for this group |
| `label` | `string` (optional) | Annotation label from notation |
| `customResults` | `T[]` (optional) | Custom face results for non-numeric dice |

### `RollResult<TValues, TRollRecord>`

Generic base type.

| Property | Type | Description |
|---|---|---|
| `rolls` | `TRollRecord[]` | Individual roll records |
| `values` | `TValues` | Aggregate result |

## Input types

| Type | Description |
|---|---|
| `RollArgument<T>` | `RollOptions<T> \| DiceNotation \| number` |
| `RollOptions<T>` | Options object with `sides`, `quantity`, `modifiers` |
| `RollConfig` | `{ randomFn?: RandomFn }` -- pass as last argument to `roll()` |
| `RandomFn` | `() => number` -- must return `[0, 1)` |
| `DiceNotation` | Branded string type for valid notation |

## Modifier types

All modifier option types are exported from `@randsum/roller`.

| Type | Description |
|---|---|
| `ModifierOptions` | Top-level modifier configuration object |
| `ModifierConfig` | Union of all individual modifier configs |
| `ComparisonOptions` | Conditions like `{ greaterThan: 3, lessThan: 18 }` |
| `DropOptions` | Extends `ComparisonOptions` with `{ lowest?, highest? }` |
| `KeepOptions` | `{ lowest?: number, highest?: number }` |
| `RerollOptions` | Reroll conditions and limits |
| `ReplaceOptions` | Value replacement rules |
| `UniqueOptions` | Unique constraint config |
| `SuccessCountOptions` | Count dice meeting a threshold |
| `FailureCountOptions` | Count dice at or below a threshold |

## Internal types

| Type | Description |
|---|---|
| `RollParams<T>` | Fully resolved parameters (extends `RollOptions`, adds `faces`, `argument`, `description`, `notation`) |
| `RequiredNumericRollParameters` | `{ quantity: number, sides: number }` |
| `ModifierLog` | `{ modifier, options, added, removed }` -- log entry for one modifier |
| `NumericRollBonus` | `{ rolls: number[], logs: ModifierLog[] }` -- intermediate modifier state |

## Validation result types

| Type | Description |
|---|---|
| `ValidationResult` | `ValidValidationResult \| InvalidValidationResult` |
| `ValidValidationResult` | `{ valid: true, argument, description, options, notation, error: null }` |
| `InvalidValidationResult` | `{ valid: false, argument, error: ValidationErrorInfo }` |
| `ValidationErrorInfo` | `{ message: string, argument: string }` |

## Subpath exports

`@randsum/roller` publishes several subpath exports for tree-shaking and specialized use cases.

| Import path | Exports | When to use |
|---|---|---|
| `@randsum/roller` | Full API — all functions, types, and error classes | Default; use when bundle size is not a concern |
| `@randsum/roller/roll` | `roll()` only | Game packages and the CLI use this to avoid bundling the full notation toolkit |
| `@randsum/roller/validate` | `validateNotation()`, `isDiceNotation()`, `notation()`, validation helpers | When you only need input validation without rolling |
| `@randsum/roller/errors` | `RandsumError`, `ValidationError`, `ModifierError`, `RollError`, `NotationParseError`, `ERROR_CODES` | Error handling only, no roll logic |
| `@randsum/roller/tokenize` | `tokenize()` | Low-level notation tokenization |
| `@randsum/roller/docs` | `NOTATION_DOCS`, `MODIFIER_DOCS`, `DICE_DOCS` and types `NotationDoc`, `ModifierCategory` | Build-time docs generation, introspection tooling |
| `@randsum/roller/trace` | `traceRoll()`, `formatAsMath()` and type `RollTraceStep` | Step-by-step roll debugging and math display |

### `/docs` subpath

```typescript
import { NOTATION_DOCS, MODIFIER_DOCS, DICE_DOCS } from '@randsum/roller/docs'
import type { NotationDoc, ModifierCategory } from '@randsum/roller/docs'
```

`NOTATION_DOCS` documents the full notation syntax. `MODIFIER_DOCS` lists each modifier with its category, syntax, and description. `DICE_DOCS` covers special die types (Fate, percentile, geometric, etc.). All three are structured data suitable for generating reference pages or powering autocomplete.

### `/trace` subpath

```typescript
import { traceRoll, formatAsMath } from '@randsum/roller/trace'
import type { RollTraceStep } from '@randsum/roller/trace'
```

`traceRoll(record)` takes a `RollRecord` (from `result.rolls[n]`) and returns `readonly RollTraceStep[]` — a discriminated union with `kind: 'rolls' | 'divider' | 'arithmetic' | 'finalRolls'` — showing each stage of roll evaluation. `formatAsMath(rolls, delta?)` takes a `readonly number[]` and optional numeric delta and returns a human-readable math string (e.g. `"2 + 4 = 6"`). Useful for verbose output displays and debugging.