#Are there any cross platform peer-to-peer networking clients?

54 messages · Page 1 of 1 (latest)

lilac bough
#

I want to create a multiplayer game where any player can host the game and other clients can connect to them (aka peer-to-peer) from either a web client or native client (aka cross platform). The only library I've found that seems to check all the boxes is bootleg_networking, but it relies on bevy_networking_turbulence which has been archived for a while now, and " a few forks of other popular libraries", so I'm a little concerned about that. GGRS might fit, but I don't need rollback networking (this is going to be a pretty casual experience). I wouldn't mind using GGRS if it supports what I need, but I'm guessing that it will make thing either more complex, or use much more bandwidth than I actually need.

Are there any networking plugins that suit these needs?

limber crown
#

The turbulance crate is still maintained, it's a very small crate that define an interface to implement to get a plateform-agnostic minimal network protocol

#

This is still the easiest way I know of to implement cross plateform networking (specifically web+native, if just limited to native+native or web+web, which arguably is also cross plateform, then the domain of possibilities extend greatly)

lilac bough
#

Do you mean I can use bevy_networking_turbulence directly (i.e. not through bootleg_networking) for web+native p2p networking?

limber crown
#

I meant using turbulance directly and build a plugin around that. But this requires networking knowledge that myself I don't have (I've been in a similar situation as you, and considered the options)

#

Oooh wait you said you don't need rollback. What kind of game are you making?

lilac bough
#

Stardew valley clone

limber crown
#

I would advise against crossplay of web/native, maybe you can do native/native (any os to any os) and web/web, but web/native seems really hard.

#

I mean it would require some abstraction around the network, which is why I'd recommend turbulance

lilac bough
#

I'm not one to shy away from something because it's hard haha. I've already started the project in Godot, but I've been a little frustrated with the networking model there (or maybe I just don't understand it well enough), so I was looking into bevy as a possible alternative.

In Godot, the cross-platform aspect is easy, you just open a web socket whether you're on native or web and those can talk to each other. I was having trouble dealing with unloading things and what to do with players that you've unloaded but are still connected to, but that's kinda irrelevant here.

limber crown
#

I'm checking my research notes on bevy networking libs

#

This is a good link: #networking message

#

AFAIK you simply can't open a websocket between two web clients, you need each client to open a websocket to an intermediary server

#

If you want to do p2p on the web you'll have to pass through WebRTC and get familiar with the protocol. You still need a server, but technically it is possible to get most of the network be between the clients

lilac bough
#

Yes, that's true. One concession I was willing to have is that you can't host the server on the web client.

#

So I'm not too worried about that. What I do want is for a native client hosting to be able to accept connections from web and native clients

limber crown
#

And if you go with WebRTC on the web client, if you also want a WebRTC implementation on the native client if you want web/native cross play

#

There is a rust crate that implements WebRTC you could theoretically use in your client, but I've not seen it used and it is very poorly documented

#

Check out the crate named webrtc-unreliable it's a minimal native webrtc implementation.

#

(specifically this isn't the crate I mentioned last paragraph)

lilac bough
#

If I'm understanding correctly, I don't think that's necessary if I don't allow web clients to host. I should be able to open a websocket and connect to the native client that's listening without anything too special. But I will admit, we're getting pretty close to the edge of things I even remotely understand haha

limber crown
#

You still need something that understands WebRTC on the native client if you want to be capable for the native client to communicate with the web client, since that's the only language the web client can talk to anything outside of a centralized server.

#

hmm. If you drop the p2p requirement, then you can use websockets, which are much less complex to deal with

#

In my research notes on bevy networking libs, the first paragraph is

Chose 1:

  • wasm target
  • p2p
#

Technically it's possible to do both, but I don't feel I have the competence for it. 😅

lilac bough
#

I'm not 100% I understand what WebRTC is. But I'm still pretty sure that it's not necessary. You should be able to open a websocket in the browser and connect to anything that's listening. Rust even has a websockets crate that doesn't mention WebRTC at all as far as I can tell. https://docs.rs/websocket/latest/websocket/ But basically, it sounds like my options are

  1. Continue to push through my pains with Godot
  2. Find another engine
  3. Write what I need myself for Bevy
limber crown
#

If you are hosting the game on a player's native client, the player must open the ports and accept the websocket from the player on the web client that wants to connect, they must also provide their own IP address to the player using web client. websocket connections are initialized on the http/s protocol, so you need an URL with a thing to connect to.

#

You remember in the olden time when you had to open your router/modem's settings and enable port forwarding to be able to play Garry's Mod? :P

You might be able to setup the port programatically using a "hole punching" or "upnp" crate.

#

If you can use websockets, you don't need WebRTC.

lilac bough
#

Yeah, so UPnP or port forwarding will be necessary, ideally UPnP, but I don't see why you can't connect by IP on a websocket.

limber crown
#

You can.

#

I might have been misleading. The "chose 1" thing is for my game, which wouldn't work with websockets. Your game seems fairly compatible with websockets.

lilac bough
#

I'm curious how websockets wouldn't work? I know they have a size limit which could be a problem, but other than that aren't they just normal sockets?

limber crown
#

I've never considered using a native client with websockets and upnp, but I don't see why it wouldn't work. I'd first write a very basic protoype that just pipes data between the two clients, to make sure it's possible.

#

Well, my game is somewhat competitive, so it needs fairly low latency communication

lilac bough
#

Well from Godot I know it's theoretically possible (I've alright prototyped out connecting between native and web clients). The only question is, is there a crate that supports this for Bevy or would I have to write it myself? And if I do have to write it myself, is it worth it?

limber crown
#

websockets force ordering of sent packets, which can lead to major lag spikes

#

Don't think there is any plugins, but it shouldn't be hard using pre-existing websocket crates.

lilac bough
#

I'd have to figure out how to serialize and send Entities over the socket to keep them in sync, but I guess that's basically it right?

limber crown
#

I've had success using ws_stream_wasm and tungstenite. I used a compile flag on target (like #[cfg(not(target_arch="wasm32"))])

#

I would use a marker component to mark entities that must be synced between clients. Then I'd write a message type that contains only the relevant components.

#

Something like

#[derive(WorldQuery)]
struct NetworkedComponents {
  position: &'static Foo,
  activity: &'static Bar,
  // etc.
}
impl  NetworkedComponents {
  fn sync_message(&self) -> NetworkMessage {
    todo!()
  }
}
fn sync_system(
  stuff_to_synchronize: Query<
    NetworkedComponents,
    (With<Networked>, Or<(Changed<Foo>, Changed<Bar>)>),
  >,
  mut events: EventWriter<NetworkMessage>,
) {
  for stuff in &stuff_to_synchronize {
    events.send(stuff.sync_message());
  }
}
fn send_network_messages(
  mut events: EventReader<NetworkMessage>,
  mut socket: NonSendMut<WsSocket>,
){
  todo!()
}
lilac bough
#

I see! I think I have some deciding to do at this point, but this has been helpful. Thanks!

hushed lichen
#

(Which was mentioned very briefly 🙂 )

simple ginkgo
#

It's also possible to libp2p to work with bevy if you want to create alot of extra work for yourself. Or at least I managed to get basic messaging with nat punchthrough/passthrough working with it previously as a test.

lilac bough
#

@hushed lichen It's not clear to me if matchbox supports running on native clients. Do you happen to know if matchbox works on native clients?

hushed lichen
#

It does work on native client, and support anyplatform* to anyplatform crossplay (like web-native)
*: supported platform (native, wasm, not sure of others)

lilac bough
#

Huh, that sounds like exactly what I'm looking for, except I'd need to host the signaling server to facilitate connections between clients right?

hushed lichen
lilac bough
#

Hmmm. I'm not sure if I want to require myself to host anything to make mulitplayer work. The possibility of multiplayer not working for everyone because I broke my signaling server is a little spooky. It's worth considering though, thanks for the idea. I'll have to do more research!