From b7220be1cb42d789d750e252d109490cb5578f2f Mon Sep 17 00:00:00 2001 From: core Date: Tue, 9 Jun 2026 23:11:11 -0400 Subject: [PATCH] Revert "netcode: planet updates" This reverts commit 08355656f50d8e095c280962b250178acbd1299f. --- crates/unified/src/client/mod.rs | 4 +- crates/unified/src/client/net.rs | 22 +++-- .../src/client/net/incoming_planets.rs | 38 -------- crates/unified/src/server/net.rs | 22 +++-- .../unified/src/server/net/update_planets.rs | 64 ------------- crates/unified/src/server/player/join.rs | 3 +- crates/unified/src/server/plugins.rs | 21 ----- crates/unified/src/shared/ecs.rs | 2 + crates/unified/src/shared/net.rs | 92 ++++++++++++++----- crates/unified/src/shared/net/planet.rs | 18 ---- .../src/shared/net/staged_transform.rs | 14 --- crates/unified/src/shared/plugins.rs | 18 +++- 12 files changed, 122 insertions(+), 196 deletions(-) delete mode 100644 crates/unified/src/client/net/incoming_planets.rs delete mode 100644 crates/unified/src/server/net/update_planets.rs delete mode 100644 crates/unified/src/shared/net/planet.rs delete mode 100644 crates/unified/src/shared/net/staged_transform.rs diff --git a/crates/unified/src/client/mod.rs b/crates/unified/src/client/mod.rs index e26f312938ca7bf13c17532ef5c268c58c2f2788..337c0b250daa62ff6026600c69a11300ef93c0d6 100644 --- a/crates/unified/src/client/mod.rs +++ b/crates/unified/src/client/mod.rs @@ -149,11 +149,11 @@ pub fn find_me( mut msgs: MessageReader, mut commands: Commands, mut time_offset: ResMut, -) {/* +) { for msg in msgs.read() { let we_are = msg.you_are; info!(?we_are, "joined successfully"); commands.entity(we_are).insert(Me); time_offset.0 = msg.time_offset; - }*/ + } } diff --git a/crates/unified/src/client/net.rs b/crates/unified/src/client/net.rs index 11d9629ae5ffeccb924e92d15b490ae26b501083..7094a80012e1e607c7016c4a3e9f1cdaaba925c0 100644 --- a/crates/unified/src/client/net.rs +++ b/crates/unified/src/client/net.rs @@ -1,10 +1,20 @@ -pub mod incoming_planets; - -use crate::{prelude::*, shared::net::{ServerEntityMap}}; -use crate::client::net::incoming_planets::handle_incoming_planets; +use crate::{prelude::*, shared::net::{ServerEntityMap, SpawnEntity}}; pub fn net_plugin(app: &mut App) { app .insert_resource(ServerEntityMap::default()) - .add_systems(Update, handle_incoming_planets); -} \ No newline at end of file + .add_systems(PostUpdate, spawn_server_entities); +} + +fn spawn_server_entities( + mut spawn_entity_messages: MessageReader, + mut entity_mapper: ResMut, + mut commands: Commands, +) { + for spawn_entity in spawn_entity_messages.read() { + let entity = commands.spawn_empty(); + debug!("client: {:?}, server: {:?}", entity.id(), spawn_entity.server); + entity_mapper.server_to_client.set_mapped(spawn_entity.server, entity.id()); + entity_mapper.client_to_server.set_mapped(entity.id(), spawn_entity.server); + } +} diff --git a/crates/unified/src/client/net/incoming_planets.rs b/crates/unified/src/client/net/incoming_planets.rs deleted file mode 100644 index 93332a1ba7dd8155495f57c53dfdfc8ecbf57dd5..0000000000000000000000000000000000000000 --- a/crates/unified/src/client/net/incoming_planets.rs +++ /dev/null @@ -1,38 +0,0 @@ -use bevy::log::{debug, warn}; -use bevy::prelude::{Commands, MessageReader, ResMut, Transform}; -use crate::prelude::Query; -use crate::shared::config::planet::Planet; -use crate::shared::net::planet::PlanetUpdatePacket; -use crate::shared::net::ServerEntityMap; - -pub fn handle_incoming_planets( - mut msgs: MessageReader, - - mut q_planets: Query<(&mut Planet, &mut Transform)>, - mut entity_map: ResMut, - mut commands: Commands -) { - for msg in msgs.read() { - 'to_next_planet: for planet in &msg.updated_planets { - if let Some(local_entity) = entity_map.server_to_client.get(&planet.server_entity) { - let Ok((mut planet_data, mut transform)) = q_planets.get_mut(*local_entity) else { - warn!("local planet entity {:?} for planet srv:{:?} doesn't exist? skipping update, this is a bug", local_entity, planet.server_entity); - continue 'to_next_planet - }; - if planet.planet_data_changed { - *planet_data = planet.planet.clone(); - } - *transform = planet.transform; - } else { - // Spawn new planet - let e = commands.spawn(( - planet.planet.clone(), - planet.transform - )).id(); - entity_map.server_to_client.insert(planet.server_entity, e.clone()); - entity_map.client_to_server.insert(e.clone(), planet.server_entity); - debug!(?planet.planet, "spawned new planet"); - } - } - } -} \ No newline at end of file diff --git a/crates/unified/src/server/net.rs b/crates/unified/src/server/net.rs index d4214611b81952a90177fde59a64dd2dc9af375f..3664b6c72cceefb2cf8a88ce12c0eab1ffcbafd3 100644 --- a/crates/unified/src/server/net.rs +++ b/crates/unified/src/server/net.rs @@ -1,8 +1,18 @@ -pub mod update_planets; - -use crate::{prelude::*, shared::net::{SendTargets, ToClients}}; -use crate::server::net::update_planets::send_updated_planets; +use crate::{prelude::*, shared::net::{Mapped, SendTargets, SpawnEntity, ToClients}}; pub fn net_plugin(app: &mut App) { - app.add_systems(Update, send_updated_planets); -} \ No newline at end of file + app.add_systems(PreUpdate, detect_entity_spawn); +} + +fn detect_entity_spawn( + mapped_entities: Query>, + mut spawn_entity: MessageWriter>, +) { + for entity in mapped_entities { + debug!("entity was spawned"); + spawn_entity.write(ToClients { + message: SpawnEntity { server: entity }, + targets: SendTargets::All, + }); + } +} diff --git a/crates/unified/src/server/net/update_planets.rs b/crates/unified/src/server/net/update_planets.rs deleted file mode 100644 index bfa374f223b0358c47a0f069361888773e3b5107..0000000000000000000000000000000000000000 --- a/crates/unified/src/server/net/update_planets.rs +++ /dev/null @@ -1,64 +0,0 @@ -use std::collections::BTreeSet; -use bevy::prelude::{Added, Changed, Commands, MessageWriter, Query}; -use crate::prelude::{Entity, Transform}; -use crate::shared::config::planet::Planet; -use crate::shared::net::planet::{PlanetUpdatePacket, UpdatedPlanet}; -use crate::shared::net::staged_transform::LastStagedTransform; -use crate::shared::net::{SendTargets, ToClients}; - -pub fn send_updated_planets( - q_new_planets: Query<(Entity, &Transform), Added>, - q_moved_planets: Query<(Entity, &Transform, &LastStagedTransform), Changed>, - q_changed_planets: Query>, - - q_planets: Query<(&Planet, &Transform)>, - - mut update_packets_out: MessageWriter>, - mut commands: Commands -) { - let mut planets_to_send: BTreeSet = BTreeSet::new(); - - // Updating the Planet behavior triggers sprite loading on the client. We don't want to send it every time the Transform changes - let mut planets_with_planet_change: BTreeSet = BTreeSet::new(); - - for (new_planet, transform) in q_new_planets.iter() { - planets_to_send.insert(new_planet); // Always send newly created planets... - // ...and add LastStagedTransform... - commands.entity(new_planet).insert(LastStagedTransform(*transform)); - // and put a marker, we need to copy planet data across - planets_with_planet_change.insert(new_planet); - } - for (moved_planet, current_transform, maybe_staged_transform) in q_moved_planets.iter() { - // have we had a significant transform change? - if !maybe_staged_transform.should_update(current_transform) { continue; } - // we have, resend - planets_to_send.insert(moved_planet); - } - for changed_planet in q_changed_planets.iter() { - // if Planet changed, always resend - planets_to_send.insert(changed_planet); - // and put a marker, we need to copy planet data across - planets_with_planet_change.insert(changed_planet); - } - - // process all planets to send - let mut packet = PlanetUpdatePacket { - updated_planets: vec![] - }; - - for planet_to_send in planets_to_send.iter() { - let Ok(planet_info) = q_planets.get(*planet_to_send) else { continue }; - - packet.updated_planets.push(UpdatedPlanet { - server_entity: *planet_to_send, - planet: planet_info.0.clone(), - planet_data_changed: planets_with_planet_change.contains(planet_to_send), - transform: *planet_info.1, - }); - } - - update_packets_out.write(ToClients { - message: packet, - targets: SendTargets::All, - }); -} \ No newline at end of file diff --git a/crates/unified/src/server/player/join.rs b/crates/unified/src/server/player/join.rs index 3d43e5051cbfebf540dea261f9d12bbeddd6d22e..df6aeda1ab34b866b33e65f0bb20df2b99d438de 100644 --- a/crates/unified/src/server/player/join.rs +++ b/crates/unified/src/server/player/join.rs @@ -5,7 +5,7 @@ use crate::shared::ecs::{Player, PlayerStorage}; use crate::prelude::*; use crate::server::ConnectedGameEntity; use crate::server::part::SpawnPartRequest; -use crate::shared::net::{ClientId, Hi, SendTargets, ToClients}; +use crate::shared::net::{ClientId, Hi, SendTargets, ToClients, Mapped}; use crate::shared::world_config::WorldConfigResource; const SPAWN_ORBIT_OFFSET: f64 = 150.0; @@ -60,6 +60,7 @@ fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldCo } #[derive(Component)] +#[require(Mapped)] pub struct PendingPlayer; pub fn handle_new_players( diff --git a/crates/unified/src/server/plugins.rs b/crates/unified/src/server/plugins.rs index e28d2470775971e357c99819e95ef9e8956057b1..438125043cbd2ed7a9b7f9b0d0f66a3033eaaa49 100644 --- a/crates/unified/src/server/plugins.rs +++ b/crates/unified/src/server/plugins.rs @@ -1,36 +1,15 @@ use std::time::Duration; use aeronet_transport::AeronetTransportPlugin; use aeronet_websocket::server::WebSocketServerPlugin; -use avian2d::interpolation::PhysicsInterpolationPlugin; -use avian2d::PhysicsPlugins; -use avian2d::prelude::{Gravity, IslandPlugin}; use bevy::app::{PluginGroup, PluginGroupBuilder, ScheduleRunnerPlugin}; -use crate::prelude::{App, Startup}; use crate::shared::plugins::TICK_RATE; pub struct ServerPluginGroup; -const PHYSICS_LENGTH_UNIT: f64 = 100.0; - impl PluginGroup for ServerPluginGroup { fn build(self) -> PluginGroupBuilder { PluginGroupBuilder::start::() .add(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f64(1.0 / TICK_RATE))) .add(WebSocketServerPlugin) - .add_group( - PhysicsPlugins::default() - .with_length_unit(PHYSICS_LENGTH_UNIT) - .set(PhysicsInterpolationPlugin::interpolate_all()) - .build() - .disable::() - ) - .add(physics_setup_plugin) } } - -fn physics_setup_plugin(app: &mut App) { - app.insert_resource(Gravity::ZERO); - app.add_systems(Startup, setup_physics); -} - -fn setup_physics() {} diff --git a/crates/unified/src/shared/ecs.rs b/crates/unified/src/shared/ecs.rs index fcda652bedc9fa7ecceb9b0a344a2f3cbdf7c8a9..37ba0686121d97f9d4173a840a368ec416e36cc4 100644 --- a/crates/unified/src/shared/ecs.rs +++ b/crates/unified/src/shared/ecs.rs @@ -1,5 +1,6 @@ pub mod thruster; +use crate::shared::net::Mapped; use crate::shared::config::part::PartConfig; use bevy::math::{Quat, Vec2}; use bevy::camera::visibility::RenderLayers; @@ -40,6 +41,7 @@ pub struct PartHandle(pub Handle); pub struct TimeOffset(pub f64); #[derive(Component, Serialize, Deserialize, Debug)] +#[require(Mapped)] pub struct Player { pub client: Entity, } diff --git a/crates/unified/src/shared/net.rs b/crates/unified/src/shared/net.rs index 750623ad08c00e69963c143bcb3656ad0bbcd775..a927be617970a9763253a816e9e074c65ffc2513 100644 --- a/crates/unified/src/shared/net.rs +++ b/crates/unified/src/shared/net.rs @@ -1,7 +1,3 @@ -pub mod planet; -pub mod staged_transform; - -use std::any::TypeId; use std::collections::HashMap; use std::sync::OnceLock; use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering}; @@ -18,29 +14,61 @@ use bevy::reflect::DynamicTypePath; use postcard::{from_bytes, to_allocvec, to_slice, to_vec}; use crate::prelude::{App, Message}; use crate::shared::thrust::ThrustSolution; +//use bevy_replicon::prelude::*; use serde::{Deserialize, Serialize}; use crate::shared::attachment::{Joint, JointOf, PartInShip, Peer, Ship, SnapOf, SnapOfJoint}; use crate::shared::config::planet::{Planet, PlanetSpring, PlanetSpringJoint}; use crate::shared::ecs::{CanCraft, CraftPartRequest, DragRequestEvent, Drill, Part, Player, PlayerStorage, SingleStorage, Temperature, ToggleDrillEvent}; use crate::shared::ecs::thruster::{Thruster, ThrusterOfPart}; -use crate::shared::net::planet::PlanetUpdatePacket; + + +/*pub fn register_replication(app: &mut App) { + app + .add_mapped_server_message::(Channel::Ordered) + + .replicate::() + .replicate::() + + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + + .replicate::() + .replicate::() + .replicate::() + + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::() + .replicate::(); +}*/ pub fn register_net(app: &mut App) { app .add_mapped_server_message::() - - .add_server_message::() + .add_server_message::() .add_client_message::() .add_client_message::() .add_client_message::() - .add_client_message::() - - .add_systems(PostStartup, |srv_msg_reg: Res, client_msg_reg: Res| { - debug!("network registration complete"); - debug!("client registry: {:#?}", client_msg_reg); - debug!("server registry: {:#?}", srv_msg_reg); - }); + .add_client_message::(); } #[derive(Message, Clone, Deserialize, Serialize, TypePath, MapEntities)] @@ -50,6 +78,10 @@ pub struct Hi { pub time_offset: f64, } +#[derive(Message, Deserialize, Serialize, TypePath)] +pub struct SpawnEntity { + pub server: Entity, +} pub fn setup_net(app: &mut App) { app.insert_resource(ServerMessageRegistry::default()); app.insert_resource(ClientMessageRegistry::default()); @@ -80,15 +112,17 @@ pub enum ClientId { Server, Client(Entity), } +#[derive(Component, Default)] +pub struct Mapped; #[derive(Resource, Default)] pub struct ServerEntityMap { pub server_to_client: EntityHashMap, pub client_to_server: EntityHashMap, } -#[derive(Resource, Default, Debug)] +#[derive(Resource, Default)] pub struct ServerMessageRegistry { - forward: HashMap, + forward: HashMap, reverse: HashMap, &mut World)>, } impl ServerMessageRegistry { @@ -96,9 +130,9 @@ impl ServerMessageRegistry { self.forward.len() } } -#[derive(Resource, Default, Debug)] +#[derive(Resource, Default)] pub struct ClientMessageRegistry { - forward: HashMap, + forward: HashMap, reverse: HashMap, ClientId, &mut World)>, } impl ClientMessageRegistry { @@ -154,17 +188,18 @@ impl NetAppExt for App { } fn register_mapped_server_message Deserialize<'a>>(registry: &mut ServerMessageRegistry) { let lane_index = get_lane_index(); - registry.forward.insert(TypeId::of::(), lane_index); + registry.forward.insert(T::type_path().to_string(), lane_index); registry.reverse.insert(lane_index, |payload: Vec, world: &mut World| { let mut entity_map = world.resource_mut::(); let mut message = from_bytes::(&payload).expect(&format!("Failed to deserialize message of type {}", T::type_path())); message.map_entities(&mut entity_map.server_to_client); + debug!("entity map: {:?}", entity_map.server_to_client); world.write_message(message).expect("Could not send message to game"); }); } fn register_server_message Deserialize<'a>>(registry: &mut ServerMessageRegistry) { let lane_index = get_lane_index(); - registry.forward.insert(TypeId::of::(), lane_index); + registry.forward.insert(T::type_path().to_string(), lane_index); registry.reverse.insert(lane_index, |payload: Vec, world: &mut World| { let message = from_bytes::(&payload).expect(&format!("Failed to deserialize message of type {}", T::type_path())); world.write_message(message).expect("Could not send message to game"); @@ -172,7 +207,7 @@ fn register_server_message Deserialize<'a>>(regi } fn register_client_message Deserialize<'a>>(registry: &mut ClientMessageRegistry) { let lane_index = get_lane_index(); - registry.forward.insert(TypeId::of::(), lane_index); + registry.forward.insert(T::type_path().to_string(), lane_index); registry.reverse.insert(lane_index, |payload: Vec, client_id: ClientId, world: &mut World| { let message = from_bytes::(&payload).expect(&format!("Failed to deserialize message of type {}", T::type_path())); world.write_message(FromClients { @@ -191,8 +226,10 @@ fn send_to_client( match &message.targets { SendTargets::All => { for (client_entity, mut transport) in &mut clients { + debug!("lane: {:?}", message_registry.forward.get(M::type_path()).unwrap()); + debug!("registry: {:?}", message_registry.forward); transport.send.push( - *message_registry.forward.get(&TypeId::of::()) + *message_registry.forward.get(M::type_path()) .expect("Failed to get message lane; the message likely isn't serialized yet"), to_allocvec(&message).expect("Failed to serialize message").into(), bevy::platform::time::Instant::now(), @@ -202,8 +239,11 @@ fn send_to_client( SendTargets::Single(client) => { for (client_entity, mut transport) in &mut clients { if let ClientId::Client(client) = client && client_entity == *client { + debug!("writing message"); + debug!("lane: {:?}", message_registry.forward.get(M::type_path()).unwrap()); + debug!("registry: {:?}", message_registry.forward); transport.send.push( - *message_registry.forward.get(&TypeId::of::()) + *message_registry.forward.get(M::type_path()) .expect("Failed to get message lane; the message likely isn't serialized yet"), to_allocvec(&message).expect("Failed to serialize message").into(), bevy::platform::time::Instant::now(), @@ -222,7 +262,7 @@ fn send_to_server( for message in messages.read() { for mut transport in &mut sessions { transport.send.push( - *message_registry.forward.get(&TypeId::of::()) + *message_registry.forward.get(M::type_path()) .expect("Failed to get message lane; the message likely isn't serialized yet"), to_allocvec(&message).expect("Failed to serialize message").into(), bevy::platform::time::Instant::now(), @@ -241,7 +281,7 @@ fn send_mapped_to_server()) + *message_registry.forward.get(M::type_path()) .expect("Failed to get message lane; the message likely isn't serialized yet"), to_allocvec(&message).expect("Failed to serialize message").into(), bevy::platform::time::Instant::now(), @@ -260,6 +300,8 @@ fn recv_from_server( let mut messages = Vec::new(); for mut transport in sessions.iter_mut() { for message in transport.recv.msgs.drain() { + debug!("forward: {:?}", message_registry.forward); + debug!("reverse: {:?}", message_registry.reverse); let payload = message.payload; let message_fn = message_registry.reverse.get(&message.lane).expect("Packet was sent across a lane that didn't have a message assigned to it yet"); messages.push((*message_fn, payload)); diff --git a/crates/unified/src/shared/net/planet.rs b/crates/unified/src/shared/net/planet.rs deleted file mode 100644 index 2e290d45f8c70f2bf5d5639e2c01104b1353cbd3..0000000000000000000000000000000000000000 --- a/crates/unified/src/shared/net/planet.rs +++ /dev/null @@ -1,18 +0,0 @@ -use bevy::prelude::{Entity, Message, Transform, TypePath}; -use serde::{Deserialize, Serialize}; -use crate::shared::config::planet::Planet; - -#[derive(Serialize, Deserialize, Message, TypePath, Debug, Clone)] -pub struct PlanetUpdatePacket { - pub updated_planets: Vec -} - -#[derive(Serialize, Deserialize, TypePath, Debug, Clone)] -pub struct UpdatedPlanet { - pub server_entity: Entity, - - pub planet: Planet, - pub planet_data_changed: bool, - - pub transform: Transform -} \ No newline at end of file diff --git a/crates/unified/src/shared/net/staged_transform.rs b/crates/unified/src/shared/net/staged_transform.rs deleted file mode 100644 index f4f490678cc446a3f0c329ddf276d1cbba0981ed..0000000000000000000000000000000000000000 --- a/crates/unified/src/shared/net/staged_transform.rs +++ /dev/null @@ -1,14 +0,0 @@ -use bevy::prelude::{Component, Transform}; - -#[derive(Component)] -pub struct LastStagedTransform(pub Transform); - -impl LastStagedTransform { - pub fn should_update(&self, given_current: &Transform) -> bool { - const VECTOR_THRESHOLD: f32 = 0.1; // how much a value needs to change to resend this transform - - if !given_current.translation.abs_diff_eq(self.0.translation, VECTOR_THRESHOLD) { return true }; - if !given_current.scale.abs_diff_eq(self.0.scale, VECTOR_THRESHOLD) { return true }; - !given_current.rotation.abs_diff_eq(self.0.rotation, VECTOR_THRESHOLD) - } -} \ No newline at end of file diff --git a/crates/unified/src/shared/plugins.rs b/crates/unified/src/shared/plugins.rs index 94951fc24ef37e0ad5c44562e0d4243d4a2d134e..4390058cffe244c1ad551b16f69d66c4ca3bafe0 100644 --- a/crates/unified/src/shared/plugins.rs +++ b/crates/unified/src/shared/plugins.rs @@ -15,6 +15,7 @@ use crate::shared::config::world::GlobalWorldConfig; use crate::shared::world_config::world_config_plugin; pub const TICK_RATE: f64 = 20.0; +const PHYSICS_LENGTH_UNIT: f64 = 100.0; pub struct SharedPluginGroup; @@ -31,6 +32,14 @@ impl PluginGroup for SharedPluginGroup { app.insert_resource(Time::::default().with_relative_speed(1.0)); app.insert_resource(TimeOffset::default()); }) + .add_group( + PhysicsPlugins::default() + .with_length_unit(PHYSICS_LENGTH_UNIT) + .set(PhysicsInterpolationPlugin::interpolate_all()) + .build() + .disable::() + ) + .add(physics_setup_plugin) //.add(register_replication) .add(register_everything) .add(setup_net) @@ -46,4 +55,11 @@ impl PluginGroup for SharedPluginGroup { } pub fn register_everything(app: &mut App) { -} \ No newline at end of file +} + +fn physics_setup_plugin(app: &mut App) { + app.insert_resource(Gravity::ZERO); + app.add_systems(Startup, setup_physics); +} + +fn setup_physics() {}