Skip to content

Salvage Union

The @randsum/games/salvageunion subpath provides mechanics for Salvage Union, a post-apocalyptic mech-based tabletop RPG that uses table-based d20 mechanics.

Terminal window
bun add @randsum/games
import { roll } from '@randsum/games/salvageunion'
// Roll on the Core Mechanic table
const result = roll('Core Mechanic')
import { roll } from '@randsum/games/salvageunion'
// Roll on a different table
const result = roll('Morale')
import { roll } from '@randsum/games/salvageunion'
const { result } = roll('Core Mechanic')
const { label, description, roll: rollValue } = result
console.log(`${rollValue} - ${label}`)
// e.g., "16 - Success"
console.log(description)
// e.g., "You have achieved your goal without any compromises."
import { roll } from '@randsum/games/salvageunion'
const { result } = roll('Core Mechanic')
// Access structured result data
switch (result.key) {
case 'nailed_it':
// Roll of 20 - exceptional success
break
case 'success':
// Roll of 11-19 - standard success
break
case 'tough_choice':
// Roll of 6-10 - success with complications
break
}

Input:

Parameter Type Description
tableName string Table to roll on (must be a valid table name from VALID_TABLE_NAMES)

Returns: GameRollResult with:

Property Type Description
result SalvageunionRollResult Table result with metadata
total number D20 roll result (1-20)
rolls RollRecord[] Raw dice data from the core roller

The SalvageunionRollResult interface includes:

Property Type Description
key string Internal result identifier
label string Human-readable result label
description string Detailed result description
table Record<string, unknown> Full table data
tableName string Name of the table rolled
roll number D20 roll result (1-20)

The default Core Mechanic table uses these result tiers:

Roll Result
20 Nailed It – exceptional success
11-19 Success – goal achieved without compromise
6-10 Tough Choice – success with complications
2-5 Failure
1 Cascade Failure – critical failure

Use the VALID_TABLE_NAMES const tuple to get all available table names. This is generated from the spec at build time.

import { VALID_TABLE_NAMES } from '@randsum/games/salvageunion'
// VALID_TABLE_NAMES is a readonly tuple of all valid table name strings
// e.g. ['Core Mechanic', 'Group Initiative', 'Critical Injury', ...]

Passing an invalid table name throws a SchemaError:

import { roll, SchemaError } from '@randsum/games/salvageunion'
try {
roll('Not A Real Table')
} catch (error) {
if (error instanceof SchemaError) {
console.log(error.code) // 'NO_TABLE_MATCH'
console.log(error.message) // 'Invalid Salvage Union table name: "Not A Real Table"'
}
}
import type { SalvageunionRollResult, GameRollResult, RollRecord } from '@randsum/games/salvageunion'
import { VALID_TABLE_NAMES, ROLL_TABLE_ENTRIES, SchemaError } from '@randsum/games/salvageunion'

This game is powered by a .randsum.json spec that defines the d20 resolution, outcome tables, and table lookup logic. The TypeScript code is generated from this spec at build time. See Schema Overview for how game specs work.