Files
settled-reach/server/src/simulation/rng.rs
T
jpmschweitzerandClaude Opus 4.6 f67caf1986 feat(server): initialize Rust/bevy_ecs simulation server
Server boilerplate epic (276) complete. Establishes the Rust simulation
server foundation per D-020 (subprocess/IPC architecture).

Structure:
- bevy_ecs 0.18 + bevy_app 0.18, MessagePack serialization (rmp-serde)
- SimulationPlugin with deterministic resources: SimulationTime (D-031),
  SimRng (D-030), InputQueue (D-010)
- Core IPC types: ObserverSnapshot, PlayerInput, SimBridge trait (D-020)
- CauseChain production component for provenance tracking (D-030)
- SimulationTier types with LRU eviction support (D-026)
- NPC 10-axis model components (D-024)
- 15 tests: inline unit tests + integration smoke/serialization tests
- make ci-server passes (clippy, fmt, build, test)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 16:54:40 +01:00

55 lines
1.3 KiB
Rust

// Simulation RNG system
// Injectable ChaCha RNG resource for deterministic replay (D-030)
// Ensures same seed produces same outcomes
use bevy_ecs::prelude::*;
use rand::SeedableRng;
use rand_chacha::ChaCha20Rng;
/// Simulation RNG resource
/// ChaCha20 RNG with stored seed for deterministic replay
#[derive(Resource)]
pub struct SimRng {
pub rng: ChaCha20Rng,
seed: u64,
}
impl SimRng {
/// Create a new SimRng with the given seed
pub fn new(seed: u64) -> Self {
Self {
rng: ChaCha20Rng::seed_from_u64(seed),
seed,
}
}
/// Get the seed used to initialize this RNG
pub fn seed(&self) -> u64 {
self.seed
}
}
#[cfg(test)]
mod tests {
use super::*;
use rand::Rng;
#[test]
fn same_seed_same_sequence() {
let mut rng1 = SimRng::new(42);
let mut rng2 = SimRng::new(42);
let vals1: Vec<u32> = (0..100).map(|_| rng1.rng.random()).collect();
let vals2: Vec<u32> = (0..100).map(|_| rng2.rng.random()).collect();
assert_eq!(vals1, vals2);
}
#[test]
fn different_seed_different_sequence() {
let mut rng1 = SimRng::new(42);
let mut rng2 = SimRng::new(43);
let val1: u32 = rng1.rng.random();
let val2: u32 = rng2.rng.random();
assert_ne!(val1, val2);
}
}