For my first game, I had two requirements in mind: first, it had to be very, very simple; and second, it had to be something that my two-year-old son would enjoy. With that in mind, I sat down and created “Bubble Popper,” which is exactly what it sounds like… tap or click bubbles to pop them and increase your score.
You can play it here, and the source code is available on GitHub.
What went right
This is as close to “finished game” as I have ever come. It’s missing a few features, both minor (a start screen and some instructions, perhaps, and the ability to pause) and major (the game doesn’t actually end when the timer runs out), but overall I’m satisfied with how it turned out. And, my son loves it.
One of the features that Phaser advertised about itself is that it’s designed0.3 with a mobile-first philosophy, both in support and performance. That meant that getting the bubble popper playing on my phone took zero effort: I coded and tested the majority of the code on my laptop, and when the idea occurred to me that this would be more fun as a mobile game than a desktop one (which it is), it already worked with no modifications. That was a little mind-blowing.
Another thing that Phaser made easy was the audio. I knew that I wanted nice little popping noises when the user taps a bubble, which, simple as it may be, is a major concession toward one of my recent efforts: to put more focus on what “feels good” – or in this case, sounds good – to the user. In web development (my day job), we call this sort of thing user experience, but I prefer the more visceral name that game devs have given it: “game feel.” Dropping in a few different popping sounds and adding a dash of screen shake goes a long way in giving immediate feedback when the player interacts with my game.
Last but not least, the game made extensive use of Phaser’s tween engine, which saved me needing to learn one of the framework’s physics engines for another week. There’s a lot of power under the hood of the tweening system, which I’m just starting to scratch the surface on (a point which I’ll address a bit more in the next section).
What went wrong
Sticking to a strict seven-day timeline, I thought that time would be the thing I ran out of first. In this case, it was actually motivation to keep polishing. I had the majority of the game created over the weekend (I made the decision to start my new game development weeks on Friday, so that I can have the weekend to make a big initial push while I still have a lot of momentum. Going into week three, it seems to be working), and then I found myself just… fiddling. Tweaking already-working code to avoid the next step.
Upon reflection, I was avoiding the two things that I mentioned earlier as missing from the game: a start menu, and a completion state after the timer runs down. State transition isn’t something I know how to do elegantly yet, so I let the problem sit on the back burner until there wasn’t enough time left to solve it. That’s a little ironic, actually, because state changes in Phaser are really as simple as calling
game.state.start('somestate') … but in software development, it’s often easy to create a complex problem from a simple one. In this case, it was things like, “I want bubbles rising in the background of the start screen, but I haven’t abstracted away that code well enough that I can do that yet,” and, “when the timer has just a few seconds left, I want it to move to a prominent position in the middle of the screen and pulse with the countdown, but I haven’t learned enough about the tween engine to accomplish that.”
As it happens, there can be too much emphasis on user experience: that is, when the desire for polish gets in the way of completing the feature you’re worrying about polishing. Not being beholden to a stakeholder (besides my son, who only cares about the popping state of the game anyway), it turned out to be easy to forget that.
As the final entry in this column, I’ll put down that I’m writing the postmortem a week after the end of development, which means that I actually have a whole other game done and waiting to be written about, and some of what I’m putting down in this postmortem is insight from distance, and not just completion. That’s not necessarily a bad thing, but I’d prefer to get the postmortems done while the whole development process is still as fresh as possible.
Working with Phaser is nice. Some of the documentation seems a little lacking, but nothing that a quick dive into the (open) source didn’t solve. It was simple to get up and running, and I felt very productive during the entire initial development phase (the first weekend, mostly), but I hit the end of the framework’s opinions fairly quickly. This isn’t a bad thing, but I will have to give more thought to architecture going forward, so that everything doesn’t become a tangled mess (spoiler alert: as I mentioned, I’m writing this a week late, so I totally did that).
The pragmatist in me knows that I’m going to eventually want to create games that span more than one screen, so menus and end states and things aren’t something that I can avoid forever; part of me wants to just hack something together quickly so I can get back to making the “meat” of the game, and the developer in me wants to create a reusable solution for it so that I only have to do the work once. Realistically, it’ll probably be somewhere in the middle until I’ve made enough start screens and pause menus to know what kind of elements belong in all of them. At some point, I’ll go back and polish up Bubble Popper, but for now it’s going to stay as-is. One thought I did have was to have a UI-themed week, and give a lot of emphasis on things like menus and HUDs and what have you. I’ll have to give some consideration to what kind of game would lend itself well to that.
Since my metrics were “simple” and “my kid likes it,” I’m going to call week one a success. I’m trusting that the things I’ll be able to accomplish in a week of game development will grow as I produce more, but for now, I’m just glad to have produced something that I can (kinda mostly) call “finished.”