Skip to content

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:

PropertyTypeDescription
modifiernumber (optional)Modifier added to the total
rollingWith'Advantage' | 'Disadvantage' | undefinedAdds or subtracts a d6
amplifyHopebooleanUse d20 instead of d12 for hope die
amplifyFearbooleanUse d20 instead of d12 for fear die

Returns: GameRollResult with:

PropertyTypeDescription
resultDaggerheartRollResult'hope' | 'fear' | 'critical hope'
totalnumberSum of all dice + modifier
detailsDaggerheartRollDetailsDetailed breakdown (see below)
rollsRollRecord[]Raw dice data from the core roller

The result type is determined by comparing the Hope and Fear die values:

ConditionOutcome
Hope > FearHope (positive narrative outcome)
Fear > HopeFear (negative narrative outcome)
Hope === FearCritical 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.