A simple multi-player online game (HTML5 + node.js) - Part IV

Thursday, July 16, 2015

This is the fourth (and last) part of series where I describe what it took me to build a simple multiplayer online game ([part 1](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_77.html){_blank}, [part 2](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_55.html){_blank}, [part 3](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5.html){_blank}).

## Intro
In this section we are going to explore the server code, the main pares are:
  1. server.js - The entry point for the server, responsible for serving static files and accepting WebSockets
  2. lobby.js - Responsible for pairing players into matches
  3. game/ - All the snake game logic sits under this folder
## Server
As stated above, `server.js` is responsible for accepting connections and serving static files, I am not using any framework here but I do use the [ws](https://github.com/websockets/ws){_blank} module for handling WebSockets connections.

### Requests handlers
In the code below we create a new http server and pass a request listener callback to handle the request, quite a straight forward code:
```js
var http = require('http');
var server = http.createServer(function(req, res) {
    // This is a simple server, support only GET methods
    if (req.method !== 'GET') {
        res.writeHead(404);
        res.end();
        return;
    }

    // Handle the favicon (we don't have any)
    if (req.url === '/favicon.ico') {
        res.writeHead(204);
        res.end();
        return;
    }

    // This request if for a file
    var file = path.join(DEPLOY_DIR, req.url);
    serveStatic(res, file);
});
```

### Static files handler
Whenever we receive a GET request (which is not the favicon) we assume it is for a file, the `serveStatic` method will look for the file and stream it back to the client.
In the code I use 2 constant variables that helps with finding the files, the first is `DEPLOY_DIR` which is actually the root folder where the static files are, and the second is `DEFAULT_FILE` which is the name of the file that should be served if the request url points to a folder (of course that in real projects these 2 should be in some config file and not hard-coded like this)
```js
var DEPLOY_DIR = path.resolve(__dirname, '../client/deploy');
var DEFAULT_FILE = 'index.html';
```
So assume we deployed the project under `/var/www/SnakeMatch`, then `DEPLOY_DIR` is `/var/www/SnakeMatch/client/deploy`, and a request to `/all.js` will serve `/var/www/SnakeMatch/client/deploy/all.js`.

Here is the code of the `serveStatic` method, where `fs` is Node's fs module:
```fs
/**
* Serves a static file
* @param {object} res - The response object
* @param {string} file - The requested file path
*/
function serveStatic(res, file) {
    // Get the file statistics
    fs.lstat(file, function(err, stat) {
        // If err probably file does not exist
        if (err) {
            res.writeHead(404);
            res.end();
            return;
        }

        // If this is a directory we will try to serve the default file
        if (stat.isDirectory()) {
            var defaultFile = path.join(file, DEFAULT_FILE);
            serveStatic(res, defaultFile);
        } else {
            // Pipe the file over to the response
            fs.createReadStream(file).pipe(res);
        }
    });
}
```

### Accepting connections
After creating http server we need to bind on a port, we are using the `PORT` environment variable (to be used in Heroku) and defaults to 3000, for WebSockets we use `ws`, whenever we get a WebSocket connection we just send it to the lobby
```js
var WebSocketServer = require('ws').Server;
var port = process.env.PORT || 3000;
server.listen(port, function () {
    console.log('Server listening on port:', port);
});

// Create the WebSocket server (it will handle "upgrade" requests)
var wss = new WebSocketServer({server: server});
wss.on('connection', function(ws) {
    lobby.add(ws);
});
```

## Lobby
The Lobby is responsible for accepting new players, and pairing players into matches.
Whenever a new socket is added to the lobby it first creates a `Player` object (werapper around the socket, more on this later) and listen to its `disconnect` event, then it tries to pair it with another player into a `Match`, if there are no available players it puts the player in the `pendingPlayers` dictionary, if it succeeded to pair this player with another player the Match object is put in the `activeMatches` dictionary and it registers to the Match's `GameOver` event.
```js
Lobby.add = function (socket) {
    // Create a new Player, add it to the pending players dictionary and register to its disconnect event
    var player = new Player(socket);
    pendingPlayers[player.id] = player;
    player.on(Player.Events.Disconnect, Lobby.onPlayerDisconnect);

    // Try to pair this player with other pending players, if success we get a "match"
    var match = this.matchPlayers(player);
    if (match) {
        // Register the Match GameOver event and store the match in the active matches dictionary
        match.on(Match.Events.GameOver, Lobby.onGameOver);
        activeMatches[match.id] = match;

        // Remove the players in the match from the pending players
        delete pendingPlayers[match.player1.id];
        delete pendingPlayers[match.player2.id];

        // Start the match
        match.start();
    } else {
        // No match found for this player, let him know he is Pending
        player.send(protocol.buildPending());
    }
};
```
The rest of the code in the Lobby is not that interesting, `matchPlayers` just loops over the `pendingPlayers` dictionary and returns a new `Match` object if it found another pending player (which is not the current player). When a match is over (`GameOver` event) we just disconnect the two players (which will close their sockets), and delete the match from the `activeMatches` dictionary.

## The Game
Now we will go over the code under the `server/game` folder, it contains the `Player`, `Match` and `SnakeEngine` classes.

### Player class
The Player is just a wrapper around the socket class, whenever new data arrives on the socket it raises a `message` event, if the socket gets closed it raises a `disconnect` event, and it exposes a `send` method which is used to write data over the socket. Below is the ctor and send methods:
```js
var Emitter = require('events').EventEmitter,
    util = require('util'),
    uuid = require('node-uuid');

function Player(socket) {
    // Make sure we got a socket
    if (typeof socket !== 'object' || socket === null) {
        throw new Error('socket is mandatory');
    }

    Emitter.call(this);

    this.id = uuid.v1();
    this.index = 0; // The player index within the game (will be set by the Match class)
    this.online = true;
    this.socket = socket;

    // Register to the socket events
    socket.on('close', this.onDisconnect.bind(this));
    socket.on('error', this.onDisconnect.bind(this));
    socket.on('message', this.onMessage.bind(this));
}
util.inherits(Player, Emitter);

Player.prototype.send = function(msg) {
    if (!msg || !this.online) {
        return;
    }

    try {
        this.socket.send(msg);
    } catch (ignore) {}
};
```

### Match class
This class is responsible for all the game logistics, it updates the snake-engine every 100 msec, it sends updates to the clients, it read messages from the client etc.
NOTE: the Match class doesn't know how to "play" snake, that's why we have the snake-engine for.
Although we described it on the first post lets go over the course of a snake match: start by sending a `Ready` message to the clients with all the game info (board size, snakes initial position etc), then there are 3 `Steady` messages (evet 1 second), then there is a `go` message signaling to the clients that the game has started, then a series of `Update` messages are being sent every 100 milliseconds, and finally there is a `GameOver` message.
The match is over if when one of the players has failed or 60 seconds has passed, if after 60 seconds the score is tied there is an overtime of 10 seconds until one player wins.
Now lets see how the Match class is doing all this, first we define some constants:
```js
var MATCH_TIME = 60000; // In milliseconds
var MATCH_EXTENSION_TIME = 10000; // In milliseconds
var UPD_FREQ = 100;
var STEADY_WAIT = 3; // number of steady messages to send
var BOARD_SIZE = {
    WIDTH: 500,
    HEIGHT: 500,
    BOX: 10
};
```
In the ctor we initialize the game, note that each player is assigned to an index (player1 / player2).
```js
function Match(player1, player2) {
    Emitter.call(this);
    this.id = uuid.v1();
    this.gameTimer = null;
    this.matchTime = MATCH_TIME; // The match timer (each match is for MATCH_TIME milliseconds)

    // Set the players indexes
    this.player1 = player1;
    this.player1.index = 1;
    this.player2 = player2;
    this.player2.index = 2;

    // Register to the players events
    this.player1.on(Player.Events.Disconnect, this.onPlayerDisconnect.bind(this));
    this.player2.on(Player.Events.Disconnect, this.onPlayerDisconnect.bind(this));

    this.player1.on(Player.Events.Message, this.onPlayerMessage.bind(this));
    this.player2.on(Player.Events.Message, this.onPlayerMessage.bind(this));

    // Create the snake game
    this.snakeEngine = new SnakeEngine(BOARD_SIZE.WIDTH, BOARD_SIZE.HEIGHT, BOARD_SIZE.BOX);
}
```

### Ready-Steady-Go
The ready-steady-go flow happens in the `start` and `steady` methods:
```js
Match.prototype.start = function() {
    // Build the ready message for each player
    var msg = protocol.buildReady(this.player1.index, this.snakeEngine.board, this.snakeEngine.snake1, this.snakeEngine.snake2);
    this.player1.send(msg);

    msg = protocol.buildReady(this.player2.index, this.snakeEngine.board, this.snakeEngine.snake1, this.snakeEngine.snake2);
    this.player2.send(msg);

    // Start the steady count down
    this.steady(STEADY_WAIT);
};

/**
 * Handles the steady count down
 * @param {number} steadyLeft - The number of steady events left
 */
Match.prototype.steady = function(steadyLeft) {
    var msg;

    // Check if steady count down finished
    if (steadyLeft === 0) {
        // Send the players a "Go" message
        msg = protocol.buildGo();
        this.player1.send(msg);
        this.player2.send(msg);

        // Starts the update events (this is the actual game)
        this.gameTimer = setTimeout(this.update.bind(this), UPD_FREQ);
        return;
    }

    // Sends the players another steady message and call this method again in 1 sec
    msg = protocol.buildSteady(steadyLeft);
    this.player1.send(msg);
    this.player2.send(msg);
    --steadyLeft;
    this.gameTimer = setTimeout(this.steady.bind(this, steadyLeft), 1000);
};
```

### Update cycle
The `update` method is being called every 100 milliseconds, the method is quite self-explanatory but do note that `snakeEngine.update()` returns a result object with info about the game state, more specifically, it tells us whether one snake has lost (by colliding into itself/border) and if there was a change to the pellets (removed/added).
```js
Match.prototype.update = function() {
    // Update the match time, this is not super precise as the "setTimeout" time is not guaranteed,
    // but ok for our purposes...
    this.matchTime -= UPD_FREQ;

    // Update the game
    var res = this.snakeEngine.update();

    // If no snake lost on this update and there is more time we just reload the update timer
    if (res.loosingSnake < 0 && this.matchTime > 0) {
        this.gameTimer = setTimeout(this.update.bind(this), UPD_FREQ);
        this.sendUpdateMessage(res);
        return;
    }

    var msg;
    // If no snake lost it means time's up, lets see who won.
    if (res.loosingSnake < 0) {
        // Check if there is a tie
        if (this.snakeEngine.snake1.parts.length === this.snakeEngine.snake2.parts.length) {
            // We don't like ties, lets add more time to the game
            this.matchTime += MATCH_EXTENSION_TIME;
            this.gameTimer = setTimeout(this.update.bind(this), UPD_FREQ);
            this.sendUpdateMessage(res);
            return;
        }

        // No tie, build a GameOver message (the client will find which player won)
        msg = protocol.buildGameOver(protocol.GameOverReason.End, null, this.snakeEngine.snake1, this.snakeEngine.snake2);
    } else {
        // Ok, some snake had a collision and lost, since we have only 2 players we can easily find the winning snake
        var winningPlayer = (res.loosingSnake + 2) % 2 + 1;
        msg = protocol.buildGameOver(protocol.GameOverReason.Collision, winningPlayer);
    }

    // Send the message to the players and raise the GameOver event
    this.player1.send(msg);
    this.player2.send(msg);

    this.emit(Match.Events.GameOver, this);
};
```

### Handling clients messages
Whenever the client sends a message it first get parsed using the Protocol object, then if it is a `ChangeDirection` request we pass it to the snake-engine for processing, note that we put the player index on the message so that snake-engine would know what player to update.
```js
Match.prototype.onPlayerMessage = function(player, msg) {
    // Parse the message
    var message = protocol.parseMessage(msg);
    if (!message) {
        return;
    }

    switch (message.type) {
        case protocol.Messages.ChangeDirection:
            message.playerIndex = player.index;
            this.snakeEngine.handleDirChangeMessage(message);
            break;
    }
};
```
That's it for the Match class, the rest of the code is not that interesting.

### Snake Engine
The snake-engine is responsible for "playing" the snake game, on every `update` it checks whether a snake had collided with itself, went out-of-bounds, ate a pellet etc.
In the ctor we create the 2 snake objects, both snakes are created at the first row of the board, one is created on the left side and the other is created on the right side. Remember that the Board is divided into boxes, and that `Board.toScreen()` gets a box index and returns the screen x/y.
```js
function SnakeEngine(width, height, boxSize) {
    this.board = new Board(width, height, boxSize);

    // The first snake is created on the left side and is heading right (very top row, y index = 0)
    var snakeLoc = this.board.toScreen(INITIAL_SNAKE_SIZE - 1);
    this.snake1 = new Snake(snakeLoc.x, snakeLoc.y, boxSize, INITIAL_SNAKE_SIZE, protocol.Direction.Right);

    // The second snake is created on the right side and is heading left (very top row, y index = 0)
    snakeLoc = this.board.toScreen(this.board.horizontalBoxes - INITIAL_SNAKE_SIZE);
    this.snake2 = new Snake(snakeLoc.x, snakeLoc.y, boxSize, INITIAL_SNAKE_SIZE, protocol.Direction.Left);

    /** @type {Pellet[]} */
    this.pellets = [];
}
```
The interesting methods are `update`, `checkCollision` and `addPellet`.
In the update method we do the following for each snake: call the snake update method (tell it to move to its next location), check for collisions, check if it ate a pellet. If there was a collision we stop immediately as the game has over, if there was no collision we try to add a new pellet to the game.
```js
SnakeEngine.prototype.update = function() {
    var res = new GameUpdateData();

    // Update snake1
    this.snake1.update();

    // Check if the snake collides with itself or out-of-bounds
    var collision = this.checkCollision(this.snake1);
    if (collision) {
        res.loosingSnake = 1;
        return res;
    }

    // Check if the snake eats a pellet
    res.pelletsUpdate = this.eatPellet(this.snake1);

    // Update snake2
    this.snake2.update();

    // Check if the snake collides with itself or out-of-bounds
    collision = this.checkCollision(this.snake2);
    if (collision) {
        res.loosingSnake = 2;
        return res;
    }

    // Check if the snake eats a pellet
    res.pelletsUpdate = this.eatPellet(this.snake2) || res.pelletsUpdate;

    // Finally add new pellet
    res.pelletsUpdate = this.addPellet() || res.pelletsUpdate;

    // No one lost (yet...).
    return res;
};
```
In `checkCollision` we first check if the snake went out-of-bounds, we do this by comparing the snake's head to the board dimensions. Remember that the snake head is a rectangle, where the upper-left corner is denoted by x/y, so when we want to check if the snake crossed the top/left border we use x/y, but when we want to check whether the snake crossed the bottom/right border we use the bottom-right corner of the snake head.
Checking whether the snake had collided with itself is quite simple, just loop thru all the snake parts (excluding the head), and check whether they are equal to the head (equals just check x/y).
```js
SnakeEngine.prototype.checkCollision = function(snake) {
    // Check if the head is out-of-bounds
    if (snake.parts[0].location.x < 0 ||
        snake.parts[0].location.y < 0 ||
        snake.parts[0].location.x + snake.parts[0].size > this.board.rectangle.width ||
        snake.parts[0].location.y + snake.parts[0].size > this.board.rectangle.height) {
            return true;
    }

    // Check if the snake head collides with its body
    for (var i = 1; i < snake.parts.length; ++i) {
        if (snake.parts[0].location.equals(snake.parts[i].location)) {
            return true;
        }
    }

    return false;
};
```
### Adding pellets
When we come to add a new pellet to the game we first check that we have not exceeded the maximum number of allowed pellets, then we select a random box on the board and check that the box is vacant. Since `addPellet` is getting called quite frequently (every update cycle) we have to do some filtering as we want the pellets to be added on a random timing, so at the very beginning of the method we check if `Math.random() > 0.2`, if yes we immediately return without adding anything, so on average we would drop 8 of 10 calls.
```js
SnakeEngine.prototype.addPellet = function() {
    // Check if we should add pellets
    if (this.pellets.length >= MAX_PELLETS || Math.random() > 0.2) {
        return false;
    }

    // Keep loop until we found a spot for a pellet (theoretically this can turn into an infinite loop, so a solution could
    // be to stop the random search after X times and look for a spot on the board).
    var keepSearch = true;
    while (keepSearch) {
        keepSearch = false;

        // Take a random spot on the board
        var boxIndex = Math.floor(Math.random() * this.board.horizontalBoxes * this.board.horizontalBoxes);
        var loc = this.board.toScreen(boxIndex);

        // check that this spot is not on snake1
        for (var i = 0; i < this.snake1.parts.length; ++i) {
            if (this.snake1.parts[i].location.equals(loc)) {
                keepSearch = true;
                break;
            }
        }

        if (!keepSearch) {
            // check that this spot is not on snake2
            for (i = 0; i < this.snake2.parts.length; ++i) {
                if (this.snake2.parts[i].location.equals(loc)) {
                    keepSearch = true;
                    break;
                }
            }
        }

        if (!keepSearch) {
            // check that this spot is not on existing pellet
            for (i = 0; i < this.pellets.length; ++i) {
                if (this.pellets[i].location.equals(loc)) {
                    keepSearch = true;
                    break;
                }
            }
        }

        if (!keepSearch) {
            // Hooray we can add the pellet
            this.pellets.push(new Pellet(loc));
        }
    }

    return true;
};
```

## THE END
Pshew... if you have made it all the way to here, well done and thank you!
I hope this series was in some of interest to you, to me it was fun programming this game, feel free to explore the [code](https://github.com/ValYouW/SnakeMatch){_blankl} and even make it better !!

A simple multi-player online game (HTML5 + node.js) - Part III

This is the third part of a 4 part series story where I describe what it took me to build a simple multiplayer online game, ([part 1](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_77.html){_blank}, [part 2](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_55.html){_blank}).

## Intro
In this section we are going to explore the client-side code of the project, that is all the code under the `client` folder.
The main parts of the client are:
  • `index.html` - This is where the canvas lives along with the options dialog.
  • `connector.js` - Responsible for the client-server communication
  • `snake-engine.js` - Manages the game
  • `lib/` - Include some helper classes
## The index file
The html in the `index.html` files is very simple
```html
<body>
<div style="float: left">
    <canvas id="boardPane" width="500px" height="500px"></canvas>
</div>
<div style="display: inline-block; margin-left: 10px">
    <div id="settingsGrid"></div>
    <input type="button" id="btnConnect" value="Connect" />
</div>
</body>
```

There are only 3 components: the canvas (yellow area), the settings property grid, and the connect button.
For the property grid I am using my [jqPropertyGrid](http://github.com/valyouw/jqPropertyGrid){_blank} which easily displays a JSON object in an editable property gird, using this code only:
```
// Create a game-settings object
var settings = {
    textColor: '#000000',
    boardColor: '#ffffff',
    homeSnakeColor: '#00D45C',
    awaySnakeColor: '#E00040',
    pelletColor: '#FF6A00'
};

// The settings metadata for the jqPropertyGrid
var settingMeta = {
    textColor: {group: 'Colors', name: 'Text', type:'color'},
    boardColor: {group: 'Colors', name: 'Board', type:'color'},
    homeSnakeColor: {group: 'Colors', name: 'Home Snake', type:'color'},
    awaySnakeColor: {group: 'Colors', name: 'Away Snake', type:'color'},
    pelletColor: {group: 'Colors', name: 'Pellet', type:'color'}
};

// Init the settings property grid
$('#settingsGrid').jqPropertyGrid(settings, settingMeta);
```
Clicking the `Connect` button will create a new instance of `SnakeEngine`, passing it the canvas, a Connector object, and the settings from the property grid:
```js
$('#btnConnect').click(function() {
    // For simplicity just check if WebSocket is a function
    if (typeof WebSocket !== 'function') {
        alert('No WebSocket support in this browser :(');
        return;
    }

    // Get the canvas element and the game settings
    var canvas = document.getElementById('boardPane');
    var settings = $('#settingsGrid').jqPropertyGrid('get');

    // Create the connector and the game object
    var connector = new VYW.Connector(location.host);
    var game = new VYW.SnakeEngine(canvas, connector, settings);

    // Remove the focus from the connect button
    this.blur();
});
```

## The Connector
The connector is responsible for the communication with the server, it lets the client send data to the server, and pass messages from the server to the client. All communication is done via WebSocket.
In the constructor we create a websocket and register to the socket events:
```js
function Connector(host) {
    if (typeof host !== 'string' || !host) {
        throw new Error('host is mandatory');
    }

    var self = this;

    // Create a new WebSocket and register to its events
    this.socket = new win.WebSocket('ws://' + host);
    this.socket.onopen = function() {
        // "raise" the onConnected event
        self.onConnected();
    };

    this.socket.onclose = function() {
        self.disconnect(Connector.DisconnectReason.SocketDisconnect);
    };

    this.socket.onerror = function() {
        self.disconnect(Connector.DisconnectReason.SocketError);
    };

    this.socket.onmessage = function(msg) {
        self.handleMessage(msg.data);
    };
}
```
The `DisconnectReason` enum is declared on the constructor function so it will be accessible by the clinet:
```js
Connector.DisconnectReason = {
    InvalidMessage: 0,
    SocketDisconnect: 1,
    SocketError: 2
};
```

### Connector Events
The connector exposes to the client different events, the events are just empty functions that are defined on the connector object, and the client could override those methods if it wants:
```js
// Those functions should be overridden by those who are interested
// We could use event emitter but no real need so save the performance...
Connector.prototype.onConnected = function() {};
Connector.prototype.onDisconnect = function(reason) {};
Connector.prototype.onPendingMatch = function() {};
Connector.prototype.onGetReady = function(readyMessage) {};
Connector.prototype.onSteady = function(steadyMessage) {};
Connector.prototype.onGameStart = function() {};
Connector.prototype.onGameUpdate = function(data) {};
Connector.prototype.onGameOver = function(reason, winningPlayerIndex) {};
```
As it says in the comment above, we could have used the event emitter pattern, but this is not necessary as we know there will be only 1 component interested in these evens, so we save some performance by not doing so.

### Handling server messages
When the connector receives a message from the server it tries to decode it (using the Protocol class discussed in the previous post), and then raise the appropriate event to the client, if for some reason it can't decode the message, it immediately disconnect and stop the game:
```js
Connector.prototype.handleMessage = function(data) {
    if (!data) {return;}

    // Parse the message and make sure we got something
    var message = VYW.Protocol.parseMessage(data);
    if (message === null) {
        this.disconnect(Connector.DisconnectReason.InvalidMessage);
        return;
    }

    // Raise the appropriate event based on the message type
    switch (message.type) {
        case VYW.Protocol.Messages.Pending:
            this.onPendingMatch(message);
            break;
        case VYW.Protocol.Messages.Ready:
            this.onGetReady(message);
            break;
        case VYW.Protocol.Messages.Steady:
            this.onSteady(message);
            break;
        case VYW.Protocol.Messages.Go:
            this.onGameStart();
            break;
        case VYW.Protocol.Messages.Update:
            this.onGameUpdate(message);
            break;
        case VYW.Protocol.Messages.GameOver:
            this.onGameOver(message);
            break;
        default:
            this.disconnect(Connector.DisconnectReason.InvalidMessage);
    }
};
```

## The SankeEngine
The snake engine is where everything really happens in the client, it is responsible for handling all the messages from the server, update the game current state (snakes, pellets, score etc), draw the game onto the canvas, handle keyboard input and handle swipe events (for mobile).

### The Constructor
In the constructor we create all the objects we would need, "register" to the connector events and register to input (keyboard/swipe) events:
```js
function SnakeEngine(canvas, connector, settings) {
    this.canvas = canvas;
    this.connector = connector;
    this.graphics = new VYW.Graphics(canvas);
    this.settings = new VYW.GameSettings(settings);

    // Game objects
    this.board = null;
    this.snake1 = null;
    this.snake2 = null;
    this.pellets = [];
    this.gameState = new VYW.GameState(this.settings);

    // Bind to connector events
    this.connector.onConnected = this.handleConnectedMessage.bind(this);
    this.connector.onDisconnect = this.handleDisconnectMessage.bind(this);
    ...
    ...

    // Bind to the window key-down event
    win.onkeydown = this.handleKeyDown.bind(this);

    // Bind to touch events on the canvas
    this.swipeTrackingData = null;
    canvas.addEventListener('touchstart', this.handleTouchStart.bind(this));
    canvas.addEventListener('touchmove', this.handleTouchMove.bind(this));
    canvas.addEventListener('touchend', this.handleTouchEnd.bind(this));
}
```

### Handling server messages
In general, server messages represent a change in the game state, some changes do not require any special processing, while others do.
Fo example, in the `steady` message we just do:
```js
SnakeEngine.prototype.handleSteadyMessage = function(steadyMessage) {
    this.gameState.state = VYW.GameState.GameState.Steady;
    this.gameState.startIn = steadyMessage.timeToStart;
};
```
But lets take a look at two more interesting messages, the `ready` message, and the `update` message.
In the `ready` message we get the initial state of all the game objects: the client player index (whether it is player 1 or player 2), the board dimensions, the snakes initial location and the snakes size.
Note in the code below that we change the canvas size according the board size we got from the server, so the size we have in the `index.html` file is irrelevant.
Also note that `date` is the info we got from the server.
```js
/**
 * Handles a ready message from the server
 * @param {GetReadyMessage} data
 */
SnakeEngine.prototype.handleReadyMessage = function(data) {
    // Set some game data
    this.gameState.state = VYW.GameState.GameState.Ready;

    // Set this client player index (either he is player1 or player2)
    this.gameState.playerIndex = data.playerIndex;

    // Create the board and adjust canvas size
    this.board = new VYW.Board(data.board.width, data.board.height, data.board.cellSize, this.settings.boardColor);
    this.canvas.width = data.board.width;
    this.canvas.height = data.board.height;

    // Create the snakes (we assume the home player is snake1, will switch color later if not)
    this.snake1 = new VYW.Snake(data.snake1.x, data.snake1.y, data.board.cellSize, data.snake1.size, data.snake1.direction, this.settings.homeSnakeColor);
    this.snake2 = new VYW.Snake(data.snake2.x, data.snake2.y, data.board.cellSize, data.snake2.size, data.snake2.direction, this.settings.awaySnakeColor);

    // If the home snake is not player1 switch.
    if (data.playerIndex !== 1) {
        this.snake1.color = this.settings.awaySnakeColor;
        this.snake2.color = this.settings.homeSnakeColor;
    }
};
```
In the `update` message we update the scores, snakes and pellets. Currently updating the pellets is done by creating a new pellets array on each update, this is not efficient and can be improved, but for the sake of simplicity (and laziness) will keep the code as is:
```js
/**
 * Handles update message
 * @param {UpdateMessage} data - Some game data from the server
 */
SnakeEngine.prototype.handleGameUpdateMessage = function(data) {
    // Update game data
    this.gameState.player1Score = data.player1Score;
    this.gameState.player2Score = data.player2Score;
    this.gameState.timeToEnd = data.timeToEnd;

    // Update snake direction and size
    this.snake1.direction = data.player1Direction;
    this.snake1.update(data.player1Size);
    this.snake2.direction = data.player2Direction;
    this.snake2.update(data.player2Size);

    // Update pellets
    if (data.pellets) {
        this.pellets = [];
        for (var i = 0; i < data.pellets.length; ++i) {
            var loc = this.board.toScreen(data.pellets[i]);
            this.pellets.push(new VYW.Pellet(loc, this.settings.pelletColor));
        }
    }
};
```
## Drawing the game
Every once in a while we need to draw the game on the canvas. Because snake is a simple game and changes occur only in the `update` message we get from the server, we could have drawn the game after processing the update message. But that is not the practice generally used in games (well at least according to what I learned in Coursera), we need to let the framework tell us when it is the best time to draw, in the browser we do that by calling to the `window.requestAnimationFrame` method ([MDN](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame){_blank}), this method gets a callback which will be called when the browser is ready to paint.
In our `draw` method we go over all the game objects and call their draw method, and at the end call `requestAnimationFrame` again in order to be called when the browser is ready to draw the next frame.
```js
SnakeEngine.prototype.draw = function() {
    // Important to clear the canvas first...
    this.graphics.clear();

    // Draw the game objects
    if (this.board) { this.board.draw(this.graphics); }
    if (this.snake1) { this.snake1.draw(this.graphics); }
    if (this.snake2) { this.snake2.draw(this.graphics); }
    if (this.gameState) { this.gameState.draw(this.graphics); }

    for (var i = 0; i < this.pellets.length; ++i) {
        this.pellets[i].draw(this.graphics);
    }

    // No need to reload the draw timer if we are disconnected or game over.
    if (this.gameState &&
            (this.gameState.state === VYW.GameState.GameState.Disconnected || this.gameState.state === VYW.GameState.GameState.GameOver)) {
        return;
    }

    // Let the browser call the draw method again when available
    win.requestAnimationFrame(this.draw.bind(this));
};
```

### Graphics class
Drawing on a Canvas element is quite simple, but in order to make things easier I decided to copy the idea of a Graphics class from .NET, which will expose drawing methods like `drawRectangle`, `drawText` etc.
Below is the Graphics ctor, it just gets the canvas element and get the drawing context from it:
```js
function Graphics(canvas) {
    if (!canvas || canvas.nodeName.toLowerCase() !== 'canvas') {
        throw new Error('canvas is mandatory and must be a canvas element');
    }

    this.canvas = canvas;
    this.context = this.canvas.getContext('2d');
}
```
Then we expose the methods we need, for example here is the `drawRectangle`
```js
/**
 * Draws a rectangle
 * @param {Rectangle} rect - The rectangle to fill
 * @param {string} [color='#000000'] - The rectangle color
 */
Graphics.prototype.drawRectangle = function(rect, color) {
    this.context.beginPath();
    this.context.rect(rect.x, rect.y, rect.width, rect.height);
    this.context.strokeStyle = color || DEFAULT_COLOR;
    this.context.stroke();
};
```
In the `SnakeEngine` ctor we create an instance of the Graphics class and pass it to the game objects where needed (take a second look at the snippet above of `SnakeEngine.prototype.draw`), for example here is the draw method of the `Board` class:
```js
Board.prototype.draw = function(graphics) {
    graphics.fillRectangle(this.rectangle,  this.color);
    graphics.drawRectangle(this.rectangle, this.borderColor);
};
```

## User input
The user can control the snake by using the arrow keys on the keyboard, or by swiping on the screen (on mobile).

### Keyboard input
On the SnakeEngine ctor we have registered to the window's `onkeydown` event, then on each key stroke we first check the `keyCode` of the pressed key and see if it is an arrow key, then we verify the new direction (snake can't make 180 degree turns) and if all is well we build a `changeDirection` message and send it to the server.
```js
win.onkeydown = this.handleKeyDown.bind(this);

SnakeEngine.prototype.handleKeyDown = function(e) {
    var newDir = null;
    // Get the new direction per key code
    switch (e.keyCode) {
        case VYW.KeyCodes.Left:
            newDir = VYW.Protocol.Direction.Left;
            break;
        case VYW.KeyCodes.Right:
            newDir = VYW.Protocol.Direction.Right;
            break;
        case VYW.KeyCodes.Up:
            newDir = VYW.Protocol.Direction.Up;
            break;
        case VYW.KeyCodes.Down:
            newDir = VYW.Protocol.Direction.Down;
            break;
    }

    if (!newDir) {
        return;
    }

    // Find the home snake (whose keyboard input we handle) current direction, if it is the same stop.
    var homeSnakeDir = this.gameState.playerIndex === 1 ? this.snake1.direction : this.snake2.direction;
    if (newDir === homeSnakeDir) {
        return;
    }

    // Make sure we can do the change (can't do 180 degrees turns)
    if (newDir === VYW.Protocol.Direction.Right && homeSnakeDir === VYW.Protocol.Direction.Left) {
        return;
    } else if (newDir === VYW.Protocol.Direction.Left && homeSnakeDir === VYW.Protocol.Direction.Right) {
        return;
    } else if (newDir === VYW.Protocol.Direction.Up && homeSnakeDir === VYW.Protocol.Direction.Down) {
        return;
    } else if (newDir === VYW.Protocol.Direction.Down && homeSnakeDir === VYW.Protocol.Direction.Up) {
        return;
    }

    // Build a message and send it
    var msg = VYW.Protocol.buildChangeDirection(newDir);
    this.connector.send(msg);
};
```

### Swipe input
On mobile we want to control the snake using swipe actions, the canvas doesn't expose any swipe events, we have to recognize it on our own using the following touch events: `touchstart` (fired when the user first touches the screen), `touchmove` (fired on each finger move) and `touchend` (fired when the user raises the finger), so first we register to those events:
```js
canvas.addEventListener('touchstart', this.handleTouchStart.bind(this));
canvas.addEventListener('touchmove', this.handleTouchMove.bind(this));
canvas.addEventListener('touchend', this.handleTouchEnd.bind(this));
```
 Now the logic is as follows: On `touchstart` we take the touch location (x/y) and store it in some object as `startX/Y`, then on each `touchmove` event we store the current location as `endX/Y`, finally on the `touchend` event we compare the start location with the end location in order to classify the swipe into an up/down/right/left move . On horizontal swipes the absolute value `endX - startX` would be greater than the absolute of `endY - startY`, and vice versa for vertical moves, that is how we classify a swipe into an horizontal/vertical move. After we know that, we compare the relevant end point with the relevant start point (x or y) in order to know if the swipe was up/down/right/left, so on swipe to the right `endX > startX`.
I believe the code will explain it better than me, note that we store the swipe start/end locations in the `swipeTrackingData` object. Also note that the event argument of a touch event exposes a `touches` array, this is for multi-touch support, since we don't do multi-touch we care only about the first finger (`touches[0]`)
```js
SnakeEngine.prototype.handleTouchStart = function(event) {
    // We care only about the first finger (meaning swipeTrackingData must be null)
    var touch = event.touches[0];
    if (!touch || this.swipeTrackingData !== null) {
        return;
    }

    // Create a new swipeTrackingData
    this.swipeTrackingData = {startX: touch.clientX, startY: touch.clientY};
};

SnakeEngine.prototype.handleTouchMove = function(event) {
    // Don't let others handle the event
    event.preventDefault();

    // Make sure we still have 1 finger (might be redundant but whatever)
    var touch = event.touches[0];
    if (!touch) {
        return;
    }

    // Update the swipe tracking end location
    this.swipeTrackingData.endX = touch.clientX;
    this.swipeTrackingData.endY = touch.clientY;
};

SnakeEngine.prototype.handleTouchEnd = function(event) {
    // Make sure we got some data
    if (!this.swipeTrackingData || isNaN(this.swipeTrackingData.endX) || isNaN(this.swipeTrackingData.endY)) {
        this.swipeTrackingData = null;
        return;
    }

    // Now we need to determine what is the swipe direction, it will never be a straight line, we check
    // what axis had the most move
    var horizontalMove = this.swipeTrackingData.endX - this.swipeTrackingData.startX;
    var verticalMove = this.swipeTrackingData.endY - this.swipeTrackingData.startY;

    // We give horizontal move the benefit in case they are equal
    var keyCode = '';
    if (Math.abs(horizontalMove) >= Math.abs(verticalMove)) {
        // This was horizontal move, check direction
        keyCode = horizontalMove > 0 ? VYW.KeyCodes.Right : VYW.KeyCodes.Left;
    } else {
        // This was vertical move, check direction
        keyCode = verticalMove > 0 ? VYW.KeyCodes.Down : VYW.KeyCodes.Up;
    }

    // Fake a KeyDown event
    this.handleKeyDown({keyCode: keyCode});

    this.swipeTrackingData = null;
};
```

## End of Part III
That's pretty much all there is for the client code, in the [next post](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_16.html) we are going to explore the server-side code, where we actually manage the game...

A simple multi-player online game (HTML5 + node.js) - Part II

This is the second part of a 4 part series story where I describe what it took me to build a simple multiplayer online game, ([part 1](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_77.html){_blank}).

## Intro
In this part we are going to dive into the code, obviously I wouldn't go over all the code but rather try to explain the concept, the code is well commented (I believe) so exploring it should be easy ([GitHub](http://github.com/ValYouW/SnakeMatch){_blank})

## Folder Structure
This is the entire project folders and files.
```
SnakeMatch
+-- common (client/Server shared files)
|   +-- game-objects (classes that represents the different game objects)
|   |   |-- board.js
|   |   |-- pellet.js
|   |   |-- snake-part.js (represent a single part of a snake)
|   |   |-- snake-head.js (represnt the snake head, inherits from snake-part)
|   |   |-- snake.js (represent the snake, a collection of snake-part and head)
|   |-- protocol.js (protocol functions for encoding / decoding messages)
|   |-- rectangle.js
+-- client (client code)
|     +-- deploy (holds the files for deploy)
|     +-- js
|       +-- lib
|       |   |-- graphics.js (functions for drawing on the canvas)
|       |   |-- util.js (Polyfill for necessary node.js util functions in the client)
|       |-- index.js (common client functions/enums, also declare our namespace on window)
|       |-- connector.js (responsible for sever communication)
|       |-- snake-engine.js (manages the game on the client)
|       |-- game-state.js (object to hold the current game state)
+-- server (server code)
|   +-- game
|   |   |-- snake-engine.js (manages the snake game on the server)
|   |   |-- match.js (manages a snake match between 2 players)
|   |   |-- player.js (represnts a single player, basically sending/receiving messages)
|   |-- server.js (starts the web server, our main file)
|   |-- lobby.js (manages client connections and pair players to matches)
|-- Gruntfile.js (grunt build tasks)
|-- .jshintrc (some jshint rules)
|-- package.json
```

## Common objects (Client + Server)
As described in the previous, the snake game is run on both the client and the server, hence there are parts of the code that can be shared (especially what we call "game objects").
Using JavaScript on the client and the server makes it very easy to share common classes, there are only few simple tweaks needed in order to make client code run in Node.js and vice versa (one could use [Browserify](http://browserify.org/){_blank}) but I've decided to go vanilla...
In order to not make a mess on the client we will use a namespace for our app, will call it `VYW`, it is declared on `index.js` as follow: `window.VYW = window.VYW || {};`.
The main difference between the browser and node.js is that node.js uses the `module.exports` object in order to export functions, while the browser uses the `window` object, so all we need is to make sure that our code knows on which object to export its functions.
We will make a use of Immediately-Invoked Function Expressions (IIFE) in order to create a closure and pass the correct "parent" object (note that we can inject any dependency we need into the module, see `util` in the example below).
```js
(function(parent, util) {
    function SomeClass(input) {
        var isArr = util.isArray(input);
    }
    ...
    ...

    // Export SomeClass on parent (this is either the module.exports object (server) or VYW object (client)
    parent.SomeClass = SomeClass;

// Pass the correct dependencies into the module, if window is undefined assume it is node.js, otherwise it's the browser
}(typeof window === 'undefined' ? module.exports : window.VYW,
  typeof window === 'undefined' ? require('util') : window.VYW.Util));
```
That's it, now this code can be used in the client as well as be required in node.js (of course that on the client we would have to create a `util` class that resembles the node.js util class).

## Game Objects
Snake is relatively a simple game, there are no many objects involved, we have the game Board, the Snake and the Pellets, under the `game-objects` folder we created a class to represent each of those.

### Board
The board class gives us methods to interact with the board (dah), as described in the first post, the board is divided into cells (boxes) with fixed size, so the `Board` class exposes methods that converts from box index to screen pixel and vice versa.
I include here the full file just to show how the IIFE looks like:
```js
(function(parent, Rectangle) {
    /**
     * Creates a new game board instance
     * @param {number} w - The board width
     * @param {number} h - The board height
     * @param {number} boxSize - The box size of each box on the board
     * @param {string} color - The board color
     * @param {string} borderColor - The board border color
     * @constructor
     */
    function Board(w, h, boxSize, color, borderColor) {
        this.rectangle = new Rectangle(0, 0, w, h);
        this.boxSize = boxSize;
        this.color = color;
        this.borderColor = borderColor || '#000000';

        // Hold the number of boxes we can have on the board on X/Y axis
        this.horizontalBoxes = Math.floor(this.rectangle.width / this.boxSize);
        this.verticalBoxes = Math.floor(this.rectangle.height / this.boxSize);
    }

    /**
     * Convert a box index to screen location
     * @param {number} boxIndex - A box index
     * @returns {Rectangle} The screen location on the box
     */
    Board.prototype.toScreen = function(boxIndex) {
        var y = Math.floor(boxIndex / this.horizontalBoxes) * this.boxSize;
        var x = (boxIndex % this.horizontalBoxes) * this.boxSize;
        return new Rectangle(x, y, this.boxSize, this.boxSize);
    };

    /**
     * Gets the box index of an x/y location
     * @param {number} x - The box x
     * @param {number} y - The box y
     * @returns {number} The box index on the board (box index run from 0 to the TotalNumberOfBoxes-1)
     */
    Board.prototype.toBoxIndex = function(x, y) {
        return Math.floor(y / this.boxSize) * this.horizontalBoxes + Math.floor(x / this.boxSize);
    };

    /**
     * Draws the board
     * @param {Graphics} graphics - The game graphics
     */
    Board.prototype.draw = function(graphics) {
        graphics.fillRectangle(this.rectangle,  this.color);
        graphics.drawRectangle(this.rectangle, this.borderColor);
    };

    parent.Board = Board;

// This file is shared between the client and the server, in case "window" is defined we assume it is the client
}(typeof window === 'undefined' ? module.exports : window.VYW,
  typeof window === 'undefined' ? require('../rectangle.js').Rectangle : window.VYW.Rectangle));
```

### Pellet
The pellet has no special logic what-so-ever, all it knows to do is to draw itself.

### Snake
The snake is our main object, we need the snake to know how to move, grow, change direction etc. 
How the snake moves? The snake keep moving in a certain direction until it is changed, on each step (update interval) it moves to the next box on the board, while the rest of the body just follows the head. In order for that to happen, we keep all the snake parts in a linked list, where each part has a reference to the part it is following, when a part `update` method is called, it saves his current location in a `prevLoaction` variable, and update its current location to the `prevLocation` of the part it is following.
Below are the interesting parts of the `Snake` class, note how in the constructor the initial snake is built as a linked-list.
```js
/**
 * Creates a new snake
 * @param {number} startX - The snake head X
 * @param {number} startY - The snake head Y
 * @param {number} partSize - The size of a single snake part
 * @param {number} length - The total number of parts of the snake
 * @param {Direction} direction - The direction of the snake
 * @param color
 * @constructor
 */
function Snake(startX, startY, partSize, length, direction, color) {
    /* @type {SnakePart[]} */
    this.parts = [];

    // Create the head
    var part = new SnakeHead(startX, startY, partSize, color);
    this.parts.push(part);
    ...
    ...
    // Create the rest of the snake body
    for (var i = 0; i < length - 1; ++i) {
        // Create the snake part, the last arg is the part it should follow
        part = new SnakePart(startX, startY, partSize, color, this.parts[this.parts.length-1]);
        this.parts.push(part);
    }
}

/**
 * Adds a new tail to the snake
 */
Snake.prototype.addTail = function() {
    var currTail = this.parts[this.parts.length-1];
    var newSnakeTail = new SnakePart(currTail.prevLocation.x, currTail.prevLocation.y, currTail.size, currTail.color, currTail);
    this.parts.push(newSnakeTail);
};

/**
 * Changes the snake direcion
 * @param {Protocol.Direction} newDir
 */
Snake.prototype.changeDirection = function(newDir) {
    if (newDir === this.direction) {
        return;
    }

    // Make sure we can do the change (can't do 180 degrees turns)
    if (newDir === protocol.Direction.Right && this.direction !== protocol.Direction.Left) {
        this.direction = newDir;
    } else if (newDir === protocol.Direction.Left && this.direction !== protocol.Direction.Right) {
        this.direction = newDir;
    } else if (newDir === protocol.Direction.Up && this.direction !== protocol.Direction.Down) {
        this.direction = newDir;
    } else if (newDir === protocol.Direction.Down && this.direction !== protocol.Direction.Up) {
        this.direction = newDir;
    }
};

/**
 * Updates the snake
 * @param {number} [newSize] - The new snake size
 */
Snake.prototype.update = function(newSize) {
    // Check if the snake grew
    if (newSize && newSize > this.parts.length) {
        this.addTail();
    }

    // Update the head first
    this.parts[0].update(this.direction);

    // Update the rest of the snake
    for (var i = 1; i < this.parts.length; ++i) {
        this.parts[i].update();
    }
};

/**
 * Draw the snake
 * @param {Graphics} graphics - The Graphics object
 */
Snake.prototype.draw = function(graphics) {
    for (var i = 0; i < this.parts.length; ++i) {
        this.parts[i].draw(graphics);
    }
};
```
And here is the update method of `snake-part`, note how it just follows the location of the part ahead of him.
```js
/**
 * Updates the snake state
 */
SnakePart.prototype.update = function() {
    // Save the current location as previous
    this.prevLocation = this.location.clone();

    // We are just followers here...
    if (this.following !== null) {
        this.location = this.following.prevLocation;
    }
};
```
### Don't lose you head
The snake head is slightly different, it is not following anyone, it inherits from `snake-part` and overrides its `update` method.
```js
function SnakeHead(x, y, size, color) {
    SnakePart.call(this, x, y, size, color);
    this.direction = null;
}
// Inherit from SnakePart
util.inherits(SnakeHead, SnakePart);

/**
 * Updates the snake head
 * @param {VYW.Direction} newDirection - A new direction for the snake
 */
SnakeHead.prototype.update = function(newDirection) {
    // Do the base update
    SnakePart.prototype.update.call(this);

    // Update location based on updated direction
    this.direction = newDirection;
    switch (this.direction) {
        case protocol.Direction.Right:
            this.location.x += this.size;
            break;
        case protocol.Direction.Left:
            this.location.x -= this.size;
            break;
        case protocol.Direction.Up:
            this.location.y -= this.size;
            break;
        case protocol.Direction.Down:
            this.location.y += this.size;
            break;
    }
};
```

## Protocol
The game is using a custom protocol (why? see the previous post) for messages, each message has a type (number), and some fields in a predefined order. A field can be either a primitive (number/bool etc), or an object.
Fields are separated by `#` where object properties are separated by `,` .
The general structure of a message is: `MsgType#field1#field2#objFieldProp1,objFieldProp2#field3#...`
For example this is how the update message is encoded:
```js
var updMessage = {
  type: 5,                     // Message type
  timeToEnd: 53,               // Time to game end
  directions: [ '6', '4' ],    // The directions each snake is heading
  sizes: [ 6, 6 ],             // The snake sizes
  pellets: [ 34, 21, 67, 54 ], // The cell indices where we have pellets
  score: [ 6, 5 ]              // The players score
};

var encoded = '5#53#6,4#6,6#34,21,67,54#6,5';
```
The Protocol module (`protocol.js`) is responsible for encoding/decoding messages, it starts with exposing some enums to be used by other modules:
```js
// Private constants
var DATA_SEP = '#',
    OBJ_SEP = ',';

/**
 * Player direction enum
 */
Protocol.Direction = {
    Up: '8',
    Right: '6',
    Down: '2',
    Left: '4'
};

/**
 * Game over reason
 */
Protocol.GameOverReason = {
    PeerDisconnect: '1',
    Collision: '2',
    End: '3'
};

/**
 * Server messages enum
 */
Protocol.Messages = {
    Pending: '1',
    Ready: '2',
    Steady: '3',
    Go: '4',
    Update: '5',
    GameOver: '6',
    ChangeDirection: '7'
};
```
Then we define a class for each message type with the relevant fields, all messages inherits from a base Message class (this is our data model).
```js
/**
 * Creates a new message
 * @param {string} type - The message type
 * @constructor
 */
function Message(type) {
    this.type = type;
}

/**
 * @constructor
 * @extends {Message}
 */
function GetReadyMessage() {
    Message.call(this, Protocol.Messages.Ready);
    this.playerIndex = 0;
    this.board = { width: 0, height: 0, cellSize: 0 };
    this.snake1 = { x: 0, y: 0, size: 0, direction: 0 };
    this.snake2 = { x: 0, y: 0, size: 0, direction: 0 };
}

/**
 * @constructor
 * @extends {Message}
 */
function SteadyMessage() {
    Message.call(this, Protocol.Messages.Steady);
    this.timeToStart = 0;
}
...
...
```
Then we have our encode methods, these methods get the data they need as arguments, and return a string result (which is the encoded message), for example this is the encoding of the update message:
```js
Protocol.buildUpdate = function(tte, snake1, snake2, pellets, board) {
    // Update msg: 5#timeToEnd#playersDirection#snakesSize#pellets#score
    // playersDirection - player1Direction,player2Direction
    // snakeSizes - snake1Size,snake2Size
    // pellets - cellIndex,cellIndex,cellIndex...
    // score - player1Score,player2Score

    var msg = Protocol.Messages.Update + DATA_SEP + tte + DATA_SEP + snake1.direction + OBJ_SEP + snake2.direction + DATA_SEP;
    msg += snake1.parts.length + OBJ_SEP + snake2.parts.length + DATA_SEP;

    // Now add the pellets
    if (pellets) {
        var currPellet;
        var delim;
        for (var i = 0; i < pellets.length; ++i) {
            currPellet = pellets[i];
            delim = (i === pellets.length - 1) ? '' : OBJ_SEP; // Don't add separator for the last element
            msg += board.toBoxIndex(currPellet.location.x, currPellet.location.y) + delim;
        }
    }

    // Finally add the score
    msg += DATA_SEP + snake1.parts.length + OBJ_SEP + snake2.parts.length;

    return msg;
};
```
Finally we need methods to decode the messages, we start by split the encoded message into the different fields, check the first field (which is the message type), and call to the appropriate decode method based on the message type:
```js
/**
 * Parse a message
 * @param {string} msg - The message
 * @returns {Message}
 */
Protocol.parseMessage = function(msg) {
    // Message: "CODE#DATA"
    if (!msg) {return null;}

    var parts = msg.split(DATA_SEP);
    var code = parts.shift(); // This also removes the code from the parts array
    switch (code) {
        case Protocol.Messages.Pending:
            // No specific data for this message type
            return new Message(code);
        case Protocol.Messages.Ready:
            return Protocol.parseGetReadyMessage(parts);
        case Protocol.Messages.Steady:
            return Protocol.parseSteadyMessage(parts);
        case Protocol.Messages.Go:
            // No specific data for this message type
            return new Message(code);
        case Protocol.Messages.Update:
            return Protocol.parseUpdateMessage(parts);
        case Protocol.Messages.GameOver:
            // No specific data for this message type
            return Protocol.parseGameOverMessage(parts);
        case Protocol.Messages.ChangeDirection:
            return Protocol.parseChangeDirectionMessage(parts);
        default:
            return null;
    }
};
```
Here is the decode method for the `update` message, note how the message is parsed field-by-field, and each field is being verified to have the expected structure and data types:
```js
/**
 * Parse an update message
 * @param {string} data - The encoded message
 * @returns {UpdateMessage}
 */
Protocol.parseUpdateMessage = function(data) {
    // Update data: timeToEnd#playersDirection#snakesSize#pellets#score
    // playersDirection - player1Direction,player2Direction
    // snakeSizes - snake1Size,snake2Size
    // pellets - cellIndex,cellIndex,cellIndex...
    // score - player1Score,player2Score

    if (data.length < 5) {
        return null;
    }

    var res = new UpdateMessage();

    // Parse tte
    res.timeToEnd = parseInt(data[0]);
    if (isNaN(res.timeToEnd)) {
        return null;
    }

    // Parse players directions
    var dirs = data[1].split(OBJ_SEP);
    if (dirs.length < 2) {
        return null;
    }

    res.player1Direction = dirs[0];
    res.player2Direction = dirs[1];

    // Parse players sizes
    var sizes = data[2].split(OBJ_SEP);
    if (sizes.length < 2) {
        return null;
    }

    res.player1Size = parseInt(sizes[0]);
    res.player2Size = parseInt(sizes[1]);
    if (!res.player1Size || !res.player1Size) {
        return null;
    }

    // Parse pellets (if we have)
    if (data[3]) {
        res.pellets = [];
        var pellets = data[3].split(OBJ_SEP);
        for (var i = 0; i < pellets.length; ++i) {
            res.pellets.push(pellets[i]);
        }
    }

    // Parse players scores
    var scores = data[4].split(OBJ_SEP);
    if (scores.length < 2) {
        return null;
    }

    res.player1Score = parseInt(scores[0]);
    res.player2Score = parseInt(scores[1]);
    // The reason we check isNaN instead of (!player1Score) is that 0 is a valid value for this field
    if (isNaN(res.player1Score) || isNaN(res.player2Score)) {
        return null;
    }

    return res;
};
```

## End of part II
This is the end of the second post describing the common objects in the game, those modules are being used both in the client (browser) and the server (node.js).
In the [next part](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5.html) we will check out the client-side code.

A simple multi-player online game (HTML5 + node.js) - Part I

This is the first part of a 4 part series story where I describe what it took me to build a simple multiplayer online game ([part 2](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_55.html){_blank}, [part 3](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5.html){_blank}, [part 4](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_16.html){_blank}).

## Intro
I took a nice Coursera class on Game Programming and decided to experiment with programming a game in the browser using the Canvas element, the result was a nice Snake game (github, codepen).
Then I thought, what would it be to convert it into an online multi-player game, using node.js and WebSockets? So let me tell ya...

## Why "simple"? Who controls the game?
I started to think about how I wanted to implement the game, and the first question was "who controls the game"? do we put all the game management and business logic in the client and use the server just as a hub for broadcasting messages? or do we let the server control the game and the client just draw what the server says.
Set "cheating" aside, implementing everything in the client was much more simple, as I already had a working snake game... but... that isn't really an online game, so I decided to let the server be the king.
But hey, if the server controls the game, it means the snake (on the client) can't move until the server told it so, and if the player wants to change the snake direction he has to wait for the server's response before it will happen, this could lead to a very laggy game, that's when I went online to read a little bit about realtime online games, obviously I'm not the first one... After reading about the concepts of "client-side predections" and "server reconciliation" (great article) I decided to start with a "simple" game, meaning a game that would work perfectly over the LAN, and will be OKish over the WAN, also I will limit it currently to a "dual" match, meaning 2 players only per match. I believe there is still a lot to learn by doing so, and adding advanced concepts could be done later.
So... you can play the game on Heroku, the lag is obviously apparent, but not that bad...

## Terminology
The SnakeMatch is a regular "snake" game where player1 competes with player2 for Pellets, each match is for 60 seconds and the player who collected/ate more pellets wins. Of course that the regular Snake rules apply (a snake can't collide with itslef and can't hit the wall).


The game is built from the following "game objects":
  • Board - This is where everything happens, we divide the board into a grid, this will help us to make sure that all elements on the board are aligned.
    We index the cells for simplicity, starting from zero, then we can convert each cell index to a canvas x/y and vice versa
  • Cell/Box - A fixed-sized rectangle, each element on the board must fit exactly into a cell
  • Snake - The snake is built from "parts", where the first part is called the "snake head", we will see later how it is different from the rest of the body. Each snake part has the size of a board cell.
  • Pellet - This is what the snake needs to eat in order to grow, it also has the size of a board cell.
  • Status Bar - Holds the scores and the time till the end of the game.
## High Level Design
As we said, this is a fairly simple game, the server is responsible for managing the game, and the client is responsible for rendering the game state and send commands to the server.
Below is a schema of a game flow:


And here is a diagram with the main classes in the client and server:


## The Protocol
The protocol determines how the messages between the client and server will look like, my first thought was to simply use json, it is easy to understand and we have built-in functions in javascript to encode/decode it (JSON.parse / JSON.stringify).
However, there are two issues with json that bothered me:
  1.  It is a wasteful protocol (compared to custom protocol)
  2. Although parse/stringify are fast, when the server is under load, a custom protocol could do better.
For example, let's take a look at the following update message (remember we have 10 of those every second):
var updMessage = { 
  type: 5,                     // Message type
  timeToEnd: 53,               // Time to game end
  directions: [ '6', '4' ],    // The directions each snake is heading
  sizes: [ 6, 6 ],             // The snake sizes
  pellets: [ 34, 21, 67, 54 ], // The cell indices where we have pellets
  score: [ 6, 5 ]              // The players score
};
var encoded = JSON.stringify(updMessage); // encoded.length = 100
On the other hand, using a custom protocol, we would get the following string:
var encoded = '5#53#6,4#6,6#34,21,67,54#6,5'; // encoded.length = 28
Performance wise, here is a simple jsperf that compares a custom decode function vs json strigify, unless I have an error in the test case (which I might :)), on my laptop, JSON.stringify is 83% slower, that is quite a difference, especially if we would want later to increase the update rate from 10/sec to something like 30/sec...


OK, enough talking, let's see some code ([part 2](http://www.valyouw.com/2015/07/a-simple-multi-player-online-game-html5_55.html))...

Developing a markdown parser for Blogger

Friday, June 5, 2015

TL;DR I wrote a small script that let me use few markdown features in Blogger, the code can be found on [GitHub](https://github.com/ValYouW/simple-md-blogger){_blank}.
For instructions on how to add it to your blog jump to the bottom, there is a "Adding to a Blogger blog" section.

When writing a blog post it is much easier to insert code blocks using 3 backticks `\`\`\`` (GitHub Flavored Markdown), for example:
```
```js
function foo() {
    console.log('Im foo !!');
}
\```
```
Or, adding code quotes using a single backtick, like: `\`quote\``.
Or, adding titles using hashes, like: `# This is a title`
Or adding links using this pattern: `\[text\](url){target}`
This can be done by parsing the html and do some replacements of the text with html tags, there are 2 methods I came up with.

## Using Regex
Here is one options with RegExp only (Note: there is no support for links pattern in this method...)
```js
function parseWithRegex(post) {
    var html = post.innerHTML;

    // Replace all titles (h1/h2/etc), regex explanation:
    // ^[\s]* - Line can start with spaces, we ignore those
    // ([#]+) - Match a sequence of #
    // (?:\s)* - After the hash we can have many spaces, we ignore those
    // (.*?)(?:<br>)?$ - Then match everything in non-greedy mode (as little as possible) until the end, line can end
    // with <br> so we ignore it
    html = html.replace(/^[\s]*([#]+)(?:\s)*(.*?)(?:<br>)?$/gm, function(match, hashes, title) {
        var headerLevel = hashes.length;
        return '<h' + headerLevel + '>' + title + '</h' + headerLevel + '>'
    });

    // Replace all code blocks, regex explanation:
    // ^``` - line should start with ```
    // ([a-zA-Z]+)? - Then optionally we could have a language (characters only)
    // ((?:.|\n)*?)``` - Then we match anything until ```, since '.' doesn't match \n we need (.|\n),
    // and we don't want that brackets in the match so adding ?:
    // and we want to match until first occurrence of ``` (non-greedy) so adding *?
    // (?:\<br>)?$ - Then we expect br tag or end-of-line
    html = html.replace(/^```([a-zA-Z]+)?((?:.|\n)*?)```(?:<br>)?$/gm, '<pre><code class="$1">$2</code></pre>');

    // Next replace code quotes, regex explanation:
    // Match anything between backticks, the character before the closing backtick should not be (escaped backtick)
    html = html.replace(/`(.*?[^\\])`/g, '<code>$1</code>');

    // Next replace all escaped backticks (\`) with backticks
    html = html.replace(/\\`/g, '`');
    // Put the final html back in the post element
    post.innerHTML = html;

    // Loop thru all the created code blocks and remove all <br>, also remove the first "\n"
    var codes = post.querySelectorAll('pre > code');
    for (var i = 0; i < codes.length; ++i) {
        var code = codes[i].innerHTML;
        code = code.replace(/<br>/g, '').replace(/^\n/, '');
        codes[i].innerHTML = code;
    }
}
```
The problem with the method above is that it will replace non-escaped single backticks (`\`xxx\``) within a code block with a <code> tag, which is not desirable.
This can be solved by escaping all backticks within the code block, but lets try another approach which will keep `code blocks` untouched

## Parsing line-by-line
We can take our post html, split it into array using `\n` (so each line is a cell in the array), then we loop thru all the lines and do replacements, if we identify that there is a code block starting, we can mark it and not do anything until the code block closes (actually there is one replace we should do in code block, and that is if we have an escaped end block backticks, `\\`\`\``)
```js
function parseWithArray(post) {
    // Define the regex we are going to use
    var brRegex = /<br>/g;

    // Line starting with ``` and an optional lang specified, can have optional <br>
    var beginCodeRegex = /^```([a-zA-Z]+)?(?:<br>)?/;
    // Line starts with ``` and nothing but spaces till the end
    var endCodeRegex = /^```[\s]*$/;
    // Escaped code is \``` and nothing till the end
    var escapedEndCodeRegex = /^\\```[\s]*$/;
    // Anything between backticks as long as the char before the closing backtick is not a "\" (escaped backtick)
    var codeQuoteRegex = /`(.*?[^\\])`/g;
    // Escaped backtick: \`
    var escapedCodeQuoteRegex = /\\`/g;

    // \[([^\]]+[^\\])] - Anything that is between brackets as long as it is not "]" and there is no "\" before the closing bracket (escaped bracket)
    // \((.*?)\) - Anything between round brackets
    // (?:{(.*?)})? - Optionally can have some text between curly brackets
    var linksRegex=/\[([^\]]+[^\\])]\((.*?)\)(?:{(.*?)})?/g;

    // Match any escaped brackets "\[" or "\]"
    var escapedLinksRegex = /\\(\[|])/g;

    // Line can start with spaces, then comes multiple "#", then can have spaces, then any text, and optional <br> before line ends
    var titleRegex = /^[\s]*([#]+)[\s]*(.*?)(?:<br>)?$/;

    var html = post.innerHTML;
    var lines = html.split('\n');
    var incode = false;
    for (var j = 0; j < lines.length; ++j) {
        var line = lines[j];
        if (line === null) {continue;} // See later that we put null in the array[j+1], skip those cells

        // Check if we are in code block
        if (incode) {
            // No <br> allowed in code blocks
            line = line.replace(brRegex, '');

            // Check if this is the end of the code block
            if (endCodeRegex.test(line)) {
                incode = false;
                line = '</code></pre>';
            } else {
                line = line.replace(escapedEndCodeRegex, '```');
            }
            lines[j] = line;
            continue;
        }

        /*  Not in code block */

        // Check if this is a beginning of code
        var m = line.match(beginCodeRegex);
        if (m) {
            incode = true;
            // The first line in a pre block must be on the same line of the pre block,
            // otherwise we will get an empty space (as pre render \n)
            lines[j] = '<pre><code class="' + (m[1] ? m[1] : '') + '">' + lines[j+1].replace(brRegex, '');
            lines[j+1] = null;
            continue;
        }

        /* This a regular line */

        // Replace titles (#)
        line = line.replace(titleRegex, function(match, hashes, title) {
            var headerLevel = hashes.length;
            return '<h' + headerLevel + '>' + title + '</h' + headerLevel + '>'
        });

        // replace any inline code quotes `xxx`
        line = line.replace(codeQuoteRegex, '<code>$1</code>');

        // Next replace all escaped backtick (\`) with backtick
        line = line.replace(escapedCodeQuoteRegex, '`');

        // Next replace links
        line = line.replace(linksRegex, '<a href="$2" target="$3">$1</a>');

        // Next replace all escaped brackets \[\] with brackets
        line = line.replace(escapedLinksRegex, '$1');

        lines[j] = line;
    }
    post.innerHTML = lines.filter(function(l) {return l !== null;}).join('\n');
}
```

## Adding to a Blogger blog
In order to use this in your blog:

* Edit your blog's template HTML
* Find the <head> tag and add the following script:
```html
<script src='//cdn.rawgit.com/ValYouW/simple-md-blogger/8a142bd56bd29221e5a73e746f49462b7046ebc4/blogger-md.js'/>
```
* Then add a script tag that will parse the blog posts when the page loads:
```html
<script type='text/javascript'>
document.addEventListener("DOMContentLoaded", function(event) {
    // NOTE: Check what is the CSS class of the posts in your blog
    var postsSelector = '.post-body';
    window.VYW.parse(postsSelector);
    // If you have some library to format code blocks (like highlight.js), call it now.
});
</script>
```
* Titles are converted to <h1> <h2> etc tags, you can set the style for those tags as the default might not suit your needs, for example I added the following style tag:
```css
<style type='text/css'>
.post-body h2 {
    font-size: 1.5em;
    font-weight: bold;
}
.post-body h3 {
    font-size: 1.2em;
    font-weight: bold;
}
</style>
```

## Performance
The performance of the two methods is quite similar, a jsperf test can be found [here](http://jsperf.com/vyw-md-parsing){_blank}
That's it, again, the code can be found on [GitHub](https://github.com/ValYouW/simple-md-blogger){_blank}
Enjoy!