npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@seroh/roll

v1.0.1

Published

An RPG dice-rolling library with a variety of built-in roll mechanics.

Downloads

55

Readme

Dice Rolling Library

This library provides a flexible and extensible system for rolling dice in tabletop RPGs, simulations, or any other applications requiring randomized results.

Installation

Install the library via npm:

npm install @seroh/roll

Usage

Here’s an example of creating a simple D&D 1d20 attack roll with a -1 modifier:

import {Roll} from "@seroh/roll";

const attack = new Roll(1, 20);
const result = attack.roll(-1);

console.log(`Natural Roll: ${result.natural}`);
console.log(`Modified Roll: ${result.modified}`);

Mechanics

A mechanic defines the rules and behavior of a roll, shaping how the final results are determined. For example, the "Advantage/Disadvantage" mechanic, commonly used in D&D, modifies rolls to favor higher or lower outcomes.

The following mechanics are currently available:

Example

import {Roll, ExplodingMechanic} from "@seroh/roll";

const explodingAttack = new Roll(1, 20, {mechanic: new ExplodingMechanic()});
const result = explodingAttack.roll();

Randomizers

Randomizers determine how randomness is achieved for rolls, enabling customizable strategies such as seeded, weighted, or default randomness.

In addition to the default strategy (which utilizes Math.random), the following randomization strategies are also supported:

Example

import {Roll, KarmicRandomizer} from "@seroh/roll";

const weightedAttack = new Roll(1, 20, {
  randomizer: new KarmicRandomizer({
    highRollThreshold: 0.8,
    lowRollThreshold: 0.2,
    biasFactor: 0.2,
  }),
});
const result = weightedAttack.roll();

Extending

The goal of this library is to provide a clear path for other developers to implement their own roll behaviours, therfore the library is seprated into core modules. Each core module is extensible and allows you to implement your own roll mechanics.

Randomizer

Developers can implement their own randomization strategies. By default, all rolls use JavaScript's standard Math.random method. However, the system is fully extensible, giving you complete control over the randomness.

In order to create your own randomization strategy, you have to extend the Randomizer class and override its generator method. This method must return a random number between 0 (inclusive) and 1 (exclusive).

Example of creating your own randomizer

Here’s an example of how seeded randomness can be achieved. It employs the 'Linear Congruential Generator' (LCG) algorithm instead of the default Math.random function, allowing the generator to produce a deterministic random value based on a provided seed.

import {Randomizer, Roll} from "@seroh/roll";

class SeededRandomizer extends Randomizer {
  constructor(private seed: number) {
    super();
  }

  // Generate a number between 0 and 1 (exclusive)
  protected generator(): number {
    return this.lcg(this.seed);
  }

  // Linear Congruential Generator (LCG) implementation
  private lcg(seed: number): number {
    const a = 1664525;
    const c = 1013904223;
    const m = 2 ** 32;

    // Generate the next seed
    this.seed = (a * seed + c) % m;
    return this.seed / m;
  }
}

const attack = new Roll(1, 20, {
  randomizer: new SeededRandomizer(12345678),
});

Mechanic

A mechanic defines the rules and behavior of a roll, determining how final results are calculated. For instance, you can use a custom mechanic to implement advanced rolling rules such as exploding roll, advantage mechanics, or other game-specific logic. This allows you to encapsulate and reuse the behavior within your rolls seamlessly.

To create your own roll mechanic, extend the Mechanic class and override its do method.

Example of creating your own roll mechanic

Here's an implementation of a standard "Advantage" mechanic. This mechanic performs two rolls instead of one and returns the highest result. Additionally, it records the history of rolls in the rolls property.

import {Randomizer, Mechanic} from "@seroh/roll";

export class AdvantageMechanic extends Mechanic {
  do(min: number, max: number, randomizer: Randomizer) {
    const a = randomizer.generate(min, max);
    const b = randomizer.generate(min, max);
    return {result: Math.max(a, b), rolls: [a, b]};
  }
}