Table of Contents

Generators

A generator, as we use it, is a class that has a Next method that always gives you an object of a certain type. They work a bit like random generators, except the elements may or may not be random. They support various LINQ-like methods, and so also resemble sequences (although generators are always infinite).

There are a few “primitive” generators that you can construct directly with the various static methods in the Generator class. These include:

Generator Description
Constant A generator that always generates the same element.
Count A generator generates the sequence 0, 1, 2, 3, ..., n, 0, 1, 2, forever.
Repeat A generator that generates the elements of a given list repeatedly in sequence.
Iterate A generator that applies a given function to the last k elements to generate the next one.

There are also various random number and bool generators (uniform, arbitrary distribution, Markov chains)

By themselves these generators are not very interesting. But there are several methods that manipulate and combine them to make more interesting generators. Some of the most important are these:

Method Description
Where Generates only elements from a source generator that satisfy a predicate.
Select Transforms the elements of a source generator and generates the transformed copies.
Choose A generator that uses an integer generator to select from a list of objects.
Group Groups elements of a source generator, and generates the groups.
Combine Uses several source generators to generate parameters for a function.
RepeatEach Uses a source generator, and repeats each generated element several times.

For a full list of all the generators and methods that can manipulate them, see Generator.

Here are some simple examples:

var generator = Generator
    .RamdomUniformInt(500)
    .Select(x => 2*x); //Generates random even numbers between 0 and 998

var generator = Generator
    .RandomUniformInt(1000)
    .Where(n => n % 2 == 0); //Same as above

var generator = Generator
    .Iterate(0, 0, (m, n) => m + n); //Fibonacci numbers

var generator = Generator
    .RandomUniformInt(2)
    .Select(n => 2*n - 1)
    .Aggregate((m, n) => m + n); //Random walk using steps of 1 or -1 one randomly

var generator = Generator
    .Iterate(0, Generator.RandomUniformInt(4), (m, n) => m + n - 1)
    .Where(n >= 0); //A random sequence that increases on average

In each case, elements are only being produced each time you call the Next method or one of its variants. Most calculations are done lazily, so the bulk of the processing is spread over getting the elements and most generators don’t required much memory.

Generators are useful in creating procedural content, or alter properties of game entities (such as their strength) procedurally. A place where you want to use randomness is the ideal candidate, especially when you want to inject some order to make the playable experience more interesting or coherent.

Here are some examples of what things generators can generate (taken from games we have built):

  • sky colors that change over time
  • scene decoration next to an infinite road
  • obstacle patterns
  • AI movement
  • game difficulty
  • random interesting paths
  • letters that have a good chance to make words