Expand description

A simple networking plugin for Bevy designed to work with Bevy’s event architecture.

Using this plugin is meant to be straightforward and highly configurable. You simply add either the EventworkPlugin to the respective bevy app, the runtime you wish to use, and the networking provider you wish to use. Then, register which kind of messages can be received through managers::network::AppNetworkMessage::listen_for_message, as well as which provider you want to handle these messages and you can start receiving packets as events of NetworkData<T>.

Example Client

use bevy::prelude::*;
use bevy_eventwork::{EventworkPlugin, NetworkData, NetworkMessage, NetworkEvent, AppNetworkMessage, tcp::TcpProvider};
use serde::{Serialize, Deserialize};

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

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

fn main() {
     let mut app = App::new();
     app.add_plugin(EventworkPlugin::<
        TcpProvider,
        bevy::tasks::TaskPool,
    >::default());
     // We are receiving this from the server, so we need to listen for it
     app.listen_for_message::<WorldUpdate, TcpProvider>();
     app.add_system(handle_world_updates);
     app.add_system(handle_connection_events);
}

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<NetworkEvent>,) {
    for event in network_events.iter() {
        match event {
            &NetworkEvent::Connected(_) => info!("Connected to server!"),
            _ => (),
        }
    }
}

Example Server

use bevy::prelude::*;
use bevy_eventwork::{
    EventworkPlugin, NetworkData, NetworkMessage, Network, NetworkEvent, AppNetworkMessage,
    tcp::TcpProvider,
};

use serde::{Serialize, Deserialize};

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

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

fn main() {
     let mut app = App::new();
     app.add_plugin(EventworkPlugin::<
        TcpProvider,
        bevy::tasks::TaskPool,
    >::default());
     // We are receiving this from a client, so we need to listen for it!
     app.listen_for_message::<UserInput, TcpProvider>();
     app.add_system(handle_world_updates);
     app.add_system(handle_connection_events);
}

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

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

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

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

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

Currently, Bevy’s [TaskPool] is the default runtime used by Eventwork.

Re-exports

pub use managers::network::AppNetworkMessage;
pub use managers::Network;
pub use async_channel;

Modules

Contains error enum.

Contains all functionality for starting a server or client, sending, and recieving messages from clients.

A default tcp provider to help get you started.

Structs

A ConnectionId denotes a single connection

The plugin to add to your bevy App when you want to instantiate a server

NetworkData is what is sent over the bevy event system

NetworkPackets are untyped packets to be sent over the wire

Enums

A network event originating from a [NetworkClient]

Traits

Any type that should be sent over the wire has to implement NetworkMessage.

A runtime abstraction allowing you to use any runtime for spicy

Attribute Macros