D&D 5th Edition
The @randsum/games/fifth subpath provides Dungeons & Dragons 5th Edition mechanics including ability checks, saving throws, and attack rolls with full support for advantage and disadvantage.
Installation
Section titled “Installation”bun add @randsum/gamesnpm install @randsum/gamesimport { roll } from '@randsum/games/fifth'
// Basic roll with modifierconst result = roll({ modifier: 5 })// result.result: 6-25 (d20 + 5)import { roll } from '@randsum/games/fifth'
// Roll with advantage (2d20, keep highest, + modifier)const result = roll({modifier: 5,rollingWith: 'Advantage'})import { roll } from '@randsum/games/fifth'
// Roll with disadvantage (2d20, keep lowest, + modifier)const result = roll({modifier: -2,rollingWith: 'Disadvantage'})roll(input?: { modifier?, rollingWith?, crit? })
Section titled “roll(input?: { modifier?, rollingWith?, crit? })”Input:
| Property | Type | Description |
|---|---|---|
modifier | number (optional) | Ability/skill modifier (-30 to +30) |
rollingWith | 'Advantage' | 'Disadvantage' | undefined | Roll 2d20, keep highest or lowest |
crit | boolean (optional) | When set, enables natural 1/20 detection in details.criticals |
Returns: GameRollResult<FifthRollResult, FifthRollDetails> with:
| Property | Type | Description |
|---|---|---|
result | FifthRollResult (number) | Final total (d20 + modifier) |
total | number | Same as result |
rolls | RollRecord[] | Raw dice data from the core roller |
details | FifthRollDetails | Contains criticals (see below) |
FifthRollDetails:
| Property | Type | Description |
|---|---|---|
criticals | { isNatural1: boolean, isNatural20: boolean } | undefined | Present when crit input is set |
Outcomes
Section titled “Outcomes”- Normal roll: 1d20 + modifier
- Advantage (
'Advantage'): Roll 2d20, drop lowest, + modifier (equivalent to2d20L+modifier) - Disadvantage (
'Disadvantage'): Roll 2d20, drop highest, + modifier (equivalent to2d20H+modifier)
The modifier is validated to be a finite number in the range -30 to +30.
Common patterns
Section titled “Common patterns”import { roll } from '@randsum/games/fifth'
// Attack roll with +5 to hitroll({ modifier: 5 })
// Attack with advantageroll({ modifier: 5, rollingWith: 'Advantage' })
// Saving throw with -1 penalty and disadvantageroll({ modifier: -1, rollingWith: 'Disadvantage' })
// Perception check with +3 Wisdomroll({ modifier: 3 })Ability score generation
Section titled “Ability score generation”The @randsum/games/fifth package handles d20 action rolls. For ability score generation (4d6, drop lowest), use the core roller directly:
import { roll } from '@randsum/roller'
// Generate one ability score: 4d6, drop lowestconst score = roll('4d6L')console.log(score.total) // 3-18
// Generate all six scoresconst scores = Array.from({ length: 6 }, () => roll('4d6L').total)console.log(scores) // e.g. [14, 12, 15, 8, 10, 13]Error handling
Section titled “Error handling”Game roll() can throw two types of errors:
ValidationError(from@randsum/roller) — numeric input out of range or not finite (e.g.,modifier: Infinity)SchemaError(from@randsum/games/fifth) — game-specific issues like invalidrollingWithvalues
import { roll, SchemaError } from '@randsum/games/fifth'import { ValidationError } from '@randsum/roller'
try {roll({ modifier: Infinity })} catch (error) {if (error instanceof ValidationError) { // Non-finite modifier value console.log(error.code) // 'VALIDATION_ERROR'} else if (error instanceof SchemaError) { // e.g., invalid rollingWith enum value console.log(error.code) // 'INVALID_INPUT_TYPE'}}import type { FifthRollResult, FifthRollDetails, GameRollResult, RollRecord } from '@randsum/games/fifth'import { SchemaError } from '@randsum/games/fifth'Schema
Section titled “Schema”This game is powered by a .randsum.json spec that defines the d20 resolution, advantage/disadvantage, and modifier validation. The TypeScript code is generated from this spec at build time. See Schema Overview for how game specs work.