Binary Serialization and Protocol

i found this page Protocols. I'm currently working on a game similar to agario and i find that page is helpful for my game.

They using WebSocket for sending game messages which is mine too. But i'm use text message (JSON) instead of binary message and i'm planning to switch to binary message for minimizing bandwidth reason because JSON are verbose even it's easy to serialize/deserialize.

On the section server->client protocol and client->server protocol, they used term of opcode. I don't about what opcode is and what the purpose of those number, but i know in WebSocket protocol RFC 6455, they used term of opcode too like 1 for text message and 2 for binary message.

My Question is:

1. How to serialize/deserialize game messages in binary message?

2. What is those number in opcode used for? for now, my assumption is those number are used for serialization in binary message, maybe not i don't know

3. If my assumption in Q2 is right, how to implement those number to my protocol? maybe some code demonstration? it will be great if the code in javascript and golang because i'm use go for server and javascript for client.

Thanks

• To tackle just the definition part (leaving the meaty implementation for answers), an "opcode" is short for "operation code." It means "a number or identifier that tells the system what action it's supposed to do next, or what data to read next from the stream." So for example, when the system in the linked Protocol article sees an opcode of 17, it knows it's supposed to do a View Update, and the next 96 bytes in the stream are the x & y coordinates and zoom level. Then it reads the next byte in the stream after those 96 bytes to figure out what the next operation is... – DMGregory Apr 5 '17 at 13:57

For Go/JavaScript may be a good solution to use MessagePack. And you can use it on client side with any platform.

You will save traffic, and you can use JavaScrtipt implementation as well.

Note: for Javascript, node.js, and browser, I suggest to use JSON. Because it simply faster for JSV8 (actually not really, see update), in case if your messages relatively small.

UPD: I was wrong. Serializing/Parsing large objects turns into serious performance issues for the browser and NodeJS server.

Also, origin object can be large and contains data I don't want to send with JSON. So in JSON-case, I need to clone an object, or create a new one, then serialize it.

So I decided to describe the serialize/parse functions for each type of messages and operating with a pre-defined structure for each message type.

Here is an example of my message processing (JS):

...
sight_ui: {
pack: function (thing) {
const slots = [];
for (let slot in thing.inv)
slots.push(slot);
return [
thing._id,
thing.name,
slots.join(SEP2)
].join(SEP1);
},
unpack: function (str) {
let s = str.split(SEP1);
return {
_id: s[0],
name: s[1],
slots: s[2] ? s[2].split(SEP2) : [],
}
}
},
...


In this case, I detect serialization function by the first part of the message. It can be 1 character or a string separated from the message body by a specific symbol. Each function can be micro-optimized and easy to test. I'm using wse WebSocket wrapper, it allows to describe protocol separately. But it's poorly documented yet.

• messages in io games are usually much smaller in binary data than using JSON objects. Speed is not the only thing to consider. I think the network traffic has very significant impact on the scale and smoothness of the MMO game. If packing and unpacking MessagePack takes so long maybe it's time to use customized binary protocol specifically for the game. But that will require a lot of work to convert everything into binary before sending it out. And some work to reverse it back to data that can be used on the client. – newguy May 2 '17 at 5:48
• @newguy, Sure, you right. I simply wrap my messsage processing into function or tiny lib. In case of slowness - I can optimize all in two functions and everything gonna be fine. – Vladimir Ishenko Jun 6 '17 at 9:16