The Boat Game 2
Play ↗Intro
The Boat Game 2 is a small online multiplayer boat-racing game featuring 10 tracks, bouncing collisions, tubes, trampolines and an online leaderboard. The project was intended to improve on my previous game, The Boat Game, but not all the goals I wanted were achieved.
The game was created in 8 months independently.
Overview
The idea was simple: create an improvement on my previous project, The Boat Game.
The goals were to:
- Build a map editor to make more maps
- Improve the multiplayer mode
- Make it fun for everyone (as the last game was too difficult)
- Have an online leaderboard which displays names and scores
In the end, I achieved two of these goals: increasing the number of available maps and adding an online leaderboard.
However, I still believe it is an improvement from the last game, and the difficulty introduced more competitiveness, as many of my friends have complimented the new art style and are competing for top spots on the leaderboards.
Technology
The movement of the boat is simple, not differing much from normal car movement other than the decrease in traction. This increases the slip on the boat, and, similar to the last game, increases the difficulty.
Collision detection is handled using sphere casts. Each obstacle is represented as a border defined by a starting point and an ending point. When the boat collides, its velocity is flipped completely with little energy lost. This introduces the boat’s bouncy behaviour (which, despite being criticised, I really enjoy).
The tubes were an early implementation in the development process, as I knew I wanted something in addition to the trampolines. They work by checking if the player is within the area to enter the tube. When so, the player’s position interpolates from one end of the tube to the other, and is then shot out at maximum speed.
The mobile version uses an npm package named “Nipple.js”. I also made the steering faster on mobile as it was too difficult and I learnt from Blockmania 2 that the mobile version may need more assistance.
The “3D” rendering of the boat is done by layering many sprites, with very small offsets in the Y-axis. This creates an interesting effect also used in my previous game. However, the decorations in the maps are simply 2D sprites.
Structure
The game runs on a Node.js server and uses Socket.IO for real-time communication. I used the npm package “better-sqlite3” to create the leaderboards and check the browser fingerprint to ensure there are no duplicates on the leaderboard. Each of the 10 tracks is a JSON file with custom data which is loaded when the player or server chooses the track.
To structure the different “pages” on my game, I used a system of scenes like this:
// Keeping the scenes in separate folders allows me to keep them contained
import * as Game from "./game/index.js";
import * as Menu from "./menu/index.js";
const scenes = {
menu: Menu,
game: Game,
};
// Having a global function allows me to change the scene simply whenever I need
window.changeScene = function (sceneName) {
scenes[currentScene]?.unload?.();
clearButtons();
currentScene = sceneName;
scenes[currentScene]?.load?.();
};
let currentScene;
changeScene("menu");
Tools
For the sprites, I used “Figma”, as all the sprites were first made as vectors, then rendered at a lower resolution. The music and sound effects are all from “Pixabay”, and I only used free sounds. I then used Howler.js to play these sounds.
Lessons learnt
-
Socket.IO handles everything on the server, including the database calls, which keeps the architecture simple, but ideally, one day I will have a singular server to handle high scores for every game.
-
The game does not have advanced client-side prediction or interpolation and lacks any server-authoritative movement. The player’s position is updated to the server every frame, and this causes stutter on other players’ devices.
The game taught me how to structure a larger game, integrate database operations into the server and more. It is the largest project I have made so far, and despite still having bugs, I believe it to be the best!




