Modding:Random Functions: Difference between revisions

m
Clarifies that Rnd isn't used in mutation picking, makes the explanation of consequences less dramatic/hyperbolic.
mNo edit summary
m (Clarifies that Rnd isn't used in mutation picking, makes the explanation of consequences less dramatic/hyperbolic.)
 
(12 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{As Of Patch| 2.0.182.1}} {{stub}}
{{Modding Info}}{{Modding Topic Prerequisites | Modding:C Sharp Scripting}}


If your mod has some element of randomness, you're gonna be looking for a function to call. However, calling the built in <code>Next()</code> function in the Random Class built into C# will net you some compilation errors. The best practice is to use the random functions inside <code>XRL/Rules/Stat.cs</code>. Below are the different random functions inside Caves of Qud and what they are used for.
If your mod has some element of randomness, you're gonna be looking for a function to call. However, calling the built in <code>Next()</code> function in the Random Class built into C# will net you some compilation errors. The best practice is to use the random functions inside <code>XRL/Rules/Stat.cs</code>. Below are the different random functions inside Caves of Qud and what they are used for.
Line 15: Line 15:


===Rnd()===
===Rnd()===
This is the main function that randomizes and determines things such as sultan artifacts, villages, and basically everything important that is based on world seed. All effects and mutations use this function. Don't use this function in your mod if you don't want to ruin world seeds.  
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 <code>Stat.Random</code> in a mod may cause a world seed to give different results than in vanilla.


===Rnd2(), Rnd4(), Rnd5()===
===Rnd2(), Rnd4(), Rnd5()===
Line 22: Line 22:
===LevelUpRandom()===
===LevelUpRandom()===
The Random used to determine randomized things at level up.
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.
<syntaxhighlight lang="c#">
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));
        }
</syntaxhighlight>
The Seed here should follow [[Modding: General Best Practices|best practice conventions]], so <code>YourName_YourMod</code> to avoid overlapping conflicts as much as possible.


==Returners==
==Returners==
Line 27: Line 41:


===Random(int low, int high)===
===Random(int low, int high)===
Calls <code>Stat.Rnd().</code>
Calls <code>Stat.Rnd()</code>




===TinkerRandom(int Low, int High)===
===TinkerRandom(int Low, int High)===
Calls <code>Stat.Rnd4()</code>.
Calls <code>Stat.Rnd4()</code>


===GaussianRandom(float Mean, float StandardDeviation)===
===GaussianRandom(float Mean, float StandardDeviation)===
Line 37: Line 51:
double num = Math.Sqrt(-2.0 * Math.Log(Stat.Rnd.NextDouble())) * Math.Sin(2.0 * Math.PI * Stat.Rnd.NextDouble());
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;
       return (double) Mean + (double) StandardDeviation * num;
</syntaxhighlight>
</syntaxhighlight>Returns a random float around the mean with a probability density of a normal distribution.


===RandomCosmetic(int low, int high)===
===RandomCosmetic(int low, int high)===
Line 43: Line 57:


===SeededRandom(string Seed, int Low, int High)===
===SeededRandom(string Seed, int Low, int High)===
Returns an int based on <code>Seed</code>, in the range of <code>[Low, High]<code>.
Returns an int based on <code>Seed</code>, in the range of <code>[Low, High]</code>.
 
== Sample Random Provider for Mod ==
 
Here is a fully usable out-of-the box random number provider for your mod, which will not interfere with the game's own random seeds.
 
This template provides:
* a <code>Rand</code> property (direct access to the Random object)
* a <code>Next</code> 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.
 
<syntaxhighlight lang="csharp">
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);
        }
    }
}
</syntaxhighlight>
 
=== Example Usage ===
# Save the code above in its own file (for example, <code>MODNAME_Random.cs</code>).
# In your other mod code files, include the following using statment: <code>using MODNAME.Utilities;</code>
# Call the code in one of the ways demonstrated below.
 
{| class="wikitable"
| Get a random number between 1 and 10 (inclusive):
|-
|
<syntaxhighlight lang="c#">
MODNAME_Random.Next(1, 10);
</syntaxhighlight>
|}
 
{| class="wikitable"
| Use the <code>Random</code> object directly. For example, supply it to another method:
|-
|
<syntaxhighlight lang="c#">
someList.ShuffleInPlace(MODNAME_Random.Rand);
</syntaxhighlight>
|}
 
{{Modding Navbox}}


[[Category:Modding]]
[[Category:Script Modding]]
45

edits