A cross platform (wasm included) networking library!
A networking plugin for the Bevy game engine that wraps around bevy_networking_turbulence and a custom TCP/UDP network server in order to make writing cross-platform multiplayer games fun and easy!
Currently, the library is not published on crates.io, due to a few forks of other popular libraries it currently uses. Because of this, in order to use the libary, you must specify it as a git dependency
[dependencies]
bootleg_networking = { version = "0.2", git = "https://github.com/billyb2/bootleg_networking" }
If you want to use this library with wasm, you should disable the native feature and enable the web feature
[dependencies]
bootleg_networking = { version = "0.2", git = "https://github.com/billyb2/bootleg_networking", default-features = false, features = ["web"]}
I recommend pinning to a specific version, since library stability can change at any time.
Below is an example of how to use this library. It mainly shows how to setup a basic server, although a client is nearly identical
use std::sync::Arc;
use bevy::prelude::*;
use bevy::tasks::IoTaskPool;
use bootleg_networking::*;
const MESSAGE_CHANNEL_ID: MessageChannelID = MessageChannelID::new(0);
const MESSAGE_SETTINGS: MessageChannelSettings = MessageChannelSettings {
channel: MESSAGE_CHANNEL_ID.id,
channel_mode: MessageChannelMode::Unreliable {
settings: turbulence::unreliable_channel::Settings {
bandwidth: 4096,
burst_bandwidth: 1024,
},
max_message_len: 256,
},
message_buffer_size: 256,
packet_buffer_size: 256,
};
fn main() {
let mut app = App::new();
app
.add_plugins(MinimalPlugins)
.add_plugin(NetworkingPlugin)
.add_startup_system(setup)
.add_system(send)
.add_system(receive);
//Uncomment the line below!
//app.run();
}
fn setup(mut commands: Commands, tokio_rt: Res<Runtime>, task_pool: Res<IoTaskPool>) {
// First we need to actually initiate the NetworkReource. In this case, it's a server
// We could use the new_client function if wanted a client
let mut net = NetworkResource::new_server(tokio_rt.clone(), task_pool.0.clone());
// Next, we need tell the server to setup listening
// The equivalent function for clients is connect
// Listen on ports 9000 for TCP and 9001 for UDP, and 9003
// The first address is the one that the connect() function needs to use, and the other two are for WebRTC
// Finally, the last argument is the maximum size of each packet. That argument is only necessary for native builds
let listen_config = ListenConfig {
tcp_addr: "127.0.0.1:9000",
udp_addr: "127.0.0.1:9001",
naia_addr: "127.0.0.1:9003",
webrtc_listen_addr: "127.0.0.1:9004",
public_webrtc_listen_addr: "127.0.0.1:9004",
};
net.listen(listen_config, Some(2048));
// If we were calling net.connect, the first argument we would either have 9000 or 9003 as the port, depending on whether we were a native client or a web client
// The second argument is only necessary on native builds, and it's asking for the UDP server SocketAddr
/* let connect_config = ConnectConfig {
* addr: "127.0.0.1:9000",
* udp_addr: Some("127.0.0.1:9001"),
* };
*
* net.connect(connect_config, Some(2048));
*/
// We need to register for the native tcp/udp server and for naia seperately
// Native registration
net.register_message_channel_native(MESSAGE_SETTINGS, &MESSAGE_CHANNEL_ID).unwrap();
// Naia registration
net.set_channels_builder(|builder: &mut ConnectionChannelsBuilder| {
builder
.register::<String>(MESSAGE_SETTINGS)
.unwrap();
});
// Finally, insert the network resource so it can be used by other systems
commands.insert_resource(net);
}
// The following two functions are equivalent for both clients and servers, provided you've set up the NetworkResource properly
fn send(mut net: ResMut<NetworkResource>) {
let message = String::from("Hello world");
net.broadcast_message(&message, &MESSAGE_CHANNEL_ID).unwrap();
}
fn receive(mut net: ResMut<NetworkResource>) {
let messages = net.view_messages::<String>(&MESSAGE_CHANNEL_ID).unwrap();
for (_handle, message) in messages.iter() {
println!("{}", message);
}
}
@totalkrill noticed that when attempting to send a message larger than 1095 bytes, the message wouldn't go through. This is due to a limitation in WebRTC that doesn't allow messages larger than 1200 bytes (which 1095 bytes + any overhead in the WebRTC protocol and anything Naia adds would definetly do). The NetworkResource will return an error upon trying to send a message above that size when sending it through Naia, though there isn't an issue on the TCP/UDP front. Just be warned though, that if you're trying to have cross platform compatibility, messages should be under that size.
Simply run cargo doc
in the terminal. If you want to view the documentation for the web version of this crate, then run cargo doc --no-default-features --features web
While working with the wonderful bevy_networking_turbulence library, I realized that I wasn't able to create network clients on anything other than wasm. While it is doable using the fantastic new WebRTC-rs library (and I even attempted it, it still currently isn't possible. After a lot of effort, I eventually gave up, and decided instead to write this library. While initially, it was just for internal use in a project I'm workin on, I realized that it would have a lot of potential as a public library.