A simple message based networking library for the bevy framework

Overview

Spicy Networking for Bevy

crates.io docs.rs spicy

bevy_spicy_networking is a solution to the "How do I connect multiple clients to a single server" problem in your bevy games.


Using tokio as the asynchronous backend, it fully integrates into bevy to allow you to quickly add networking to your game. Simply add either the server/client plugins, register the types of messages you plan on receiving and listen for them as events!

It is meant as a unifying crate for networking. Other crates can extend your game by registering their own messages. This is achieved through the amazing typetag crate.


Contents

Documentation

You can check out the online documentation, or build it yourself by cloning this repo and running cargo doc -p bevy_spicy_networking.

For examples, check out the examples directory.

  • In server.rs you will find a simple chat server, that broadcasts the messages it receives from clients
  • In client.rs you will find a simple graphical chat client, where you can connect to a server and send messages to

(Note: Since bevy does not include a text input widget, it is a very simplified demo. This should be easy to extend once the UI part of bevy is more complete.)

Quickstart

  1. Add bevy_spicy_networking, serde_derive and typetag to your Cargo.toml
  2. Create the messages you wish to exchange beetween a client and server, or vice-versa.
    • Implement Serialize and Deserialize from Serde on it
    • Implement NetworkMessage, and make sure to annotate it with typetag::serde
    • Implement ServerMessage when it is sent to the server from a client
    • Implement ClientMessage when it is sent to a client from the server
#[derive(Serialize, Deserialize)]
struct WhisperMessage {
    recipient: UserId,
    message: String,
}

#[typetag::serde]
impl NetworkMessage for WhisperMessage {}

// In this case, its a client sending a message to a server
impl ServerMessage for WhisperMessage {
    const NAME: &'static str = "example:WhisperMessage"; // This name needs to be unique!
    // Otherwise, the recipient will mix up the messages
}
  1. On the recipient side, register the type to be received
use bevy_spicy_networking::AppNetworkServerMessage;

let appbuilder: &mut AppBuilder = /* Get an AppBuilder, which is returned by bevy from App::build() */;


// Now whenever a client sends a `WhisperMessage` the server will generate an event of
// `NetworkData` which your application can then handle
appbuilder.listen_for_server_message::();
  1. Listen for events of that type
fn handle_incoming_whisper_messages(
    mut whisper_messages: EventReader>,
) {
    for whisper_message in whisper_messages.iter() {
        // Handle the whisper
    }
}
  1. Enjoy easy and 🌶 networking in your game!

Bevy Version Compatibility

Simply pick the version compatible to your bevy version:

Bevy Spicy Networking Bevy
0.5 0.5

Any version that is not compatible with the latest bevy version is in maintenance mode. It will only receive minor bug fixes from my side, or community supplied ones.

Supported Platforms

Currently only Linux and Windows are officially supported, I don't see why MacOS wouldn't be, but I do not have a Mac to test. If you have a Mac, and wish to test it out and report back, please let me know!

Roadmap

Currently bevy_spicy_networking uses TCP only. This will change at some point, with individual messages being able to specify how they should be delivered. This change will be compatible, or with only minor changes necessary.

Crates using bevy_spicy_networking

Currently none, you can help by expanding this list. Just send a PR and add it to the table below!

Name Version
- -

Contributing

To contribute, simply fork the repository and send a PR. Feel free to chat me up on the bevy discord under @Hemera#2040 if you have any questions or suggestions.

Comments
  • Cannot send message with String value

    Cannot send message with String value

    I'm unable to receive messages through bevy_spicy_networking that contain strings- I've sent and received empty messages and messages with u8 values, and so far this issue only occurs with string messages (video).

    See this issue that I submitted to erased-serde for error messages etc. I'm not sure if I've done something wrong, if this is an issue with bevy_spicy_networking or erased-serde.

    If it's a bug it seems like a bad one. You can clone and build warfare-rs (at this commit) if you need to reproduce. The messages are defined in networking/messages.rs, and the actual send/receive code is in systems/network.rs.

    (there are some dependencies to build warfare, check the readme)

    opened by mjhouse 4
  • It's impossible to aquire ownership of incoming `MyData`

    It's impossible to aquire ownership of incoming `MyData`

    Since NetworkData does not implement Clone, it is impossible to acquire ownership of inner as one has only access through EventReader::iter() which hides e behind a reference. Thus, into_inner cannot be called.

    fn handle(mut incoming: EventReader<NetworkData<MyData>>){
        for e in incoming.iter(){ // e:&NetworkData<MyData>
            // I want to retrieve e (and use it elsewhere)
            let data: MyData = e.into_inner(); // errors: cannot move
            let data: MyData = e.inner; // errors: inner is private
        }
    }
    

    I would propose making inner public.

    edit: What I want is to clone inner :)

    opened by KuSpa 4
  • Make `AppNetwork---Message` consistent with `AppBuilder` API

    Make `AppNetwork---Message` consistent with `AppBuilder` API

    This PR provides a small QoL improvement by allowing the user to chain registering ServerMessages (or ClientMessages). This is helpful when using listen_for_XXX_message::<T>() in for example Plugins or just having a lot of different Messagetypes to initialize. It furthermore resembles the API of the Appbuilder, which is IMHO desirable.

    opened by KuSpa 3
  • Can a server receive it's own messages?

    Can a server receive it's own messages?

    I'm working on a game in which players can play with each other on a LAN, with anyone acting as the server. Practically, what this means is that the server is also acting as a client, and should react to messages broadcast by itself exactly as a client would.

    I've experimented a little with different arrangements, but there's a lot of code duplication because the server can't receive it's own messages. If NetworkData had a public new method, for example, I could insert the events myself when they are sent, and then the same systems that the client is using to receive messages would be used for reacting to local messages.

    I can't find any easy way to do this that doesn't look like a maintenance nightmare down the road. Does anyone have any pointers?

    opened by mjhouse 1
  • Use Single Buffer For Sending Packets

    Use Single Buffer For Sending Packets

    Prior to this a new heap allocation is made every time you encode a packet to be sent on the socket. This change allocates a buffer the max size specified by the network settings and it is used to dump the encoded bytes into before being written by the socket.

    I also cleaned up the receive buffer a little; while it wasn't much, it seems to save a few extra asm instructions :)

    I tested this with the server/client examples and it seemed to work.


    This introduces a crate compile feature flag to set the packet size headers down to u16 instead of relying on the u32 default. I added this as the client I wish to interfact with expects these to be u16; however, for a lot of games you probably won't need u32 as those are some big packets :smile:


    Screenshot of examples after changes:

    image

    opened by benfalk 1
  • Updated to Bevy 0.9, updated crates, update rust to 2021

    Updated to Bevy 0.9, updated crates, update rust to 2021

    Fixed/Updated

    • Updated the project to Bevy 0.9,
    • Updated the other dependent crates
    • Updated the Rust version to 2021
    • Fixed miscellaneous documentation misspellings.
    • Bumped the version number to 0.5.2.

    The examples work for the local multiplayer however I am unable to test the external networking so that would be appreciated if anyone else can

    opened by NoahShomette 0
  • Feature/provider driver model

    Feature/provider driver model

    I'm proposing a new model for bevy spicy networking that will allow users to bring they're own transport layer, this will enable users to use udp or tcp based protocols (or really anything they can get to work), without adding too much overhead, and still keeping all the convenience of spicy. This is gonna need some more changes and docs to be a little bit nicer, but it does work! Here's an example using a udp (via QUIC) based provider that's nearly working (I don't completely understand the protocol, but it does compile and allow us to send messages, it:

    https://github.com/jamescarterbell/bevy_spicy_networking_tokio_quinn

    opened by jamescarterbell 1
  • Other Stream Types

    Other Stream Types

    Currently Spicy Networking is very cool, but is bound to only using TCPStream, I don't think it will be to turn this crate into a driver for different providers of streams and such, mainly because the Server and Client are essentially holding JoinHandles for tasks that could be swapped out for tasks using different channel types. I'm going to play around with this and see where it goes.

    opened by jamescarterbell 0
  • Version bump and small cleanup on one sync channel

    Version bump and small cleanup on one sync channel

    The new_connections channel seemed to be sending a Result instead of just the new connections, I'm not seeing a real reason why we can't move that logic into the listen loop so I did that. Feel free to deny, that's the only difference between this one and the other version bump pr.

    opened by jamescarterbell 0
Releases(v0.5.2)
Owner
Cabbit Studios
Cabbit Studios
Backroll is a pure Rust implementation of GGPO rollback networking library.

backroll-rs Backroll is a pure Rust implementation of GGPO rollback networking library. Development Status This is still in an untested alpha stage. A

Hourai Teahouse 273 Dec 28, 2022
Cross-platform, low level networking using the Rust programming language.

libpnet Linux ∪ OS X Build Status: Windows Build Status: Discussion and support: #libpnet on freenode / #rust-networking on irc.mozilla.org / #rust on

null 1.8k Jan 6, 2023
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...

Tokio A runtime for writing reliable, asynchronous, and slim applications with the Rust programming language. It is: Fast: Tokio's zero-cost abstracti

Tokio 18.7k Dec 30, 2022
The Rust Implementation of libp2p networking stack.

Central repository for work on libp2p This repository is the central place for Rust development of the libp2p spec. Warning: While we are trying our b

libp2p 3k Jan 4, 2023
Painless peer-to-peer WebRTC networking for rust wasm

Matchbox Painless peer-to-peer WebRTC networking for rust wasm applications. The goal of the Matchbox project is to enable udp-like, unordered, unreli

Johan Klokkhammer Helsing 363 Jan 5, 2023
Final Project for "Computer Networking Security": A Layer-3 VPN implementation over TLS

Final Project for "Computer Networking Security": A Layer-3 VPN implementation over TLS

Siger Yang 2 Jun 7, 2022
pam-send-slack-message is a program that publishes messages on slack when a linux server is accessed through ssh.

pam-send-slack-message pam-send-slack-message is a program that publishes messages on slack when the linux server is accessed through ssh. Installatio

Iuri Diniz 2 Aug 17, 2022
The Safe Network Core. API message definitions, routing and nodes, client core api.

safe_network The Safe Network Core. API message definitions, routing and nodes, client core api. License This Safe Network repository is licensed unde

MaidSafe 101 Dec 19, 2022
Fullstack development framework for UTXO-based dapps on Nervos Network

Trampoline-rs The framework for building powerful dApps on the number one UTXO chain, Nervos Network CKB. This is an early-stage, currently very incom

TannrA 2 Mar 25, 2022
Astar Network is an interoperable blockchain based the Substrate framework and the hub for dApps within the Polkadot Ecosystem

Astar Network is an interoperable blockchain based the Substrate framework and the hub for dApps within the Polkadot Ecosystem. With Astar Network and

Astar Network (Plasm) 43 Dec 14, 2022
Bevy asset loader that transparently supports loading over http(s)

Bevy Web Asset This is a tiny crate that that wraps the standard bevy asset loader, and adds the ability to load assets from http and https urls. Supp

Johan Klokkhammer Helsing 28 Jan 2, 2023
Client-server architecture for Bevy

Sabi Opinionated client-server architecture for Bevy Goals: Prediction based on inputs Replication by a simple derive and adding a system to server/cl

Aceeri 10 Nov 14, 2022
A simple configuration-based module for inter-network RPC in Holochain hApps.

DNA Auth Resolver A simple configuration-based module for inter-network RPC in Holochain hApps. About Usage In the origin zome In the destination DNA

Shadman Baig 0 Feb 4, 2022
Peer-to-peer communications library for Rust based on QUIC protocol

qp2p Crate Documentation MaidSafe website SAFE Dev Forum SAFE Network Forum Overview This library provides an API to simplify common tasks when creati

MaidSafe 337 Dec 14, 2022
Tachyon is a performant and highly parallel reliable udp library that uses a nack based model

Tachyon Tachyon is a performant and highly parallel reliable udp library that uses a nack based model. Strongly reliable Reliable fragmentation Ordere

Chris Ochs 47 Oct 15, 2022
A generic Rust based Bigtable connection library implemented using gRPC

A generic Rust based Bigtable connection library refactored out the solana mono-repo so that can be shared for different applications.

Lijun Wang 3 Sep 25, 2022
Modrinth API is a simple library for using Modrinth's API in Rust projects

Ferinth is a simple library for using the Modrinth API in Rust projects. It uses reqwest as its HTTP(S) client and deserialises responses to typed structs using serde.

null 20 Dec 8, 2022
A simple web server(and library) to display server stats over HTTP and Websockets/SSE or stream it to other systems.

x-server-stats A simple web server(and library) to display server stats over HTTP and Websockets/SSE or stream it to other systems. x-server(in x-serv

Pratyaksh 11 Oct 17, 2022
Actor framework for Rust.

Actix Actor framework for Rust Documentation User Guide API Documentation API Documentation (master branch) Features Async and sync actors Actor commu

Actix 7.6k Jan 7, 2023