Customisation
Random number generator
By default, the dice rolls use Javascript's built-in Math.random()
function to generate the roll values. This is a form of pseudo random number generation (PRNG).
For most purposes, Math.random()
should be suitable, however, if you want something more random, or would rather something more powerful, or even cryptographically secure, you can change the "engine" used for the number generation.
Engines
A random number generation (RNG) engine is a class, or object, that determines the next random number that will be generated. There are several built-in engines that you can use:
nativeMath
: UtilisesMath.random()
browserCrypto
: Utilisescrypto.getRandomValues()
nodeCrypto
: Utilisesrequire('crypto').randomBytes()
MersenneTwister19937
: Produces a new Mersenne Twister. Must be seeded before use.
Custom engine
You can also create your own engines. This can be any class or object that has a next()
method which returns a 32-bit integer. e.g:
// a simple object
const engineA = {
next () {
// logic to generate and return random integer...
},
};
// or a class
class myEngine {
next() {
// logic to generate and return random integer...
}
}
const engineB = new myEngine();
TIP
We use random-js behind the scenes, and the built-in engines are taken from that library. You can read more about how they work in the random-js documentation
Usage
You can access the number generator by importing the NumberGenerator
namespace:
import { DiceRoller, NumberGenerator } from '@dice-roller/rpg-dice-roller';
const { DiceRoller, NumberGenerator } = require('@dice-roller/rpg-dice-roller');
// `NumberGenerator` is available on the global `rpgDiceRoller` variable
rpgDiceRoller.NumberGenerator
NumberGenerator
has two properties:
engines
: a list of the built-in engines (See list above).generator
: an instance of theNumberGenerator
class, that generates the random numbers.
Setting the engine
You can change the engine that generator
uses by setting the numberGenerator.engine
property:
const roller = new DiceRoller();
const engines = NumberGenerator.engines;
const generator = NumberGenerator.generator;
// use the nodeCypto engine
generator.engine = engines.nodeCrypto;
// roll the notation using nodeCrypto
roller.roll('d6');
// change the engine to Mersenne Twister (This requires a seed)
generator.engine = engines.MersenneTwister19937.seed(521);
// roll the notation using Mersenne Twiste
roller.roll('d6');
// use a custom engine
generator.engine = {
next() {
// logic to generate and return random integer...
}
};
// roll the notation using the custom engine
roller.roll('d6');
If you want to revert back to using the default Math.random()
, you can either set the engine to nativeMath
, or to a falsy value (e.g. null
):
generator.engine = engines.nativeMath;
generator.engine = null;
Generating a random number
TIP
It's unlikely that you'll need to generate your own random numbers, as the dice rolls handle this for you, but the functionality is there if you need to work with it.
If you need to generate random numbers outside of rolling dice, the generator
has two methods, integer
and real
, which produce a random integer or float number respectively.
// generate an integer between 1 and 4
generator.integer(1, 4);
// generate a float between 1 and 4 exclusive - [min, max)
generator.real(1, 4);
// generate an float between 1 and 4 inclusive - [min, max]
generator.real(1, 4, true);
More information
For more information on the engines, and how the generator works, check out:
- random-js documentation; this is used behind the scenes. You can find more info on the engines and how to use the Mersenne Twister engine.
- API docs for more detail on the
NumberGenerator
class.
Modifier execution order
WARNING
Be careful when changing the modifier execution order. The default order is purposefully defined and changing it may lead to unexpected behaviour.
If you change the order of a modifier to the same order as another modifier, there is no guarantee of which one will run first.
Modifiers always run in a specific order, regardless of the order you specify them in the notation. This is determined by the modifier's order
property, and works in ascending order.
However, sometimes the default order is not desired, because certain games require a slightly different order.
For example, Open Legend requires the keep modifier to be run before the explode modifier. However, by default, the explode modifier runs first.
This is because the explode modifier has an order of 3
, and the keep modifier has an order of 6
.
Fortunately, you can modify the execution order for any modifier either globally, or on a per-instance basis.
Change default order
To change the execution order when rolling string notations (e.g. DiceRoll('4d6!kh1')
), you can set the default order for a modifier.
Each Modifier
class has a static order
property, which is used to set the order when a new Modifier is created.
You can change it like:
// set the explode modifier order to 7
ExplodeModifier.order = 7;
// set the keep modifier order to 2
KeepModifier.order = 2;
Any new ExplodeModifier
, and KeepModifier
objects will now have the new orders. Other modifiers will retain their original order.
This also works with manually created Modifier
objects:
const mod = new ExplodeModifier();
mode.order === 7;
Conflicting order values
When changing a modifier order, any modifiers with the same order value should be changed to a unique value.
Example
Using the Open Legend example, we would need the keep modifier to run before the explode modifier.
// With the default order;
// roll the dice, explode any that roll a 4, then keep only the highest 4 rolls
const roll = new DiceRoll('8d4kh4!');
// Set the keep modifier order to `3` (The current order for the explode modifier)
KeepModifier.order = 3;
// The drop modifier should always run after the keep modifier, so set that to `4`
DropModifier.order = 4;
// Set the explode modifier to run after keep and drop modifiers
ExplodeModifier.order = 5;
// Order 4 and 5 are alreday used for the re-roll and unique modifiers.
// We need to change them as well, otherwise the order is ambiguous
ReRollModifier.order = 6;
UniqueModifier.order = 7;
// With the new order;
// roll the dice, keep only the highest 4 rolls, then explode any that roll a 4
const roll = new DiceRoll('8d4kh4!');
Change individual instance order
Limitations
This will not affect modifiers created from rolling string notation, and is only useful if you are manually creating modifier instances.
To affect roll notations, change the default order instead.
You can change the order on an individual modifier object, by setting the non-static order
property:
const mod1 = new ExplodeModifier();
mod1.order = 7;
This only affects the object you have modified. Creating another ExplodeModifier
will still use the default order.