Renet

Latest version Documentation MIT Apache

Renet is a network library for Server/Client games written in rust. It is focused on fast-paced games such as FPS, and competitive games. Provides the following features:

Channels

Renet communication is message based, and channels describe how the messages should be delivered. Channels are unilateral, ConnectionConfig.client_channels_config describes the channels that the clients sends to the server, and ConnectionConfig.server_channels_config describes the channels that the server sends to the clients.

Each channel has its own configuration ChannelConfig:

```rust // No garantee of message delivery or order let sendtype = SendType::Unreliable; // Garantee of message delivery and order let sendtype = SendType::ReliableOrdered { // If a message is lost, it will be resent after this duration resendtime: Duration::frommillis(300) };

// Garantee of message delivery but not order let sendtype = SendType::ReliableUnordered { resendtime: Duration::from_millis(300) };

let channelconfig = ChannelConfig { // The id for the channel, must be unique within its own list, // but it can be repeated between the server and client lists. channelid: 0, // Maximum number of bytes that the channel may hold without acknowledgement of messages before becoming full. maxmemoryusagebytes: 5 * 1024 * 1024, // 5 megabytes sendtype }; ```

Usage

Renet aims to have a simple API that is easy to integrate with any code base. Pool for new messages at the start of a frame with update. Call send_packets from the transport layer to send packets to the client/server.

Server

```rust let mut server = RenetServer::new(ConnectionConfig::default());

// Setup transport layer const SERVERADDR: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1), 5000)); let socket: UdpSocket = UdpSocket::bind(SERVERADDR).unwrap(); let serverconfig = ServerConfig { maxclients:64 protocolid: 0, publicaddr: SERVERADDR, authentication: ServerAuthentication::Unsecure }; let currenttime = SystemTime::now().durationsince(SystemTime::UNIXEPOCH).unwrap(); let mut transport = NetcodeServerTransport::new(currenttime, serverconfig, socket).unwrap();

// Your gameplay loop loop { let deltatime = Duration::frommillis(16); // Receive new messages and update clients server.update(deltatime)?; transport.update(deltatime, &mut server)?;

// Check for client connections/disconnections
while let Some(event) = server.get_event() {
    match event {
        ServerEvent::ClientConnected { client_id } => {
            println!("Client {client_id} connected");
        }
        ServerEvent::ClientDisconnected { client_id, reason } => {
            println!("Client {client_id} disconnected: {reason}");
        }
    }
}

// Receive message from channel
for client_id in server.connections_id() {
    // The enum DefaultChannel describe the channels used by the default configuration
    while let Some(message) = server.receive_message(client_id, DefaultChannel::ReliableOrdered) {
        // Handle received message
    }
}

// Send a text message for all clients
server.broadcast_message(DefaultChannel::ReliableOrdered, "server message".as_bytes().to_vec());

// Send message to only one client
let client_id = 0; 
server.send_message(client_id, DefaultChannel::ReliableOrdered, "server message".as_bytes().to_vec());

// Send packets to clients
transport.send_packets(&mut server);

} ```

Client

```rust let mut client = RenetClient::new(ConnectionConfig::default());

// Setup transport layer const SERVERADDR: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1), 5000)); let socket = UdpSocket::bind("127.0.0.1:0").unwrap(); let currenttime = SystemTime::now().durationsince(SystemTime::UNIXEPOCH).unwrap(); let clientid: u64 = 0; let authentication = ClientAuthentication::Unsecure { serveraddr: SERVERADDR, clientid, userdata: None, protocolid: 0, };

let mut transport = NetcodeClientTransport::new(current_time, authentication, socket).unwrap();

// Your gameplay loop loop { let deltatime = Duration::frommillis(16); // Receive new messages and update client client.update(deltatime)?; transport.update(deltatime, &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".as_bytes().to_vec());
}

// Send packets to server
transport.send_packets(&mut client)?;

} ```

Demos

You can checkout the echo example for a simple usage of the library. Or you can look into the two demos that have more complex uses of renet:

Bevy Demo
Simple bevy application to demonstrate how you could replicate entities and send reliable messages as commands from the server/client using renet:

Bevy Demo.webm

Repository

Chat Demo
Simple chat application made with egui to demonstrate how you could handle errors, states transitions and client self hosting:

Chat Demo.webm

Repository

Plugins

Checkout bevy_renet if you want to use renet as a plugin with the Bevy engine.

Visualizer

Checkout renet_visualizer for a egui plugin to plot metrics data from renet clients and servers:

https://user-images.githubusercontent.com/35241085/175834010-b1eafd77-7ea2-47dc-a915-a399099c7a99.mp4