Crate bevy_spicy_networking

Source
Expand description

A spicy simple networking plugin for Bevy

Using this plugin is meant to be straightforward. You have one server and multiple clients. You simply add either the ClientPlugin or the ServerPlugin to the respective bevy app, register which kind of messages can be received through listen_for_client_message or listen_for_server_message (provided respectively by AppNetworkClientMessage and AppNetworkServerMessage) and you can start receiving packets as events of NetworkData<T>.

§Example Client

use bevy::prelude::*;
use bevy_spicy_networking::{ClientPlugin, NetworkData, NetworkMessage, ServerMessage, ClientNetworkEvent, AppNetworkServerMessage};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct WorldUpdate;

#[typetag::serde]
impl NetworkMessage for WorldUpdate {}

impl ServerMessage for WorldUpdate {
    const NAME: &'static str = "example:WorldUpdate";
}

fn main() {
     let mut app = App::build();
     app.add_plugin(ClientPlugin);
     // We are receiving this from the server, so we need to listen for it
     app.listen_for_server_message::<WorldUpdate>();
     app.add_system(handle_world_updates.system());
     app.add_system(handle_connection_events.system());
}

fn handle_world_updates(
    mut chunk_updates: EventReader<NetworkData<WorldUpdate>>,
) {
    for chunk in chunk_updates.iter() {
        info!("Got chunk update!");
    }
}

fn handle_connection_events(mut network_events: EventReader<ClientNetworkEvent>,) {
    for event in network_events.iter() {
        match event {
            &ClientNetworkEvent::Connected => info!("Connected to server!"),
            _ => (),
        }
    }
}

§Example Server

use bevy::prelude::*;
use bevy_spicy_networking::{ServerPlugin, NetworkData, NetworkMessage, NetworkServer, ServerMessage, ClientMessage, ServerNetworkEvent, AppNetworkClientMessage};

use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct UserInput;

#[typetag::serde]
impl NetworkMessage for UserInput {}

impl ClientMessage for UserInput {
    const NAME: &'static str = "example:UserInput";
}

fn main() {
     let mut app = App::build();
     app.add_plugin(ServerPlugin);
     // We are receiving this from a client, so we need to listen for it!
     app.listen_for_client_message::<UserInput>();
     app.add_system(handle_world_updates.system());
     app.add_system(handle_connection_events.system());
}

fn handle_world_updates(
    net: Res<NetworkServer>,
    mut chunk_updates: EventReader<NetworkData<UserInput>>,
) {
    for chunk in chunk_updates.iter() {
        info!("Got chunk update!");
    }
}

#[derive(Serialize, Deserialize)]
struct PlayerUpdate;

#[typetag::serde]
impl NetworkMessage for PlayerUpdate {}

impl ClientMessage for PlayerUpdate {
    const NAME: &'static str = "example:PlayerUpdate";
}

impl PlayerUpdate {
    fn new() -> PlayerUpdate {
        Self
    }
}

fn handle_connection_events(
    net: Res<NetworkServer>,
    mut network_events: EventReader<ServerNetworkEvent>,
) {
    for event in network_events.iter() {
        match event {
            &ServerNetworkEvent::Connected(conn_id) => {
                net.send_message(conn_id, PlayerUpdate::new());
                info!("New client connected: {:?}", conn_id);
            }
            _ => (),
        }
    }
}

As you can see, they are both quite similar, and provide everything a basic networked game needs.

For a more

§Caveats

Currently this library uses TCP under the hood. Meaning that it has all its drawbacks, where for example a very large update packet can ‘block’ the connection. This is currently not built for fast-paced games that are not meant to be played on LAN, but should suffice for slow-paced games where less-stringent latency delays might be acceptable.

Structs§

ClientPlugin
The plugin to add to your bevy AppBuilder when you want to instantiate a client
ConnectionId
A ConnectionId denotes a single connection
NetworkClient
An instance of a NetworkClient is used to connect to a remote server using NetworkClient::connect
NetworkData
NetworkData is what is sent over the bevy event system
NetworkServer
An instance of a NetworkServer is used to listen for new client connections using NetworkServer::listen
NetworkSettings
Settings to configure the network, both client and server
ServerPlugin
The plugin to add to your bevy AppBuilder when you want to instantiate a server

Enums§

ClientNetworkEvent
A network event originating from a NetworkClient
ServerNetworkEvent
A network event originating from a NetworkServer

Traits§

AppNetworkClientMessage
A utility trait on AppBuilder to easily register ClientMessages
AppNetworkServerMessage
A utility trait on AppBuilder to easily register ServerMessages
ClientMessage
A marker trait to signal that this message should be sent to a client
NetworkMessage
Any type that should be sent over the wire has to implement NetworkMessage.
ServerMessage
A marker trait to signal that this message should be sent to a server