Table of Contents

Class DeterministicRNG

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

A fast, deterministic, thread-safe pseudo-random number generator. Drop-in replacement for Random in all game code.

Algorithm: xoshiro128** (Blackman & Vigna, 2018). Period: 2^128 − 1. Passes BigCrush. Thread safety: no shared mutable state — each instance is independent.

API surface matches the subset of Random used in this codebase: Next(), Next(int), Next(int,int), NextDouble(), NextFloat(), Range(int,int), Range(float,float).

A static Shared instance is provided for fire-and-forget usage that does not require determinism (replaces UnityEngine.Random).

public sealed class DeterministicRNG
Inheritance
DeterministicRNG
Inherited Members

Constructors

DeterministicRNG()

Creates a new unseeded RNG using TickCount for a non-deterministic seed. Use this only for server-side cases where determinism is not required (e.g., loot rolls, shuffle).

public DeterministicRNG()

DeterministicRNG(int)

Creates a new RNG seeded from an integer. Uses a Murmur3-finalizer counter mix to expand the single int seed into 128 bits of state.

public DeterministicRNG(int seed)

Parameters

seed int

Deterministic seed value.

DeterministicRNG(uint, uint, uint, uint)

Creates a DeterministicRNG from raw xoshiro128** state words. Used to restore the exact generator position during reconcile, since the 128-bit state cannot be reconstructed from a single 32-bit output.

public DeterministicRNG(uint state0, uint state1, uint state2, uint state3)

Parameters

state0 uint

First state word.

state1 uint

Second state word.

state2 uint

Third state word.

state3 uint

Fourth state word.

Fields

Shared

Global shared instance for non-deterministic / fire-and-forget usage. Replaces UnityEngine.Random for all game code. NOT thread-safe — use only from the main thread (same contract as UnityEngine.Random).

public static readonly DeterministicRNG Shared

Field Value

DeterministicRNG

Methods

CaptureState(out uint, out uint, out uint, out uint)

Captures the full 128-bit xoshiro128** state for serialization. Must be included in reconcile data alongside or instead of the single-int seed — storing only the seed causes permanent desync after any prediction mismatch because the 128-bit generator state cannot be reconstructed from a 32-bit output.

public void CaptureState(out uint state0, out uint state1, out uint state2, out uint state3)

Parameters

state0 uint

First state word.

state1 uint

Second state word.

state2 uint

Third state word.

state3 uint

Fourth state word.

Next()

Returns a non-negative random integer (0 ≤ result < MaxValue). Equivalent to Next().

public int Next()

Returns

int

Next(int)

Returns a non-negative random integer less than maxValue. Equivalent to Next(int). When maxValue is a power of two (including 1), a single bitmask replaces the rejection loop — Next(1) costs exactly one FishMMO.Shared.DeterministicRNG.NextRaw() call. The rejection-sampling path for non-power-of-two values is unchanged, preserving the same output sequence.

public int Next(int maxValue)

Parameters

maxValue int

Exclusive upper bound (must be > 0).

Returns

int

Next(int, int)

Returns a random integer in the range [minValue, maxValue). Equivalent to Next(int, int). The range is computed as long to avoid overflow when maxValueminValue > MaxValue.

public int Next(int minValue, int maxValue)

Parameters

minValue int

Inclusive lower bound.

maxValue int

Exclusive upper bound.

Returns

int

NextDouble()

Returns a random double in the range [0.0, 1.0). Equivalent to NextDouble(). Uses 32 bits of entropy (sufficient for float/game use). All game code should prefer NextFloat() or Range(float, float) which avoid double-promotion overhead.

public double NextDouble()

Returns

double

NextFloat()

Returns a random float in the range [0.0f, 1.0f). Drop-in replacement for UnityEngine.Random.value. Computed entirely in float — no double promotion.

public float NextFloat()

Returns

float

Range(int, int)

Returns a random integer in the range [min, max). Drop-in replacement for UnityEngine.Random.Range(int, int). Alias for Next(int, int).

public int Range(int min, int max)

Parameters

min int

Inclusive lower bound.

max int

Exclusive upper bound.

Returns

int

Range(float, float)

Returns a random float in the range [min, max). Drop-in replacement for UnityEngine.Random.Range(float, float).

public float Range(float min, float max)

Parameters

min float

Inclusive lower bound.

max float

Exclusive upper bound.

Returns

float

RestoreState(uint, uint, uint, uint)

Restores the full 128-bit xoshiro128** state from previously captured values. Call this instead of allocating a new instance during reconcile to avoid per-tick heap allocation.

public void RestoreState(uint state0, uint state1, uint state2, uint state3)

Parameters

state0 uint

First state word.

state1 uint

Second state word.

state2 uint

Third state word.

state3 uint

Fourth state word.