From d9c41b9b6bdbccebe9f14c229dcee40543498d7e Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 18 Nov 2025 11:02:14 -0500 Subject: dungeon: switch rng to rand_xoshiro --- Cargo.lock | 22 ++++++++++++++++----- Cargo.toml | 3 ++- dungeon/Cargo.toml | 1 + dungeon/src/rng.rs | 58 +++++++++++------------------------------------------- 4 files changed, 31 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e7846b..dfa2443 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,7 @@ version = "0.1.0" dependencies = [ "getrandom", "rand", + "rand_xoshiro", "strum", "strum_macros", ] @@ -320,19 +321,30 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" -version = "0.10.0-rc.5" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be866deebbade98028b705499827ad6967c8bb1e21f96a2609913c8c076e9307" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "getrandom", "rand_core", ] [[package]] name = "rand_core" -version = "0.10.0-rc-2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xoshiro" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "104a23e4e8b77312a823b6b5613edbac78397e2f34320bc7ac4277013ec4478e" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +dependencies = [ + "rand_core", +] [[package]] name = "raylib" diff --git a/Cargo.toml b/Cargo.toml index 86909dc..847fe53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ dungeon = { path = "dungeon" } game = { path = "game" } getrandom = "0.3" graphics = { path = "graphics" } +rand_xoshiro = "0.7" strum_macros = "0.27" [workspace.dependencies.argh] @@ -28,7 +29,7 @@ default-features = false features = ["help"] [workspace.dependencies.rand] -version = "0.10.0-rc.5" +version = "0.9" default-features = false features = ["os_rng"] diff --git a/dungeon/Cargo.toml b/dungeon/Cargo.toml index 213fc3b..cef2cf5 100644 --- a/dungeon/Cargo.toml +++ b/dungeon/Cargo.toml @@ -10,6 +10,7 @@ rust-version.workspace = true [dependencies] getrandom.workspace = true rand.workspace = true +rand_xoshiro.workspace = true strum.workspace = true strum_macros.workspace = true diff --git a/dungeon/src/rng.rs b/dungeon/src/rng.rs index bb9151b..ae8cae6 100644 --- a/dungeon/src/rng.rs +++ b/dungeon/src/rng.rs @@ -1,74 +1,38 @@ //! Implements rng using the xoshiro256++ algorithm -use rand::{ - SeedableRng, - rand_core::{RngCore, le}, -}; +use rand::rand_core::{RngCore, SeedableRng}; +use rand_xoshiro::Xoshiro256PlusPlus; /// Deterministic pseudo random number generator. -/// -/// Is is a copy of `SmallRng` from `rand`, but is gurenteed -/// to be reproducible across versions and platforms. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct DungeonRng { - s: [u64; 4], -} +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DungeonRng(Xoshiro256PlusPlus); impl SeedableRng for DungeonRng { // Fix to 256 bits. Changing this is a breaking change! - type Seed = [u8; 32]; + type Seed = ::Seed; #[inline] fn from_seed(seed: Self::Seed) -> Self { - let mut state = [0; 4]; - le::read_u64_into(&seed, &mut state); - Self { s: state } + Self(Xoshiro256PlusPlus::from_seed(seed)) } #[inline] - fn seed_from_u64(mut state: u64) -> Self { - const PHI: u64 = 0x9e3779b97f4a7c15; - let mut s = [0; 4]; - for i in &mut s { - state = state.wrapping_add(PHI); - let mut z = state; - z = (z ^ (z >> 30)).wrapping_mul(0xbf58476d1ce4e5b9); - z = (z ^ (z >> 27)).wrapping_mul(0x94d049bb133111eb); - z = z ^ (z >> 31); - *i = z; - } - Self { s } + fn seed_from_u64(state: u64) -> Self { + Self(Xoshiro256PlusPlus::seed_from_u64(state)) } } impl RngCore for DungeonRng { #[inline] fn next_u32(&mut self) -> u32 { - let val = self.next_u64(); - (val >> 32) as u32 + self.0.next_u32() } #[inline] fn next_u64(&mut self) -> u64 { - let res = self.s[0] - .wrapping_add(self.s[3]) - .rotate_left(23) - .wrapping_add(self.s[0]); - - let t = self.s[1] << 17; - - self.s[2] ^= self.s[0]; - self.s[3] ^= self.s[1]; - self.s[1] ^= self.s[2]; - self.s[0] ^= self.s[3]; - - self.s[2] ^= t; - - self.s[3] = self.s[3].rotate_left(45); - - res + self.0.next_u64() } #[inline] fn fill_bytes(&mut self, dst: &mut [u8]) { - le::fill_bytes_via_next(self, dst); + self.0.fill_bytes(dst); } } -- cgit v1.2.3-freya