How to Build a Multiplayer Web App [Code Lab with Mad Genius Escapes]

The hardest part of a project is often just getting started. In my interview with Peter Lewis, co-creator of The Truth About Edith and Boobano Farm, he ended with some advice to fellow creators: even as no-code platforms for multiplayer escape games become increasingly available, there is still much to be gained from building this sort of interactivity from scratch. Not only will you learn something new, you’ll also inject your personality into the game through the hands-on development process.

With this in mind, Peter and I put together this step-by-step walkthrough for coding a simple web app which uses the same tech stack as The Truth About Edith and Boobano Farm. If you have some coding experience and want to learn about developing collaborative or asymmetrical web-based gameplay, this code lab is for you. 

We hope this serves as a jumping-off point for you to build your own games, and we’d love to hear about your future creations!

Digital Boobano Farm jigsaw puzzle scrambled.


  • Make a simple web app which allows multiple players to solve a jigsaw together
  • Learn how to use Socket.IO and Node.js to implement server-synced interactions


Stage 0: Getting started

  1. Make a folder for the app, and cd there. Add two new empty files called index.html and server.js.
  2. Initialize a Node package for the folder with npm init. You can hit “enter” to accept the default options. When asked for an “entry point”, make sure server.js is specified.
  3. Install the dependencies needed for this app. You’ll see how these are used later.
npm install express
npm install
  1. Initialize the folder as a Github repository. This allows us to directly deploy to Heroku. If this is your first time using Git, you’ll be prompted to configure your GitHub email and username.
git init
git add .
git commit -m "first commit"
  1. Create a new empty Heroku app with heroku create <projectname>. If this is your first time using Heroku, you’ll be prompted to log in here.
  2. Deploy our (empty) app to Heroku to check that all this initial config worked properly with git push heroku master. If this is your first time running this, you may be prompted to log into your Heroku account online.

Your app will now be available at <projectname> However, you’ll just get an “Application error” page since index.html is currently empty. (You’ll be able to redeploy the app anytime later once we’ve started building it!)

Stage 1: App structure and puzzle piece initialization

  1. In server.js, add the following boilerplate code setting up Express (a helpful framework for Node.js) and Socket.IO.
'use strict';
const express = require('express');
const socketIO = require('');
const PORT = process.env.PORT || 3000;
const INDEX = __dirname + '/index.html';
const server = express();
server.get('/', (req, res) => {
const listener = server.listen(PORT, () => console.log('Listening on ${PORT}'));
const io = socketIO(listener, {
    pingTimeout: 120000
  1. In server.js, add on the following code. We’ll store an array of the coordinates of each piece server-side, initialized randomly within a 600px x 600px canvas. Then using socket.emit(), we’ll send this position data to a client-side function which we’ll call placePieces().
var piecePositions = [];
for(var i = 0; i < 20; i++){
    piecePositions.push([600 * Math.random(), 600 * Math.random()]);
io.on('connection', (socket) => {    // Any functions we want to listen for go in here
    socket.emit('placePieces', piecePositions);
  1. Now let’s define that client-side function placePieces. In index.html, add a div playArea as a container for all the jigsaw pieces. Then, add some JavaScript which places the pieces using the position data from the server. Once we add in the ability to move the pieces around, this function will update the piece locations essentially continuously.

For the purposes of this demo, Mad Genius Escapes has provided a set of 20 Boobano Farm-themed puzzle pieces, hosted on their server and named “piece1” through “piece20”. To ensure the correct sizing, we also explicitly set the correct width for each piece. (There are more elegant ways to do this if we were actually building a jigsaw app.)

<!DOCTYPE html>
<div id='playArea'></div>
<script src="/"></script>

let socket = io();
var pieces = [];
const sizes = [150, 221, 209, 316, 217, 138, 233, 234, 318, 183, 145, 216, 290, 257, 181, 151, 213, 279, 270, 194];

function placePieces(positions){
    var thisPiece;
    let playArea = document.getElementById('playArea');
    for(var i = 0; i < 20; i++){
        thisPiece = document.createElement('img');
        thisPiece.src = '' + (i + 1) + '.png'; = positions[i][0] + 'px'; = positions[i][1] + 'px'; = sizes[i] + 'px'; = 'auto';
        thisPiece.pieceNum = i;

socket.on('placePieces', placePieces);

  1. In index.html, add some styling to get rid of the default image drag effect, change our mouse to a pointer hand when hovering over a piece, and set a transformation so we’ll eventually be dragging from the center of each piece.
.piece {
    position: absolute;
    cursor: pointer;
    transform: translate(-50%, -50%);
img {
    user-drag: none; 
    user-select: none;
    -moz-user-select: none;
    -webkit-user-drag: none;
    -webkit-user-select: none;
    -ms-user-select: none;

Now is a great time to check in on what this code is doing. After pushing the new code to Heroku, you should see the 20 pieces randomly scattered around the screen. Next up: making the pieces moveable!

git add .
git commit -m "place pieces"
git push heroku master

Stage 2: Make the pieces moveable

  1. In index.html, add the following functions in the script block. We’ll use selectedPiece to keep track of which piece, if any, is currently being clicked by the user. This is set back to null onMouseUp. In onMouseMove(), if the user has a piece selected, we send the coordinates for that piece back to the server.
var selectedPiece = null;

function pieceClicked(){
 selectedPiece = this.pieceNum;

function onMouseMove(e){
 if(selectedPiece == null)
 socket.emit('movePiece', [selectedPiece, e.clientX, e.clientY])

function onMouseUp(e){
 selectedPiece = null;

Now let’s use these new functions. In index.html, add the following 3 lines to the existing placePieces() function:

function placePieces(positions){
    for(var i = 0; i < 20; i++){
        thisPiece.onmousedown = pieceClicked;
    document.addEventListener('mouseup', onMouseUp);
    document.addEventListener('mousemove', onMouseMove);
  1. Socket.IO allows for ongoing two-way communication between servers and clients. For placePieces, we have a socket.emit() on the server and a socket.on() on the client, sending data from the server which is received by each connected client.

For movePiece(), we’ll be sharing data in both directions, from the client to the server and back from the server to the client.

We already added socket.emit('movePiece', [selectedPiece, e.clientX, e.clientY]) in onMouseMove. Add the following code in server.js to receive this position data and update the piecePositions array for that piece. Then, we’ll send the updated position data back to the client.

io.on('connection', (socket) => {
    socket.emit('placePieces', piecePositions);

    socket.on('movePiece', (data) => {
        let pieceNum = data[0];
        let piecePos = piecePositions[pieceNum];
        piecePos[0] = data[1];
        piecePos[1] = data[2];
        io.emit('movePiece', data);

Back in index.html, we’ll receive this data and update the position of the moved piece accordingly.

socket.on('movePiece', movePiece);

function movePiece(data){
    let piece = pieces[data[0]]; = data[1] + 'px'; = data[2] + 'px';

While this back-and-forth would be redundant if there were just one client connected to our app, it suddenly becomes really powerful when multiple clients are connected. Each client sends data on which piece they’re moving, and the server sends updated piece positions aggregated from all the clients back to each client. Thus, in real time each client sees their own pieces moving as well as any pieces that are being moved by other clients.

To test the final version of the app, git commit your most recent changes and git push heroku master.

What’s next?

This code lab demonstrates how to use Socket.IO, not how to make the perfect jigsaw app. The jigsaw app we built is admittedly quite janky, and some simple improvements might include:

  • Add a “claimed” property to pieces so multiple players can’t try to move the same piece at the same time.
  • Snap together correctly placed pieces.
  • Drag pieces from the actual mouse position rather than the center of the piece.

More importantly, the simple code pattern you’ve now seen can be used to share any sort of data between clients and a server. Players might all see the same interface and have the same controls, as in this jigsaw example, or players might each have a different view and different controls for asymmetrical interactions. To accomplish this, we could give players unique login codenames, as in The Truth About Edith, or dynamically assign players roles based on the order in which they arrive on a page.

Players might each have their own button, control their own character, or be presented with a unique subset of puzzle data. The possible interactions you can build using Socket.IO are endless, and we look forward to seeing what you create on your own. This cheat sheet for Socket.IO emits is useful, and there are numerous other tutorials and resources available online.

If you’ve made it this far, you probably like learning about escape game design and technology. We invite you to the Reality Escape Convention, August 22-23, 2021. This digital event brings the global escape room player and creator communities together for 2 days of connection, learning, and sharing.

Creating a Remote Escape Room with Asymmetrical Gameplay: Interview with Mad Genius Escapes

The Truth About Edith was one of the first online escape games I played during lockdown last May, and a year and a hundred-odd remote escape games later, it’s still the game I most frequently recommend. For my team and so many others, this game facilitated meaningful, joyful, laughter-filled remote connection early on in the pandemic, at a time when we were all mourning the recent closure of escape rooms globally. From a design standpoint, I consider this game to be groundbreaking in demonstrating how caringly home-brewed artwork, tech, and acting can lead to a compelling remote experience.

I hopped on a Zoom with Peter Lewis, the co-owner of Mad Genius Escapes in Portland, OR, to dive into his experience creating The Truth About Edith and Boobano Farm. In the last section of the interview, we discuss the tech behind building web apps with asymmetrical gameplay.

Additionally, here is the Code Lab that accompanies this interview. Using the same tech stack as Edith and Boobano, you’ll learn how to build a simple web app that allows players on multiple devices to solve a jigsaw together.

Note: This interview contains light spoilers for The Truth About Edith and Boobano Farm.

Edith up close to the camera on a Zoom call.
The Truth About Edith

You released The Truth About Edith very early on in the pandemic. What were your goals in creating the game?

We realized that if we designed it right, it could be played by anyone, anywhere. We didn’t know if it would end up being fun. We didn’t know what a good price point would be. But at that point, it’s like, the world is falling apart and we just had to do something, and it did seem like there was a lot of potential.

Edith seems like it’d be fun and accessible to a very broad audience. Is there anyone for whom the game hasn’t landed?

One lady signed in and immediately said, “I didn’t know this was going to be on Zoom. I’m not doing this.” And we’re like, “oh what, really?” And she’s like, “I’m not paying to be in a Zoom for an hour.” She demanded a refund, which we gave her, and then she left a one star review that said “this is just on Zoom.”

That’s one person out of everybody, and everyone else has been lovely! Young people have played it. Old people have played it. People seem to get it really well. That’s where it helps to have a clue master. Our clue masters are probably 25 or 30% tech support at this point. Refresh Chrome, try this, try that, because people have problems with tech for sure.

How did you develop the asymmetrical gameplay in Edith?

The asymmetrical aspect was going to make it unique and different and fun off the bat. When building The Truth About Edith, we played a lot of Keep Talking and Nobody Explodes. That was the first asymmetrical game I’ve played and I loved it, so we knew that style of gameplay was fun and the way we ended up setting up our online framework, it was included.

When somebody logs in, they’re sent a role. You’re looking around for some information – that’s great, that’s a puzzle. But you’re looking around for some information and everyone has a different control, that’s something else. It requires communication and teamwork, which is what you lose when you go virtual.

Unfortunately, there are times when the gameplay can really hinge on one person, and it’s completely random. If you get the wrong person, you’re a little screwed…. But again, the clue master can just fill in. Over time, as stuff has popped up, I’ve given extra abilities to the clue masters in their interface.

How did the actor interactions in Edith develop?

The game used to have three different characters, and it was just too long. So, we worked with one of my friends who’s a story consultant and pared it down, and it made the whole narrative a lot clearer. We realized that by taking out the first two characters, it makes the point where you actually meet Edith more exciting and more fun.

Plus, it’s so much easier for us. When we started, one person would be the clue master and two people would be actors, and that was just financially impossible. We were paying three people to be on for every game. 

It was one of those moments where everything just kind of lines up and makes sense all at once. The great part is that the other characters can be in our next game! We have this part all built out where there’s this creepy Mad Genius employee, and he has a robot that he’s tinkering with, and then you can log in and control the robot… I don’t want to give too much away, but it’s pretty cool.

I’m really curious about your next game. Is there already a plan for it?

We actually all have other jobs now, which is sort of tricky. This was our full-time thing for a couple years. I do all the programming, half the puzzle design, and the music. My sister Katie does puzzle design, business management, and the art. We have two employees who also do art.

But now, as a combination of just being at that point in your life and it not really being sustainable with the pandemic, we’ve all gotten involved in other things. Which, to tell you the truth, is working out pretty well. We haven’t built a full game since then, but we’ve managed to run the games we have and maintain them and make improvements. But I think there’s just so much we could do with another game and people are so awesome and so supportive that I feel like it’s inevitable that we come out with our next game at some point.

Wow, you also write the music for your games?

Yes! I’ve played music all my life. I love recording – it’s my main hobby and passion. And so, Boobano Farm was especially fun. I composed and recorded all the music for it and am really proud of the Boobano theme. Maybe I’ll put out an album of Mad Genius music one day…

A Boonabos on a journey.
Boobano Farm

Speaking of Boobano Farm, while Edith is designed for 4 players, Boobano Farm is for 8-16 players. Tell me about designing gameplay for larger teams.

At first there was no asymmetrical gameplay at all, and it was supposed to be for 40-50 people who are not communicating because we didn’t think that many people would be able to talk at all. So the idea was: wouldn’t it be cool if the players figure out a puzzle just by seeing whatever everyone else is doing? You see, you mimic, you participate, and then together you actually accomplish a huge task that would have been impossible otherwise. That inspired the ant colony metaphor of Boobano Farm.

After our first test, we realized a lot of it wasn’t working. Even after you figured out what to do, it felt too much like a chore. So, we set out to make it more puzzly. The way we decided to do that was to introduce an asymmetrical element to each puzzle, where we’d split players into two groups. We’d also realized in our beta tests that people could talk and they were talking. Even with 40 people, communication wasn’t really an issue.

We thought that by bringing down the number of people, we could make the puzzles a little smaller and more puzzly, bringing it closer to a traditional escape room. That really worked, luckily, and we’ve just been tweaking the puzzles in that direction ever since.

Is there anything you wish you’d done differently in creating Boobano Farm?

The design of the puzzles in Boobano Farm could have been better from the beginning. We were thinking of things that a lot of people could do at once, like a crossword or memory flipping cards, but then we went back and tried to add in the aha. I think we did the best we could and I think it does work, but I’d recommend to everyone: never cut your design process short. Never underestimate how important that part is, because you’re going to do so much work coding it up that it’s really worth designing it first.

Speaking of coding, what was your tech stack for these games?

The whole thing is built in HTML, JavaScript, Node, and Socket.IO, a websocket library. 80% of it is client code, and 20% is server code. Socket.IO lets people connect to your server and let your server connect to anybody who visits the page, making it relatively easy to build in asymmetrical gameplay.

The server runs Node.js, and there are a few lines of this thing called Express which set up the Socket.IO connection. Each browser that connects gets a socket ID. They can send any message they want, like text or data, to the server. The server reads the message and the ID and can send messages back, either just to that person or to everyone. Once you have that, you can really do whatever you want. It works so well: there’s no latency, and they say you can have thousands of connections.

Where it gets a bit trickier is parceling your sockets into different “rooms” and knowing who’s in which, if you want to run multiple games at once. And then there’s the question of how to block just anyone from logging in. We didn’t really want to have account logins, so we thought as simple as possible – let’s just make it a one-word password.

What tech changes did you make going from Edith to Boobano Farm?

With Edith, each individual app was its own Node/Heroku folder that I was copying and pasting most of each time. Going into Boobano Farm, I took all the stuff that was happening every time and made these “engine” files their own thing which I can now “include.” This sets up room management, codename verification, and some basic shared functions like clearing the room. I was so close to getting players’ video and audio into the site, but it just wasn’t working consistently enough. I was heartbroken that we couldn’t get it, but we just had to move on.

Do you have any advice for other creators interested in making remote escape games?

We’re going to see several platforms come out soon that let people make interactive, maybe asymmetrical, custom stuff for their games – which is great. But I hope it doesn’t dissuade a few people from still trying to build these elements themselves. I would love to play anything someone makes from scratch because they’ll just inject so much of their character into it, just by means of doing it.

We always give ourselves a lot of permission. That’s why we do it – to have fun and express ourselves creatively. If it makes us laugh, it’s probably going to go in, even if it’s really stupid.

For a deeper dive into the tech stack mentioned in this interview, check out the code lab we put together with Peter. You’ll learn the basics of Socket.IO through building a simple web app which allows players on multiple devices to solve a jigsaw together.

Mad Genius Escape Co. – Boobano Farm [Hivemind Review]

Boobano Farm is included in our recommendation guide for  The Best Online Escape Games for Large Groups. For more of the best online escape games in this style, check out the recommendation guide.

Boobano Farm is a multiplayer online puzzle game created by Mad Genius Escape Co. in Portland, OR.

A collection of adoable and colorful cartooish bugs called Boonabos.
Note the game’s name was changed from Boonabo Farm to Boobano Farm (and this image is from before the name change.)


Style of Play: multiplayer online puzzle game – somewhere between a digital escape game and a point-and-click adventure

Required Equipment: computer with an internet connection

Recommended Team Size: 8-10 (supports teams of up to 16 players)

Play Time: 60 minutes

Price: $15 per person

Booking: book online for a specific time slot


Boobano Farm was a chaotic multiplayer online game. This was a browser-based live game with a Zoom-based component. Nearly all interactions took place in a point-and-click interface, played live. It focused on collaborative puzzles that required teamwork. Boobano Farm was meant to be played with a team of 8-16 players.

A Boonabos on a journey.

Hivemind Review Scale

Mad Genius Escape Co. – The Truth About Edith [Hivemind Review]

The Truth About Edith is a virtual escape game created by Mad Genius Escape Co. in Portland, OR.

Edith up close to the camera on a Zoom call.


Style of Play: Natively online escape game blending multiple media

Required Equipment: computer with internet connection

The game has to be played on a computer with Zoom downloaded and either Chrome or Firefox. It’s helpful to have a second screen. You’ll be interacting with both websites and video. It won’t work on tablets or phones.

Recommended Team Size: exactly 4

Play Time: 60 minutes

Price: $80 for a team of 4 players

Booking: book online for a specific time slot


The Truth About Edith is played over Zoom with a live gamemaster and a live actor. However, it is not played via an avatar in a real-life escape room. Our job was to investigate a strange woman. We followed clues to different bepuzzled websites, and encountered a couple of different characters over video call.

Hivemind Review Scale