Inspiration
We were inspired by mazes and cooperative games where each player has a unique action and their own part, akin to things like twitch plays pokemon. Octolabyrinth is a fun online multiplayer party game that can handle up to 16 players.
What it does
One person is the host and displays their screen ideally on a large projector. Then up to 16 players can join on their phones/laptops by visiting a unique url (or scanning qr code).
The aim is to work together as a team to get to the center of the maze before the other teams. Once the game is started everyone is assigned to teams of at most 4 players. Within a team players are allocated directions they’re allowed to move their character in. Crucially only one player has each direction. So if there was a team of 4 then everyone has a single direction. Then to increase the pressure the team furthest away from the center is eliminated every 30 seconds until only one remains.
Players send controls by pressing buttons on their devices, and the maze is only visible on the host’s computer - ideally projected in a way that’s visible to all players.
How we built it
The project turned out to be much more complex to implement than we initially thought.
We needed to create a backend that could handle multiple games and each game has multiple players. The code also has to be fast enough to handle a large number of simultaneous connections, and also so that the game feels responsive. We achieved this by making careful use of maps and avoiding unnecessary searches. For example we intentionally store both a mapping from players to teams and teams to players. The average response time for a request is only ~15ms
When the create game button is pressed a game is created and a maze generated using a sophisticated maze algorithm that ensures every cell of the maze is reachable from any other cell. Then anyone visiting /play/ gets assigned a player id, and added to the game. They’re also prompted for a name which is displayed to everyone when they connect on the projector screen.
We need the host’s computer to poll the server so we can show a list of all connected users.
Once the start button is pressed players get assigned to teams and also assigned moves. The players poll the server and then display their moves on their screens.
From this point the game is being played. We’ve implemented server side throttling so players can only send moves every ~300ms. We’ve also implemented a watchdog for each player so that if a player disconnects they’re removed from their team and their moves are reassigned to their teammates. All moves are validated server side to prevent players from trying to make moves that they don’t have access to.
We ended up using a React/Typescript, Express/Typescript stack. Using typescript for everything allowed us much faster development as we weren’t constantly switching languages. Both React and Express have extensive documentation which was helpful when we ran into issues.
The site is bundled in a docker container which we have deployed on digital ocean. It’s currently running on a droplet with 4 cpu cores and 8gb ram but this might be overkill.
Challenges we ran into
Some bugs were present that we had to take care of. What if a player leaves the game at any point? The game would continue as normal but the team the players left would be pretty unhappy with losing movement in one direction, which would render it unplayable and not very fun. The solution to this was to keep track of when we last saw the player (we should see them frequently as they are polling the backend) and if we haven’t seen them for 5 seconds, then we remove them from the game and redistribute their moves to the first player in that team;. Nothing has been done for when all members of a team have disconnected as it wasn’t necessary. The game will run its natural course anyway.
Trying to split players across teams evenly and then the directions of movement for players between them was quite a challenge. We have a maximum of 4 players per team as long as there are enough players. If we had less than 4 players then we could assign each person their own teams of which there would be three. Each player would have the full movement set too. If there were 5 players then one team would have an extra player and the movement set for each player in that team is halved, It took a while, but the way this was done was to round the number of players divided against the maximum number of people per team and clamp it so there’s at least two teams and it doesn’t increase past 4. It would be possible to increase the number of teams past four as there’s a constant value that can be changed in the code. We then iterate over every player and assign to any team that isn’t full then. For splitting the movement set we also do something similar in which we keep iterating over players in each team until the directions have been exhausted for that team. This ensures we spread the directions over all members of the team and each team has access to every direction
Accomplishments that we're proud of
This was our most complex project to date and we’re happy it works. Syncing state across many clients with a server is something we’re not accustomed to, and was a challenge. In addition writing high performance server code was something completely new. Essentially we’d never written any online multiplayer game or even any game before.
What we learned
We learnt how to look out for and handle issues with syncing state between many clients and issue corrective action when something goes wrong. We know now all maze generation libraries have only most recently been updated several years ago and so are tricky to get working with modern javascript.
We’ve both learned a lot about writing online games and also using express and react.
What's next for octolabyrinth
Adding power ups into the maze. More complex / interesting mazes. New game modes / other games using the tech we’ve developed. Potentially moving to websockets rather than polling to decrease latency, however given latency currently isn’t an issue this might not be needed.

Log in or sign up for Devpost to join the conversation.