
Security News
CVE Volume Surges Past 48,000 in 2025 as WordPress Plugin Ecosystem Drives Growth
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.
@risadams/dice-roller
Advanced tools
Elegant TypeScript dice rolling library for tabletop RPGs, games, and applications requiring dice mechanics
A sophisticated TypeScript dice rolling library for tabletop RPGs, games, and any application requiring elegant dice mechanics.
No installation required! Try the dice roller immediately:
# Quick dice rolls
npx @risadams/dice-roller "3d6+5"
npx @risadams/dice-roller roll d20
npx @risadams/dice-roller "2d8+1d4-2"
# Custom dice
npx @risadams/dice-roller scrum # Scrum planning
npx @risadams/dice-roller fibonacci # Fibonacci sequence
npx @risadams/dice-roller coin # Coin flip
npx @risadams/dice-roller magic8 # Magic 8-Ball
npx @risadams/dice-roller yesno # Yes/No decision
# Verbose output (with details)
npx @risadams/dice-roller "3d6+5" --verbose
npx @risadams/dice-roller coin -v
# Advanced mechanics
npx @risadams/dice-roller advantage d20
npx @risadams/dice-roller disadvantage d20
npx @risadams/dice-roller exploding 3d6
# Interactive demo
npx @risadams/dice-roller demo
# Statistical analysis
npx @risadams/dice-roller stats "3d6"
# Get help
npx @risadams/dice-roller help
npm install @risadams/dice-roller
import { Roller, CustomDie, DicePresets } from '@risadams/dice-roller';
const roller = new Roller();
// Basic rolling
const d20Roll = roller.rollDie(20);
const damage = roller.rollSum(3, 6); // 3d6 damage
// Expression rolling
const attack = roller.rollExpression('1d20+5');
const fireball = roller.rollExpression('8d6');
// Custom dice
const customDie = new CustomDie([2, 4, 6, 8, 10]);
const customRolls = roller.rollCustomDice(customDie, 3);
// Fibonacci die for Scrum planning
const fibDie = DicePresets.createFibonacciDie(8);
const storyPoints = fibDie.roll(); // Returns: 0, 1, 1, 2, 3, 5, 8, or 13
// Scrum planning with actual "?" character
const scrumDie = DicePresets.createScrumPlanningDie();
const estimate = scrumDie.roll(); // Returns: 1, 2, 3, 5, 8, 13, 20, or "?"
// Text-based dice
const coinDie = DicePresets.createCoinDie();
const coinFlip = coinDie.roll(); // Returns: "Heads" or "Tails"
const magic8Ball = DicePresets.createMagic8BallDie();
const answer = magic8Ball.roll(); // Returns various text responses
// Weighted dice
const lootDie = DicePresets.createWeightedDie([
{ value: 'Common', weight: 5 },
{ value: 'Rare', weight: 1 }
]); // Use lootDie.getProbability('Common') to get actual percentages
// Advanced mechanics
const advantageRoll = roller.rollWithAdvantage(20);
const abilityScores = roller.rollKeepHighest(4, 6, 3); // 4d6 drop lowest
rollDie(sides: number): number - Roll a single dierollDice(count: number, sides: number): number[] - Roll multiple dicerollSum(count: number, sides: number): number - Roll and sum multiple dicerollExpression(expression: string): number - Evaluate dice expressionrollExpressionDetailed(expression: string) - Get detailed resultsrollWithAdvantage(sides: number) - Roll twice, take higherrollWithDisadvantage(sides: number) - Roll twice, take lowerrollKeepHighest(count: number, sides: number, keep: number) - Drop lowest dicerollKeepLowest(count: number, sides: number, keep: number) - Drop highest dicerollExploding(count: number, sides: number, maxExplosions?: number) - Reroll on maxrollStandard() - Roll standard RPG dice setgetStatistics(expression: string, samples: number) - Generate statisticsrollCustomDice(customDie: CustomDie, count: number) - Roll custom dicerollCustomDiceSum(customDie: CustomDie, count: number) - Sum custom dice rollsgetCustomDieStatistics(customDie: CustomDie, samples: number) - Analyze custom dicecompareCustomDice(die1: CustomDie, die2: CustomDie, samples: number) - Compare diceimport { CustomDie } from '@risadams/dice-roller';
// Create a custom die with specific values
const customDie = new CustomDie([1, 3, 5, 7, 9]);
console.log(customDie.roll()); // Returns one of: 1, 3, 5, 7, 9
console.log(customDie.getExpectedValue()); // 5
console.log(customDie.getProbability(5)); // 0.2 (20%)
import { DicePresets } from '@risadams/dice-roller';
// Fibonacci sequence die (perfect for Scrum planning)
const fibDie = DicePresets.createFibonacciDie(8);
// Values: [0, 1, 1, 2, 3, 5, 8, 13]
// Standard Scrum planning poker die
const scrumDie = DicePresets.createScrumPlanningDie();
// Values: [1, 2, 3, 5, 8, 13, 20, '?']
// Arithmetic progression die
const arithDie = DicePresets.createArithmeticDie(5, 3, 4);
// Values: [5, 8, 11, 14]
// Weighted die (some values more likely than others)
const weightedDie = DicePresets.createWeightedDie([
{ value: 1, weight: 1 },
{ value: 2, weight: 2 },
{ value: 3, weight: 3 }
]);
// Probability: 1=16.7%, 2=33.3%, 3=50.0% (calculated dynamically via getProbability())
import { DiceExpression } from '@risadams/dice-roller';
const expr = new DiceExpression('3d6+5');
console.log(expr.evaluate()); // Roll the expression
console.log(expr.getMinValue()); // 8
console.log(expr.getMaxValue()); // 23
console.log(expr.toString()); // "3d6+5"
import { Die } from '@risadams/dice-roller';
const d6 = new Die(6);
console.log(d6.roll()); // 1-6
console.log(d6.rollMultiple(3)); // [1-6, 1-6, 1-6]
The library supports mathematical expressions with dice notation:
d6, 3d6, 1d203d6+5, 2d8-2, 1d4*2, 10d6/22d20+1d6+3, 4d6+2d8-1d4const roller = new Roller();
// Ability scores (4d6 drop lowest)
const strength = roller.rollKeepHighest(4, 6, 3);
console.log(`Strength: ${strength.result} (${strength.kept.join('+')}, dropped: ${strength.dropped})`);
// Attack roll with advantage
const attack = roller.rollWithAdvantage(20);
console.log(`Attack: ${attack.result} (rolled: ${attack.rolls})`);
const roller = new Roller();
// Weapon damage
const swordDamage = roller.rollExpression('1d8+3');
const criticalHit = roller.rollExpression('2d8+3'); // Double dice on crit
// Spell damage
const fireball = roller.rollExpression('8d6');
const healingPotion = roller.rollExpression('2d4+2');
const roller = new Roller();
// Create a Fibonacci die for story point estimation
const fibDie = DicePresets.createFibonacciDie(8);
console.log(`Story points: ${fibDie.roll()}`); // 0, 1, 1, 2, 3, 5, 8, or 13
// Standard Scrum planning poker with actual "?" character
const scrumDie = DicePresets.createScrumPlanningDie();
const estimate = scrumDie.roll();
console.log(`Estimate: ${estimate}`); // Could be 1, 2, 3, 5, 8, 13, 20, or "?"
// Analyze the distribution
const stats = roller.getCustomDieStatistics(fibDie, 1000);
if (stats.expectedValue !== null) {
console.log(`Average story points: ${stats.expectedValue.toFixed(1)}`);
}
const roller = new Roller();
// Simple Yes/No decision
const yesNoDie = DicePresets.createTextDie(['Yes', 'No', 'Maybe']);
console.log(`Decision: ${yesNoDie.roll()}`);
// Magic 8-Ball style responses
const magic8Ball = DicePresets.createMagic8BallDie();
console.log(`Magic 8-Ball says: "${magic8Ball.roll()}"`);
// Coin flip
const coinDie = DicePresets.createCoinDie();
console.log(`Coin flip: ${coinDie.roll()}`);
// Game loot with weighted text values
const lootDie = DicePresets.createWeightedDie([
{ value: 'Common', weight: 5 },
{ value: 'Uncommon', weight: 3 },
{ value: 'Rare', weight: 2 },
{ value: 'Legendary', weight: 1 }
]);
console.log(`Loot rarity: ${lootDie.roll()}`);
// Custom die with mixed values
const mixedDie = new CustomDie([1, 2, 'Skip', 4, 'Double']);
console.log(`Roll result: ${mixedDie.roll()}`);
// Scrum planning with actual "?" for unknown complexity
const scrumDie = DicePresets.createScrumPlanningDie();
const estimate = scrumDie.roll();
console.log(`Story points: ${estimate}`); // Could be number or "?"
// Statistics handle mixed types gracefully
const stats = roller.getCustomDieStatistics(scrumDie, 1000);
console.log(`Has numeric values: ${stats.hasNumericValues}`);
console.log(`Has non-numeric values: ${stats.hasNonNumericValues}`);
if (stats.expectedValue !== null) {
console.log(`Expected value of numeric faces: ${stats.expectedValue}`);
}
const roller = new Roller();
// Analyze weapon damage over 1000 rolls
const stats = roller.getStatistics('1d8+3', 1000);
console.log(`Average damage: ${stats.mean.toFixed(1)}`);
console.log(`Range: ${stats.min}-${stats.max}`);
console.log(`Standard deviation: ${stats.standardDeviation.toFixed(2)}`);
// Analyze custom dice (works with both numeric and non-numeric)
const customDie = new CustomDie([2, 4, 6, 8, 10]);
const customStats = roller.getCustomDieStatistics(customDie, 1000);
if (customStats.expectedValue !== null && customStats.mean !== null) {
console.log(`Expected value: ${customStats.expectedValue}`);
console.log(`Theoretical vs actual mean: ${customStats.expectedValue} vs ${customStats.mean.toFixed(2)}`);
}
// Mixed dice statistics
const mixedDie = new CustomDie([1, 'A', 2, 'B']);
const mixedStats = roller.getCustomDieStatistics(mixedDie, 1000);
console.log(`Has numeric values: ${mixedStats.hasNumericValues}`);
console.log(`Has non-numeric values: ${mixedStats.hasNonNumericValues}`);
import { Roller } from 'roller';
// Use a seeded random function for reproducible results
const seededRandom = () => 0.5; // Always returns middle value
const roller = new Roller(seededRandom);
console.log(roller.rollDie(6)); // Always returns 4
npm run build
npm test
npm run test:watch
npm run test:coverage
npm run demo
This library is written in TypeScript and includes full type definitions. All classes and methods are properly typed for excellent IDE support and compile-time error checking.
MIT - see the LICENSE file for details.
--verbose/-v flag for detailed output with emojis and breakdownscoin (alias: flip) - Coin flip (Heads/Tails)magic8 (aliases: 8ball, magic8ball) - Magic 8-Ball responsesyesno (aliases: yn, decision) - Simple Yes/No decision makernpx @risadams/dice-roller scrum)npx @risadams/dice-roller fibonacci)CustomDie<T> class with TypeScript generics for type-safe custom diceDicePresets with factory methods for common custom dice patterns:
hasNumericValues(), hasNonNumericValues())Roller class now supports custom dice operations with full type safetyFAQs
Elegant TypeScript dice rolling library for tabletop RPGs, games, and applications requiring dice mechanics
We found that @risadams/dice-roller demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.

Security News
Socket CEO Feross Aboukhadijeh joins Insecure Agents to discuss CVE remediation and why supply chain attacks require a different security approach.

Security News
Tailwind Labs laid off 75% of its engineering team after revenue dropped 80%, as LLMs redirect traffic away from documentation where developers discover paid products.