From 946e961633d4a7ecdfd0241042526285ce2e5922 Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Sun, 23 Mar 2025 22:32:57 -0400 Subject: [PATCH 1/2] Make RNG seedable --- Cargo.lock | 1 + Cargo.toml | 1 + src/lib.rs | 2 ++ src/main.rs | 34 ++++++++++++++++++++-------------- src/random.rs | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 src/lib.rs create mode 100644 src/random.rs diff --git a/Cargo.lock b/Cargo.lock index 4180317..01267cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1607,6 +1607,7 @@ dependencies = [ "bevy", "log", "rand 0.9.0", + "rand_chacha 0.9.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 68b934e..9c260e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,4 @@ log = { version = "*", features = [ "release_max_level_warn", ] } rand = "0.9.0" +rand_chacha = "0.9.0" diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d2c9234 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,2 @@ +mod random; +pub use random::Random; diff --git a/src/main.rs b/src/main.rs index 7878fc1..6c51414 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,18 +9,26 @@ use bevy::{ input::common_conditions::input_pressed, prelude::*, }; -use rand::Rng; + +use distributed_physics_test::Random; const AREA_WIDTH: f32 = 750.; const PLAYER_SIZE: f32 = 30.; -fn main() { +#[derive(Default)] +struct AppSettings { + seed: String, +} + +fn main() -> AppExit { + run_app(AppSettings::default()) +} + +fn run_app(settings: AppSettings) -> AppExit { App::new() .add_plugins(( DefaultPlugins, - PhysicsPlugins::default() - .with_length_unit(50.0) - .set(PhysicsInterpolationPlugin::interpolate_all()), + PhysicsPlugins::default().with_length_unit(50.0), )) .add_systems( Startup, @@ -31,11 +39,12 @@ fn main() { (move_player, quit.run_if(input_pressed(KeyCode::KeyQ))), ) .insert_resource(Gravity(Vector::ZERO)) - .run(); + .insert_resource(Random::seed(&settings.seed)) + .run() } fn setup_scene(mut commands: Commands) { - commands.spawn(Camera2d); + commands.spawn((Name::new("Camera"), Camera2d, IsDefaultUiCamera)); } #[derive(Component, Default)] @@ -50,19 +59,16 @@ fn setup_balls( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, + mut rng: ResMut, ) { - let mut rng = rand::rng(); for _ in 0..20 { - let circle = Circle::new(rng.random_range(10.0..(PLAYER_SIZE - 5.))); + let circle = Circle::new(rng.range(10.0..(PLAYER_SIZE - 5.))); let mut transform = Transform::from_xyz( 0., - rng.random_range((PLAYER_SIZE + 5.)..(AREA_WIDTH / 2. - PLAYER_SIZE)), + rng.range((PLAYER_SIZE + 5.)..(AREA_WIDTH / 2. - PLAYER_SIZE)), 0., ); - transform.rotate_around( - Vec3::ZERO, - Quat::from_rotation_z(rng.random_range(0.0..(PI * 2.))), - ); + transform.rotate_around(Vec3::ZERO, Quat::from_rotation_z(rng.range(0.0..(PI * 2.)))); commands.spawn(( Ball, Collider::from(circle), diff --git a/src/random.rs b/src/random.rs new file mode 100644 index 0000000..490003d --- /dev/null +++ b/src/random.rs @@ -0,0 +1,33 @@ +use std::hash::{DefaultHasher, Hash, Hasher}; + +use bevy::prelude::*; +use rand::{ + Rng, SeedableRng, + distr::uniform::{SampleRange, SampleUniform}, +}; +use rand_chacha::ChaCha8Rng; + +#[derive(Resource)] +pub struct Random(ChaCha8Rng); + +impl Random { + pub fn seed(seed: &String) -> Self { + Random(ChaCha8Rng::seed_from_u64( + seed.parse::().unwrap_or_else(|_| hash_string(seed)), + )) + } + + pub fn range(&mut self, range: R) -> T + where + T: SampleUniform, + R: SampleRange, + { + self.0.random_range(range) + } +} + +fn hash_string(string: &String) -> u64 { + let mut state = DefaultHasher::new(); + string.hash(&mut state); + state.finish() +} From 4476bdfeeb765ca9e4e4d2e45e24c0e6ac2dfa66 Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Sun, 23 Mar 2025 22:49:05 -0400 Subject: [PATCH 2/2] Add CLI Initially just basic options and seed --- Cargo.lock | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 + src/main.rs | 7 ++- 3 files changed, 128 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01267cd..8af8874 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,6 +148,56 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "approx" version = "0.5.1" @@ -1349,6 +1399,46 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -1359,6 +1449,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "combine" version = "4.6.7" @@ -1605,6 +1701,7 @@ version = "0.1.0" dependencies = [ "avian2d", "bevy", + "clap", "log", "rand 0.9.0", "rand_chacha 0.9.0", @@ -2038,6 +2135,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.4.0" @@ -2091,6 +2194,12 @@ dependencies = [ "hashbrown 0.15.2", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.13.0" @@ -3545,6 +3654,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "svg_fmt" version = "0.4.4" @@ -3877,6 +3992,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.12.1" diff --git a/Cargo.toml b/Cargo.toml index 9c260e1..4f58035 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "distributed_physics_test" version = "0.1.0" edition = "2024" +description = "Experimental distributed physics system" [profile.dev] opt-level = 1 @@ -29,6 +30,7 @@ bevy = { version = "0.15.3", default-features = false, features = [ "multi_threaded", "wayland", ] } +clap = { version = "4.5.32", features = ["derive"] } log = { version = "*", features = [ "max_level_debug", "release_max_level_warn", diff --git a/src/main.rs b/src/main.rs index 6c51414..60468e5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,19 +9,22 @@ use bevy::{ input::common_conditions::input_pressed, prelude::*, }; +use clap::Parser; use distributed_physics_test::Random; const AREA_WIDTH: f32 = 750.; const PLAYER_SIZE: f32 = 30.; -#[derive(Default)] +#[derive(Parser)] +#[command(version, about)] struct AppSettings { + #[arg(short, long, default_value = "")] seed: String, } fn main() -> AppExit { - run_app(AppSettings::default()) + run_app(AppSettings::parse()) } fn run_app(settings: AppSettings) -> AppExit {