### ServerConfig Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Example of how to initialize a ServerConfig struct. Ensure current_time is set to the current epoch duration and protocol_id is set appropriately. ```rust use renet_netcode::{ServerConfig, ServerAuthentication}; use std::net::{SocketAddr, IpAddr, Ipv4Addr}; use std::time::SystemTime; let config = ServerConfig { current_time: SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap(), max_clients: 128, protocol_id: 0x12345678, public_addresses: vec![ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 5000), ], authentication: ServerAuthentication::Unsecure, }; ``` -------------------------------- ### Renet Steam AccessPermission Examples Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Examples demonstrating how to set up different access permissions for a Renet server using the `AccessPermission` enum. ```rust use renet_steam::AccessPermission; // Public server let access = AccessPermission::Public; // Friends only let access = AccessPermission::FriendsOnly; // Specific list let mut whitelist = std::collections::HashSet::new(); whitelist.insert(friend_steam_id); let access = AccessPermission::InList(whitelist); ``` -------------------------------- ### Bevy App Setup with RenetClientPlugin Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Example of how to add RenetClientPlugin to a Bevy application. Ensure to insert the RenetClient resource and define systems to handle client messages. ```rust use bevy::prelude::*; use bevy_renet::RenetClientPlugin; use renet::RenetClient; fn main() { App::new() .add_plugins(RenetClientPlugin) .insert_resource(RenetClient::new(Default::default())) .add_systems(Update, handle_client_messages) .run(); } fn handle_client_messages(mut client: ResMut) { if client.is_connected() { while let Some(msg) = client.receive_message(0) { println!("Server message: {:?}", msg); } } } ``` -------------------------------- ### Bevy App Setup with RenetServerPlugin Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Example of how to add RenetServerPlugin to a Bevy application. Ensure to insert the RenetServer resource and define systems to handle server messages. ```rust use bevy::prelude::*; use bevy_renet::RenetServerPlugin; use renet::RenetServer; fn main() { App::new() .add_plugins(RenetServerPlugin) .insert_resource(RenetServer::new(Default::default())) .add_systems(Update, handle_server_messages) .run(); } fn handle_server_messages(mut server: ResMut) { for client_id in server.clients_id() { while let Some(msg) = server.receive_message(client_id, 0) { println!("Message from {}: {:?}", client_id, msg); } } } ``` -------------------------------- ### ChannelConfig Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Illustrates how to create a ChannelConfig instance with specific settings for channel ID, memory usage, and send type. ```rust let channel = ChannelConfig { channel_id: 0, max_memory_usage_bytes: 5 * 1024 * 1024, send_type: SendType::ReliableOrdered { resend_time: Duration::from_millis(300), }, }; ``` -------------------------------- ### DefaultChannel Usage Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Demonstrates using DefaultChannel for sending messages and obtaining default connection configurations. ```rust use renet::DefaultChannel; // Using in send/receive client.send_message(DefaultChannel::ReliableOrdered, "important"); // Or convert to u8 client.send_message(DefaultChannel::Unreliable.into(), "fast"); // Getting default config let config = ConnectionConfig { server_channels_config: DefaultChannel::config(), client_channels_config: DefaultChannel::config(), ..Default::default() }; ``` -------------------------------- ### Run Renetcode Echo Server Source: https://github.com/lucaspoffo/renet/blob/master/renetcode/README.md Execute the echo server example using Cargo. Specify the port to listen on. ```bash cargo run --example echo -- server 5000 ``` -------------------------------- ### Example Server Configuration Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/configuration.md Illustrates how to create a `ServerConfig` instance with essential parameters like current time, maximum clients, protocol ID, public addresses, and authentication method. ```rust use renet_netcode::{ServerConfig, ServerAuthentication}; use std::net::{SocketAddr, IpAddr, Ipv4Addr}; use std::time::SystemTime; let config = ServerConfig { current_time: SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap(), max_clients: 256, protocol_id: 0x12345678, public_addresses: vec![ SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100)), 5000), ], authentication: ServerAuthentication::Unsecure, }; ``` -------------------------------- ### Server Setup with Bevy Renet Source: https://github.com/lucaspoffo/renet/blob/master/bevy_renet/README.md Set up a Bevy application as a server using RenetServerPlugin and NetcodeServerPlugin. Requires adding RenetServer and NetcodeServerTransport as resources. ```rust fn main() { let mut app = App::new(); app.add_plugin(RenetServerPlugin); let server = RenetServer::new(ConnectionConfig::default()); app.insert_resource(server); // Transport layer setup app.add_plugin(NetcodeServerPlugin); let server_addr = "127.0.0.1:5000".parse().unwrap(); let socket = UdpSocket::bind(server_addr).unwrap(); let server_config = ServerConfig { current_time: SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(), max_clients: 64, protocol_id: 0, public_addresses: vec![server_addr], authentication: ServerAuthentication::Unsecure }; let transport = NetcodeServerTransport::new(server_config, socket).unwrap(); app.insert_resource(transport); app.add_system(send_message_system); app.add_system(receive_message_system); app.add_system(handle_events_system); } ``` -------------------------------- ### Run Renetcode Echo Client Source: https://github.com/lucaspoffo/renet/blob/master/renetcode/README.md Execute the echo client example using Cargo. Specify the port to connect to and a username. ```bash cargo run --example echo -- client 5000 my_username ``` -------------------------------- ### ClientAuthentication Examples Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Demonstrates initializing ClientAuthentication for both testing (Unsecure) and production (Secure) scenarios. The Secure variant requires a valid connect_token. ```rust use renet_netcode::{ClientAuthentication}; // Testing let auth = ClientAuthentication::Unsecure { server_addr: "127.0.0.1:5000".parse()?, client_id: 0, user_data: None, protocol_id: 0, }; // Production (requires token from server) let auth = ClientAuthentication::Secure { server_addr: server_addr, protocol_id: 0x12345678, connect_token, client_key: client_key, server_key: server_key, }; ``` -------------------------------- ### Basic Server Setup and Event Handling Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/quick-reference.md Initialize a Renet server and process client events and messages in a loop. Ensure to update the server with delta time and handle disconnections. ```rust use renet::{RenetServer, ConnectionConfig}; use std::time::Duration; let mut server = RenetServer::new(ConnectionConfig::default()); loop { let delta = Duration::from_millis(16); server.update(delta); // Handle events while let Some(event) = server.get_event() { match event { ServerEvent::ClientConnected { client_id } => { println!("Client {} connected", client_id); } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {} disconnected: {}", client_id, reason); } } } // Receive and respond for client_id in server.clients_id() { while let Some(msg) = server.receive_message(client_id, 0) { println!("From {}: {:?}", client_id, msg); server.send_message(client_id, 0, "response"); } } // Send packets via transport transport.send_packets(&mut server); thread::sleep(delta); } ``` -------------------------------- ### Client Setup with Bevy Renet Source: https://github.com/lucaspoffo/renet/blob/master/bevy_renet/README.md Set up a Bevy application as a client using RenetClientPlugin and NetcodeClientPlugin. Requires adding RenetClient and NetcodeClientTransport as resources. ```rust fn main() { let mut app = App::new(); app.add_plugin(RenetClientPlugin); let client = RenetClient::new(ConnectionConfig::default()); app.insert_resource(client); // Setup the transport layer app.add_plugin(NetcodeClientPlugin); let authentication = ClientAuthentication::Unsecure { server_addr: SERVER_ADDR, client_id: 0, user_data: None, protocol_id: 0, }; let socket = UdpSocket::bind("127.0.0.1:0").unwrap(); let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); let mut transport = NetcodeClientTransport::new(current_time, authentication, socket).unwrap(); app.insert_resource(transport); app.add_system(send_message_system); app.add_system(receive_message_system); } ``` -------------------------------- ### Basic Client Setup and Message Handling Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/quick-reference.md Initialize a Renet client and manage its connection and message exchange in a loop. Update the client with delta time and handle transport updates. ```rust use renet::{RenetClient, ConnectionConfig, DefaultChannel}; use std::time::Duration; let mut client = RenetClient::new(ConnectionConfig::default()); loop { let delta = Duration::from_millis(16); client.update(delta); // Receive from transport transport.update(delta, &mut client)?; if client.is_connected() { // Receive messages while let Some(msg) = client.receive_message(DefaultChannel::ReliableOrdered) { println!("Server says: {:?}", msg); } // Send messages client.send_message(DefaultChannel::ReliableOrdered, "hello"); } // Send packets via transport transport.send_packets(&mut client)?; thread::sleep(delta); } ``` -------------------------------- ### NetcodeClientTransport Example Usage Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Example demonstrating how to create a NetcodeClientTransport. It involves parsing the server address, binding a UDP socket, getting the current time, and configuring client authentication. ```rust use renet_netcode::{NetcodeClientTransport, ClientAuthentication}; use std::net::UdpSocket; use std::time::SystemTime; let server_addr = "127.0.0.1:5000".parse()?; let socket = UdpSocket::bind("127.0.0.1:0")?; let current_time = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH)?; let authentication = ClientAuthentication::Unsecure { server_addr, client_id: 0, user_data: None, protocol_id: 0, }; let transport = NetcodeClientTransport::new(current_time, authentication, socket)?; ``` -------------------------------- ### Renet Message Operation Examples Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Illustrates how to use Renet's message sending and receiving functions. Examples cover sending private messages, broadcasting to all clients, excluding a specific client, and continuously receiving messages. ```rust // Send to one client server.send_message(client_id, 0, "private message"); // Broadcast to all server.broadcast_message(0, "all clients"); // Broadcast except one server.broadcast_message_except(client_id, 0, "to others"); // Receive from client while let Some(msg) = server.receive_message(client_id, 0) { println!("From client: {:?}", msg); } ``` -------------------------------- ### Connection Lifecycle Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/INDEX.md Illustrates the connection lifecycle states: Connecting, Connected, and Disconnected. Shows how to check connection status and retrieve disconnection reasons. ```rust Connecting → Connected → (Disconnected with reason) Status checked with: - `is_connected()`, `is_connecting()`, `is_disconnected()` - `disconnect_reason()` for failure details ``` -------------------------------- ### SteamServerTransport Construction Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Example of how to create a SteamServerTransport. This requires a Steamworks client instance and a SteamServerConfig specifying connection limits and permissions. ```rust use renet_steam::{SteamServerTransport, SteamServerConfig, AccessPermission}; let config = SteamServerConfig { max_clients: 32, access_permission: AccessPermission::Public, }; let transport = SteamServerTransport::new(steam_client, config)?; ``` -------------------------------- ### Client Usage Example for Renet Visualizer Source: https://github.com/lucaspoffo/renet/blob/master/renet_visualizer/README.md Demonstrates how to integrate RenetClientVisualizer into a client application's main loop. Ensure Renet client is updated and network info is added before showing the window. ```rust let mut visualizer = RenetClientVisualizer::<200>::new(RenetVisualizerStyle::default()); // .. loop { // Update Renet Client client.update(delta).unwrap(); // Add metrics to the visualizer visualizer.add_network_info(client.network_info()); // Draws a new egui window with the metrics visualizer.show_window(egui_ctx); // .. } ``` -------------------------------- ### DefaultChannel Conversion Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Shows how to convert a DefaultChannel variant into its corresponding u8 channel ID. ```rust let channel_id: u8 = DefaultChannel::Unreliable.into(); // 0 ``` -------------------------------- ### Server Usage Example for Renet Visualizer Source: https://github.com/lucaspoffo/renet/blob/master/renet_visualizer/README.md Illustrates the integration of RenetServerVisualizer on the server side. This includes handling client connections/disconnections and updating the visualizer with server-wide metrics. ```rust let mut visualizer = RenetServerVisualizer::<200>::new(RenetVisualizerStyle::default()); // .. loop { // Update Renet Server server.update(delta).unwrap(); // Add/Remove clients from the visualizer while let Some(event) = server.get_event() { match event { ServerEvent::ClientConnected(client_id, user_data) => { visualizer.add_client(client_id); // ... } ServerEvent::ClientDisconnected(client_id) => { visualizer.remove_client(client_id); // ... } } } // Add all clients metrics to the visualizer visualizer.update(&server); // Draws a new egui window with all clients metrics visualizer.show_window(egui_ctx); // .. } ``` -------------------------------- ### NetworkInfo Usage Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Shows how to retrieve and interpret NetworkInfo to monitor connection health and performance, such as checking packet loss and latency. ```rust let info = client.network_info(); if info.packet_loss > 0.05 { println!("Warning: {:.1}% packet loss", info.packet_loss * 100.0); } println!("Latency: {:.0}ms", info.rtt * 1000.0); ``` -------------------------------- ### Using RenetReceive System Set Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Example of how to add a system to the RenetReceive set. This ensures your network handler runs after the server has updated and processed incoming data. ```rust app.add_systems( PreUpdate, my_network_handler .in_set(RenetReceive) .after(RenetServerPlugin::update_system), ); ``` -------------------------------- ### Bevy Renet Server Setup Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Sets up a Renet server within a Bevy application. This includes adding the RenetServerPlugin, inserting the RenetServer resource, and defining systems for handling server events, receiving, and sending messages. ```rust use bevy::prelude::*; use bevy_renet::{RenetServerPlugin, RenetServerEvent, RenetReceive}; use renet::{RenetServer, ConnectionConfig, ServerEvent}; use std::time::Duration; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(RenetServerPlugin) .insert_resource(RenetServer::new(ConnectionConfig::default())) .add_systems(PreUpdate, setup_server) .add_systems(Update, ( handle_network_events, receive_messages, send_messages, )) .run(); } fn setup_server( mut commands: Commands, mut server: ResMut, ) { // Transport setup happens here (not shown) println!("Server started"); } fn handle_network_events( mut events: EventReader, ) { for RenetServerEvent(event) in events.read() { match event { ServerEvent::ClientConnected { client_id } => { println!("Client {} connected", client_id); } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {} disconnected: {}", client_id, reason); } } } } fn receive_messages( mut server: ResMut, ) { for client_id in server.clients_id() { while let Some(message) = server.receive_message(client_id, 0) { println!("From {}: {:?}", client_id, message); // Echo back server.send_message(client_id, 0, message); } } } fn send_messages( mut server: ResMut, ) { // Periodic broadcast example server.broadcast_message(0, "Hello all clients"); } ``` -------------------------------- ### Configure Server and Client Channels Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/configuration.md Sets up separate channel configurations for server-to-client and client-to-server communication. This example demonstrates defining channel IDs, memory limits, and send types for both directions. ```rust let config = ConnectionConfig { available_bytes_per_tick: 60_000, // Server sends these types to clients server_channels_config: vec![ ChannelConfig { channel_id: 0, max_memory_usage_bytes: 10 * 1024 * 1024, send_type: SendType::ReliableOrdered { resend_time: Duration::from_millis(300), }, }, // ... more channels ], // Clients send these types to server client_channels_config: vec![ ChannelConfig { channel_id: 0, max_memory_usage_bytes: 5 * 1024 * 1024, send_type: SendType::Unreliable, }, // ... more channels ], }; ``` -------------------------------- ### RenetClient Construction Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Creates a new RenetClient instance with the specified connection configuration. Use ConnectionConfig::default() for basic setup. ```Rust use renet::RenetClient; use renet::ConnectionConfig; let client = RenetClient::new(ConnectionConfig::default()); ``` -------------------------------- ### Manage RenetServer Client Limits Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Allows getting and setting the maximum number of clients that can connect to the server. ```rust pub fn max_clients(&self) -> usize pub fn set_max_clients(&mut self, max_clients: usize) ``` -------------------------------- ### Using RenetSend System Set Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Example of how to add a system to the RenetSend set. This ensures that messages queued for sending are processed by the transport layer after the main update loop. ```rust app.add_systems( PostUpdate, queue_server_broadcasts .in_set(RenetSend), ); ``` -------------------------------- ### Bevy Renet Client Setup Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Sets up a Renet client within a Bevy application. This includes adding the RenetClientPlugin, inserting the RenetClient resource, and defining systems for receiving messages, sending input, and handling connection events. ```rust use bevy::prelude::*; use bevy_renet::{RenetClientPlugin, client_connected, client_just_connected}; use renet::RenetClient; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins(RenetClientPlugin) .insert_resource(RenetClient::new(Default::default())) .add_systems(Startup, setup_client) .add_systems(Update, ( receive_messages.run_if(client_connected), send_input.run_if(client_connected), on_just_connected.run_if(client_just_connected), )) .run(); } fn setup_client(mut commands: Commands) { // Transport setup happens here println!("Client initialized"); } fn receive_messages( mut client: ResMut, ) { while let Some(message) = client.receive_message(0) { println!("Server says: {:?}", message); } } fn send_input( mut client: ResMut, keys: Res>, ) { if keys.pressed(KeyCode::ArrowUp) { client.send_message(0, "move_up".as_bytes()); } } fn on_just_connected( mut commands: Commands, ) { println!("Connected! Spawning player..."); } ``` -------------------------------- ### Renet Channel Diagnostics Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Shows how to check if a message can be sent before attempting to send it, and how to retrieve detailed network information for a client. The `network_info` call can return an error if the client is not found. ```rust if server.can_send_message(client_id, 0, 1024) { server.send_message(client_id, 0, vec![0u8; 1024]); } let info = server.network_info(client_id)?; ``` -------------------------------- ### Renet Client Enumeration Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Demonstrates iterating over connected clients to send them a message and printing the total number of connected clients. This is useful for batch operations or status checks. ```rust for client_id in server.clients_id_iter() { server.send_message(client_id, 0, "hello"); } println!("{} clients connected", server.connected_clients()); ``` -------------------------------- ### Define Renet Connection Configuration Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md This snippet shows the structure for configuring Renet's network channels and bandwidth limits. It includes default values and an example of a custom configuration. ```rust pub struct ConnectionConfig { pub available_bytes_per_tick: u64, pub server_channels_config: Vec, pub client_channels_config: Vec, } ``` ```rust impl Default for ConnectionConfig { fn default() -> Self { Self { available_bytes_per_tick: 60_000, server_channels_config: DefaultChannel::config(), client_channels_config: DefaultChannel::config(), } } } ``` ```rust let config = ConnectionConfig { available_bytes_per_tick: 100_000, server_channels_config: vec![ ChannelConfig { channel_id: 0, max_memory_usage_bytes: 10 * 1024 * 1024, send_type: SendType::ReliableOrdered { resend_time: Duration::from_millis(300), }, }, ], client_channels_config: DefaultChannel::config(), }; let server = RenetServer::new(config); ``` -------------------------------- ### SendType Usage Examples Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Demonstrates the creation of different SendType variants for various use cases, such as real-time updates, ordered commands, and unordered reliable data. ```rust use std::time::Duration; use renet::SendType; // Real-time movement updates let unreliable = SendType::Unreliable; // Game commands that must arrive in order let ordered = SendType::ReliableOrdered { resend_time: Duration::from_millis(300), }; // Asset transfers that must arrive but order doesn't matter let unordered = SendType::ReliableUnordered { resend_time: Duration::from_millis(500), }; ``` -------------------------------- ### Check Network Quality Warnings Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/configuration.md Provides an example function to check network quality based on `NetworkInfo` statistics and print warnings for high packet loss, latency, or bandwidth usage. ```rust fn check_network_quality(info: NetworkInfo) { if info.packet_loss > 0.05 { println!("⚠️ High packet loss: {:.1}%", info.packet_loss * 100.0); } if info.rtt > 0.2 { println!("⚠️ High latency: {:.0}ms", info.rtt * 1000.0); } // Warn if bandwidth approaching limits if info.bytes_sent_per_second > 20_000_000.0 { // 20 Mbps println!("⚠️ High outgoing bandwidth: {:.1} Mbps", info.bytes_sent_per_second / 1_000_000.0); } } ``` -------------------------------- ### Set Available Bytes Per Tick Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/configuration.md Configures the maximum bandwidth available per update tick. This example sets the value to 100,000 bytes, which translates to approximately 48 Mbps at a 60 Hz tick rate. ```rust use renet::ConnectionConfig; let mut config = ConnectionConfig::default(); config.available_bytes_per_tick = 100_000; // 48 Mbps at 60 Hz ``` -------------------------------- ### NetcodeClientTransport Update and Send Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Illustrates the main loop for a Renet client using NetcodeClientTransport. It includes updating the client and transport, processing events, receiving messages, sending messages, and sending packets to the server. ```rust loop { let delta = Duration::from_millis(16); // Update client and transport client.update(delta); transport.update(delta, &mut client)?; // Process events while let Some(event) = server.get_event() { // Handle event } // Receive messages while let Some(msg) = client.receive_message(0) { // Handle message } // Send messages client.send_message(0, "data"); // Send packets to server transport.send_packets(&mut client)?; thread::sleep(delta); } ``` -------------------------------- ### Channel ID Uniqueness Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/configuration.md Illustrates the rules for channel_id uniqueness within Renet configurations. It shows a valid scenario where the same channel ID can exist in both server and client lists, and an invalid scenario with duplicate IDs in the same list. ```rust // Valid: same ID in both lists let config = ConnectionConfig { server_channels_config: vec![ ChannelConfig { channel_id: 0, ..Default::default() }, ], client_channels_config: vec![ ChannelConfig { channel_id: 0, ..Default::default() }, ], ..Default::default() }; // Invalid: duplicate IDs in same list let config = ConnectionConfig { server_channels_config: vec![ ChannelConfig { channel_id: 0, ..Default::default() }, ChannelConfig { channel_id: 0, ..Default::default() }, // PANIC: assertion fails ], ..Default::default() }; ``` -------------------------------- ### NetcodeClientTransport Timeout Detection Example Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Example showing how to detect a server timeout using `time_since_last_received_packet`. If the duration exceeds a specified threshold (e.g., 5 seconds), a timeout message is printed. ```rust if transport.time_since_last_received_packet() > Duration::from_secs(5) { println!("Server timeout"); } ``` -------------------------------- ### Get RenetServer Public Addresses Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Retrieves a list of all public network addresses the server is configured to listen on. ```rust pub fn addresses(&self) -> Vec ``` -------------------------------- ### Get RenetServer Connected Client Count Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Retrieves the current number of clients actively connected to the server. ```rust pub fn connected_clients(&self) -> usize ``` -------------------------------- ### Get RenetServer Client Network Address Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Retrieves the network address (IP and port) of a specific connected client. ```rust pub fn client_addr(&self, client_id: ClientId) -> Option ``` ```rust // Access client address for logging if let Some(addr) = transport.client_addr(client_id) { println!("Client {} from {}", client_id, addr); } ``` -------------------------------- ### Get Network Statistics Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/quick-reference.md Retrieve network statistics like RTT, packet loss, and bandwidth usage for a client. ```rust // Get all stats let info = client.network_info(); println!("RTT: {:.0}ms", info.rtt * 1000.0); println!("Loss: {:.1}%", info.packet_loss * 100.0); println!("Send: {:.0} bytes/s", info.bytes_sent_per_second); println!("Recv: {:.0} bytes/s", info.bytes_received_per_second); // Individual metrics println!("RTT: {:.0}ms", client.rtt() * 1000.0); println!("Loss: {:.2}%", client.packet_loss() * 100.0); println!("Bandwidth: {:.0} KB/s", client.bytes_sent_per_sec() / 1024.0); ``` -------------------------------- ### Get RenetServer Client User Data Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Retrieves the user data associated with a specific client's connection token. ```rust pub fn user_data(&self, client_id: ClientId) -> Option<[u8; NETCODE_USER_DATA_BYTES]> ``` -------------------------------- ### Initialize and Run Renet Client Source: https://github.com/lucaspoffo/renet/blob/master/README.md Sets up a Renet client and the NetcodeClientTransport. The loop continuously updates the client and transport, handles incoming messages, and sends outgoing messages. Ensure the server address and protocol ID are correctly configured. ```rust let mut client = RenetClient::new(ConnectionConfig::default()); // Setup transport layer using renet_netcode const server_addr: SocketAddr = "127.0.0.1:5000".parse().unwrap(); let socket = UdpSocket::bind("127.0.0.1:0").unwrap(); let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); let authentication = ClientAuthentication::Unsecure { server_addr, client_id: 0, user_data: None, protocol_id: 0, }; let mut transport = NetcodeClientTransport::new(current_time, authentication, socket).unwrap(); // Your gameplay loop loop { let delta_time = Duration::from_millis(16); // Receive new messages and update client client.update(delta_time); transport.update(delta_time, &mut client).unwrap(); if client.is_connected() { // Receive message from server while let Some(message) = client.receive_message(DefaultChannel::ReliableOrdered) { // Handle received message } // Send message client.send_message(DefaultChannel::ReliableOrdered, "client text"); } // Send packets to server using the transport layer transport.send_packets(&mut client)?; std::thread::sleep(delta_time); // Running at 60hz } ``` -------------------------------- ### Create RenetServer Instance Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Instantiate a new RenetServer with a default connection configuration. ```rust impl RenetServer { pub fn new(connection_config: ConnectionConfig) -> Self } ``` ```rust use renet::RenetServer; use renet::ConnectionConfig; let server = RenetServer::new(ConnectionConfig::default()); ``` -------------------------------- ### Handling RenetServerEvents Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Example of how to read `RenetServerEvent`s from Bevy's event stream. This allows you to react to client connection and disconnection events. ```rust use bevy_renet::RenetServerEvent; use renet::ServerEvent; fn handle_network_events(mut events: EventReader) { for RenetServerEvent(event) in events.read() { match event { ServerEvent::ClientConnected { client_id } => { println!("Client {} connected", client_id); } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {} disconnected: {}", client_id, reason); } } } } ``` -------------------------------- ### Accessing RenetServer and RenetClient Resources Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Demonstrates how to access RenetServer and RenetClient as Bevy resources within your systems. Use `Res` for read-only access and `ResMut` for mutable access. ```rust // In systems: fn my_system(server: Res) { // Read-only access } fn my_mut_system(mut server: ResMut) { // Mutable access for sending messages, updating state } ``` -------------------------------- ### Initialize Renet Server and Transport Source: https://github.com/lucaspoffo/renet/blob/master/README.md Sets up a Renet server and the NetcodeServerTransport for handling network connections and message exchange. ```rust let mut server = RenetServer::new(ConnectionConfig::default()); // Setup transport layer using renet_netcode const SERVER_ADDR: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 5000); let socket: UdpSocket = UdpSocket::bind(SERVER_ADDR).unwrap(); let server_config = ServerConfig { current_time: SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(), max_clients: 64, protocol_id: 0, public_addresses: vec![SERVER_ADDR], authentication: ServerAuthentication::Unsecure }; let mut transport = NetcodeServerTransport::new(server_config, socket).unwrap(); ``` -------------------------------- ### RenetServer Construction Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Creates a new `RenetServer` instance with the specified connection configuration. ```APIDOC ## RenetServer Construction ### Description Creates a new `RenetServer`. ### Method `new(connection_config: ConnectionConfig) -> Self` ### Parameters - `connection_config` (`ConnectionConfig`): Shared configuration for all client connections. ### Returns - `RenetServer` instance ### Example ```rust use renet::RenetServer; use renet::ConnectionConfig; let server = RenetServer::new(ConnectionConfig::default()); ``` ``` -------------------------------- ### Main Classes Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/README.md Key classes for managing client and server connections, and configuring network settings. ```APIDOC ## Main Classes - **RenetClient**: Client-side connection manager - **RenetServer**: Server-side connection manager - **ConnectionConfig**: Global bandwidth and channel setup - **ChannelConfig**: Individual channel tuning - **SendType**: Enum for delivery guarantees ``` -------------------------------- ### RenetClient Construction Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Creates a new RenetClient instance with the specified connection configuration. This is the entry point for initializing the client-side network handler. ```APIDOC ## RenetClient::new ### Description Creates a new `RenetClient` with the given configuration. ### Method `impl RenetClient` ### Parameters #### Request Body - **config** (`ConnectionConfig`) - Required - Configuration for channels and bandwidth ### Response #### Success Response - `RenetClient` instance ### Request Example ```rust use renet::RenetClient; use renet::ConnectionConfig; let client = RenetClient::new(ConnectionConfig::default()); ``` ``` -------------------------------- ### Test with Local Client Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/quick-reference.md Sets up and tests communication between a Renet server and a local client. This involves initializing both, updating them in a loop, and processing messages. ```rust let mut server = RenetServer::new(ConnectionConfig::default()); let mut local_client = server.new_local_client(0); // In loop server.update(Duration::from_millis(16)); local_client.update(Duration::from_millis(16)); // Exchange packets server.process_local_client(0, &mut local_client)?; // Test as normal local_client.send_message(0, "test"); while let Some(msg) = server.receive_message(0, 0) { println!("Got: {:?}", msg); } ``` -------------------------------- ### Renet Server Configuration Methods Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/transport-layers.md Methods for configuring the Renet server, such as setting the maximum number of clients and access permissions. ```rust pub fn max_clients(&self) -> usize pub fn set_access_permissions(&mut self, access_permission: AccessPermission) ``` -------------------------------- ### Renet Client Enumeration Functions Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Retrieve lists or iterators of connected and disconnected client IDs, or get a count of currently connected clients. Useful for managing client lists and monitoring connection status. ```rust pub fn clients_id(&self) -> Vec ``` ```rust pub fn clients_id_iter(&self) -> impl Iterator + '_ ``` ```rust pub fn disconnections_id(&self) -> Vec ``` ```rust pub fn disconnections_id_iter(&self) -> impl Iterator + '_ ``` ```rust pub fn connected_clients(&self) -> usize ``` -------------------------------- ### RenetServer Methods Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/types.md Provides documentation for the methods available on the RenetServer struct, enabling server-side network management and communication. ```APIDOC ## RenetServer Methods ### Description Documentation for the methods available on the `RenetServer` struct, enabling server-side network management and communication with clients. ### Methods - `new(connection_config: ConnectionConfig) -> Self`: Creates a new Renet server instance. - `add_connection(&mut self, client_id: ClientId)`: Adds a new client connection to the server. - `remove_connection(&mut self, client_id: ClientId)`: Removes a client connection from the server. - `get_event(&mut self) -> Option`: Retrieves the next server event. - `send_message, B: Into>(&mut self, client_id: ClientId, channel_id: I, message: B)`: Sends a message to a specific client on a given channel. - `broadcast_message, B: Into>(&mut self, channel_id: I, message: B)`: Broadcasts a message to all connected clients on a given channel. - `receive_message>(&mut self, client_id: ClientId, channel_id: I) -> Option`: Receives a message from a specific client on a given channel. - `clients_id(&self) -> Vec`: Returns a list of all connected client identifiers. - `update(&mut self, duration: Duration)`: Updates the server's internal state, processing network events. - `get_packets_to_send(&mut self, client_id: ClientId) -> Result, ClientNotFound>`: Retrieves raw packets to be sent to a specific client. - `process_packet_from(&mut self, payload: &[u8], client_id: ClientId) -> Result<(), ClientNotFound>`: Processes an incoming network packet from a specific client. ``` -------------------------------- ### Manage Server Connections Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/quick-reference.md Add, remove, list, and disconnect clients from the server. ```rust // Accept connection (from transport) server.add_connection(client_id); // Remove connection (from transport) server.remove_connection(client_id); // List clients for client_id in server.clients_id() { println!("Client: {}", client_id); } let count = server.connected_clients(); // Disconnect specific client server.disconnect(client_id); // Disconnect all server.disconnect_all(); ``` -------------------------------- ### Manage Local Clients for Testing Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md This snippet demonstrates how to create, process, and disconnect local Renet clients within the same process for testing purposes. It bypasses the transport layer for easier simulation. ```rust pub fn new_local_client(&mut self, client_id: ClientId) -> RenetClient pub fn disconnect_local_client(&mut self, client_id: ClientId, client: &mut RenetClient) pub fn process_local_client( &mut self, client_id: ClientId, client: &mut RenetClient, ) -> Result<(), ClientNotFound> ``` ```rust let mut client = server.new_local_client(0); // In loop server.update(Duration::from_millis(16)); client.update(Duration::from_millis(16)); server.process_local_client(0, &mut client)?; // Send/receive as normal client.send_message(0, "test"); while let Some(msg) = server.receive_message(0, 0) { server.send_message(0, 0, "response"); } ``` -------------------------------- ### Renet Server with Steam Transport Source: https://github.com/lucaspoffo/renet/blob/master/renet_steam/README.md Set up a Renet server using Steam's transport layer. Ensure Steam client is initialized and callbacks are run. This replaces the default renet transport. ```rust let (steam_client, single) = Client::init_app(480).unwrap(); steam_client.networking_utils().init_relay_network_access(); let connection_config = ConnectionConfig::default(); let mut server: RenetServer = RenetServer::new(connection_config); let access_permission = AccessPermission::Public; let steam_transport_config = SteamServerConfig { max_clients: 10, access_permission, }; let mut steam_transport = SteamServerTransport::new(&steam_client, steam_transport_config).unwrap(); loop { let delta_time = Duration::from_millis(16); single.run_callbacks(); server.update(delta_time); steam_transport.update(&mut server); while let Some(event) = server.get_event() { match event { ServerEvent::ClientConnected { client_id } => { println!("Client {} connected.", client_id) } ServerEvent::ClientDisconnected { client_id, reason } => { println!("Client {} disconnected: {}", client_id, reason); } } } steam_transport.send_packets(&mut server); thread::sleep(delta_time); } ``` -------------------------------- ### RenetClient Methods Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/types.md Provides documentation for the methods available on the RenetClient struct, allowing for network communication from a client's perspective. ```APIDOC ## RenetClient Methods ### Description Documentation for the methods available on the `RenetClient` struct, enabling client-side network operations. ### Methods - `new(config: ConnectionConfig) -> Self`: Creates a new Renet client instance. - `send_message, B: Into>(&mut self, channel_id: I, message: B)`: Sends a message to the server on a specified channel. - `receive_message>(&mut self, channel_id: I) -> Option`: Receives a message from the server on a specified channel. - `update(&mut self, duration: Duration)`: Updates the client's internal state, processing network events. - `process_packet(&mut self, packet: &[u8])`: Processes an incoming network packet. - `get_packets_to_send(&mut self) -> Vec`: Retrieves raw packets that need to be sent to the server. - `is_connected(&self) -> bool`: Checks if the client is currently connected to the server. - `network_info(&self) -> NetworkInfo`: Returns network statistics for the client connection. ``` -------------------------------- ### Manage RenetServer Client Connections Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/renet-core-api.md Add, remove, or disconnect clients from the server. Check connection status. ```rust pub fn add_connection(&mut self, client_id: ClientId) pub fn remove_connection(&mut self, client_id: ClientId) pub fn disconnect(&mut self, client_id: ClientId) pub fn disconnect_all(&mut self) pub fn is_connected(&self, client_id: ClientId) -> bool pub fn has_connections(&self) -> bool ``` ```rust server.disconnect(client_id); server.disconnect_all(); ``` -------------------------------- ### ConnectionConfig Structure Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/types.md Defines the configuration parameters for establishing a Renet connection, including bandwidth limits and channel settings. ```APIDOC ## ConnectionConfig Structure ### Description Configuration parameters for establishing a Renet connection, including bandwidth limits and channel settings. ### Fields - `available_bytes_per_tick` (u64): Bandwidth limit per update tick in bytes. - `server_channels_config` (Vec): Configuration for server-to-client channels. - `client_channels_config` (Vec): Configuration for client-to-server channels. ### Default 60,000 bytes/tick with 3 default channels each. ``` -------------------------------- ### Configure Bandwidth Distribution Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/configuration.md Sets up connection configuration with specific bandwidth allocations for three channels. Each channel is assigned a percentage of the total available bytes per tick. ```rust let config = ConnectionConfig { available_bytes_per_tick: 60_000, server_channels_config: vec![ // Channel 0: 40% of bandwidth ChannelConfig { channel_id: 0, max_memory_usage_bytes: 10 * 1024 * 1024, send_type: SendType::Unreliable, }, // Channel 1: 30% of bandwidth ChannelConfig { channel_id: 1, max_memory_usage_bytes: 5 * 1024 * 1024, send_type: SendType::ReliableUnordered { resend_time: Duration::from_millis(300) }, }, // Channel 2: 30% of bandwidth ChannelConfig { channel_id: 2, max_memory_usage_bytes: 5 * 1024 * 1024, send_type: SendType::ReliableOrdered { resend_time: Duration::from_millis(300) }, }, ], ..Default::default() }; ``` -------------------------------- ### Use Built-in Run Conditions Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Employ provided run conditions like `client_connected` for systems instead of implementing custom logic. ```rust // Use provided conditions instead of custom logic app.add_systems( Update, gameplay_system.run_if(client_connected), ); ``` -------------------------------- ### Configure Netcode Transport (UDP) Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/quick-reference.md Set up and update the Netcode UDP transport for client connections. ```rust use renet_netcode::{NetcodeClientTransport, ClientAuthentication}; use std::net::UdpSocket; use std::time::SystemTime; let socket = UdpSocket::bind("127.0.0.1:0")?; let auth = ClientAuthentication::Unsecure { server_addr: "127.0.0.1:5000".parse()?, client_id: 0, user_data: None, protocol_id: 0, }; let current_time = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH)?; let mut transport = NetcodeClientTransport::new(current_time, auth, socket)?; // In loop transport.update(delta, &mut client)?; transport.send_packets(&mut client)?; ``` -------------------------------- ### Integrate Netcode Transport Layer Source: https://github.com/lucaspoffo/renet/blob/master/_autodocs/bevy-renet-integration.md Set up RenetClientPlugin with a RenetClient and NetcodeClientTransport. Systems are added to handle transport updates and packet sending. ```rust use bevy::prelude::*; use bevy_renet::{RenetClientPlugin, RenetReceive, RenetSend}; use renet::RenetClient; use renet_netcode::NetcodeClientTransport; fn main() { App::new() .add_plugins(RenetClientPlugin) .insert_resource(RenetClient::new(Default::default())) .insert_resource(/* NetcodeClientTransport setup */) .add_systems(PreUpdate, transport_update.in_set(RenetReceive)) .add_systems(PostUpdate, transport_send.in_set(RenetSend)) .run(); } fn transport_update( mut client: ResMut, mut transport: ResMut, ) { transport.update(/* delta */, &mut client).ok(); } fn transport_send( mut client: ResMut, mut transport: ResMut, ) { transport.send_packets(&mut client).ok(); } ```