UNPKG

@randsum/salvageunion

Version:

A flexible, type-safe dice roller for the Salvage Union system

80 lines (71 loc) 2.63 kB
import type { SURefObjectTable } from 'salvageunion-reference' import { SalvageUnionReference, resultForTable } from 'salvageunion-reference' import type { SalvageUnionRollRecord, SalvageUnionTableListing, SalvageUnionTableName } from '../types' import type { GameRollResult, RollRecord } from '@randsum/roller' import { roll } from '@randsum/roller' /** * NOTE: This package does not use the createGameRoll factory pattern because: * * 1. External library dependency: The implementation requires integration with * the `salvageunion-reference` library for table lookups, which doesn't fit * the standard factory pattern focused on dice mechanics. * * 2. Table lookup pattern: The roll result is used as a lookup key for table * resolution rather than being the primary game mechanic itself. The actual * game logic is in the table lookup, not the dice roll. * * 3. Custom result structure: The result includes table-specific metadata * (table data, table name, key, label, description) that extends beyond * standard game roll interpretation. * * 4. Table processing logic: The implementation includes complex table result * processing (label/value extraction, success checking) that is specific to * the Salvage Union table system. * * This is more accurately a table lookup utility than a dice rolling mechanic, * and would benefit from a specialized table-based factory if such a pattern * emerges in other packages. */ function tableDataForTable(tableName: SalvageUnionTableName): SURefObjectTable { const rollTable = SalvageUnionReference.RollTables.find(t => t.name === tableName) if (!rollTable?.table) { throw new Error(`Invalid Salvage Union table name: "${tableName}"`) } return rollTable.table } export function rollTable( tableName: SalvageUnionTableName = 'Core Mechanic' ): GameRollResult< SalvageUnionRollRecord, undefined, RollRecord<SalvageUnionTableListing | string> > { const { total, rolls } = roll({ sides: 20 }) const tableData = tableDataForTable(tableName) const tableResult = resultForTable(tableData, total) if (!tableResult.success) { throw new Error(`Failed to get result from table: "${tableName}"`) } const { result, key } = tableResult const resultTyped = result as { label?: string; value?: string } const label = resultTyped.label ?? resultTyped.value ?? '' const description = resultTyped.label ? (resultTyped.value ?? '') : '' return { rolls, total, result: { key, label, description, table: tableData, tableName, roll: total } } }