Crate bevy_spicy_networking[][src]

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