From 1edd0f92899d8b946b19502c96df56eac44b3256 Mon Sep 17 00:00:00 2001 From: poffo Date: Sat, 22 Oct 2022 01:19:40 -0300 Subject: [PATCH] DemoBevy: use sequenced unreliable channel for syncing entities Now we don't need to use the a tick for discarding old frames, we can use the sequenced option in the unreliable channel. --- demo_bevy/src/bin/client.rs | 32 ++++++------------ demo_bevy/src/bin/server.rs | 50 +++++++++-------------------- demo_bevy/src/lib.rs | 42 ++++++++++++------------ rechannel/src/channel/unreliable.rs | 2 +- renet/src/lib.rs | 2 +- 5 files changed, 48 insertions(+), 80 deletions(-) diff --git a/demo_bevy/src/bin/client.rs b/demo_bevy/src/bin/client.rs index 1c939f62..5aeffedd 100644 --- a/demo_bevy/src/bin/client.rs +++ b/demo_bevy/src/bin/client.rs @@ -10,8 +10,8 @@ use bevy_renet::{ run_if_client_connected, RenetClientPlugin, }; use demo_bevy::{ - client_connection_config, setup_level, ClientChannel, NetworkFrame, PlayerCommand, PlayerInput, Ray3d, ServerChannel, ServerMessages, - PROTOCOL_ID, + client_connection_config, setup_level, ClientChannel, NetworkedEntities, PlayerCommand, PlayerInput, Ray3d, ServerChannel, + ServerMessages, PROTOCOL_ID, }; use renet_visualizer::{RenetClientVisualizer, RenetVisualizerStyle}; use smooth_bevy_cameras::{LookTransform, LookTransformBundle, LookTransformPlugin, Smoother}; @@ -33,9 +33,6 @@ struct ClientLobby { players: HashMap, } -#[derive(Debug)] -struct MostRecentTick(Option); - fn new_renet_client() -> RenetClient { let server_addr = "127.0.0.1:5000".parse().unwrap(); let socket = UdpSocket::bind("127.0.0.1:0").unwrap(); @@ -65,7 +62,6 @@ fn main() { app.insert_resource(ClientLobby::default()); app.insert_resource(PlayerInput::default()); - app.insert_resource(MostRecentTick(None)); app.insert_resource(new_renet_client()); app.insert_resource(NetworkMapping::default()); @@ -116,13 +112,11 @@ fn player_input( mouse_button_input: Res>, target_query: Query<&Transform, With>, mut player_commands: EventWriter, - most_recent_tick: Res, ) { player_input.left = keyboard_input.pressed(KeyCode::A) || keyboard_input.pressed(KeyCode::Left); player_input.right = keyboard_input.pressed(KeyCode::D) || keyboard_input.pressed(KeyCode::Right); player_input.up = keyboard_input.pressed(KeyCode::W) || keyboard_input.pressed(KeyCode::Up); player_input.down = keyboard_input.pressed(KeyCode::S) || keyboard_input.pressed(KeyCode::Down); - player_input.most_recent_tick = most_recent_tick.0; if mouse_button_input.just_pressed(MouseButton::Left) { let target_transform = target_query.single(); @@ -135,13 +129,13 @@ fn player_input( fn client_send_input(player_input: Res, mut client: ResMut) { let input_message = bincode::serialize(&*player_input).unwrap(); - client.send_message(ClientChannel::Input.id(), input_message); + client.send_message(ClientChannel::Input, input_message); } fn client_send_player_commands(mut player_commands: EventReader, mut client: ResMut) { for command in player_commands.iter() { let command_message = bincode::serialize(command).unwrap(); - client.send_message(ClientChannel::Command.id(), command_message); + client.send_message(ClientChannel::Command, command_message); } } @@ -152,10 +146,9 @@ fn client_sync_players( mut client: ResMut, mut lobby: ResMut, mut network_mapping: ResMut, - mut most_recent_tick: ResMut, ) { let client_id = client.client_id(); - while let Some(message) = client.receive_message(ServerChannel::ServerMessages.id()) { + while let Some(message) = client.receive_message(ServerChannel::ServerMessages) { let server_message = bincode::deserialize(&message).unwrap(); match server_message { ServerMessages::PlayerCreate { id, translation, entity } => { @@ -209,17 +202,12 @@ fn client_sync_players( } } - while let Some(message) = client.receive_message(ServerChannel::NetworkFrame.id()) { - let frame: NetworkFrame = bincode::deserialize(&message).unwrap(); - match most_recent_tick.0 { - None => most_recent_tick.0 = Some(frame.tick), - Some(tick) if tick < frame.tick => most_recent_tick.0 = Some(frame.tick), - _ => continue, - } + while let Some(message) = client.receive_message(ServerChannel::NetworkedEntities) { + let networked_entities: NetworkedEntities = bincode::deserialize(&message).unwrap(); - for i in 0..frame.entities.entities.len() { - if let Some(entity) = network_mapping.0.get(&frame.entities.entities[i]) { - let translation = frame.entities.translations[i].into(); + for i in 0..networked_entities.entities.len() { + if let Some(entity) = network_mapping.0.get(&networked_entities.entities[i]) { + let translation = networked_entities.translations[i].into(); let transform = Transform { translation, ..Default::default() diff --git a/demo_bevy/src/bin/server.rs b/demo_bevy/src/bin/server.rs index 54857e00..0b40b977 100644 --- a/demo_bevy/src/bin/server.rs +++ b/demo_bevy/src/bin/server.rs @@ -11,8 +11,8 @@ use bevy_renet::{ RenetServerPlugin, }; use demo_bevy::{ - server_connection_config, setup_level, spawn_fireball, ClientChannel, NetworkFrame, Player, PlayerCommand, PlayerInput, Projectile, - ServerChannel, ServerMessages, PROTOCOL_ID, + server_connection_config, setup_level, spawn_fireball, ClientChannel, NetworkedEntities, Player, PlayerCommand, PlayerInput, + Projectile, ServerChannel, ServerMessages, PROTOCOL_ID, }; use renet_visualizer::RenetServerVisualizer; @@ -21,13 +21,6 @@ pub struct ServerLobby { pub players: HashMap, } -#[derive(Debug, Default)] -struct NetworkTick(u32); - -// Clients last received ticks -#[derive(Debug, Default)] -struct ClientTicks(HashMap>); - const PLAYER_MOVE_SPEED: f32 = 5.0; fn new_renet_server() -> RenetServer { @@ -51,8 +44,6 @@ fn main() { app.add_plugin(EguiPlugin); app.insert_resource(ServerLobby::default()); - app.insert_resource(NetworkTick(0)); - app.insert_resource(ClientTicks::default()); app.insert_resource(new_renet_server()); app.insert_resource(RenetServerVisualizer::<200>::default()); @@ -79,7 +70,6 @@ fn server_update_system( mut lobby: ResMut, mut server: ResMut, mut visualizer: ResMut>, - mut client_ticks: ResMut, players: Query<(Entity, &Player, &Transform)>, ) { for event in server_events.iter() { @@ -97,7 +87,7 @@ fn server_update_system( translation, }) .unwrap(); - server.send_message(*id, ServerChannel::ServerMessages.id(), message); + server.send_message(*id, ServerChannel::ServerMessages, message); } // Spawn new player @@ -126,24 +116,23 @@ fn server_update_system( translation, }) .unwrap(); - server.broadcast_message(ServerChannel::ServerMessages.id(), message); + server.broadcast_message(ServerChannel::ServerMessages, message); } ServerEvent::ClientDisconnected(id) => { println!("Player {} disconnected.", id); visualizer.remove_client(*id); - client_ticks.0.remove(id); if let Some(player_entity) = lobby.players.remove(id) { commands.entity(player_entity).despawn(); } let message = bincode::serialize(&ServerMessages::PlayerRemove { id: *id }).unwrap(); - server.broadcast_message(ServerChannel::ServerMessages.id(), message); + server.broadcast_message(ServerChannel::ServerMessages, message); } } } for client_id in server.clients_id().into_iter() { - while let Some(message) = server.receive_message(client_id, ClientChannel::Command.id()) { + while let Some(message) = server.receive_message(client_id, ClientChannel::Command) { let command: PlayerCommand = bincode::deserialize(&message).unwrap(); match command { PlayerCommand::BasicAttack { mut cast_at } => { @@ -163,15 +152,14 @@ fn server_update_system( translation: translation.into(), }; let message = bincode::serialize(&message).unwrap(); - server.broadcast_message(ServerChannel::ServerMessages.id(), message); + server.broadcast_message(ServerChannel::ServerMessages, message); } } } } } - while let Some(message) = server.receive_message(client_id, ClientChannel::Input.id()) { + while let Some(message) = server.receive_message(client_id, ClientChannel::Input) { let input: PlayerInput = bincode::deserialize(&message).unwrap(); - client_ticks.0.insert(client_id, input.most_recent_tick); if let Some(player_entity) = lobby.players.get(&client_id) { commands.entity(*player_entity).insert(input); } @@ -198,21 +186,15 @@ fn update_visulizer_system( } #[allow(clippy::type_complexity)] -fn server_network_sync( - mut tick: ResMut, - mut server: ResMut, - networked_entities: Query<(Entity, &Transform), Or<(With, With)>>, -) { - let mut frame = NetworkFrame::default(); - for (entity, transform) in networked_entities.iter() { - frame.entities.entities.push(entity); - frame.entities.translations.push(transform.translation.into()); +fn server_network_sync(mut server: ResMut, query: Query<(Entity, &Transform), Or<(With, With)>>) { + let mut networked_entities = NetworkedEntities::default(); + for (entity, transform) in query.iter() { + networked_entities.entities.push(entity); + networked_entities.translations.push(transform.translation.into()); } - frame.tick = tick.0; - tick.0 += 1; - let sync_message = bincode::serialize(&frame).unwrap(); - server.broadcast_message(ServerChannel::NetworkFrame.id(), sync_message); + let sync_message = bincode::serialize(&networked_entities).unwrap(); + server.broadcast_message(ServerChannel::NetworkedEntities, sync_message); } fn move_players_system(mut query: Query<(&mut Velocity, &PlayerInput)>) { @@ -255,6 +237,6 @@ fn projectile_on_removal_system(mut server: ResMut, removed_project let message = ServerMessages::DespawnProjectile { entity }; let message = bincode::serialize(&message).unwrap(); - server.broadcast_message(ServerChannel::ServerMessages.id(), message); + server.broadcast_message(ServerChannel::ServerMessages, message); } } diff --git a/demo_bevy/src/lib.rs b/demo_bevy/src/lib.rs index e5fa827e..569988b5 100644 --- a/demo_bevy/src/lib.rs +++ b/demo_bevy/src/lib.rs @@ -15,7 +15,6 @@ pub struct Player { #[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Component)] pub struct PlayerInput { - pub most_recent_tick: Option, pub up: bool, pub down: bool, pub left: bool, @@ -34,7 +33,7 @@ pub enum ClientChannel { pub enum ServerChannel { ServerMessages, - NetworkFrame, + NetworkedEntities, } #[derive(Debug, Serialize, Deserialize, Component)] @@ -51,30 +50,26 @@ pub struct NetworkedEntities { pub translations: Vec<[f32; 3]>, } -#[derive(Debug, Serialize, Deserialize, Default)] -pub struct NetworkFrame { - pub tick: u32, - pub entities: NetworkedEntities, -} - -impl ClientChannel { - pub fn id(&self) -> u8 { - match self { - Self::Input => 0, - Self::Command => 1, +impl From for u8 { + fn from(channel_id: ClientChannel) -> Self { + match channel_id { + ClientChannel::Command => 0, + ClientChannel::Input => 1, } } +} +impl ClientChannel { pub fn channels_config() -> Vec { vec![ ReliableChannelConfig { - channel_id: Self::Input.id(), + channel_id: Self::Input.into(), message_resend_time: Duration::ZERO, ..Default::default() } .into(), ReliableChannelConfig { - channel_id: Self::Command.id(), + channel_id: Self::Command.into(), message_resend_time: Duration::ZERO, ..Default::default() } @@ -83,23 +78,26 @@ impl ClientChannel { } } -impl ServerChannel { - pub fn id(&self) -> u8 { - match self { - Self::NetworkFrame => 0, - Self::ServerMessages => 1, +impl From for u8 { + fn from(channel_id: ServerChannel) -> Self { + match channel_id { + ServerChannel::NetworkedEntities => 0, + ServerChannel::ServerMessages => 1, } } +} +impl ServerChannel { pub fn channels_config() -> Vec { vec![ UnreliableChannelConfig { - channel_id: Self::NetworkFrame.id(), + channel_id: Self::NetworkedEntities.into(), + sequenced: true, // We don't care about old positions ..Default::default() } .into(), ReliableChannelConfig { - channel_id: Self::ServerMessages.id(), + channel_id: Self::ServerMessages.into(), message_resend_time: Duration::from_millis(200), ..Default::default() } diff --git a/rechannel/src/channel/unreliable.rs b/rechannel/src/channel/unreliable.rs index be316855..2d14d785 100644 --- a/rechannel/src/channel/unreliable.rs +++ b/rechannel/src/channel/unreliable.rs @@ -330,7 +330,7 @@ mod tests { // Send first message let first_message = Bytes::from(vec![0]); - send_channel.send_message(first_message.clone(), current_time); + send_channel.send_message(first_message, current_time); let first_channel_data = send_channel.get_messages_to_send(u64::MAX, sequence, current_time).unwrap(); assert_eq!(first_channel_data.messages.len(), 1); diff --git a/renet/src/lib.rs b/renet/src/lib.rs index c8653bd7..f1379055 100644 --- a/renet/src/lib.rs +++ b/renet/src/lib.rs @@ -5,7 +5,7 @@ mod error; mod network_info; mod server; -pub use rechannel::channel::{ChunkChannelConfig, ChannelConfig, DefaultChannel, ReliableChannelConfig, UnreliableChannelConfig}; +pub use rechannel::channel::{ChannelConfig, ChunkChannelConfig, DefaultChannel, ReliableChannelConfig, UnreliableChannelConfig}; pub use rechannel::error::{ChannelError, DisconnectionReason, RechannelError}; pub use renetcode::{generate_random_bytes, ConnectToken, NetcodeError};