Skip to content

Daggerheart

The @randsum/games/daggerheart subpath provides mechanics for Daggerheart, a fantasy tabletop RPG featuring the unique hope and fear dice system.

Terminal window
bun add @randsum/games
import { roll } from '@randsum/games/daggerheart'
// Basic roll with modifier
const 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 die
roll({
amplifyFear: true,
modifier: 3
})
// Amplify both
roll({
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 } = details

roll(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

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.

The details object provides full visibility into each component:

  • hope – Hope die result and whether it was amplified
  • fear – Fear die result and whether it was amplified
  • extraDie – Advantage/disadvantage die result (if applicable)
  • modifier – Applied modifier value

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 invalid rollingWith values
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'

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.