Crate bevy_eventwork

source ·
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 the EventworkPlugin to the respective bevy app with the runtime you wish to use and the networking provider you wish to use. Next add your runtime to the app as the EventworkRuntime Resource. Then, register which kind of messages can be received through managers::network::AppNetworkMessage::listen_for_message, as well as which provider you wantto handle these messages and you can start receiving packets as events of NetworkData<T>.

This plugin also supports Request/Response style messages, see that modules documentation for further info: Request Documentation

§Example Client

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

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

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

fn main() {
     let mut app = App::new();
     app.add_plugins(EventworkPlugin::<
        TcpProvider,
        bevy::tasks::TaskPool,
    >::default());

    //Insert our runtime and the neccessary settings for the TCP transport
    app.insert_resource(EventworkRuntime(
        TaskPoolBuilder::new().num_threads(2).build(),
    ));
    app.insert_resource(NetworkSettings::default());

    // We are receiving this from the server, so we need to listen for it
     app.listen_for_message::<WorldUpdate, TcpProvider>();
     app.add_systems(Update, (handle_world_updates,handle_connection_events));
}

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

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

§Example Server

use bevy::prelude::*;
use bevy_eventwork::{EventworkRuntime,
    EventworkPlugin, NetworkData, NetworkMessage, Network, NetworkEvent, AppNetworkMessage,
    tcp::TcpProvider,tcp::NetworkSettings
};
use bevy::tasks::TaskPoolBuilder;
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_plugins(EventworkPlugin::<
        TcpProvider,
        bevy::tasks::TaskPool,
    >::default());


    //Insert our runtime and the neccessary settings for the TCP transport
    app.insert_resource(EventworkRuntime(
        TaskPoolBuilder::new().num_threads(2).build(),
    ));
    app.insert_resource(NetworkSettings::default());

     // We are receiving this from a client, so we need to listen for it!
     app.listen_for_message::<UserInput, TcpProvider>();
     app.add_systems(Update, (handle_world_updates,handle_connection_events));
}

fn handle_world_updates(
    mut chunk_updates: EventReader<NetworkData<UserInput>>,
) {
    for chunk in chunk_updates.read() {
        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.read() {
        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§

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§

Enums§

  • A network event originating from another eventwork app

Traits§

Attribute Macros§