// mulberry32 PRNG. The generator state lives in state.rngState (a uint32) so a // saved game resumes with the exact same sequence. export function nextFloat(state) { state.rngState = (state.rngState + 0x6d2b79f5) >>> 0; let t = state.rngState; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; } // Uniform in [-amp, amp]. export function nextNoise(state, amp) { return (nextFloat(state) * 2 - 1) * amp; } export function nextInt(state, maxExclusive) { return Math.floor(nextFloat(state) * maxExclusive); } export function pickWeighted(state, items, weights) { let total = 0; for (const w of weights) total += w; if (total <= 0) return null; let r = nextFloat(state) * total; for (let i = 0; i < items.length; i++) { r -= weights[i]; if (r < 0) return items[i]; } return items[items.length - 1]; }