Meta

I recently wrote a small Slack integration for my gaming group. I wanted to handle dice rolls for tabletop games, so I needed to match patterns like 1d8, d20+2, or 2d6-4. I wrote a simple regex to handle it, which could probably be greatly improved, but works for my use case: /(\d+)?d(\d+)([\+\-]\d+)?/i (you can play with it on RegExr).

With ES5, I probably would have done something like this with the regex match results:

Two lines for four! Once you’re used to it, destructuring is pretty intuitive, but for the sake of explanation, let’s go over what just happened: we used essentially the same syntax that we use for creating an array, but on the left-hand side of the expression, to pull our target apart (or “destructure” it) and extract individual elements into named variables for further use. We started with a matches array that looked (assuming that we had an input string of d20+2) like this: ['d20+2', undefined, '20', '+2'], and “reached inside” to pull out the values that we were interested in (count, die, and modifier), ignoring the one that we didn’t care about (the whole input string, d20+2).

Additionally, since count and modifier have sensible default values (if you don’t specify the number of dice, we assume that you’re rolling a single one, and if you don’t specify a modifier, we assume that it’s 0), we were able to specify those within the destructuring expression, in case they were undefined in the array. In the above case, the count was undefined, and so defaulted to 1, but the modifier was +2, and so did not receive its default value.

In the same way that you can destructure arrays, you can also destructure objects. For example, Slack sends a payload to my HTTP endpoint (running a small express server) that comes to me looking something like this (some fields omitted for brevity):

I recently set up Unity Cloud Build so I could take it for a test drive, and while I was walking through the setup instructions, I came across a bit that was really concerning:

Adding Unity SSH key to GitHub account

Please, please, please don’t do this. Adding an SSH key to your account like this is essentially giving the Unity Cloud Build tool unlimited read/write access to all of your repositories; you are in effect saying, “Unity Cloud Build can access all of my repos as if it were me.” Even if you trust Unity not to misuse this ability (most likely a safe bet, but not one I want to take), there is still the possibility of potentially destructive code errors or the possibility that Unity’s servers are compromised and attackers gain access to an SSH key that has read/write access to your code. Even if these scenarios are unlikely, the fact that they could happen should be enough to give you pause.

They are often used to clone repositories during deploys or continuous integration runs.

That’s the exact scenario we’re setting up with the Cloud Build tool, so just drop the Unity-provided SSH key in as a deploy key on your game repo, and you’re done. Unity Cloud Build now has read-only access to that specific repository, your cloud builds work great, and you can sleep a little better at night. If you have lots of repos running through Cloud Build, the help docs have information about creating a machine user to manage that specific case, or you can just set up deploy keys for the lot of them. Problem solved.

Summary

Use the through2 npm library to pipe your gulp stream through Browserify, and use the babelify Browserify transformer instead of gulp-babel. Check out the gist

Building with magic

As a developer working primarily in JavaScript, my relationship with build processes can be best described as “hot and cold.” My expected workflow is thus: make a change in my editor, flip over to my browser, see my changes already up on the page without a manual refresh (thanks to LiveReload or something similar).

With that as a baseline, build processes that make me wait (or worse, do things manually!) can quickly become beyond frustrating. On the other side of the spectrum, build processes that maintain the illusion of “instant magic” and make it easier to work with the code itself?

To that end, Browserify has been a part of my build process for a while now… I’m enamored with the idea of using not just the same language but the exact same codebase on both the client and the server, and letting Browserify do all the heavy lifting of the boilerplate for that seems like an obvious win.

Additionally, I’ve traditionally been a grunt user, but I made the switch to gulp recently. Two reasons for that: first, I like the philosophy of operating on streams instead of files, but mostly, I like that a gulp task is actually code instead of mostly configuration. It mostly comes down to style and personal preference, but there it is. Making Browserify work in gulp was an interesting exercise at first, but it seemed worth it.

Enter Babel

I’ve been excited about some of ES6’s features for a while now: arrow functions, iterators and generators, easier use of classes… these are all awesome. When I’m working on a personal project, I try to make as much use of them as possible, but even Chrome (my browser of choice) doesn’t support the full range yet. So when I hear about Babel (which was named 6to5 at the time), I was instantly on board. It’s a preprocessor that will transpile ES6 to ES5, and according to kangax’s ES6 compatibility table, it’s currently leading in terms of supported feature count. Running a shell command to process everything was of course out of the question, but Babel’s docs have information on using Babel with both gulp and with Browserify.

… erm, that is to say, the docs have information on using Babel with gulp and using Babel with Browserify separately, but trying to get them to play together was not as easy. First, I tried using gulp-babel and piping that to Browserify, but that didn’t work, as Browserify reads the input files itself and didn’t want to play nicely with my stream. Then I tried using vinyl-transform and piping the gulp stream through that and using babelify instead of gulp-babel, but that let me with a frustrating stack trace that would disappear as soon as I stopped trying to preprocess with babel:

Error: write after end
at writeAfterEnd (/Users/problematic/dev/node_modules/browserify/node_modules/readable-stream/lib/_stream_writable.js:161:12)
at Labeled.Writable.write (/Users/problematic/dev/node_modules/browserify/node_modules/readable-stream/lib/_stream_writable.js:208:5)
at write (_stream_readable.js:602:24)
at flow (_stream_readable.js:611:7)
at _stream_readable.js:579:7
at process._tickCallback (node.js:442:13)

In frustration, after playing with it for a few hours, I opened an issue on the babelify, and within five minutes (!), one of the devs (possibly the head dev, but I’m not that familiar with the development on the project) got back to me.

Looks like it’s due to vinyl-transform. Quick search shows that it’s an issue a lot of people run into when using it, substack/node-browserify#1044. The suggestion here might work.

Mild embarrassment from not finding the same result as his “quick search” aside, I gave it a whirl, and it works great. I now have my files being preprocessed by Browserify and Babel, managed by gulp. Here’s how my gulp task ended up looking:

The code

When I settled on this week’s concept, I envisioned a stealth game in the spirit of Commandos: Behind Enemy Lines and Metal Gear Solid. The mechanic that I wanted to design around was a “smart gun” with projectiles that could lock onto targets and curve to hit them… I was picturing firing around corners to take out guards and clear the path.

The Bad

I’m starting with what went wrong because… there was kind of a lot. Not only did I fail to implement the learnings from last week (menus/win conditions/etc), I didn’t even come close to making something that could be called a game. All told, I probably only managed a couple hours of actual development on the project, which amounted to a moving player (circle) who fired bullets that curved toward whatever enemy (also circles) was last clicked. I actually debated giving this project another week, just to see it through to completion, but in the end, I decided to wrap it up, try to address the week’s shortcomings in this postmortem, and move on to another game.

First, while brainstorming, I actually started implementing a few different things before ultimately landing on the tactical stealth genre. I think lack of initial momentum was one of the big failings of the week. Something I want to try, in addition to the weekly postmortems, is a design doc/work breakdown for what I’m planning to do in the coming week. By writing out a rough plan, hopefully I can abort early from ideas that don’t fit well (either because they won’t be fun, or they’ll be too complicated to develop in a single week).

Second, real life caught up to me, and I repeatedly found myself wishing I had more time to sit down at my computer and hack on the game, but other things took priority. I’m not really classifying this as a “bad thing” overall, as it will probably happen again in the future (real life is like that), but it was a negative for progress on the project. I’m not really sure how to mitigate it, except to try and schedule time.

The Good

As I mentioned in the lede, I did manage to prototype the core mechanic, which I’ll count as a small victory. I think an explorable index of different mechanics (something like this, which is actually implemented in Phaser) would be an interesting future project.

After experimenting with a couple different ways of making the projectiles track toward their targets, I settled on a simple implementation of Craig Reynolds’ flocking algorithm, as discussed in this fantastic tutorial series. It’s straightforward and effective, and I think I can factor the code into a reusable component for future games.

Conclusion

I guess the biggest takeaway is that I want to start creating design documents for the upcoming weeks’ games. I’m not under the illusion that this will be foolproof, but hopefully it’ll provide enough early direction to get things moving. If not, at least I’ll have some documentation of my thought process for when I come back to the idea in the future.

The concept for this week’s game came from a conversation I had with my brother-in-law about wanting to make a click/idler game, but wishing that they had more substance. There were a lot of grand aspirations, but I kept narrowing the scope of the project until it became something resembling a space-themed shoot-em-up.

The Good

I had a lot of fun with this one. I mean, a lot of fun. I stripped my original, nebulous idea down to the very minimum I could be happy with: a ship that you can fly sound the screen, and bad guys that you can blow up.

I should pause right here and point out that the fancy artwork (and sounds and fonts, actually) for the ships flying around the screen are free (CC0) stuff from the extremely talented Kenney, without which, the game would really consist of boxes flying around the screen. I know my strengths, and art is not one of them! Working with preexisting art assets was a really refreshing change of pace, and I think it made an immediate and significant contribution to how enjoyable it felt to play the game.

At any rate, version 1 of the game was exactly that. The enemies moved toward you, but didn’t fire, and you had to click directly on them (echoes of the original theme, again) to make them explode. But, I sat down with my brother-in-law and made a Trello board (which is actually open to the public, if you’re interested), and added bits one at a time for what would help make the game actually, y’know, fun.

I think that was actually the single greatest thing I did for the development process: being able to move development tasks around and see a roadmap one piece at a time was invaluable in being able to stay on task and keep delivering… I might even venture to say that it was my most successful use of “agile methodology” to date, and it just happened, rather than being a strict thing that I sat down and planned out in advance. There’s probably a lesson to be learned there.

I read an article recently about having a “forever project,” one that you never call done, but keep adding to and learning from indefinitely. That really resonated with me, and I think I could see this game as mine… within the week, I didn’t even scratch the surface of the things I wanted to accomplish with it.

I mentioned in my last postmortem that I was going to have to pay more attention to architecture to keep making good use out of Phaser with more complex projects, and that came true here. Earlier revisions of the code show a cursory attempt on my part to break things up into separate classes, but toward the end of the week, I found myself hitting a wall where the way the code was structured was preventing me from adding the features that I wanted. So, I stopped adding new features and refactored everything to be much cleaner. In software development, we call that “paying off technical debt,” which is a topic I’d like to write more about in the future. Suffice it to say, in a business environment, reducing technical debt can be one of the hardest sells a dev has to make to management, because it’s pretty much what it sounds like: “we want to stop making new features for a while to fix the way we wrote the old features.” Generally not a very popular request.

Anyway, game development is not (yet) a “business environment” for me, so I got to make that call. It was a blast. I got to see where some of my quick hacks, made with the future in mind (“I’m going to write this as an ugly hack now, but I’m going to write it like this so it’s easier to fix later”), paid off, and some where I just didn’t have a clear idea of what a well-architected solution would even look like. Let’s be honest, maybe I still don’t, but now I’ve been there and done that at least once!

The Bad

The flip side to the thrill of refactoring everything is that it did just what it sounds like it would do: it killed momentum. I’ll be honest, I had that “forever project” article in mind when I made the decision, and while I don’t regret it from that and a personal enjoyment perspective, I don’t think it was the right call for a week-long development sprint where the project gets set aside afterward. It does reaffirm the idea I had with last week’s game that I should earmark some time for polish and refactoring and all the things I wish I could have gotten to before the week was up. Maybe I’ll dedicate a week to that instead of a new game sometime soon.

Once again, you may notice that the game is lacking both start screen and a victory/loss condition. This is a great testament to how well postmortems can work as a tool, because if I’d completed the Bubble Popper postmortem in a timely manner, I would have focused on those two things. Well, there’s always next week.

The Ugly Conclusion

I wanted to write more in the “Bad” section, but honestly, I think this week was a strong success. I’d like to keep working on the game, but I’m going to shelf it for now and keep momentum going in the game-a-week challenge. I had a blast creating this game, and it was encouraging that I was able to build it up starting from very simple steps. That’s a tactic I’m going to try to keep replicating.

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.

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.

Conclusion

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.”

I was recently inspired by a Gamasutra article to try a new experiment: making a game a week. Based on previous experience, I knew going in that my biggest problem coming in would be properly scoping the project to my skill level and time constraints… true for software development in general and game development specifically, it’s much easier to brainstorm tons of cool features that a project should have than to actually implement them.

Most of the games that have been kicking around in my brain are 2D. The reason for this is probably a lack of 3D experience combined with personal preference, but I knew that I wanted to look into something more directly suited to 2D than Unity’s 2D workflow. I also had a vague idea in my brain that I wanted to be able to easily display my games in the browser, which meant either flash or JavaScript (or Unity’s web player, but again, I was looking for something better-suited to 2D).

Enter Phaser. It’s an HTML5 game framework, built on top of pixi.js. It’s oriented toward arcade-style games, is open-source under the MIT license, and is actively developed and supported by a team who uses it to build games in the wild. After a couple weeks of using it, I’ve discovered that it’s not perfect, but it’s very hackable, and suits what I’m trying to do very well.

My tentative plan is to build a game every week around a different theme or genre, open-source them where I can, and post them to the web for people to play. I’ll be writing postmortems here about what I learned during the process.

Are you familiar with Kenney? If you check out his Open Game Art profile, you’ll see that he does awesome work, and makes a lot of it CC0/public domain, so that anyone can use it for their projects.

Well, he just started an IndieGoGo campaign to fund a space in the Netherlands called “Kenney Land,” for game developers to work, learn, and play. The campaign closes on 18 October, so you should check it out while you have the chance! If that idea alone is not reason enough to throw your money at him, backers at the $20+ level get a brand new 2D asset pack, including reworks and expansions for some of his previous work, a 2100+ asset “Roguelike pack,” and a bunch of audio clips and tracks.

Here’s an example of the default script that Unity will create when you ask for a new C# script:

Most of this makes sense, but I’ve found myself wondering, “why would they include System.Collections, but not System.Collections.Generic?” There aren’t very many cases where I’d rather use an array than a generic List. The other default import, UnityEngine, makes sense because it provides access to the Unity API, but I couldn’t figure out System.Collections.

I discovered the answer while reading through Catlike Coding‘s Unity tutorials (specifically, the tutorial on making fractals):

Move the two child creation lines to a new method named CreateChildren. This method needs to have IEnumerator as a return type, which exists in the System.Collections namespace. That’s why Unity includes it in their default script template and why I included it in the beginning as well.

CreateChildren in the script referenced is a coroutine[ref]See the Unity manual entry on Coroutines for more information[/ref], which provides our answer: Unity coroutines must have a return type of IEnumerator, which is found in the System.Collections namespace. As a core framework feature, it makes sense that the Unity team would choose to include this by default in the new scripts created by the editor.