Multiplayer
kayhhh opened this issue · 5 comments
Need to figure out the networking layer.
Original plan was WebSocket, then WebRTC for UDP + voice chat (using mediasoup).
Am a little unsure whether mediasoup will work client side in native and WASM web build, so would need to test.
Also was looking at WebTransport which seems cool, so could potentially do everything over it instead of WebSocket + WebRTC. Seems most browsers support it except for Safari (which has it in a technology preview), good enough for me. The spec is evolving so might be less stable.
Also also, should see how things would work with our existing axum server.
Ultimately need to see what kind of crates exist already for us to use.
It looks like axum / hyper doesnt support WebTransport yet, but we might be able to just run the HTTP3 server on a different port (ie using https://github.com/BiagioFesta/wtransport)? Will need to try some things out.
There are a lot of great bevy libraries for handling networking, trying to see if we want to use any of them.
-
renet
(https://github.com/lucaspoffo/renet) has a whole family of crates handling networking, interpolation, rollback, but sadly it doesn't work in the web. It looks like eventual WebRTC support is planned. -
bevy_quinnet
(https://github.com/Henauxg/bevy_quinnet) is another good looking library, using QUIC, but again does not work in the web. They mention preferring WebTransport instead of using WebRTC, so they might go down that road in the future. -
naia
(https://github.com/naia-lib/naia) is an option that does actually support the web, using WebRTC. Doesn't seem to have super active development but has a lot of built-in features like entity replication and interpolation. -
aeronet
(https://github.com/aecsocket/aeronet) seems to be a newer library using WebTransport, in the web or native. Is transport agnostic if we wanted to use something else.
A question that has been on my mind is how standardized this communication should be. These libraries all seem to use an approach of defining rust structs or enums using serde
, and sending that over the wire, but because of what we want to build with the wired protocol we may want to define communication over protobufs.
This is likely additional work compared to just using rust structs, but clearly defines communication in a language and implementation agnostic format. I was debating whether this is worth it or not, ie should the protocol be defined this far up, but if we want moddable clients / extended infrastructure (which we most certainly do) then we want a clearly defined spec to avoid client divergence.
So that is all to say, we should define all networking communication in a wired protocol protobuf spec, which means we may not be able to use any of these libraries effectively.
Ok slowly making progress lol. Been playing with some implementations, but for more info:
- We can (and should) use one of these libraries with protobufs by doing our own serialization.
renet
actually does have WebTransport support in the form of a PR that looks close to ready.aeronet
doesn't support web yet but its in the works.renet
usesh3
,aeronet
useswtransport
Looking like a choice between renet
and aeronet
.
hm looks like renet
only supports webtransport in the browser, at least currently. h3
provides a server side implementation but no client side.
And I think I did actually get aeronet
working after a few failed attempts, so looks like this might work after all.