Multiplayer Minesweeper with Socket.IO
I built this project to learn technologies I hadn't used before and finish a small game from end to end.
I wanted to make something in real time to try out and learn Socket.IO, and a simple game with straightforward multiplayer interactions seemed like a good idea. I had different ideas, like using Phaser to create some new but simple game that could be played by any number of players, similar to Agar.io and its many clones.
That seemed a bit too much for the purpose of learning a real-time communication library, so I ended up with a much simpler concept: a turn-based multiplayer Minesweeper game.
My inspiration was Minesweeper Flags, the minesweeper game some of us played many years ago in MSN Instant Games within MSN Messenger and Windows Live Messenger:

In this game, players take turns revealing tiles on a board with the goal of finding as many mines as possible. The player that finds the most mines when all of them have been found wins. There is also the bomb, a power up that reveals a square of tiles at once, and it can be used once per game. When a player finds a mine, they can play again, allowing for fun streaks and comebacks.
The main difference between the old game and my implementation is that the new one allows for any number of players. You can set up a big board and play with a group of friends while talking in the game chat.
This is how it looks:

Tech breakdown
These are the technologies used in the full project:
| Client | Server | Shared | |-------------------------------------------------|----------------------------------------------|----------------------------------------------------------| | Rendering: ReactJS | Server: NodeJS | Real-time communication: Socket.IO | | Styling: TailwindCSS | Database: MongoDB | |
React was the only technology in this table I already knew. I used it to render the interface, keep client state, and handle user events.
Socket.IO
Socket.IO was the most interesting and useful library I used. It has separate client and server libraries, with support for several languages, and you can actually combine any of the implementations.
To keep things simple, and because I hadn't built a server with Node.js before, I used JavaScript on both the client and server.
Here's a small example of client and server sending and handling messages:
// Client
// Sending a message to create a room with custom parameters to the server:
socket.emit('create_room', gameType.boardSize, gameType.mineCount)
// Listening and handling a message from the server:
socket.on('room_created', ({ id }) => {
// Handle `room_created` from the server using the parameter `id`.
})
// Server
// Sending a message to the client connected to `socket`:
socket.emit('room_list', exportedRooms)
// Listening and handling a message from the client connected to `socket`:
socket.on('create_room', async ([boardSize, mineCount]) => {
// Handle `create_room` using parameters `boardSize` and `mineCount` sent by client.
})
As you can see, messages are sent and received in a very similar way from the client and the server. There are some differences and details to take into account, like for broadcasting a message to a room:
// Server
// Add the user connected to `socket` to a room:
socket.join('room_' + state.currentRoomId)
// Send a message to a room:
io.to('room_' + room._id).emit('room', roomData)
If you want to learn more, you can see Socket.IO's excellent documentation here.
There is also a very good Get Started with some interesting small projects.
I want to play
You can play the game on https://minesweeper.clotet.dev and see the code on https://gitlab.com/rogerclotet/minesweeper.