diff --git a/PKHeX.Core/Legality/RNG/Algorithms/XorShift128.cs b/PKHeX.Core/Legality/RNG/Algorithms/XorShift128.cs
new file mode 100644
index 000000000..f99828215
--- /dev/null
+++ b/PKHeX.Core/Legality/RNG/Algorithms/XorShift128.cs
@@ -0,0 +1,54 @@
+using System.Runtime.CompilerServices;
+
+namespace PKHeX.Core;
+
+///
+/// Self-modifying RNG structure that implements xorshift.
+///
+/// https://en.wikipedia.org/wiki/Xorshift
+///
+public ref struct XorShift128
+{
+ private uint x, y, z, w;
+
+ public XorShift128(uint x, uint y, uint z, uint w)
+ {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+
+ public (uint x, uint y, uint z, uint w) GetState32() => (x, y, z, w);
+ public (ulong s0, ulong s1) GetState64() => (((ulong)y << 32) | x, ((ulong)w << 32) | z);
+ public string GetState128 => $"{w:X8}{z:X8}{y:X8}{x:X8}";
+
+ ///
+ /// Gets the next random .
+ ///
+ public uint Next()
+ {
+ var t = x ^ (x << 11);
+ x = y;
+ y = z;
+ z = w;
+ return w = w ^ (w >> 19) ^ t ^ (t >> 8);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public uint NextUInt() => (uint)NextInt();
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public uint NextUInt(uint max) => NextUInt() % max;
+
+ ///
+ /// Gets the next random .
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public int NextInt(int start = int.MinValue, int end = int.MaxValue)
+ {
+ var next = Next();
+ var delta = unchecked((uint)(end - start));
+ return start + (int)(next % delta);
+ }
+}
diff --git a/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus8b.cs b/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus8b.cs
index edb48d901..211ffbbff 100644
--- a/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus8b.cs
+++ b/PKHeX.Core/Legality/RNG/Algorithms/Xoroshiro128Plus8b.cs
@@ -76,25 +76,5 @@ public uint NextUInt(uint max)
var rnd = NextUInt();
return rnd - ((rnd / max) * max);
}
-
- ///
- /// Gets the next random .
- ///
- public int NextInt(int start = int.MinValue, int end = int.MaxValue)
- {
- var _s0 = s0 & 0xFFFFFFFF;
- var _s1 = s1 >> 32;
-
- _s0 ^= (_s0 << 11) & 0xFFFFFFFF;
- _s0 ^= (_s0 >> 8);
- _s0 ^= (_s1 ^ (_s1 >> 19));
-
- // Final calculations and store back to fields
- s0 = ((s1 & 0xFFFFFFFF) << 32) | (s0 >> 32);
- s1 = _s0 << 32 | (s1 >> 32);
-
- var delta = unchecked(end - start);
- return start + (int)(_s0 % (ulong)delta);
- }
}
}