The tech behind the game
Overview
Bored To Death is an arcade style brawler intended as a throw back to arcade games of the past and powered by JavaScript and HTML5. Developed in partnership between Internet Explorer and digital agency Bradley and Montgomery, the game was initially developed to be playable in an arcade machine running IE9 at Internet Explorer's Badger Palooza event at the 2012 SXSW Interactive festival.
The game's main characters, style and gameplay are based on Jason Steele's popular Marshmallow People online video series. An accelerated development timeline and goal of getting the game running in an arcade machine, as well as the organic style of Jason Steele's videos influenced many of the development decisions including the use of frameworks and large sprites. Despite the goal of getting the game up and running in an arcade machine running IE9, Microsoft and Bradley and Montgomery wanted to focus on a web standards based approach, programming in a way that would work cross-browser. The end goal being to create a game using only web standards that players would want to come back to over and over again.
Scenario
The Marshmallow People have a mindless desire to wreak havoc all in the name of having something to do. When we decided to make a game with these characters, we knew that we needed to pick a gaming genre that matched the essence and feeling in the videos. We quickly decided that we wanted to make an old, arcade-style brawler game (think Double-Dragon or Battletoads) with the simple goals of playing for as long as possible and competing with your friends to get the highest score, all while beating the stuffing out of cute and cuddly creatures.
Technology
From a technical point of view, we knew that we wanted to focus on releasing a polished game that felt like a full experience rather than just a tech demo to show off the bells and whistles of HTML5. One of the decisions that we made was to focus all the development energy on creating a game that was addictively fun to play rather than spending all of our limited time on creating our own game engine. From that point we began looking at the long list of available HTML5 game engines. After evaluating a few approaches, we landed on Impact JS. Impact comes out of the box with great cross-browser compatability, powerful tools like its debug tools, a level editor, a strong developer community that we could go to if we ran into issues and all of the building blocks that we needed to focus on building a fun and engaging game with canvas.
There is more to a good arcade game, however, than just fun gameplay. The arcade game experience starts even before you put a quarter into the machine, and then runs all the way through to entering your initials after you’ve conquered your best friend’s high score. Since the kind of tweening and graphical animation were looking for is not a main focus of Impact, we turned to Grant Skinner’s Create JS suite to build the game’s attraction loop, intro screens, in game heads-up-display, and high score screens.
Using Impact JS and Create JS together gave us the fine-grained display control we wanted for non-play elements, and an extremely easy to use and powerful engine for the play itself, all output nicely to an HTML5 canvas.
Underscore.js also played an integral role in the rapid development of this game by adding many powerful and easy to use functions, while at the same time, keeping the code base clean and efficient. In a specific instance like the Otter Destruction powerup, we needed a way to easily loop through our active enemy array, perform the appropriate functions in order to run them off screen, and awarding the correct score and boredom bonuses to all players.
One of the great benefits of using HTML5’s canvas is rendering speed and hardware acceleration. We never had to worry about performance in Internet Explorer while developing. Despite our attempts to push limits with canvas, Internet Explorer was able to handle whatever we could throw at it and keep the game playable.
Multiplayer Marshmallows
Before now, most games that show off emerging web standards like web sockets have either been slow-paced dirges or simple examples. This second iteration of Bored to Death aims to set that perception aflame, as if struck by a match from a foul-tempered marshmallow man.
Taking inspiration from classic side-scrolling cooperative games like Double Dragon, this fresh take on Jason Steele’s Marshmallow People characters finds our heroes(?) fighting their way against both boredom and one mad Mama Narwhal. Through the use of a cutting-edge game server architecture and IE10’s native support for web sockets, two players can play cooperatively from across the table or across the globe.
Let’s talk a bit about how we accomplished this.
To power the server-side of our game, we chose node.js and Socket.io. Socket.io makes it quick and easy to get a web socket server up and running, plus it provides fallbacks for browsers that do not support web sockets.
To connect Impact to our game server, we created a plugin called Impact-Multiplayer-Plugin. This plugin extends Impact’s Game class as well as injecting some additional functionality into Impact’s Entity class to provide hooks for a multiplayer experience. There’s a demo of this plugin in this repo. The demo requires an Impact license to use.
The web socket server itself contains very little game logic. By keeping the server fairly dumb, we were able to firstly keep more of the logic client-side (feel free to take a peek) and secondly, be better able to keep things in relative sync. Animations follow a sequence, and the game server simply kicks the sequence off based on a player’s action and lets each browser run it themselves occasionally syncing them to help ensure consistency.
For the player class, we defined a series of controls. For local players, these controls are mapped to the player’s keyboard. For remote players, these controls are delivered via the server. The client-side game listens for the controls to be toggled on and off. You can see an example of some of the code added to the Entity class via Impact’s inject to do this below.
Since we’re relying on the browser to animate our entities and not every browser will run the game at exactly the same speed, we needed a way to sync the entities. Since players were being sync’d by their actions we only needed to sync our “enemies.” We did this by using an Impact Timer, which fired from the initiator’s game (the person who initiated the game) every second transferring all enemy positions. From there, we could use code like what is show below to loop through all the enemies and reset their position.
Our example code and plugin attempts to provide a base for getting your multiplayer game going in Impact, as well as some hooks to get you started. As with creating any game in Impact (or any game engine for that matter), there is not a one-size-fits-all approach to creating a multiplayer game.
Keeping Time
Once we had decided on combining the two frameworks, one of the things we had to overcome was how to combine two different frameworks to create one very unified experience.
Both Impact and CreateJS require a “heartbeat" to constantly update frames as enemies move, health levels change, and powerups are activated. We needed to be sure that the two engines were acting in sync and drawing in the correct order. For every frame of gameplay occurred in Impact, we needed to notify EaselJS of the updates and make sure the game’s head’s up display was up to date. There were a few things we needed to do to make this happen.
The first thing we had to overcome was that both EaselJS and Impact were going to draw to the same canvas. This meant that we needed to ensure that neither engine was drawing over the other at the incorrect time. Since we wanted to use Impact’s excellent preloader and overall application structure, we decided to use Impact’s ticker function to regulate the entire game. We just tapped into the draw method on the main object to take care of telling EaselJS to update at the correct time.
After having Impact handle the main heartbeat of the application, we needed to set a few things in EaselJS to make sure it heeded the heartbeat and not its own Ticker class. The code below was pulled from our SystemManager class which manages the EaselJS drawing methods.
Once we had these settings in place we could use Impact to render the game and use EaselJS to place anything else we needed on top of it.
Otter Destruction
Another interesting aspect that we ran across came into play when we wanted to add in an ultimate powerup that would kill all of the enemies on screen — Otter Destruction. Our main issue was with the style of animation that we wanted to use, it benefited us the most for the powerup to be a sprite just like the other characters instead of using a video or some other kind of overlay. The Otter animation that was rendered full screen and required the use of an extremely large spritesheet (about 25 megapixels) to achieve the look and detail that we wanted for such an awesome powerup. Internet Explorer handled the large spritesheet better than any of the other modern browsers that we threw it at.
Closing
With this project we really wanted to push the limits of web standards and see how close we could get to the feel of a classic arcade game. Using the vast selection of libraries that the web development community has created and the power of HTML5, we achieved just what we were looking to.