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 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
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
NetworkPacket
s 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