In my last post I wrote about how we prefer creating games directly for the browser, using web technologies based on HTML5, instead of using game engines like Unity or Unreal. The result is games that are fast to load, easy to share, and quick to develop. Once the games are ready, we can then embed them in mobile or desktop apps.
To do this, we rely on some key technologies present in your web browser. Let’s take a look at what they are.
What’s in a game? To make this article more concrete, I’ll take the game Red Boat Quest that we made for Edenred as an example, and go through the technical components that we built upon to make it happen.
Red Boat Quest is meant to be a casual game, meaning easy to pick up even for those who don’t consider themselves serious gamers. The player controls a boat, and goes around trying to pick up trash floating in the sea. If they hit icebergs or animals, they lose a life, and after 3 lives it’s game over. The game then shows them their score, and adds it to a global tally across all players. Hopefully they want to play again, and the game goes on!
Despite the simplicity of this casual game, there are quite a few technologies involved:
Programming - If(hitWhale) then gameOver()
Graphics & Animation - The boat doesn’t stand still, after all!
Video - While the player is waiting for the game to load, they can watch a short video that explains the rules and shows off the graphics.
Input - The player can use the mouse, keyboard, or touch controls on mobile
Sound - We play music and sound effects during the game
Networking - Although the game isn’t multiplayer, we submit the score
Analytics - We want to know how many times the game is played, and ideally some information about where the player is coming from
Now let’s break down each of these features one by one, and see how we can implement them on the web.
Back in the good ol’ days, web documents were just text. Then came images, blinking scrolling headlines, and before you know it we have full-featured virtual machines running on our phones.
Often, there are several ways to accomplish the same kind of task in the world of web development. Let’s go through the features we identified earlier and see what our options are.
In particular, we make heavy use of TypeScript, which is a language that adds static type-safety features. For medium- to large-size projects this really helps to catch bugs and typos before they bite you in the rear.
Another interesting development is the WebAssembly standard, previously called asm.js, in which programs written in lower-level languages like C can be run in the browser. This is how Unity compiles their games for the web, for example. Currently, this is supported only on desktop browsers, but I don’t see any reason why we won’t see this on mobile soon.
The major dividing line for graphics and animation is whether you are looking for 2D or 3D graphics.
What about 2D graphics? Here, you have a few choices:
Canvas - You can use the Canvas API to draw primitive shapes, as well as images.
Use 3D graphics again - Actually that’s what we do!
In Red Boat Quest, we use the excellent Pixi.js library. It uses the power of the 3D graphics card and applies it to 2D graphics. The result is smooth and fast animation that is difficult to achieve with the other techniques.
Handling input from mouse and keyboard is fairly standard at this point. And simple touch controls (touch from one finger), basically works like a mouse, which is what we used for Red Boat Quest.
Multi-touch controls are a bit more complicated to handle, but there is good support for them using the Touch Events API.
A more interesting use case is gamepads, aka joysticks or controllers. There is a solid Gamepad API that allows you to plug in several controllers at once. Support for this used to be quite limited, but now almost all desktop browsers support it. Go couch gaming!
Video is still one of those pain points where different web browsers exhibit different restrictions and bugs. In particular, browsers don’t want video ads with sound to start blaring out when you visit a page. For this reason, most browsers will block the developer playing sound, or playing a video with sound, until the user has clicked somewhere on the page.
Normally we should be able to play video using Pixi.js, which allows you to manipulate the resulting images and integrate them into an animated scene. But after running into a bunch of issues I now reserve video for the classic .
If you want to do something more interesting, then turn to the Web Audio API. This allows you to chain up audio effects and mix audio sources together in creative ways. Of course, it’s a bit more complicated to understand as well.
For Red Boat Quest, we used the howler.js library to load and play our sounds. For our purposes, we simply want to define which sounds loop (the music) and which don’t (the sound effects).
I’m a bit jealous of the kind of work people have done with FMOD - modifying the audio in real time to adapt to the level of action in the gameplay. There is a HTML5 port of FMOD, but the last time I tested it, we had trouble even getting the example project to run correctly.
Networking can be a gargantuan task in itself, especially if you’re looking at a massively multiplayer online game where slight differences in timing can mean life or death, for a player’s character at least!
If your game doesn’t require such exact timing, you can use simpler techniques that are available in modern web browsers. The most straightforward is sending HTTP requests to get updates from the server or send in data, using the XHR or Fetch APIs. The downside is that the browser needs to send the request, the server can’t “stream” the data to it whenever something interesting happens.
WebSockets, on the other hand, opens up a realtime 2-way communication channel, where both server and client can send data back and forth when they want.
Both these techniques require coding a custom backend, usually a server and database, to process the requests. To save time, you might consider using existing services, such as Firebase or Nakama, which are free or cheap with smaller games but can become expensive if the game is played heavily.
Last but not least, you probably want to know how well your game is doing. How many people are playing, how long do they stay, where are they coming from, and how did they hear about your game, are all questions you’d certainly like answered.
Once again, you could code your own custom solution, or turn to existing services. In this case, several companies offer free analytics services, with the caveat that they have access to your data. GameAnalytics is a popular choice, as is Firebase Analytics, which is basically Google Analytics, but with some extra features specific to games.
In our case, our client wanted to avoid storing any personal data or using external services that might do so. For this reason, we chose to use Firebase but not Firebase Analytics, and only stored generic data such as the play time, points scored, and browser language.
That concludes our tour of the key web technologies for building games. But with all the different browsers out there, how can you be sure it will work for your players?
Building games for the web isn’t all roses and rainbows. Probably the largest technical problem is inconsistent implementation of web standards, particularly on old browser versions. This is more of a problem on older phones, which could stop receiving updates to their browsers and operating systems.
From the very start, the browser market has been a highly competitive jungle, in which companies compete to establish market dominance for their browser. Often, this means striking off on their own to make features that will set them apart from their competitors. When the efforts work, others will copy them, eventually converging on some kind of standard. Other times, the feature won’t pan out, and browsers will drop support over time.
As a result, there is no single HTML5 standard. Instead, there are different feature sets, and for each there is differing browser support. These standards are written up by committees like the W3C (World Wide Web Consortium) and WHATWG, but individual browser makers are free to pay attention to them or totally ignore them.
Luckily for developers, sites like CanIUse and MDN give up-to-date information about which browsers support which features, and even what percentage of potential users have those browsers. However at some point, nothing replaces testing it out for yourself!
When you mix all these ingredients together, you have the recipe for making an awesome game for the web browser.
This approach is in stark contrast to how most game development is done, which is based around a unified game engine, like Unity or Unreal, that packages all these components together. Indeed, there are advantages and disadvantages to working with a unified system.
In our case, we’ve found that using discrete components allows us to maximize our flexibility- we can relatively easily switch out our networking components, for example, or use a different rendering engine if needed. This is enabled by our in-house game engine, called Booyah, which isn’t tied to a particular component (more on this in a later post).
However, for those who yearn for a more unified experience, there are some well-established HTML5 game engines, such as Phaser or PlayCanvas.
So now you see the key technologies used to make a game for the browser, what about this mysterious game engine that we keep alluding to? That’s what I’ll talk about in my next post.
– Jesse Himmelstein