Rhubarb: A WebSocket library optimized for multiplayer WebGL games

Hey guys!

I realized there’s still not a multiplayer 3D WebGL game around that runs on 60 FPS both on mobile and desktop devices, so written this library to make this happen!

Rhubarb allows users to define their protocols in a JSON file, but converts everything to binary data (to reduce bandwidth usage and enable transferables) and do the data transfer within WebWorkers to give the good old WebGLRenderer some space to render things in 60 FPS :slight_smile:

Thanks to protocol definition files the same protocol can be shared between the server and the client.

The library is here: GitHub - oguzeroglu/Rhubarb: A WebSocket library optimized for multiplayer JS games, works on WebWorkers with binary data.

It is well documented and there’re two examples, it even has a Wiki. Do not hesitate to hit me up with your questions/bug reports/critiques and use this if you’re up to some crazy multiplayer project.

Big love to all of you!

5 Likes

Interesting project!

I’ve experimented in this area some time ago and did not make good experiences with WebSockets in context of large scale, time-critical applications. It works well with a few clients but if you have to deal with dozen of players in a fast game like a shooter, WebSockets is probably not a good choice.

The problem with WebSockets is the fact that it’s based on TCP which is in general a heavy-weight protocol. It guarantees a reliable communication without data loss (via re-transmission). The problem is that this quality of communication is unwanted in many application areas because of the respective latency.

Hence, games often used UDP (sometimes with a custom protocol to add certain quality features) for the synchronization of time-critical data because it’s a faster, simpler and way more efficient protocol than TCP. A typical use case for UDP is the synchronization of transformation/movement data of other players. Game clients usually implement extrapolation so even if packages are temporarily not delivered, the game can still transform other players and resolve any conflicts at a later point.

Also note the recommendation here: UDP vs. TCP | Gaffer On Games

Never use TCP for time critical data. The problem with using TCP for realtime games like FPS is that unlike web browsers, or email or most other applications, these multiplayer games have a real time requirement on packet delivery. What this means is that for many parts of a game, for example player input and character positions, it really doesn’t matter what happened a second ago, the game only cares about the most recent data. TCP was simply not designed with this in mind.

Have you considered to use WebRTC in your library? If not, why? I’m actually very interested in any experiences in this area since I’m sure that TCP based communication is not a good choice for all scenarios. I would love to see how WebRTC can be used to implement a game server. That might be possible with (unreliable) data channels but I’ve not seen a showcase so far.

6 Likes

@Mugen87
I’ve considered WebRTC, and am aware of low level differences between TCP and UDP, however I don’t have much experience with WebRTC yet but will definitely integrate data channels into Rhubarb in the future.

I happened to experience same kinda problems that you encountered that’s why I wanted to experiment with transferring typed arrays instead of JSON (the typical way) instead.

For instance, for most of the shooter games, the most basic data you want to send includes:

position.x, position.y, position.z, quaternion.x, quaternion.y, quaternion.z

These are all floats, lets say with 6 floating points, so when you do a JSON.stringify into this kinda message the data you’ll eventually send would be at least 44 bytes. Rhubarb converts these into Float32 values, so you simply send 24 bytes instead, and without JSON.stringify, so much faster (and inside the WebWorker so main thread would be lighter). But the library also allow users to fetch the received datas in a high level way such as: protocol.getPositionX(). The same thing happens for strings as well, Rhubarb fits strings into 4bytes of chunks.

The initial results are promising. Hopefully I’ll come up with a nice game with this!

2 Likes

Wow, that sounds great! Please report your progress here when this is ready :innocent:

2 Likes

I created a WebRTC library for multiplayer games while I was coding a Phaser 3 game. Take a look at GitHub - geckosio/geckos.io: 🦎 Real-time client/server communication over UDP using WebRTC and Node.js http://geckos.io

Hope it helps :slight_smile:

4 Likes

Thanks, I’ll check it out! Is the game online somewhere?

The lib looks good however seems to address different issues than Rhubarb. Rhubarb focuses on GC usage and main thread performance rather than latency (no JSON)

However I might create a fork to integrate WebRTC communication into the byte conversion/web worker logic of Rhubarb :stuck_out_tongue:

1 Like

My game not. But https://dattank.io/ is using it.

Oh ok :slight_smile:

:+1:

2 Likes

Hey guys, saw this thread in my email. It took FOREVER to figure out how to get 60fps on my ThreeJS MMO.

I implore you to come try it out :slight_smile:

Here’s a couple of Gift Cards to the store for some free stuff. Please use only one and maybe reply that you’ve taken one.

FmeKaYEsA4PebgnTD

bCyYxdbqji8RRNH3r

zoMvrbhwwAMteHtc5

oqi7NTysF6Ner3H2w

hmqNqyLgPKgqdiNc9

I also might hire someone to help me with the ThreeJS particle effects and in generally tighten things up.

1 Like