Skip to content

Fate Core

The @randsum/games/fate subpath provides mechanics for Fate Core, a tabletop RPG that rolls four Fate dice (4dF), adds a skill rating, and reads the total off the Fate ladder.

Terminal window
bun add @randsum/games
import { roll } from '@randsum/games/fate'
// Roll 4dF with no skill modifier
const { result, total } = roll()
console.log(total) // -4 to +4
console.log(result) // e.g. 'mediocre'
import { roll } from '@randsum/games/fate'
// Add a skill rating (a rung on the Fate ladder, -2 to +5)
roll(3) // scalar overload: skill of +3
roll({ modifier: 3 }) // object overload: the same roll
import { roll } from '@randsum/games/fate'
const { result } = roll({ modifier: 4 })
switch (result) {
case 'legendary':
case 'epic':
case 'fantastic':
// A standout success
break
case 'superb':
case 'great':
case 'good':
// A solid success
break
default:
// Fair and below
break
}

roll(modifier?: number) / roll(input?: { modifier?: number })

Section titled “roll(modifier?: number) / roll(input?: { modifier?: number })”

Input:

Parameter Type Description
modifier number (optional) Skill rating — a rung on the Fate ladder (-2 to +5), added to the 4dF total

Returns: GameRollResult with:

Property Type Description
result FateRollResult The ladder rung the total lands on
total number The 4dF total plus the skill modifier
rolls RollRecord[] Raw dice data from the core roller (each Fate die is -1, 0, or +1)

Fate dice are six-sided dice with two + faces, two blank faces, and two faces, read as +1, 0, and −1. Four of them (4dF) sum to a total between -4 and +4. Add your skill rating and read the result off the ladder:

Total Rung
+8 or more legendary
+7 epic
+6 fantastic
+5 superb
+4 great
+3 good
+2 fair
+1 average
0 mediocre
-1 poor
-2 or less terrible

The open-ended legendary and terrible rungs absorb any total beyond the ends of the ladder.

Game roll() can throw two types of errors:

  • ValidationError (from @randsum/roller) — the skill modifier is out of range (-2 to +5) or not finite
  • SchemaError (from @randsum/games/fate) — game-specific issues like an unmatched ladder rung
import { roll, SchemaError } from '@randsum/games/fate'
import { ValidationError } from '@randsum/roller'
try {
roll(99)
} catch (error) {
if (error instanceof ValidationError) {
// Out-of-range skill rating (must be -2 to +5)
console.log(error.code) // 'VALIDATION_ERROR'
} else if (error instanceof SchemaError) {
// Game-specific error
console.log(error.code) // 'NO_TABLE_MATCH'
}
}
import type { FateRollResult, GameRollResult, RollRecord } from '@randsum/games/fate'
import { SchemaError } from '@randsum/games/fate'

This game is powered by a .randsum.json spec that defines the dice pool, the ladder outcomes, and validation rules. The TypeScript code is generated from this spec at build time. See Schema Overview for how game specs work.