This is a postmortem written for a game I created for ADX Labs, LLC under the GameSmart brand as their employee.
This postmortem documents the decision making process that ultimately led to my first game being published at work.
At the time of writing, SlideCity has 2.5 million plays, and within the GameSmart platform is rated 4.8 out of 5 stars.
In August 2016, I was working between contracts and making pizzas to pay rent. Chiefly, I worked on Iris Burning in my spare time, and my fiancee helped me by pruning through tons of job applications to help me get employed before it was time for me to start paying student loans back. On August 8th, I received an invite for a phone interview with a company in Minneapolis specializing in mobile game development, and then proceeded to have the interview over Skype. Within 48 hours I had an offer by phone, and began preparations to move to start work as a mobile games developer.
In September, I began working on games for the new job.
Upon initial arrival, the mobile games branch of the company was still fairly fresh, and the Android application frontend for delivering the games was still under development. Due to this, the type of games I could develop was limited: work told me that while I was interviewed on the basis of Unity knowledge, I’d need to use a different, more browser-friendly game engine (Unity’s WebGL implementation was very mobile-browser-unfriendly at this stage). Not a problem, I thought, the skills transfer between engines.
Sigtopolis, a SimCity 2000 clone attempt I toyed with a few years before GameSmart.
Weeks 1-3: Getting a workable game
The next thing I looked at was to actually develop the game.
SlideCity’s EaselJS implementation rendering a grid using the math I learned doing Sigtopolis.
My boss opted to be the artist to help me out on the aesthetics of the game since I would be footing all of the programming work. We settled on prerendered, 2D renderings of voxel-based graphics, in a cyberpunk Blade-Runner-esque urban environment, with some neon TRON-like influences as is popular in the high-tech-low-life look of the genre. The buildings would represent the 2048 numbers, and would become increasingly tall and extravagant as each building leveled up.
git inited the game under the name punkcity in reference to the cyberpunk influences of the art direction, and got to work mapping out how the game should work in terms of code.
An art test utilizing postprocessing done in Photoshop and voxel art by my supervisor.
Initially, we wanted a subway transit map type of overworld between levels and had each level work with one type of building that would get bigger little by little, in addition to later playing fields being larger than the base 4×4 grid in most 2048 implementations. This worked in testing quite well until we started introducing the game to players who weren’t familiar with how it plays or how the art looked in context. Players found it to be difficult to tell which buildings lined up with each other, making tight 4×4 grids quite hard to work with if you couldn’t distinguish the buildings. This wasn’t the worst outcome, but it’s something I should have seen coming from the start.
The game functioned as a 2048 clone, but it was hard to tell what was what with similar buildings of varying heights.
Weeks 4-6: Cracks beginning to show
As with any solo developer’s first published game, things started to fall apart slightly at this point.
I was already self-conscious about the game taking more than 3 weeks to develop, which may prompt some eyebrow raises from readers: Three weeks isn’t much time to develop a game; there’s game jams that take place in that time frame. Why be self conscious? At the time, my coworkers had published one game each–games that I wasn’t involved in the development of–and even though they had a head start before I had started working there, I felt like I was the new kid on the block, something to prove, needing validation, and so forth. This is the mobile industry, where fast turnaround and constant daily plays is required. I needed to get it together! Obviously as the youngest employee in the office, this kind of attitude was good motivation to start, but bad motivation to continue with as development progressed, as it became a cancer on my own self-outlook and ability to produce meaningful work in the timeframe given, as I became more and more disheartened with every issue that hit the game, every bug report that came back, and every “how’s progress?” checkup question I’d receive.
Now that I have been here a while, I know that week 4 is the time you should have a serviceable build for QA to look at and start picking apart, to see if the game works on its own. By week 4, I had a play/win/lose/repeat feedback cycle. Okay! That’s progress. But many key features were still missing, such as the energy-based monetization scheme, the entire GameSmart SDK integration (handling user save data, high scores, and anything involving our server backend), and proper level progression. You could move between levels, but the UX of getting between them was very janky, very ‘programmer-centric,’ and certainly not ready for mass audiences. I was spending nearly a day getting a single animated sprite implemented in the game for the overworld map, and given the timeframe these games are developed on, you should know that having issues like that isn’t good.
getElementByID() was the way to do things, none of this strange
What I should have done: admit that trivial tasks were taking longer than they should have in an engine I wasn’t familiar with, and seek out a better way.
What I did instead: stick to my guns and attempt to overcome. It’s just a new engine, right? Surely it’s just a hiccup of having used the same tech for the last few years and having to switch on short notice.
Week 7: “Test Like You’re a User, and Do It Early and Often” – Captain Hindsight
A word of advice from the horse’s mouth: Test the damn game the same way your users would play it. Compile it. Deploy it to a device. Abuse it as much as you can. Don’t do what I did here and wait nearly 2 months into development to see how the game plays.
I confidently packaged my game into a compact 11MB archive that the web team could upload to our dev server for testing. It was time to see it in action!
We deploy our games to our platform by using Android WebView as a browser context (meaning Chrome/Chromium makes an excellent analog for testing), meaning testing in the browser directly also demonstrates roughly how the game will behave not only in our app, but for casual users perusing our website. This means we can just pop open our web browser on our computers and smartphones and navigate to the internal dev website to see the games live for testing on the fly–after having the web team upload a build, of course.
For non-webview clients like just using Chrome to look at the website, this means an
<iframe> is used to create the game context.
The game was designed on my 4K LG monitor provided by the IT department.
There was no scaling applied within EaselJS. It was all scaled individually by the sprite.
If you can imagine playing a 4K game on a 1080×1920 portrait device like the ZenFone-based devices we had on hand, you can imagine how this would go. Everything was tiny!
The game was otherwise serviceable. You could play, win, lose, switch levels, level up, expend energy by playing, recharge it by waiting (though the refill timer was not exposed to the end-user at this stage), and so on. All of the things needed for a workable game. But the scaling issue persisted.
At the end of it all, I just couldn’t get scaling to work correctly–not to mention getting the game to respond to fullscreen requests was another sub-problem related to this one that I had no idea how to begin addressing. I tossed in the towel, feeling like a failure. In spite of this, my boss reminded me that the Game Maker-based prototype still existed, and that I could try it out. At this point, I felt like I had little to lose, so I jumped on it the second I could.
I was essentially starting over, eight weeks into development, and my coworkers were almost finished with their second games from the time I had started working there. This didn’t bode well. Nevertheless, there was not much choice here. I still had something to prove.
Week 8-11: Acceptance & Adoption of Game Maker
Its concept of object-orientedness is fleeting: don’t expect to get nice things like polymorphism, interfaces, or overrides in the traditional sense. You’ll miss out on things like the ternary operator:
condition ? operationIfTrue() : operationIfFalse(). In HTML5 deployed games, you have to render your text to a spritesheet: you can’t hook the browser’s text rendering features–irritating for games like ours that require translations in non-Latin languages, where the character sets are so massive and diverse that you’d need to know all of the text in the game before the game was finished. It runs on its framerate and system time rather than a fixed timestep or a time delta like Unity or Unreal Engine. All of these things were sources of frustration, but all of it dwarfed in comparison to having a game that didn’t work.
You do have to do some extra work to get started, but the important thing here was that everything was working from the start. Foundational issues like scaling weren’t a problem here, and that was all that mattered.
Despite much frustration, I altered the template significantly from its original form. I put city streets in between the buildings, making it easier to distinguish which buildings are which level (and preventing tall buildings from totally occluding short ones, since isometric perspective dictates that height also indicates depth). I integrated the SDK, though with a some hiccups here and there. The testing phase only took about 2 weeks to complete before the game was considered production ready. Bugs were related to gameplay and logic errors, not fundamental flaws in the core implementation. I was home again, even if home meant working in a verbose world where array length is called upon with
array_length_1d() instead of
At the end of November, the game released finally. I can’t speak specifics on how well it did sales-wise, but it performed well enough that I didn’t feel as bad about taking that much time to make it, especially for a first game. But hot damn, was I glad to see that monster put behind me. It was done and over with. I was free, and I had a game out in the wild.
The game, as it stands, is one of my most-played published titles on GameSmart, despite being one of the most turbulent.
I did have to make some hotfixes after the fact, such as energy not recharging correctly at the right time, or Game Over text not appearing in the correct localization, but that’s typical fare compared to your entire game being an unusable hot mess on your first major beta.
Final Thoughts: Your First Game Will Suck (But That’s Okay)
Hear me out. Even if you clone a known-fun gameplay paradigm like I did, there will be some degree of notable suckiness in your first game. In my case, I should have made sure the game was rendering correctly in a smaller iframe, on a phone screen, deployed from a remote server. I should have tested fullscreen functionality early on. I should have checked on fundamental aspects like this likely to hurt me later, but I didn’t, due to a combination of pride and lack of experience. I should have conceded earlier for my own sake and used the right tool for the right job.
An important lesson in life to know is that a wise man knows when to admit he is wrong, and a foolish man doubles down. Here, I learned the hard way. I’m still learning–but that’s the important part of this line of work; if you don’t grow, you will never walk among the elite developers.