Skip to content

Commit 958bdc8

Browse files
committed
Create our own Random class using the xoshiro256 algorithm
- This same algorithm can be chosen by .NET internally (and is Public Domain), but there is no guarantee that this is the case. By having a specific implementation, we can guarantee deterministic output. - This gives access to the state of the Random object at any point via GetState and SetState methods that use Base64 strings. This should allow us to capture the RNG state if an error occurs and reproduce it as needed. - This Random class exists in the RandomizerCore package and will take precedence when working inside this package. It is not a subclass of the System.Random class, so trying to use the wrong class somewhere will just not compile. It has no constructor without a seed. When we don't need to specify a seed, we can still use System.Random (as that implies we don't care about deterministic output). Implements #395
1 parent ea265e3 commit 958bdc8

9 files changed

Lines changed: 321 additions & 15 deletions

File tree

CommandLine/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public int OnExecute()
6767

6868
if (!Seed.HasValue)
6969
{
70-
var r = new Random();
70+
var r = new System.Random();
7171
Seed = r.Next(1000000000);
7272
}
7373
configuration!.Seed = Seed.Value.ToString();

CrossPlatformUI/ViewModels/RandomizerViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public RandomizerViewModel(MainViewModel main)
9797

9898
RerollSeed = ReactiveCommand.Create(() =>
9999
{
100-
Main.Config.Seed = new Random().Next(0, 999999999).ToString();
100+
Main.Config.Seed = new System.Random().Next(0, 999999999).ToString();
101101
});
102102

103103
LoadPreset = ReactiveCommand.Create<RandomizerConfiguration>(config =>

RandomizerCore/CharacterSprite.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public CharacterSprite(string displayName, byte[]? patch = null)
5656

5757
public static CharacterSprite Random(CharacterSprite[] options)
5858
{
59-
Random random = new Random();
59+
System.Random random = new();
6060
return options[random.Next(options.Length - 1)];
6161
}
6262
};

RandomizerCore/Hyrule.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
using DynamicData;
2-
using FtRandoLib.Importer;
3-
using js65;
4-
using NLog;
5-
using System;
1+
using System;
62
using System.Buffers;
73
using System.Collections.Generic;
84
using System.Diagnostics;
95
using System.IO;
106
using System.Linq;
11-
using System.Reflection;
127
using System.Text;
138
using System.Text.Json;
149
using System.Threading;
1510
using System.Threading.Tasks;
11+
using NLog;
12+
using js65;
13+
using FtRandoLib.Importer;
1614
using Z2Randomizer.RandomizerCore.Enemy;
1715
using Z2Randomizer.RandomizerCore.Overworld;
1816
using Z2Randomizer.RandomizerCore.Sidescroll;
@@ -174,7 +172,7 @@ public class Hyrule
174172
*/
175173

176174
public ROM ROMData { get; set; }
177-
public Random r { get; set; }
175+
public RandomizerCore.Random r { get; set; }
178176
public string Flags { get; private set; }
179177
public int SeedHash { get; private set; }
180178
public RandomizerProperties Props
@@ -1273,7 +1271,7 @@ private async Task<bool> FillPalaceRooms(AsmModule sideviewModule)
12731271
try
12741272
{
12751273
ROM testRom = new(ROMData);
1276-
Random testRng = new Random();
1274+
Random testRng = new(SeedHash);
12771275
//This continues to get worse, the text is based on the palaces and asm patched, so it needs to
12781276
//be tested here, but we don't actually know what they will be until later, for now i'm just
12791277
//testing with the vanilla text, but this could be an issue down the line.

RandomizerCore/Music.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public MusicRandomizer(
158158
bool safeOnly)
159159
{
160160
_hyrule = hyrule;
161-
_shuffler = new RandomShuffler(new Random(seed));
161+
_shuffler = new RandomShuffler(new System.Random(seed));
162162
_rom = _hyrule.ROMData.GetBytes(0, ROM.RomSize);
163163
_romAccess = new(_rom);
164164
_jsonLibPaths = new(jsonLibPaths);

RandomizerCore/ROM.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ public void UpdateSpritePalette(NesColor tunicColor, NesColor skinTone, NesColor
616616

617617
static int RandomUniqueColor(params int?[] forbiddenColors)
618618
{
619-
Random random = new Random();
619+
System.Random random = new();
620620
int color;
621621
do
622622
{
@@ -678,7 +678,7 @@ public void UpdateProjectileSprite(BeamSprites beamSprite)
678678
{
679679
if (beamSprite == BeamSprites.RANDOM)
680680
{
681-
Random r2 = new();
681+
System.Random r2 = new();
682682
beamSprite = (BeamSprites)r2.Next(Enum.GetValues(typeof(BeamSprites)).Length - 1);
683683
}
684684

0 commit comments

Comments
 (0)