realtime-multiplayer-in-html5
realtime-multiplayer-in-html5 copied to clipboard
Exchange protocol too verbose for real world use
For production deployment it's paramount that data exchange between the client and the server is kept to a minimum. Currently there seems to be zero optimization on this area. For reference here's an example of an exchange payload with only 1 user inside the game room:
"onServerUpdate",{"serverTime":30.091000000001493,"ownPlayer":{"id":"a8061581-7929-4b37-9477-c472e8959634","name":"jay","lastInputSeq":"121","position":{"x":156.355,"y":119.995},"fireing":false,"reloading":false},"players":[],"events":[]}] as {"type":2,"nsp":"/","data":["onServerUpdate",{"serverTime":30.091000000001493,"ownPlayer":{"id":"a8061581-7929-4b37-9477-c472e8959634","name":"jay","lastInputSeq":"121","position":{"x":156.355,"y":119.995},"fireing":false,"reloading":false},"players":[],"events":[]}]}
Here's a few ways in which I believe this could be optimized:
-
Rounding-off time to a meaningful precision: this is the most obvious one. For instance: ' '
30.091000000001493
could be sent as30.091
or (maybe30.02
?) and specially the rounding off of positions could be a benefit in a scenario where there are +20 players in the same room. -
Client UIDs should not be included on frequent exchanges: UIDs should be only be included in meaningful, one-time-off events such as joining rooms, etc. After that a much shorter id can be used that can be mapped to the actual client UID whenever that is needed
-
Avoid sending 'state of the world' types of updates inside of frequent exchanges: instead only "diffs" should be send.
Thanks for pointing out!
I would use binary data like agar.io On 3 Jul 2016 14:24, "Arjan Frans" [email protected] wrote:
Thanks for pointing out!
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/arjanfrans/realtime-multiplayer-in-html5/issues/10#issuecomment-230167608, or mute the thread https://github.com/notifications/unsubscribe/ABLfznfu82wWAkW4f7S-ucl8RIP8UnQuks5qR_5wgaJpZM4JD60N .
@asdfuken : that sounds awesome but how does it affect your debugging capabilities? Do you have a way to revert back to normal characters when running in test mode?
I have made a huge modification to messaging, but I would have to documentate the changes :C http://pastebin.com/hCBvk8q7 this is how it's made
2016-07-03 14:42 GMT-04:00 jgamedev [email protected]:
@asdfuken https://github.com/asdfuken : that sounds awesome but how does it affect your debugging capabilities? Do you have a way to revert back to normal characters when running in test mode?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/arjanfrans/realtime-multiplayer-in-html5/issues/10#issuecomment-230168455, or mute the thread https://github.com/notifications/unsubscribe/ABLfzs1AyU6DEZoWcnMx7_cojITpLxUhks5qSAJ6gaJpZM4JD60N .
@asdfuken , thanks for sharing! I translated the comments in your pastebin into English in case any non-spanish speaking ppl are interested: (http://pastebin.com/nesHjmxZ)
@asdfuken , I like how you use ws, I think you have moved away from socket.io, if that's the case can you comment on that?
Here's some more information I have been able to collect about binary protocols:
- Article discussing the use of binary protocols in the context of a Node multiplayer game: (http://buildnewgames.com/optimizing-websockets-bandwidth/) (Warning! Probably outdated because it predates Socket.io binary support)
- bops provides a common API on top of Node Buffers and client side TypedArrays
- Conversion from/to UTF-8 is supposed to be slow.. so maybe stay away from that?
- Socket.io blog on adding support for the Buffer type. Binary is so powerful that in his experiment guy is piping in whole game frames (actual pngs!) and using the browser like a VNC client. :scream: Crazy stuff!
My protocol is based on that http://agar.gcommer.com/index.php?title=Protocol I use binary because I wont transfer blops data, binary is enough :) For Strings I use this function
var Uint32ArrayToString = function(data, offset)
{
var s = "";
for(var i = offset; i< data.length;i++)
{
s += String.fromCharCode(data[i]);
}
return s;
}
And I init the server with
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({ port: 8001 });
wss.binaryType = 'arraybuffer'; //IMPORTANT!!!!!
Those are ascii encoded
I am thinking about some sort of compress function that transforms the original object to the most minimal possible and then only send the diff. Then on the other side a decompress function will convert it back to a usable object and it then applies the diff to the previously received state.
@arjanfrans , binary has a extremely small footprint so you would not need to diff it, unless you need to reduce message frequency as opposed to payload size.
@arjanfrans , binary has a extremely small footprint so you would not need to diff it, unless you need to reduce message frequency as opposed to payload size.
I tried something with sending the diffs only and converting those to binary.
https://github.com/arjanfrans/realtime-multiplayer-in-html5/pull/13/commits/6141375f1167426ed142ce8b354da4c09898bbf4