Daggerheart
The @randsum/games/daggerheart subpath provides mechanics for Daggerheart, a fantasy tabletop RPG featuring the unique hope and fear dice system.
Official Site Daggerheart by Darrington Press
Installation
Section titled “Installation”bun add @randsum/gamesnpm install @randsum/gamesimport { roll } from '@randsum/games/daggerheart'
// Basic roll with modifierconst result = roll({ modifier: 5 })import { roll } from '@randsum/games/daggerheart'
// Roll with advantage (adds a d6)roll({modifier: 5,rollingWith: 'Advantage'})
// Roll with disadvantage (subtracts a d6)roll({modifier: -2,rollingWith: 'Disadvantage'})import { roll } from '@randsum/games/daggerheart'
// Amplify hope die (d12 becomes d20)roll({amplifyHope: true,modifier: 2})
// Amplify fear dieroll({amplifyFear: true,modifier: 3})
// Amplify bothroll({amplifyHope: true,amplifyFear: true,modifier: 4})import { roll } from '@randsum/games/daggerheart'
const { result, total, details } = roll({ modifier: 3 })// result: 'hope' | 'fear' | 'critical hope'// details: { hope, fear, extraDie, modifier }
const { hope, fear, extraDie, modifier } = detailsroll(input?: { modifier?: number, rollingWith?: 'Advantage' | 'Disadvantage', amplifyHope?: boolean, amplifyFear?: boolean })
Section titled “roll(input?: { modifier?: number, rollingWith?: 'Advantage' | 'Disadvantage', amplifyHope?: boolean, amplifyFear?: boolean })”Input:
| Property | Type | Description |
|---|---|---|
modifier | number (optional) | Modifier added to the total |
rollingWith | 'Advantage' | 'Disadvantage' | undefined | Adds or subtracts a d6 |
amplifyHope | boolean | Use d20 instead of d12 for hope die |
amplifyFear | boolean | Use d20 instead of d12 for fear die |
Returns: GameRollResult with:
| Property | Type | Description |
|---|---|---|
result | DaggerheartRollResult | 'hope' | 'fear' | 'critical hope' |
total | number | Sum of all dice + modifier |
details | DaggerheartRollDetails | Detailed breakdown (see below) |
rolls | RollRecord[] | Raw dice data from the core roller |
Outcomes
Section titled “Outcomes”The result type is determined by comparing the Hope and Fear die values:
| Condition | Outcome |
|---|---|
| Hope > Fear | Hope (positive narrative outcome) |
| Fear > Hope | Fear (negative narrative outcome) |
| Hope === Fear | Critical Hope |
The total (sum of all dice + modifier) determines mechanical success or failure.
Details Object
Section titled “Details Object”The details object provides full visibility into each component:
hope— Hope die result and whether it was amplifiedfear— Fear die result and whether it was amplifiedextraDie— Advantage/disadvantage die result (if applicable)modifier— Applied modifier value
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/daggerheart) — game-specific issues like invalidrollingWithvalues
import { roll, SchemaError } from '@randsum/games/daggerheart'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 { DaggerheartRollResult, DaggerheartRollDetails, GameRollResult, RollRecord } from '@randsum/games/daggerheart'import { SchemaError } from '@randsum/games/daggerheart'Schema
Section titled “Schema”This game is powered by a .randsum.json spec that defines the duality dice, amplification rules, and outcome logic. The TypeScript code is generated from this spec at build time. See Schema Overview for how game specs work.