Hackathon#4 - Toy Project Sn4k3
Nov 24, 2016
As they had only two days and a half to implement a full realtime multiplayer game, they had to pick something very simple - or even better - to reuse concepts they had already experienced.
Yevhenii was already familiar with Phaser (https://phaser.io/), a HTML5 game engine. Olivier, as a former Flash developer, had already worked on a “snake-like” game named Wurms (http://www.jemamuse.com/jeux/reflexion/wurms/wurms-jouer.html). Thanks to that he already knew which simple-and-stupid algorithms the team could use to generate the snakes bodies from circles, to make snakes move and detect snakes collisions. The Sn4k3-Team had setup backend with PHP 7 and Crossbar.io networking platform. Backend on PHP was based on ReactPHP(https://github.com/reactphp/react) framework in addition to Thruway (https://github.com/voryx/Thruway) for WebSockets.
Frontend was built with ES6 (converted on the fly to ES5 with Babel), bundled with Browserify (wink to Olivier’s presentation during the last hackathon), and powered by Autobahn.js for WebSockets layer.
The Crossbar.io was used as a middleware between frontend and backend, so they could easily communicate over websockets. The frontend sends events to the server and renders the snakes, and handles user interactions. Olivier and Alex worked on backend algorithms for collisions and movements, based on Wurms concepts. Meanwhile Adrien created a proof-of-concept with browserify and canvas. Alex worked on adjusting the speed of the game and growth of the snakes and adding the fruits into the world. Yevhenii introduced design elements to the front-end and the fruit generation. He also implemented the game canvas using Phaser library and created a score table.
They had performance problems, because in the first naive-but-quick implementation they were sending the whole world data to all clients on every tick, so performance started to degrade quickly over time. An improvement would be to send to each client only the world around it and not the whole world. Also there is a lighter network protocol : we send verbose integer, we can use binary information. In backend we use objects, so binary would help a lot. And of course, instead of sending the whole data of a given game area, it’s a lot lighter to send only a diff between the last known state of this area and the new state - like in video algorithms like MPEG.
The killer feature ;-) : a quick optimization of performances of picking fruits and their growth : because every 25 ms they had to calculate the collision between all snakes heads and all snakes bodies parts, it was better to optimize a bit before using Pythagoras's theorem.
This is why they first calculated very approximative distances between each objects. If it was below a given threshold, then they calculated a raw collision, based on a simple rectangles intersection formula. In the end, if the rectangles seemed to be in junction with each other (it felt like they were back to school) they finally used Pythagora’s theorem to check the collision with precision.
Here is their github : https://github.com/KnpLabs/Sn4k3