I’m an escape room enthusiast, some may say addict, and for the past few months I’ve been missing it. A friend of mine, a true addict with over 500 rooms to his name, started organizing online competitions. After playing a few of the online games, I thought, “I want to build my own.”
So for that past couple of months I’ve been writing an online escape game — which you could say is a web puzzle game, but with the exciting flare of escape! It’s suitably called “Prototype”. I assumed that name would let me get away with some rough edges. This will be an evolving project, but the first installment is a success.
I’m proud of my game. I want to tell you how I made it.
Technology for the user
I had a few major goals for the game. These sit somewhere in the spectrum between user epics and use cases.
- Painless experience for the user: I wanted it all in the browser. These types of games are relatively short, and needing to download something would be a pain.
- A multi-player team experience: Real rooms admit teams of 2-6 or more players, and I wanted my game to allow the same. Additionally, a certain world crisis is an excellent motivator for remote team play.
- Painless registration: Beyond paying, I didn’t want any registration at all. This bugged me about many other games. Just let people play as quickly as possible.
Obviously clever puzzles and a fun experience were paramount, but it’s harder to quantify those directly. Those would be the product goals, and I felt the above points were critical to supporting those goals.
Given these requirements, I set out to write my own engine, as I saw nothing that would come close to what I want. I was picky with my game, not letting it get away with anything I’d complain about in other games. Naturally, a few priorities chipped a few notches in that plan.
Overall, I achieved those goals. Let me know where I should elaborate — priorities again, I don’t want to be writing blindly about everything!
A puzzling web stack
A design had been floating in my head for a while before I set down any code. There was some trial and error, but the architecture was stable from the start, with only a few deviations in method.
Here are some major pieces of the stack.
- React: Just React. No optional modules, no plugins, nothing. The core of React provided what I needed. Since I had a state machine, there was no need for something like Redux.
- Python and Flask: The server components, and game processing, are written in Python using Flask, with Flask-SocketIO, with Eventlet (always so unavoidable many layers here).
- Redis: A small, but essential part to coordinate the multi-player actions.
- SVG: I’m listing this as it’s a key part of the engine. Everything is based on SVG working well in the browsers. It was a major trouble point, yet surprisingly rewarding.
There are also the typical web server bits, using Jinja templates, talking to Mongo, Paypal… Zzz. Yeah, I’ll mention these bits more, but I suspect there’s nothing novel here.
Until late in the project, this was a mass of wiggling bits! I had many stressful days trying to juggle tech in my head. Getting something working was my primary goal, and I did that in stages. Now, as I write more games, I’ll keep refining the stack, but there won’t likely be any major architectural changes.
Languages are what I do
As a good friend of mine said, “No Edaqa project would be complete unless there’s a new language.” I’m too blinded by the beauty of languages to even catch a hint of criticism there.
The most important question of the technology is: did I want to write a game engine? The answer is a resounding “no!” I wrote the engine because I wanted to achieve my primary goals, saw nothing else that fit, and knew an engine was within reach. I wanted to design games. And I wanted to not be overly burdened while designing.
Thus there’s a domain-specific language for the games. It’s a high-level declarative language. I fully expect that long-term I’ll write other engines for it. My goal was to keep the game logic clean, without being bound to the engine. I want to write games and ensure that long-term I can maintain those games.
I’ll be happy to show you how the language works, what the preprocessor does, and how the game handles the code.
As they say, “Ask me anything”
I hit a lot of knowledge pockets and defects on this project. Not everything I did is obvious — and I hesitate to say some illogical bits remain. But I’m happy to talk about all of it.
Let me know what interests you the most, and I’ll answer what I can, providing more writeups where necessary. And if you like puzzles, or escape rooms, I invite you to play the game.