Web-Marbles is an online multiplayer browser game where players race each other's marbles down a hill. But good luck trying to win: Once the marbles start rolling you'll have no control over it! It's a game of chance, empty boasts, and heartbreak.
This project (brought to life by Merlijn van der Kamp) is inspired by the original Marble Racing Twitch game, and aims to recreate it as a cost-effective and completely web based game. All game logic runs on a server, leaving the client to do the rendering. Web-Marbles also comes with an in-browser level editor. The game is free to play and open source!
Levels play a large role in what makes marble racing fun, and it was an early decision to have a level editor that allows anyone to create and export a level that can be used to race on. While Merlijn created a prototype and was responsible for the interface, I focused on the workings behind the scenes such as serialisation and physics.
Due to our goal to be cost-effective, it was a priority to reduce the size of our levels as much as possible while keeping it easy to use and maintain. The levels are structured to prevent duplicate data, and are optimised separately for the server and client upon export, to keep data transfer and loading time to a minimum. For serialisation I opted to use MessagePack rather than JSON, as the former has proven to be smaller/faster and allows for embedding binary data without converting it to a text format. The level loading code is backward-compatible with older versions of the editor, a feature which has already been used extensively in production.
In order to create physically correct levels easily, I implemented a feature for users to generate and use mesh colliders (both convex and concave) in the editor with any given model. The convex collider generation uses the QuickHull algorithm, which is conveniently available in Three.js, the renderer that we use. To further improve our use of physics in the game, I refactored the physics code to support physics-related game logic (such as collision callbacks), which didn't work out of the box for our physics library, Ammo.js.
Since the marbles are simulated on the server, the resulting positions and rotations are sent over to the client, where they are interpolated. In order to keep the client's experience smooth and without hiccups, I implemented a flexible buffer system that minimises these hiccups if network issues are detected, while keeping the latency as low as possible. Following various additional optimisations, the server now performs much better with a large number of clients and the bandwidth use has been reduced significantly.
This is a living project, and there are still features we aim to add in the future! For a sneak peak of what we have planned, visit our GitHub page!