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.
Official Site Salvage Union by Leyline Press
Installation
Section titled “Installation”bun add @randsum/gamesnpm install @randsum/gamesimport { roll } from '@randsum/games/salvageunion'
// Roll on the Core Mechanic tableconst result = roll('Core Mechanic')import { roll } from '@randsum/games/salvageunion'
// Roll on a different tableconst 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 dataswitch (result.key) {case 'nailed_it': // Roll of 20 - exceptional success breakcase 'success': // Roll of 11-19 - standard success breakcase 'tough_choice': // Roll of 6-10 - success with complications break}roll(tableName: string)
Section titled “roll(tableName: string)”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 |
Result structure
Section titled “Result structure”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) |
Core Mechanic table
Section titled “Core Mechanic table”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 |
Table names
Section titled “Table names”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', ...]Error handling
Section titled “Error handling”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'Schema
Section titled “Schema”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.