bevy_renet

Crates.iobevy_renet
lib.rsbevy_renet
version
sourcesrc
created_at2022-04-30 20:53:02.104786+00
updated_at2024-12-24 18:55:50.9129+00
descriptionBevy plugin for the renet crate: Server/Client network library for multiplayer games with authentication and connection management
homepage
repositoryhttps://github.com/lucaspoffo/renet
max_upload_size
id578327
Cargo.toml error:TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
(lucaspoffo)

documentation

README

Bevy Renet

Latest version Documentation MIT Apache

A Bevy Plugin for the renet crate. A network crate for Server/Client with cryptographically secure authentication and encrypted packets. Designed for fast-paced competitive multiplayer games.

Usage

Bevy renet is a small layer over the renet crate, it adds systems to call the update function from the client/server. RenetClient, RenetServer, NetcodeClientTransport and NetcodeServerTransport need to be added as a resource, so the setup is similar to renet itself:

Server

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);
}

// Systems

fn send_message_system(mut server: ResMut<RenetServer>) {
    let channel_id = 0;
    // Send a text message for all clients
    // The enum DefaultChannel describe the channels used by the default configuration
    server.broadcast_message(DefaultChannel::ReliableOrdered, "server message");
}

fn receive_message_system(mut server: ResMut<RenetServer>) {
    // Receive message from all clients
    for client_id in server.clients_id() {
        while let Some(message) = server.receive_message(client_id, DefaultChannel::ReliableOrdered) {
            // Handle received message
        }
    }
}

fn handle_events_system(mut server_events: EventReader<ServerEvent>) {
    for event in server_events.read() {
        match event {
            ServerEvent::ClientConnected { client_id } => {
                println!("Client {client_id} connected");
            }
            ServerEvent::ClientDisconnected { client_id, reason } => {
                println!("Client {client_id} disconnected: {reason}");
            }
        }
    }
}

Client

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);
}

// Systems

fn send_message_system(mut client: ResMut<RenetClient>) {
    // Send a text message to the server
    client.send_message(DefaultChannel::ReliableOrdered, "server message");
}

fn receive_message_system(mut client: ResMut<RenetClient>) {
    while let Some(message) = client.receive_message(DefaultChannel::ReliableOrdered) {
        // Handle received message
    }
}

Example

You can run the simple example with:

  • Server: cargo run --features="netcode" --example simple -- server
  • Client: cargo run --features="netcode" --example simple -- client

If you want a more complex example you can checkout the demo_bevy sample:

Bevy Demo.webm

Bevy Compatibility

bevy bevy_renet
0.15 1.0
0.14 0.0.12
0.13 0.0.11
0.12 0.0.10
0.11 0.0.9
0.10 0.0.8
0.9 0.0.6
0.8 0.0.5
0.7 0.0.4

Steam

By default bevy_renet uses renet_netcode as the transport layer, but you can also use the steam transport layer if you wish by enabling the steam feature.

This adds the transport structs SteamServerTransport, SteamClientTransport and the bevy plugins SteamServerPlugin, SteamClientPlugin, the setup should be similar to default transport layer.

You can check the Bevy Demo for how to use the default and steam transport switching between them using feature flags.

Custom Schedules

If you want more control over how renet is run, instead of adding the RenetServerPlugin, RenetClientPlugin, you can manually setup the functions they implement (they are all public). Make sure to also setup the plugins for the desired Transport layer.

Commit count: 505

cargo fmt