namespace SVSim.BattleNode.Lifecycle;
///
/// Deterministic per-battle seed derivation. Given one random master seed (chosen once per battle
/// on ), derives every RNG value the node hands
/// the clients: the shared effect seed (Matched.seed), each side's deck-shuffle RNG seed, and each
/// side's Ready.idxChangeSeed.
///
/// IMPORTANT: uses a fixed splitmix64-style bit-mix, NOT System.HashCode / string.GetHashCode
/// (those are randomized per process). Stability across process runs is what makes "same master
/// seed reproduces the same battle" — the foundation of replay — actually hold.
///
internal static class BattleSeeds
{
/// Shared effect-RNG seed; identical for both sides (it seeds the synced stream).
public static int Stable(int master) => Derive(master, "stable");
/// Per-side Ready.idxChangeSeed (client XorShift for mid-battle card-into-deck).
public static int IdxChange(int master, long viewerId) => Derive(master, "idx", viewerId);
/// Per-side deck-shuffle RNG seed (node-side Fisher–Yates).
public static int DeckShuffle(int master, long viewerId) => Derive(master, "deck", viewerId);
/// Derive a stable non-negative int from (master, tag, discriminator). Pure arithmetic
/// — reproducible across process runs and platforms.
public static int Derive(int master, string tag, long disc = 0)
{
ulong h = Mix((uint)master);
foreach (char c in tag) h = Mix(h ^ c);
h = Mix(h ^ (ulong)disc);
return (int)(h & 0x7FFFFFFFUL);
}
private static ulong Mix(ulong x)
{
x += 0x9E3779B97F4A7C15UL;
x = (x ^ (x >> 30)) * 0xBF58476D1CE4E5B9UL;
x = (x ^ (x >> 27)) * 0x94D049BB133111EBUL;
return x ^ (x >> 31);
}
}