# Make It Random

Development Discontinued | Discuss | Basic

Documentation | Quick Start | Changes | Demos

Requires Unity 5.0.0 or higher.

*A serious RNG library for serious engineers.*

Make It Random is a fast, flexible, extensible, and feature-rich random number generation library.
Unlike `UnityEngine.Random`

, Make It Random provides the following benefits:

- Offers a wide variety of utilities on top of the basic random number generation.
- Produces higher quality uniform distributions of integer and floating point numbers.
- Allows multiple concurrent random engines, each seeded differently, independently generating sequences of random values.
- Can be seeded using a wider variety of data, such as strings or byte arrays of any length.
- Can be used on any thread, not just the main thread.
- Includes multiple random engine algorithms and supports implementation of your own.
- Reduces confusion about whether the lower and upper bounds of ranges are inclusive or exclusive.

The categories of random data that Make It Random can generate includes:

- bits
- integers
- floating point numbers
- angles
- vectors and quaternions
- strings
- dice rolls
- colors (includes Make It Colorful)

In addition, Make It Random includes utilities for the following, with support for non-uniform weights where applicable:

- evaluating probabilities
- sampling from distributions
- selecting elements from a list
- selecting values from an enumeration
- selecting values from the set {-1, 0, +1}
- shuffling a list

The library is very extensible, to support whatever underlying RNGs and extension functions you might want. Full source code is included.

The basic edition is also available, offering just the core RNG functionality for free!

## The Details

### Random Engines

- XorShift128+ is great for general use.
- XorShift1024* offers a huge state space and long period, ideal for card games.
- An instance of SplitMix64 uses just 8 bytes of memory.
- XorShiftAdd is optimal for 32-bit platforms.
- Wrappers for
`UnityEngine.Random`

and`System.Random`

allow them to be used with all the available extension functions. - An abstract base class to simply the process of porting your favorite random engine or creating your own.

### Random Integers

- Supports all built-in integer types, both signed and unsigned, for 8-, 16-, 32-, and 64-bit sizes, so that you can directly and optimally get the type you need.
- Explicit upper and lower bound inclusiveness. Open, closed, and half-open ranges all supported, with no need to frequently check documentation to be reminded of what a function does.
- Overloads make it easy to provide both an upper and lower bound, or just an upper bound with an implicit lower bound of 0, or no bound at all to pull from the full range of the integer type requested.

### Random Floating Point Numbers

- Direct support for both
`float`

and`double`

. - Explicit upper and lower bound inclusiveness, as with integer ranges.
- Perfect uniformity and no irregular clumpiness for the unit range (between 0 and 1).
- Incredibly fast implementation, no division or remainder operations involved.
- Special functions for increased precision near zero, and for the signed unit range (between -1 and +1).

### Probabilities and Chance

- Easy way to get a direct true or false result, including a zero-parameter 50/50 chance function.
- Direct probabilities: likelihood of true value, specified between 0 and 1.
- Ratio of true to false:
*n*true results for every*m*false results. - Frequency:
*n*true results out of*d*total results.

### Distribution Sampling

- Sample from the following continuous distributions: uniform, triangular, trapezoidal, linear, Hermite spline, normal, and exponential.
- Combine piecewise uniform, linear, or Hermite spline distributions to form more complex aggregate distributions.
- Initialize Hermite spline distributions using Unity animation curves, making it easy to configure the shape directly from the editor.

### Vectors and Quaternions

- High precision 2D, 3D, and 4D unit vectors.
- Uniformly distributed 2D vectors within circles, circular rings, squares, rectangles, parallelograms, and triangles
- Uniformly distributed 3D vectors within spheres, spherical shells, cubes, boxes, and rhomboids.
- Very fast implementation fixed point intermediate arithmetic, guarantees reliable determinism across platforms.

### Strings

- Fast binary, octal, decimal, hexadecimal, and base64 strings.
- Alphabetic, alphanumeric, and identifier strings, with nuanced control over separators like spaces or underscores.
- Strings made from custom character sets, also with separator control.

### Angles

- Degrees and radians both supported.
- Half (180°) and full (360°) revolution ranges.
- Signed (centered on 0°) and unsigned ranges (starting at 0° upward).

### Dice

- Any number of sides per die, any number of dice.
- Options to keep or drop the
*n*highest or lowest rolls from a group. - Dice string parsing to make use of common dice notation such as "4d6k3" to roll 4 6-sided dice and keep the highest 3.

### Colors

- Supports standard RGB, plus all the color spaces provided by Make It Colorful: HSV, HSL, HSY, HCV, HCL, HCY, CMY, and CMYK.
- Pick random colors uniformly from within an entire color space.
- Pick colors from within common categories such as bold, mellow, warm, or cool.
- Randomly modify one or more components of an existing color according to specifiable constraints.
- Easily lighten or darken, brighten or dull, or hue shift an existing color.

### List Access and Shuffling

- Supports arrays and anything implementing
`IList<T>`

. - Can generate random indices for lists or directly pull elements.
- Supports both uniform and weighted selection.
- Shuffle in-place or into a different list.
- Optionally force a shuffle to guarantee that all elements get moved to a new location.

### Enumerations

- Automatically examines any desired
`enum`

type and prepares an efficient enumeration item generator. - Can treat duplicate values as either distinct or identical.
- Can return both enumeration item value and name, useful when duplicate values are still considered distinct.
- Can provide weights for the different items in an enumeration, influencing how likely each is to be randomly selected.

### {-1, 0, +1}

- Great in certain numerical situations, to multiply an existing number to make it negative or positive, or to zero it out.
- Similar probability, ratio, and frequency interfaces as for random true/false values.
- Can be limited to just the pairs {0, 1} or {-1, +1}.

### Miscellaneous

- Many operations can be wrapped into generator instances, remembering parameters and optimizing the generation process.
- Numerous options for seeding random engines, all with a common interface regardless of engine implementation.
- Easily store or load the state of a random engine as an opaque byte array, or access it using that engine's particular state format.
- A global static instance available for convenience, if that interface suits your needs.

## Samples

The following script can be used to place multiple copies of a prefab into the scene, with random positions selected near the surface of a sphere.

```
using UnityEngine;
using Experilous.MakeItRandom;
public void SphericalShellDistributor : MonoBehaviour
{
public MeshRenderer prefab;
public int objectCount = 100;
public string randomSeed = "andy";
public float minShellRadius = 9f;
public float maxShellRadius = 11f;
public float minScale = 0.5f;
public float maxScale = 1.5f;
protected void OnStart()
{
// Use the seed to create the random engine which
// will provide the randomness of each child.
var random = MIRandom.CreateStandard(randomSeed);
for (int i = 0; i < objectCount; ++i)
{
var meshRenderer = Instantiate(prefab);
var meshTransform = meshRenderer.transform;
meshTransform.SetParent(transform, false);
// Assign a random position within the shell.
meshTransform.localPosition =
random.PointWithinSphericalShell(minRadius, maxRadius);
// Give it a completely random orientation.
meshTransform.localRotation = random.Rotation();
// Pick a random scale within the specified range.
var scale = random.RangeCC(minScale, maxScale);
meshTransform.localScale = new Vector3(scale, scale, scale);
// Assign a color pulled randomly from the HCY color space.
meshRenderer.color = random.ColorHCY();
}
}
}
```

Here are quick samples from the various categories of random content generation available:

```
// Initialize random engine with a transient seed
var random = XorShift128Plus.Create();
// Generate an integer where 1 <= n <= 10
int num1to10 = random.RangeCC(1, 10);
// Generate a number where 0 <= n < 1
float num0to1 = random.FloatCO();
// Flip a coin
bool heads = random.Chance();
// Check a 3 in 10 probability
bool criticalHit = random.Probability(3, 10);
// Generate a random height for a male character in cm
float height = random.NormalSample(176f, 8f);
// Generate an angle in degrees where -90 < n < +90
float angleNeg90toPos90 = random.SignedHalfAngleDegOO();
// Generate +1, -1, or 0 where +1 is twice as likely as -1, and 0 is rare
int numPNZ = random.SignOrZero(200, 100, 1);
// Roll 43 20-sided dice
int[] diceRolls = random.RollDice(43, 20);
// Roll 5 4-sided dice and just keep the sum
int diceRollSum = random.SumRollDice(5, 4);
// Shuffle the array of earlier dice rolls
random.Shuffle(diceRolls);
// Select a random die roll from the array
int dieRoll = random.Element(diceRolls);
// Select index where higher die rolls are more likely to be picked
int dieRollIndex = random.WeightedIndex(diceRolls);
// Generate a random 3D unit vector
Vector3 direction = random.UnitVector3();
// Generate a position within a cirle of radius = 5
Vector2 point = random.PointWithinCircle(5f);
// Generate a 32-character string with only alpha-numeric characters.
string str = random.AlphaNumericString(32);
// Make a generator which will produce random font styles.
var fontStyleGen = random.MakeEnumGenerator
```();
// Generate a font style
var style = fontStyleGen.Next();
// Pick a random warm color
var color = random.ColorWarm();
// Alter the color's hue randomly by no more than 1/10.
color = random.HueShift((ColorHSV)color, 0.1f);