This is a record of my exploits in building Overworld, a mobile mini-RPG currently in beta testing. It looks like this.
I’ve been a back-end engineer for about 20 years, most of that in games and always working on a game side-project. Most of these have been MMORPGs that I built for fun. Two projects I tried to commercialize, Overworld being the second. After wrapping up the last MMO, my artist Santiago said I should try something small for a change. So I spent 6 years building a mobile roguelike! (It felt small at the beginning.)
My previous big project, Battle Mines, had been written in Flash. We all know how that went, I finally shut down its servers at the end of last year. It never generated a stable following, but some players hung on to the bitter end, and some spent thousands of dollars on in-game currency. The takeaway is, if you build it they might not come, but SOMEONE will come so that’s kinda cool!
As for the game, the hook was to be its simplicity. Most RPGs/roguelikes feature a lot of depth, which can be hard to cram elegantly onto a small device. I wanted something highly accessible with low hardware spec, but still deep and engaging. Overworld features:
- 10 minute sessions
- 3×3 visible map
- 6-item inventory
- No numbers larger than 3
- Concise dialogue
This material fits comfortably on pretty much any device from the past 4 years.
Early Dev (~2015)
For several years the game was made of crude static images rendered in an old tag. You’d tap to move your hero, and the page would refresh. No animation, just 3×3 tiles of programmer art and an inventory. In this environment I was happy building game mechanics, but the game wouldn’t have gotten a second look from most players.
Graphics Engine (2016)
An out-of-town client engineer friend came to stay with me. For rent, he added a proper canvas renderer to the game in Pixel.js, and animated the hero moving between tiles. This was arcane magic to me. I have spent months wrestling with the 500 or so lines of code he wrote (now ballooned all the way to 1700) and even now barely understand it. Slight exaggeration but I’m more used to databases and rest clients.
At this point I didn’t even have sprite maps, and the browser started to chug just from the sheer number of 16×16 images it had to load. Fortunately my friend had added the basic capability to capture assets from a sprite map, so my artist friend Santi started creating actual 2D assets. Still going strong today!
Optimize and Obfuscate (2017)
There were two main challenges. First I had to get rid of my non-standard uses of javscript. Misplaced globals, undeclared vars, stuff like that. Second, to get the game running discretely from the renderer, I had to segregate some of the hot organic mess I’d created so far. This involves being much cleaner with globals and leveraging externs. I made a blog post about it, details in the link.
Server Side Validation (2019)
A game of Overworld looks like this:
The numbers are player movements (3×3 map movements, per the number pad). The letters are actions taken with inventory items, and some special actions. Along with a number seed, the whole payload is miniscule and human readable. Since the whole game is rerun on the server from the same code, it’s cheap and reliable to validate user input. I started building out meta, adding challenges to unlock heroes (eg. Kill 10 rats!) and nethack-style conducts for fun. The challenges fill up passively just by playing the game, though can be focused for faster completion.
I did another blog post on this subject. I was up to 3 or 4 posts a year by now. 🙂
Mobile Client (2020)
Until now everything was through a web browser. You could play on a mobile browser, but only on my website. It was time to make the game into an app.
Capacitor is an app container built that makes interfacing with native device features easy. Even if not adopting the “look” of a native app, you’ll probably want access to stuff like haptics, focus detection, keyboard, native browser, clipboard, not to mention the native game platform (Play Services, Game Center), store (Play Store, App Store), and billing.
As a side note, with ionic you have to pick an engine: angular, react, or vue. In a single act of contrarianism I went with vue, and happily have not regretted it yet. There was some trouble injecting my pixel.js canvas renders into the vue world, another friend helped me with that. At the end of the day I’m not doing much with that medium. The graphics are very unambitious, and a pass to improve them would be hot on the heels of any commercial traction.
Testing and Iterating (2021)
A lot of this past year has been spent fleshing out the economy and testing with real users. This has been tricky during the pandemic, fortunately it’s very easy to record video these days. I used playtestcloud.com until the freebies ran out, then I used fiverr to have gamers record their first-play experience. This has informed a lot of the recent design. I’d been gearing towards a free-to-play payment model from the start, and first time user experience (FTUE) is integral to the success of that business model. Retention, retention retention!
Production Servers and Monitoring (2021)
Fortunately there are capacitor libraries for Firebase integration, which gave me analytics and crashlytics for free.
I had an old dev box on Linode which saw me through about a decade of general use. For this app I’ve moved to Digital Ocean, who are getting big and have lots of app rollout support, without being AWS in terms of complexity + price. I set up a simple load-test using Locust, which indicated I should be able to handle around 1000 DAU on a $5/month box. Even with a safety factor of 2 or 3 that should be in my price range. (Remember that tiny 100-byte game payload?)
Still a two-man team (me + artist), right now I’m working to generate some very modest hype and get my beta test filled up. That’ll prove the tech, and hopefully give me a core cadre of followers. I just started this last week, it’s intense but fun. You have to integrate the delays of getting approval from google to publish changes (even just adding a new list of testers) with your release pipeline. That created a few launch-week snafus but good learnings.
Overworld Meets Real World (Present day)
What do you think of my story? Did I make any obvious mistakes? I’ve been pretty happy with the pace of development, and the end result. Overworld doesn’t look as flashy as 90% of games these days with store-bought assets, but I feel it conveys the gameplay experience I’ve always been shooting for. Unlike my old Flash game it’s built on tech that doesn’t look like it will go away soon. It’s cheap to run, cheap to develop, and can be played on just about any machine.