Handling network messaging

I've came up with some basic rules on how to implement the networking for my multiplayer, web-based game:

  • Server always has the most up-to-date state of the game
  • Real-time communication is sent over Web Sockets
  • Physics, collisions etc. happens only on the server side, client just gets dummy position updates. This might not work for a dynamic, 3D FPS but will do just fine for a 2D action game
  • Don't do anything too clever on the front end. It should render the output and relay the input.
  • Never trust the client, verify all data coming from the client and discard anything that doesn't check out
  • Very small frames containing only relevant changes in a compacted form will be sent the clients as often as feasible. Initially aiming for 20 frames a second
  • Larger updates containing state of the game or info about new player joining sent as required to the clients - still in a compacted form
  • Meta information (e.g. player name change, game score) sent in a separate message as rarely as possible (this messages will be larger)
  • Client sends compact messages based on user input (move/attack etc.) and meta messages (change character name) as required
  • To make the experience smoother, client might do some extrapolation (predicting the movement) or interpolation (drawing movement between 2 frames). This will require further research.

As you can see above, I would like to use compact messages for the most common client-server traffic. I would like to use just few bytes of data per frame and luckily Web Sockets specification allows for sending binary data. It's a relatively new feature but is supported by all the modern browsers (Chrome 15+, Firefox 11+, Internet Explorer 10, and Safari nightly). Luckily my back end framework (Autobahn) is capable of sending and receiving binary messages over Web Socket.

To keep the message size to the minimum, I've devised a schema-based, binary protocol. Client and server will need a small JSON file listing all the possible messages as well as details on how to read/build each individual message. For example a simple frame message would consist of four unsigned integers, first representing message id (so that decoder can pull up correct schema), second and third representing X and Y coordinates of the character and fourth representing unique character id. Since each integer requires 4 bytes, the frame message as specified above would require a total of 16 bytes. Much less than the equivalent message sent as JSON.

So instead of this:

{
	"message_id": 1,
	"coordinates": {
		"x": 123,
		"y": 456
	},
	"user_id": 1001
}

I'll be transmitting this:

\x00\x00\x00\x01\x00\x00\x00{\x00\x00\x01\xc8\x00\x00\x03\xe9

However this message will be automatically re-assembled on the other end so I can conveniently access properties by their names.

I haven't been able to find any open-source library that support efficient messaging over Web Sockets as described above. Once the game is release I hope to release the part of code that does message encoding & decoding as a stand-alone library