Seeding Options

Seeding is a fundamental concept in random number generation. By providing a seed, you can ensure that a sequence of random numbers is reproducible. This is invaluable in scenarios where you want to recreate a specific sequence of events, like replaying a game level with the same random challenges. Let's dive into how RNGNeeds handles seeding.


Seeding in RNGNeeds

At its core, the plugin leverages the Unity.Mathematics Random object for all random number generation tasks. This object requires initialization with a uint seed. RNGNeeds features an extensible Seed Provider, responsible for providing the uint value. Later in this section, you'll learn how to make your own Seed Provider.

Here's a step-by-step breakdown of how our selection methods utilize seeds:

  1. At the start of a selection process, the Probability List generates a new seed using the ProbabilityList.Seed property.
  2. This generated seed determines the random pick count, either supplied via parameters or derived from the List's PickCountMin and PickCountMax properties, depending on the PickValues() overload used.
  3. The Probability List is subsequently passed to the chosen Selection Method. As the Seed is included with the List, the selection method retrieves it through the ProbabilityList.CurrentSeed property to initialize a new Random object.
  4. This newly initialized Random object is then used to generate random numbers for the entire selection process.

By default, invoking ProbabilityList.Seed generates a new seed using the RNGNeeds Seed Provider. In simpler terms, each time you pick values, the list uses a unique seed to produce results.

After the selection process, the list retains the newly generated seed that was used. You can access this value using the ProbabilityList.CurrentSeed property.

Default Seed Provider

RNGNeeds comes with a built-in seed provider named DefaultSeedProvider. This provider uses the .NET System.Random class in conjunction with the current UTC time's ticks to generate a seed. The combination ensures a high degree of randomness. To prevent potential threading issues, the seed generation is thread-safe, using a lock mechanism.

Default Seed Provider Code

public class DefaultSeedProvider : ISeedProvider
{
    private readonly System.Random _random = new System.Random();
    private readonly object _lockObject = new object();

    public uint NewSeed
    {
        get
        {
            lock (_lockObject)
            {
                return (uint)(_random.Next() * DateTime.UtcNow.Ticks % uint.MaxValue);
            }
        }
    }
}

Keep Seed

The "Keep Seed" feature allows you to maintain the same seed between selections, by disabling the seed automatic generation. To enable "Keep Seed", navigate to the PICK section of the drawer. Ensure that the Drawer Options Level is set to Advanced in the Preferences window.

Seeding Options - Inspector

Enabling Keep Seed in Code

var result = myProbabilityList.PickValue();     // a new seed is generated
myProbabilityList.KeepSeed = true;
var newResult = myProbabilityList.PickValue();  // produces the same results

Seed Provider

If you want more control over the seed generation mechanics, you can implement the ISeedProvider interface and design your custom seeding logic.

Here's a step-by-step guide:

  1. Start by creating a new class that implements the ISeedProvider interface:

Custom Seed Provider Example

using System;
using RNGNeeds;

public class MySeedProvider : ISeedProvider
{
    public uint NewSeed
    {
        get
        {
            // Replace this with your custom seed generation logic
            return (uint)(DateTime.UtcNow.Ticks % uint.MaxValue);
        }
    }
}
  1. Next, register your custom seed provider with the RNGNeedsCore class:

Setting Custom Seed Provider

RNGNeedsCore.SetSeedProvider(new MySeedProvider());

Once set, all Probability Lists will utilize your custom seed generation logic. And if you ever need a new seed for other purposes, you can obtain it using RNGNeedsCore.NewSeed.

To revert to the default seed provider, simply call RNGNeedsCore.ResetSeedProvider().