From e013fb427a71ef7a03f738f9816e320f0ea0c9c7 Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Mon, 13 Oct 2025 01:04:16 -0400 Subject: [PATCH 1/2] Switch back to nightly, update deps --- .cargo/config.toml | 2 +- .vscode/launch.json | 18 ++++++++++-------- .vscode/settings.json | 6 ++++++ Cargo.lock | 26 +++++++++++++------------- Cargo.toml | 28 ++++++++++++++++++++++++---- clippy.toml | 2 ++ rust-toolchain.toml | 3 +-- 7 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 clippy.toml diff --git a/.cargo/config.toml b/.cargo/config.toml index 8099b7a..9079b92 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,4 +1,4 @@ [target.x86_64-unknown-linux-gnu] linker = "clang" # TODO: Share generics when using nightly no longer causes an undefined symbol error -rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/mold"] #, "-Zshare-generics=y"] +rustflags = ["-C", "link-arg=-fuse-ld=/usr/bin/mold", "-Zshare-generics=y"] diff --git a/.vscode/launch.json b/.vscode/launch.json index 424d2c8..48ad4dc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,13 +15,13 @@ "cwd": "${workspaceFolder}", "env": { "CARGO_MANIFEST_DIR": "${workspaceFolder}", - "LD_LIBRARY_PATH": "${workspaceFolder}/target/debug/deps:${env:HOME}/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" + "LD_LIBRARY_PATH": "${workspaceFolder}/target/debug/deps:${env:HOME}/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" }, "presentation": { "hidden": false, "group": "run", "order": 1 - } + }, }, { "type": "lldb", @@ -34,13 +34,14 @@ "cwd": "${workspaceFolder}", "env": { "CARGO_MANIFEST_DIR": "${workspaceFolder}", - "LD_LIBRARY_PATH": "${workspaceFolder}/target/debug/deps:${env:HOME}/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" + "LD_LIBRARY_PATH": "${workspaceFolder}/target/debug/deps:${env:HOME}/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" }, "presentation": { "hidden": false, "group": "run", "order": 2 - } + }, + "suppressMultipleSessionWarning": true, }, { "type": "lldb", @@ -53,13 +54,14 @@ "cwd": "${workspaceFolder}", "env": { "CARGO_MANIFEST_DIR": "${workspaceFolder}", - "LD_LIBRARY_PATH": "${workspaceFolder}/target/debug/deps:${env:HOME}/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" + "LD_LIBRARY_PATH": "${workspaceFolder}/target/debug/deps:${env:HOME}/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" }, "presentation": { "hidden": false, "group": "run", "order": 2 - } - } - ] + }, + "suppressMultipleSessionWarning": true, + }, + ], } diff --git a/.vscode/settings.json b/.vscode/settings.json index 7d9ea05..8ebe79c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,6 +15,12 @@ "RUSTFLAGS": "-Clinker=clang -Clink-arg=-fuse-ld=lld" }, "rust-analyzer.check.command": "clippy", // "check", // +// "rust-analyzer.check.overrideCommand": [ +// "bevy_lint", +// "--workspace", +// "--all-targets", +// "--message-format=json-diagnostic-rendered-ansi", +// ], "rust-analyzer.cargo.targetDir": true, "cSpell.words": [ "Backquote", diff --git a/Cargo.lock b/Cargo.lock index 90ccc97..6780b49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1623,9 +1623,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.39" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -1633,9 +1633,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.39" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -1645,9 +1645,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck", "proc-macro2", @@ -1923,7 +1923,7 @@ dependencies = [ "clap", "crossbeam-channel", "log", - "rand 0.9.1", + "rand 0.9.2", "uuid", "wyrand", ] @@ -2680,9 +2680,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "malloc_buf" @@ -3549,9 +3549,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", @@ -4480,9 +4480,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index a48d89a..d8468b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,12 +5,32 @@ edition = "2024" description = "Experimental distributed physics system" license = "AGPL-3.0-only" +[lints.rust] +# Mark `bevy_lint` as a valid `cfg`, as it is set when the Bevy linter runs. +unexpected_cfgs = { level = "warn", check-cfg = ["cfg(bevy_lint)"] } + +[lints.clippy] +# Bevy supplies arguments to systems via dependency injection, so it's natural for systems to +# request more than 7 arguments, which would undesirably trigger this lint. +too_many_arguments = "allow" +# Queries may access many components, which would undesirably trigger this lint. +type_complexity = "allow" +# Make sure macros use their standard braces, such as `[]` for `bevy_ecs::children!`. +nonstandard_macro_braces = "warn" + +[package.metadata.bevy_lint] +panicking_methods = "deny" +pedantic = "warn" + [profile.dev] opt-level = 1 [profile.dev.package."*"] opt-level = 3 +[profile.dev.package.wgpu-types] +debug-assertions = false + [profile.release] lto = true opt-level = 3 @@ -35,14 +55,14 @@ bevy = { version = "0.16.1", default-features = false, features = [ "wayland", ] } bevy_rand = { version = "0.11.0", features = ["wyrand", "std"] } -clap = { version = "4.5.39", features = ["derive"] } +clap = { version = "4.5.48", features = ["derive"] } crossbeam-channel = "0.5.15" -log = { version = "0.4.27", features = ["release_max_level_warn"] } -rand = { version = "0.9.1", default-features = false, features = [ +log = { version = "0.4.28", features = ["release_max_level_warn"] } +rand = { version = "0.9.2", default-features = false, features = [ "std", "thread_rng", ] } -uuid = { version = "1.17.0", features = ["v4"] } +uuid = { version = "1.18.1", features = ["v4"] } wyrand = "0.3.2" [features] diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..af8b632 --- /dev/null +++ b/clippy.toml @@ -0,0 +1,2 @@ +# Require `bevy_ecs::children!` to use `[]` braces, instead of `()` or `{}`. +standard-macro-braces = [{ name = "children", brace = "[" }] diff --git a/rust-toolchain.toml b/rust-toolchain.toml index c672579..5d56faf 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,2 @@ [toolchain] -# TODO: Switch back to nightly when it no longer causes an undefined symbol error -channel = "stable" # "nightly" +channel = "nightly" From 53fe3333f09ca5c9a58a8dbe4fb8f15e713b90fe Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Mon, 13 Oct 2025 01:06:31 -0400 Subject: [PATCH 2/2] More complete Peer distribution Slightly better implementation of peers, still need to create a more generic system for deciding which components to distribute where and then use that for Peers. --- src/game/net.rs | 11 +- src/game/plugin.rs | 30 ++++-- src/game/seed.rs | 2 +- src/game/ui.rs | 55 +++++++--- src/lib.rs | 4 +- src/main.rs | 4 +- src/net/distribution.rs | 30 ++---- src/net/heartbeat.rs | 77 ++++++++++++++ src/net/io.rs | 99 +++++++----------- src/net/mod.rs | 7 +- src/net/packet.rs | 80 +++++++++++++- src/net/peer.rs | 226 +++++++++++++++++++++++----------------- src/net/plugin.rs | 70 ++++++------- src/net/state.rs | 8 -- 14 files changed, 438 insertions(+), 265 deletions(-) create mode 100644 src/net/heartbeat.rs delete mode 100644 src/net/state.rs diff --git a/src/game/net.rs b/src/game/net.rs index 8e43e3f..c52f85f 100644 --- a/src/game/net.rs +++ b/src/game/net.rs @@ -2,13 +2,16 @@ use bevy::prelude::*; use crate::net::prelude::*; -pub fn handle_new_peer(new_peers: Query<&Peer, Added>) { +pub fn handle_new_peer(new_peers: Query<&PeerID, Added>) { for peer in new_peers { info!("Peer {} was added", peer.id); } } -pub fn handle_deleted_peer(mut old_peers: RemovedComponents, peers: Query<&Peer>) -> Result { +pub fn handle_deleted_peer( + mut old_peers: RemovedComponents, + peers: Query<&PeerID>, +) -> Result { for entity in old_peers.read() { if let Ok(peer) = peers.get(entity) { info!("Peer {} was removed", peer.id); @@ -20,7 +23,7 @@ pub fn handle_deleted_peer(mut old_peers: RemovedComponents, peers: Query< } pub fn handle_incoming_packets(mut packets: EventReader) { - for packet in packets.read() { - info!("Packet received: {:?}", packet.0.message); + for InboundPacket(packet) in packets.read() { + info!("Packet received: {:?}", packet.message); } } diff --git a/src/game/plugin.rs b/src/game/plugin.rs index d879c20..a7fdf48 100644 --- a/src/game/plugin.rs +++ b/src/game/plugin.rs @@ -13,7 +13,10 @@ use super::{ check_for_seed, setup_balls, setup_camera, setup_from_seed, setup_player, setup_walls, }, state::AppState, - ui::{setup_peer_ui, setup_seed_ui, update_peer_ui, update_peer_ui_timings, update_seed_ui}, + ui::{ + setup_peer_ui, setup_potential_peer_ui, setup_seed_ui, update_peer_ui, + update_peer_ui_timings, update_potential_peer_ui, update_seed_ui, + }, }; #[derive(Debug, Clone, Copy)] @@ -55,11 +58,20 @@ impl GamePlugin { impl Plugin for GamePlugin { fn build(&self, app: &mut App) { app.add_plugins(( - NetIOPlugin::new(self.port, self.source.try_to_address()), + NetIOPlugin::maybe_peer(self.port, self.source.try_to_address()), + distribution_plugin::, PhysicsPlugins::default().with_length_unit(50.0), )) .init_state::() - .add_systems(Startup, (setup_camera, setup_seed_ui, setup_peer_ui)) + .add_systems( + Startup, + ( + setup_camera, + setup_seed_ui, + setup_peer_ui, + setup_potential_peer_ui, + ), + ) .add_systems( OnEnter(AppState::InGame), ( @@ -75,8 +87,7 @@ impl Plugin for GamePlugin { handle_new_peer, handle_deleted_peer, handle_incoming_packets, - ) - .run_if(in_state(NetworkState::MultiPlayer)), + ), ), ) .add_systems( @@ -85,14 +96,15 @@ impl Plugin for GamePlugin { ((move_player, move_camera).chain(), zoom_camera) .run_if(in_state(AppState::InGame)), update_seed_ui, - (update_peer_ui, update_peer_ui_timings) - .run_if(in_state(NetworkState::MultiPlayer)), + ( + update_peer_ui, + update_peer_ui_timings, + update_potential_peer_ui, + ), quit.run_if(input_pressed(KeyCode::KeyQ)), ), ); - Seed::register(app); - match self.source { DataSource::Address(peer) => { info!("Will retrieve seed from peer => {peer}"); diff --git a/src/game/seed.rs b/src/game/seed.rs index 085c10c..d95a957 100644 --- a/src/game/seed.rs +++ b/src/game/seed.rs @@ -61,7 +61,7 @@ impl From for Vec { impl TryFrom> for Seed { type Error = TryFromSliceError; - fn try_from(value: Vec) -> Result { + fn try_from(value: Vec) -> std::result::Result { Ok(TryInto::<[u8; 8]>::try_into(value.as_slice())?.into()) } } diff --git a/src/game/ui.rs b/src/game/ui.rs index 391a39f..60f17a1 100644 --- a/src/game/ui.rs +++ b/src/game/ui.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; -use crate::net::prelude::{Peer, PeerReceiveTiming, PeerSendTiming}; +use crate::net::prelude::{Peer, PeerID, PeerReceiveTiming, PeerSendTiming, PotentialPeers}; use super::seed::Seed; @@ -54,11 +54,11 @@ pub fn setup_peer_ui(mut commands: Commands) { } #[derive(Component)] -pub struct PeerID(Entity); +pub struct UIPeerID(Entity); pub fn update_peer_ui( ui: Query<(Entity, &Children), With>, - rows: Query<&PeerID>, + rows: Query<&UIPeerID>, added: Query>, mut removed: RemovedComponents, mut commands: Commands, @@ -67,14 +67,14 @@ pub fn update_peer_ui( for addition in added { commands .entity(table) - .with_child((Text::new("---- ---- ----"), PeerID(addition))); + .with_child((Text::new("---- ---- ----"), UIPeerID(addition))); } for removal in removed.read() { for child in children { - if let Ok(id) = rows.get(*child) { - if id.0 == removal { - commands.entity(*child).despawn(); - } + if let Ok(&UIPeerID(id)) = rows.get(*child) + && id == removal + { + commands.entity(*child).despawn(); } } } @@ -82,12 +82,12 @@ pub fn update_peer_ui( } pub fn update_peer_ui_timings( - rows: Query<(&mut Text, &PeerID)>, - peers: Query<(&Peer, &PeerReceiveTiming, &PeerSendTiming)>, + rows: Query<(&mut Text, &UIPeerID)>, + peers: Query<(&PeerID, &PeerReceiveTiming, &PeerSendTiming)>, time: Res