// core/rng.js (Lane F) — THE only randomness source in GUTS. qa.sh greps for violators. // mulberry32: tiny, fast, deterministic. Same seed => same sequence, forever. export function mulberry32(seed) { let a = seed >>> 0; return function () { a |= 0; a = (a + 0x6D2B79F5) | 0; let t = Math.imul(a ^ (a >>> 15), 1 | a); t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t; return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; } // Named sub-streams so lanes don't perturb each other's sequences: // rng('world'), rng('enemies'), ... each is an independent deterministic stream. export function createRng(seed) { const streams = new Map(); function hash(str) { let h = 2166136261 >>> 0; for (let i = 0; i < str.length; i++) { h ^= str.charCodeAt(i); h = Math.imul(h, 16777619); } return h >>> 0; } const rng = (stream = 'main') => { if (!streams.has(stream)) streams.set(stream, mulberry32((seed ^ hash(stream)) >>> 0)); return streams.get(stream); }; rng.seed = seed; rng.float = (stream, min = 0, max = 1) => min + rng(stream)() * (max - min); rng.int = (stream, min, max) => Math.floor(rng.float(stream, min, max + 1)); return rng; }