Skip to content

Randomization

using Clockwork.Utilities;

C#'s random class is lacking in many features. Especially for a game engine. So, Clockwork reinvents this system.

Generate

The Generate class is a static utility for quick random values. For example, to generate a random unit Vector2:

Vector2 launchDirection = Generate.UnitVector2();

Or to generate random degrees from 0 to 360, which is almost silly but still saves enough boilerplate to be worth it:

float degrees = Generate.Degrees();

There are plenty more methods available:

int number = Generate.Integer(0, 100);
float value = Generate.Float(0.5f, 1.5f);
bool coinFlip = Generate.Bool();
bool weighted = Generate.Bool(0.75f); // 75% chance of true
Vector3 direction3D = Generate.UnitVector3();

You can also generate a random position inside a region, which is handy for scattering things across the screen or within a bounding box:

Vector2 spawn = Generate.Vector2(0, 0, Engine.GameWidth, Engine.GameHeight);
Vector2 inBounds = Generate.Vector2(areaRectangle); // within a Rectangle

And you can work with collections:

Generate.Shuffle(myList);                  // shuffle in place
List<Enemy> shuffled = Generate.GetShuffled(enemies); // shuffled copy
int randomIndex = Generate.Index(myCollection);
Enemy randomEnemy = Generate.Item(enemies);
Generate.RemoveItem(enemies);              // remove a random item

Most collection methods have extension variants too, for a more natural syntax:

myList.Shuffle();
int index = myCollection.GetRandomIndex();
Enemy enemy = enemies.GetRandomItem();
enemies.RemoveRandomItem();

Seed

If you need deterministic randomization, you can either change the seed of the Generate class or use the Seed class for independent random streams:

Generate.Seed = 42;

Seed seed = new(12345);
bool isEvil = seed.NextBool();
float speed = seed.NextFloat(1f, 5f);
Vector2 direction = seed.NextUnitVector2();

Seed mirrors Generate, with method names prefixed by Next (NextInteger, NextFloat, NextVector2, NextItem, and so on). This is useful for procedural generation where you want reproducible results — the same seed always produces the same sequence:

Seed seed = new(worldSeed);
Vector2 treePosition = seed.NextVector2(mapBounds);
Biome biome = seed.NextItem(biomes);