Liquid Chess
This is another example of liquid experience and how it can be incorporated with gaming applications to bring seamless multi-device experience to the user.
A game of chess that follows the user in his device of choice. The player (white pieces) can start and continue a game where he left off and the board state and the AI will follow on the next device.
As soon as the user runs the application, it will load the last run state. The game will continue where he stopped last time, start a new game if this is the first time or game is restarted with the 'reset game' button.
The gameplay continues normally with AI replies after every white move. Note that for demo purposes AI does dumb legal moves, there is no intelligence implemented.
In the scenario where the user is playing the game in his laptop and wishes to continue on his phones web browser, all he needs to do is drag the white king out of the board as if the king was fleeing the battle and the game will continue on his phone.
The state of the application is automatically transferred so the user experience is smooth and minimalistic.
A live demo can be played here
Code
Below we are going to discuss some of the key lines of code that make this possible.
First is setting up a connection to the Firebase database, this is where the application state is stored and retrieved from, in this case the board state.
var url="https://liquidchess.firebaseio.com/";
var chessbase = new Firebase(url);
To keep track of joining clients we keep a reference of their presence (allclientsRef), so how many clients are connected at the same time and make a distinction from ourselves (clintRef).
var allclientsRef = new Firebase(url+"presence/");
var clientRef = allclientsRef.push();
var presenceRef = new Firebase(url+".info/connected");
Whenever a new device connects to this application, its online state is recorded and when it disconnects it is removed.
presenceRef.on("value", function(snap) {
if (snap.val()) {
clientRef.set(true);
clientRef.onDisconnect().remove();
}
});
Application synchronization is triggered whenever player makes a move
var onSnapEnd = function() {
chessbase.update({ fen: game.fen() });
};
or the AI moves.
game.move(possibleMoves[random]);
chessbase.update({ fen: game.fen() });
Note that fen is a standard notation for describing a particular board position of a chess game. It provides all the necessary information like piece placement, active color, castling availability, en passant, halfmove clock and fullmove number. This encoding helps us move the state of the application with the least amount of information necessary needed, thus decreasing action delay over the network.
On client connection we also keep track of how many clients are connected (onlineClients) and our id (id), which for this demo is assigned incrementally when joining.
When the white king is dragged outside the board, which client has active application (possession) is updated, for this demo the next application in line (id+1) is chosen.
if(piece=='wK' && target=='offboard')
kingOut();
var kingOut = function(){
nextpossession=id+1;
}
chessbase.update({ possession: nextpossession});
};
As soon as the chosen client is updated in the firebase, it triggers events on all clients, the original one is paused, hidden thus not taking anymore inputs and the client whose id matches loads the board data and resumes the application state.
chessbase.on('value', function(data) {
possession=data.val().possession;
if( possession == id ){
document.getElementById("container").style.visibility="visible";
board.position(data.val().fen);
game.load(data.val().fen);
}
else{
document.getElementById("container").style.visibility="hidden";
}
});
Used technologies
- Data synchronization is done using Firebase
- Chess UI and game logic is done using chess.js and chessboardjs.