Game Development with Phaser

Posted by Stephen Cook

A little while ago, I decided I wanted to remake an old Flash game I made back in 2011. (You can check out the old game, but I warn you it is an old Flash game…)

I wanted to spend longer crafting its story and its artwork. I’m still early on in the development of the game, but I want to share just a sample of the game art I’ve been working on

Some blocks, and a robot stood next to a girl

I also wanted to set myself a much higher software development bar. My previous games were AS2/3 Flash games, limited to playing on desktop browsers, and with a very manual build sequence set up.

I set myself the following goals, for the game:

  • availability: should be available on browsers, as well as iPhone and Android
  • pragmatism: leverage an established engine
  • automation: have an automated build and development system

And ultimately I came up with a workspace that looks a little like this.

Availability #

For my game to be ubiquitous, I decided to write it in HTML5, with Javascript. This is the only real option if I want it to be widely available on browsers nowadays.

For mobile devices, the build system leverages Apache’s Cordova library. This allows us to seamlessly create a native application for Android and iOS, from one Javascript codebase.

Pragmatism #

For the game engine, I have chosen Phaser.

Phaser has a huge community behind it, and seems to be the most feature-rich, and active Javascript game-engine.

Phaser is (very roughly speaking) made up of 3 parts:

  • pixi.js — for leveraging WebGL (gotta use that GPU!)
  • p2 — for fairly complex rigid-body physics
  • Phaser (the main bulk) — orchestrates pixi and p2, and provides lots of useful utilities and objects

A large drawback of Phaser is that it’s really not designed to be modular. But with a bit of jiggery-pokery, we can get it into a nice CommonJS environment.

The jiggery-pokery is in webpack.config.js, where you can see we’re doing 2 things.

First, we’re adding a script loader for /(pixi|phaser(-split)?|p2)\.js$/. The script-loader is going to treat each require as if the resolved Javascript was being included in a <script type="text/javascript" src="x"></script> before our code in the browser. This is how Phaser expects to be included, rather than as CommonJS modules.

Second, we’re adding an alias for phaser, pixi.js and p2 as direct paths to their JS file.

Now, in our src/main.js we import the 3 “modules” before starting with our game logic. This sets up all of the Phaser in a global context for the rest of our development.

Not very modular, but we’re set up such that we can do everything else in a modular fashion.

Automated #

For the build system I made use of Gulp.

Gulp is a code-over-configuration build-system, set around vinyl-fs streams.

It has a very large community behind it, and is meant to be one of the faster build systems, because of its heavy use of streams.

If you look at the gulpfile.babel.js you can see a few of the build steps. The most important from a high level are these:

  • gulp server: starts a server running our game, and watches our workspace so it can automatically rebuild the game upon a change
  • gulp default: doesn’t start a server, just creates the build artefacts
  • gulp cordova-run: use our Cordova configuration to kick off a test app to a mobile device we’ve got connected to our development machine

Everything Else #

Webpack #

Webpack is a module bundler for Javascript environments. It lets us write our code in CommonJS modules, and will bundle it all down to browser-friendly Javascript files.

In fact, Webpack can handle several file formats (using its loaders). For example, it can handle images, to help us inline and optimise our images; or other scripts (that can transpile to Javascript), meaning we can easily leverage transpilers, like Babel.

Babel #

Babel is a transpiler that can turn more modern ECMAScript into ES5. This means our development language is not limited to what browsers people are running.

If you haven’t checked out the benefits of ES6 over ES5, I would definitely recommend looking into it.

Gamefroot Texture Packer #

Games often make use of a texture atlas to help optimise the rendering of each individual sprite. The process and the reasons for it are explained quite well in this Wikipedia page.

Now obviously, manually creating this atlas each time we create/modify a sprite would be insanely mundane. Fortunately, the Gamefroot Texture Packer can fit nicely into our build system, taking all of our source images as its input, and outputting both a texture atlas, and a JSON map to read the atlas.

Our build system puts this output into pre_assets, where it can be accessed by our Javascript (before being built by Webpack, minified etc., and output to build, if not inlined to the actual Javascript file for optimisation reasons)

And More… #

There’s plenty more stuff in my workspace that I’m pretty happy with, and would like to talk about — but it’s quite hard to separate it from the actual game-specific code, that I don’t want to share (at least not yet).

I may talk about this a little more, with the release of the game.