Modding:Random Functions
This page is about modding. See the modding overview for an abstract on modding. 
If your mod has some element of randomness, you're gonna be looking for a function to call. However, calling the built in Next()
function in the Random Class built into C# will net you some compilation errors. The best practice is to use the random functions inside XRL/Rules/Stat.cs
. Below are the different random functions inside Caves of Qud and what they are used for.
Randoms
These are the methods that return the Random class. These are all hashed from
Stat.Rand = new Random(Hash.String("Seed0" + (object) Seed));
Stat.Rnd = new Random(Hash.String("Seed1" + (object) Seed));
Stat.Rnd2 = new Random(Hash.String("Seed2" + (object) Seed));
if (includeLifetimeSeeds)
Stat.LevelUpRandom = new Random(Hash.String("Seed3" + (object) Seed));
Stat.Rnd4 = new Random(Hash.String("Seed4" + (object) Seed));
Stat.Rnd5 = new Random(Hash.String("Seed5" + (object) Seed));
Rnd()
This is the main function that randomizes and determines things such as sultan artifacts, villages, and many other things based on world seed. Using this generator or Stat.Random
in a mod may cause a world seed to give different results than in vanilla.
Rnd2(), Rnd4(), Rnd5()
These functions deals with the smaller events you find in Qud.
LevelUpRandom()
The Random used to determine randomized things at level up.
GetSeededRandomGenerator(string Seed)
If you don't want to use the game's seeds in fear of altering worldseed too much, there is a helper function that returns a new random that hashes a new random. This allows your mod to be affected by world seed but does not alter the base game's random number calls.
public static Random GetSeededRandomGenerator(string Seed)
{
if (XRLCore.Core.Game == null)
{
return new Random();
}
return new Random(Hash.String(XRLCore.Core.Game.GetWorldSeed(null) + Seed));
}
The Seed here should follow best practice conventions, so YourName_YourMod
to avoid overlapping conflicts as much as possible.
Returners
These use a specific random class to return a multitude of things.
Random(int low, int high)
Calls Stat.Rnd()
TinkerRandom(int Low, int High)
Calls Stat.Rnd4()
GaussianRandom(float Mean, float StandardDeviation)
double num = Math.Sqrt(2.0 * Math.Log(Stat.Rnd.NextDouble())) * Math.Sin(2.0 * Math.PI * Stat.Rnd.NextDouble());
return (double) Mean + (double) StandardDeviation * num;
Returns a random float around the mean with a probability density of a normal distribution.
RandomCosmetic(int low, int high)
Used most often when getting random angles for particles and other cosmetic effects. Calls Stat.Rnd2()
.
SeededRandom(string Seed, int Low, int High)
Returns an int based on Seed
, in the range of [Low, High]
.
Sample Random Provider for Mod
Here is a fully usable outofthe box random number provider for your mod, which will not interfere with the game's own random seeds.
This template provides:
 a
Rand
property (direct access to the Random object)  a
Next
method that returns a random number in the specified range
It also ties itself to each game's worldseed and automatically resets for new games or save loads.
using System;
using XRL;
using XRL.Core;
using XRL.Rules;
namespace MODNAME.Utilities
{
[HasGameBasedStaticCache]
public static class MODNAME_Random
{
private static Random _rand;
public static Random Rand
{
get
{
if (_rand == null)
{
if (XRLCore.Core?.Game == null)
{
throw new Exception("MODNAME mod attempted to retrieve Random, but Game is not created yet.");
}
else if (XRLCore.Core.Game.IntGameState.ContainsKey("MODNAME:Random"))
{
int seed = XRLCore.Core.Game.GetIntGameState("MODNAME:Random");
_rand = new Random(seed);
}
else
{
_rand = Stat.GetSeededRandomGenerator("MODNAME");
}
XRLCore.Core.Game.SetIntGameState("MODNAME:Random", _rand.Next());
}
return _rand;
}
}
[GameBasedCacheInit]
public static void ResetRandom()
{
_rand = null;
}
public static int Next(int minInclusive, int maxInclusive)
{
return Rand.Next(minInclusive, maxInclusive + 1);
}
}
}
Example Usage
 Save the code above in its own file (for example,
MODNAME_Random.cs
).  In your other mod code files, include the following using statment:
using MODNAME.Utilities;
 Call the code in one of the ways demonstrated below.
Get a random number between 1 and 10 (inclusive): 
MODNAME_Random.Next(1, 10);

Use the Random object directly. For example, supply it to another method:

someList.ShuffleInPlace(MODNAME_Random.Rand);

