@randsum/notation
Version:
Dice notation parser and types for the @randsum ecosystem
181 lines (165 loc) • 5.1 kB
text/typescript
export interface ComparisonOptions {
/** Threshold for "greater than" comparisons (strict: roll > N) */
greaterThan?: number
/** Threshold for "greater than or equal to" comparisons (roll >= N) */
greaterThanOrEqual?: number
/** Threshold for "less than" comparisons (strict: roll < N) */
lessThan?: number
/** Threshold for "less than or equal to" comparisons (roll <= N) */
lessThanOrEqual?: number
/** Exact values to match */
exact?: number[]
}
export interface DropOptions extends ComparisonOptions {
/** Number of highest dice to drop */
highest?: number
/** Number of lowest dice to drop */
lowest?: number
}
export interface KeepOptions {
/** Number of highest dice to keep */
highest?: number
/** Number of lowest dice to keep */
lowest?: number
}
export interface RerollOptions extends ComparisonOptions {
/** Maximum number of rerolls allowed */
max?: number
}
export interface ReplaceOptions {
/** Value or comparison to match for replacement */
from: number | ComparisonOptions
/** Value to replace matched rolls with */
to: number
}
export interface UniqueOptions {
/** Values that are allowed to repeat */
notUnique: number[]
}
export interface SuccessCountOptions {
/** Threshold for counting successes (rolls >= this value) */
threshold: number
/** Optional: threshold for counting botches/failures (rolls <= this value) */
botchThreshold?: number
}
export type ModifierConfig =
| number
| boolean
| ComparisonOptions
| DropOptions
| KeepOptions
| ReplaceOptions
| ReplaceOptions[]
| RerollOptions
| UniqueOptions
| SuccessCountOptions
export interface ModifierOptions {
/** Cap roll values to a range */
cap?: ComparisonOptions
/** Drop dice from the result */
drop?: DropOptions
/** Keep dice from the result (complement to drop) */
keep?: KeepOptions
/** Replace specific values */
replace?: ReplaceOptions | ReplaceOptions[]
/** Reroll dice matching conditions */
reroll?: RerollOptions
/** Ensure unique values (true or options) */
unique?: boolean | UniqueOptions
/** Exploding dice: reroll and add on max value */
explode?: boolean | number
/** Compounding exploding: add to triggering die instead of creating new dice */
compound?: boolean | number
/** Penetrating exploding: subtract 1 from each subsequent explosion */
penetrate?: boolean | number
/** Count successes instead of summing (for dice pool systems) */
countSuccesses?: SuccessCountOptions
/** Multiply dice result (before +/- arithmetic) */
multiply?: number
/** Add a fixed value to the total */
plus?: number
/** Subtract a fixed value from the total */
minus?: number
/** Multiply final total (after all other modifiers) */
multiplyTotal?: number
}
/**
* The result of parsing a dice notation string.
* Similar to RollOptions but with sides always numeric and
* quantity/arithmetic always present.
*/
export interface ParsedNotationOptions {
/** Number of dice to roll */
quantity: number
/** How this roll combines with others */
arithmetic: 'add' | 'subtract'
/** Number of sides on each die */
sides: number
/** Modifiers to apply to the roll */
modifiers?: ModifierOptions
}
/**
* Template literal type for dice notation strings.
*/
export type DiceNotation = `${number}${'d' | 'D'}${number}${string}`
/**
* Configuration options for a dice roll.
*
* @template T - Type for custom dice faces (defaults to string)
*/
export interface RollOptions<T = string> {
/** Number of dice to roll (default: 1) */
quantity?: number
/** How this roll combines with others: 'add' or 'subtract' (default: 'add') */
arithmetic?: 'add' | 'subtract'
/** Number of sides, or array of custom face values */
sides: number | T[]
/** Modifiers to apply to the roll (drop, reroll, explode, etc.) */
modifiers?: ModifierOptions
/**
* Optional identifier for this roll in multi-roll expressions.
* Default keys are auto-generated as "Roll 1", "Roll 2", etc.
*/
key?: string | undefined
}
/**
* Successful validation result.
*/
export interface ValidValidationResult {
/** Indicates successful validation */
valid: true
/** Original input as DiceNotation */
argument: DiceNotation
/** Human-readable descriptions for each roll */
description: string[][]
/** Parsed roll options for each roll */
options: ParsedNotationOptions[]
/** Notation strings for each roll */
notation: DiceNotation[]
/** No error on success */
error: null
}
/**
* Error information from validation.
*/
export interface ValidationErrorInfo {
/** Description of what's wrong */
message: string
/** The input that failed validation */
argument: string
}
/**
* Failed validation result.
*/
export interface InvalidValidationResult {
/** Indicates failed validation */
valid: false
/** Original input string */
argument: string
/** Error information */
error: ValidationErrorInfo
}
/**
* Result of notation validation.
*/
export type ValidationResult = ValidValidationResult | InvalidValidationResult