HTML5 games have come a long way in the past few years. As the tech continues to progress it becomes possible to make gameplay more complex, but first you have to learn the basics! In this tutorial series, I'll cover how to make a 2-D game, Birdu. The objective of Birdu is to eat small birds, and avoid being eaten by large ones. This post examines the tech stack behind Birdu and how the pieces all fit together.
This tutorial is great for all skill levels and people interested in Phaser, gamedev, webdev and front-end tools. At the end we'll have a browser based game published to mobile with Cordova and Crosswalk, enabling you to also publish to desktop with Electron. These publishing tools add a layer (an embedded browser) between your game code and native performance, and thus there is a performance hit (except in web, which will likely run better than the compiled output from other engines). If you're working in 3D or intend to have many thousands of elements on screen, it likely won't run smoothly on mobile. However, performance keeps improving in these framworks and its more than enough for most simple games. By building your game with HTML5 technologies you'll be double dipping in game and web development experience and have access to many great NPM packages (like D3) that would be very difficult to reproduce in other game engines. And with that, let's get started!
It's a browser game, let's play!
Here it is fullscreen. If the game doesn't load, try using an updated Chrome browser or just check out the video below.
Git
Git is a Version Control System. VCS's track changes to your source documents and maintain your sanity. They are absolutely ESSENTIAL to development: providing backups, versioning, code differential comparisons, and more. GitHub, GitLab, and BitBucket are the big boys using the Git protocol. I recommend GitHub for public repositories due to its large community, but GitLab for free private repos and rapidly growing features.
These tools are free, with some caveats. Public repos are free on GitHub & GitLab. Private repos are free on GitLab. Public & private repos are free for small teams (less than 5) on BitBucket.
There are other VCS protocols like SVN, Mercurial, Bazaar, etc. Git is really the go-to though, as it has a huge community, gentle learning curve, powerful features, and near-ubiquitous presence in universities.
Linux
Linux is a completely free and open-source operating system (available on GitHub). It runs most of the world's servers, powers Android, has a penguin (Tux), and a lot of community software will only be tested on it. I like to use Ubuntu.
You could develop your Phaser game entirely in Windows or Mac, but I wouldn't recommend it. Mac is easier than Windows as it shares a common ancestor with Linux, but both will likely have issues eventually. I choose to use what makes development easiest, and that's Linux. If you have a Mac or Windows machine, I would recommend using VirtualBox to run an isolated, local VM for development. Or, if you're comfortable messing with your hard drive partitions, you can setup a dual boot system.
HTML5 & JS
Many big game companies program in a platform-specific manner to acheive performant games, or due to special deals they've made to be exclusives. Indie developers don't have the ability to make these deals, nor as strict performance needs in a 2-D world. It's more beneficial to increase your audience, lower dev time, and have maintainable code. HTML5 allows you to write code once and target all web, mobile and desktop platforms. I'll cover how to publish on mobile devices with Cordova at the end of this tutorial series.
Making HTML5 games can also help you become a better web developer. You'll gain experience with JavaScript tools, best practices, be prototyping in the browser and developing for a fragmented audience. Imagine working on a game as a passion project while becoming more generally employable by using tools/tech like Node, NPM, Grunt, ES6, etc.
Phaser.js
Phaser is a lightweight 2-D game engine that is free and Open-Source. Free is always a plus. Being open-source allows you to debug at all levels of the stack, while closed source engines can complicate things. This allows you to know exactly what the engine is doing by examining its code on GitHub or as it runs, instead of having to make an educated guess from online documentation.
I have heard that on mobile Unity and UE4 can have large packages and be inefficient, with Unity appearing to be slightly better. In addition, their GUIs can be awkward to use for 2D work (at least in my opinion). Phaser doesn't have an annoying GUI (though I think the paid editor might), only adds itself to the build output, and is wholly optimized for the browser and 2D Gaming. One of Phaser's greatest strengths is the documentation. The offical tutorials, community tutorials, and specific examples give this engine a gentle learning curve, ultimately making your game quicker (and cheaper) to make. Just compare LibGDX's API to Phaser's.
Phaser is the most popular open source JS game engine. It's not perfect, but it's pretty great. Since it's built on top of Pixi, some functions (like Group.addChild vs Group.add) can be confusing. The next generation of Phaser, Phaser3, will come with its own rendering engine and hopefully solve those types of issues. If something in the docs/source can be improved you can contribute back to the community by submitting a pull request to the Phaser repository. Phaser adds a lot on top of Pixi: a variety of physics engines, a game world with pannable camera, Tilemap support, particle systems, etc.
Even with Phaser3 coming up, Phaser2 will still be around for a long time. Phaser2's development recently ceased and entered Community Edition. Rich's company is stepping out of the reigns of leading development, and allowing the community to take over. This allows him to save his limited resources for Phaser3's dev. Thus the Phaser repo is divided into 3 parts: v2 (Phaser2), v2-community (CE edition), and v3 (new version of Phaser). CE was recently broken off into its own repo, and its documentation has its own website as well. This tutorial will use the most up-to-date stable version of Phaser, the Community Edition.
Cordova
Cordova is the magic glue that allows us to stick all platforms to one code base. Cordova was originally named PhoneGap until open sourced and released by Adobe, now it is maintained by the Apache foundation. The PhoneGap project lives on and now runs on Cordova, offering some extra goodies (like cloud compiling) on top. There are actually a lot of platforms to make hybrid apps: Cordova, PhoneGap, Ionic, React-Native, and more. I choose to use Cordova as it has the biggest community and allows me to pivot to similar platforms (like PhoneGap or Ionic) if desired. Community is always a hugely important consideration when choosing your toolset. It ensures software will be maintained going into the future, and that there are people knowledgable on your issues out in the world.
As stated in the opening paragraph, making hybrid apps has a performance hit. Generally they take a bit longer to open and use more RAM than a native application. These stats are indictative of what you might see, but are also over a year old. Things have gotten better. From my testing, I can say that hybrid apps are quite "snappy", and "performant". I didn't notice any big troubles with Birdu. I also used Cordova Crosswalk, which allows your hybrid app to use the newest Chrome browser instead of the device's default WebView. This really boosts performace and allows you to only target the newest web APIs.
Node and NPM
We are now entering the land of Node and its tools. It may get a bit confusing, but it is managable. Hang in there. You don't need perfect knowledge of all these tools to start on your game, in fact, you probably shouldn't have it.
Node…so hot right now.
Node is JavaScript for the server. It's event based back-end tech, meaning it doesn't make threads wait on I/O, which makes it scalable. Honestly though, I've never used it to build a web server (yet) so I won't pretend to know much about it. For making Birdu and other Phaser games we're more interested in the Node Package Manager (NPM). NPM is a massive collection of tools written in JavaScript that you are free to use. Very similar to Ruby's Gems. Many of these tools use Node (hence the NPM name). Many don't (like Phaser).
NPM allows us to use a file, package.json, to manage project dependencies, both for development (like Cordova) and production (like Phaser). There are a TON of extremely awesome open source projects on NPM. D3.js, Phaser, Cordova, express, React, Passport, to just name a few. NPM gives developers a one-stop shop for JS tools, and a great management system. As you get a bit deeper, you'll find that there's even more you can manage with package.json.
Generator-Phaser-Plus
Generator-Phaser-Plus is a Yeoman generator that will output the intial skeleton of our game. Its maintainer, RBlopes did all the hard work of finding the relevant JS tools, linking them together, and making an easy to use API to generate the project. To make phaser-plus usable for a wider audience, he didn't include Cordova, I will cover the process of adding it in a later post. The rest of the tools I'm going to cover below are already set up in the generator's output, and likely won't require much configuration. But it's still good info to know if you intend to break out of the given mold.
Gulp
Gulp, Grunt and NPM scripts can all be used to build a JavaScript project. There are a lot of opinions on which is best, and you can get lost down a rabbit-hole of research for choosing the perfect tool. You'll notice this is a common theme in Node: similar tools with relatively subtle differences that perform comparably. Gulp is newer than Grunt, supposedly faster, and has a similarly sized community. Both are considered to be simpler than NPM scripting, but it's more robust. The generator uses Gulp.
In a simple web page (like this one) you may be able to write a few functions, include them in the <head>
and be done.
No build or complex integration required.
As your projects increase in complexity, you'll want to create small, modular files (components), and import them to their consuming components.
The build step allows you to take advantage of tools that can automatically bundle, minify, and preprocess (e.g. SASS) files, spin up a local server, and more.
Babel
Babel is a step in the compilation/transpiling process that ensures you can use modern JavaScript. This allows you to include all of the fancy new features of ES6/ECMAScript2015 (like classes, arrow functions, promises, and much more), and end up with code compiled to an older version of JavaScript, compatible with all browsers. As ECMAScript/JavaScript continues to evolve, Babel will let you incorporate the most up-to-date syntax in your development, while simultaneously maintaining wide browser support.
Browserify
Browserify bundles all your separate JS files into one large file. Webpack is a similar tool to complete the same task.
Bundling is important for a few reasons. In HTTP1.1 downloading a lot of files was much slower than downloading one big file, due to specifications in the protocol. HTTP2 adoption is improving, but it helps to support as much as possible. Note: this isn't really relevant to a downloaded Cordova application, but you may one day decide to host your code in a website or PWA. If you're creating a library, and potentially publishing on NPM, a bundled file is easier for consumers to use than a bunch of disjoint files. Bundling will also automatically pull in outside dependencies (like the phaser.js engine) and ensure your source code can use it. Finally, in the process of bundling you can do things like minify/uglify to lower the storage space required for your code in a production system.
Browsersync
Browsersync is used in this project to create a local server that refreshes automatically upon file changes. Phaser requires a server to work, and Browsersync conveniently makes that possible. The generator gives us this for free, but Browsersync is capable of more. To name a few: click & interaction mirroring, simulated network throttling, maintaining URL history across test devices, etc. Check out their website.
ESLint
ESLint is one of many JavaScript linters: utilities that check your code for potential bugs and deviations from a style guide. Notably, other linters include JSLint, JSHint, JSCS, and of course, ESLint. ESLint is the best as it comes with default configuration yet is highly extensible. It also supports JSX (though that's not relevant to us) and ES6 (relevant to us). Linters are awesome. They make your code more consistent, maintainable, and fun to read. If you haven't used one before, prepare for JS to become a lot easier (and to be annoyed by minor formatting errors - sorry).
Atom
Atom is not a build tool, it is a text editor/IDE lite. It feels like we're in the middle of WEW II, World Editor Wars 2, between Atom, VSCode, and to a lesser extent, Brackets. The first war never really finished, but was merely left at a ceasefire. I suppose a second one was inevitable.
Atom is my personal choice. All are good choices (though Brackets feels more like a text-editor than an IDE-lite). VSCode gets a lot of love as the Microsoft team continues to add more features and maintain a tool with a clear performance edge. Atom however, has a vibrant community with over 5,000 home-grown, easy to use plug-ins. I keep my favorites up-to-date here. They include a file mini-map, auto-completion of HTML tags, linting in-editor, auto-beautification upon saving, in-editor terminals (my favorite), and much more. I'm sure a lot of this is also available in VSCode, the big difference being their package manager is a "Marketplace" while Atom's is a community. I would guess that Atom's performance continues to improve, and their plug-ins stay community driven, open source, and ahead of VSCode.
That's all folks
Next time I'll be covering the set up using our Phaser-Plus Yeoman generator. Thanks for stopping by!