Skip to content

@randsum/games

Roll dice for Salvage Union, D&D, Blades in the Dark, PbtA, and more with typed, game-specific functions. Each game package validates input, rolls using the core engine, and interprets the result according to that system’s rules.

Salvage Union

@randsum/games/salvageunion — D20 table-based rolls for mech combat and salvage operations.

View documentation

D&D 5th Edition

@randsum/games/fifth — Ability checks, saving throws, attack rolls with advantage/disadvantage.

View documentation

Blades in the Dark

@randsum/games/blades — Dice pool action rolls with critical, success, partial, and failure outcomes.

View documentation

Powered by the Apocalypse

@randsum/games/pbta — 2d6+stat rolls for Dungeon World, Monster of the Week, Apocalypse World, and more.

View documentation

Daggerheart

@randsum/games/daggerheart — Hope and fear dice with amplification and advantage/disadvantage.

View documentation

Root RPG

@randsum/games/root-rpg — 2d6+bonus with Strong Hit, Weak Hit, and Miss outcomes.

View documentation

Every game package follows a three-step pipeline: validate input, roll dice, interpret the result.

import { roll } from '@randsum/games/salvageunion'
// 1. Validate — checks that tableName matches a known table
// 2. Roll — executes the d20 roll via @randsum/roller
// 3. Interpret — looks up the result in the matching table by range
const result = roll('Core Mechanic')
console.log(result.result.label) // 'Success' | 'Tough Choice' | 'Failure' | ...
console.log(result.result.description) // full outcome text
console.log(result.total) // d20 roll
console.log(result.rolls) // raw RollRecord[] from the roller

All game packages share these characteristics:

  • Single roll() export — each subpath exports one roll() function as the main API
  • Game-specific input types — typed input objects, not raw notation strings
  • GameRollResult return type — includes result (game outcome), total, rolls, and optional details
  • Input validation — throws ValidationError (from roller) for out-of-range numeric input and SchemaError for game-specific issues like invalid enum values or unmatched outcome tables
  • No cross-dependencies — game packages depend only on @randsum/roller, never on each other
  • Under 8KB bundled — lightweight subpath imports (Salvage Union is larger due to table data)
GameDiceInputOutcomes
salvageunion1d20tableName (string)Table result with label + description
fifth1d20 or 2d20modifier, rollingWith, critNumeric total
bladesNd6 poolrating (number, 0-4)critical, success, partial, failure
pbta2d6stat, forward, ongoing, rollingWithstrong_hit, weak_hit, miss
daggerheartHope/Fear dicemodifier, amplifyHope, amplifyFear, rollingWithcritical hope, hope, fear
root-rpg2d6bonus (number)Strong Hit, Weak Hit, Miss

Install @randsum/games once, then import the game you need via subpath exports. This also installs @randsum/roller as a dependency.

Terminal window
bun add @randsum/games
import { roll } from '@randsum/games/salvageunion'
import { roll } from '@randsum/games/fifth'
import { roll } from '@randsum/games/blades'
import { roll } from '@randsum/games/pbta'
import { roll } from '@randsum/games/daggerheart'
import { roll } from '@randsum/games/root-rpg'
  • Getting Started — install, roll your first game-specific dice, read the result
  • Schema Overview — how .randsum.json specs power the codegen pipeline
  • Individual game pages — detailed docs for each supported system (linked in the cards above)