‘Pileup’ Game Postmortem

This article is cross-posted from #AltDevBlogADay.

Last month I participated in the Toronto Game Jam, where game developers make a game over one weekend. The game ‘Pileup’ was made that way, with most coding done during the TOJam. This is a detailed postmortem of the game ‘Pileup’. You can read more about my TOJam experience on a previous post,  ‘Things I Learned in TOJam‘.

 

[]


Play Pileup

What Went Right

The Development Platform

Pileup is a game built on the Flash platform. Making it a Flash game enables us to easily target both desktop web browsers with Flash player, and mobile devices with Adobe AIR. The game is small and simple enough to fit within the technical limits of Flash and its media handling is extremely simple and easy to use – a perfect fit for a very short development schedule like the one we had.

Game Framework and Physics

We made an early decision to base Pileup on physics, specifically the Box2D physics engine. It made perfect sense in the context of TOJam, since the game has to be simple enough to create and entertaining at the same time. In order for that to work, we needed a framework or game engine that can handle physics, and so had to consider one of the following  options:

  1. Use one of the popular game engines, like Flixel, FlashPunk or PushButton
  2. Integrate physics with a wrapper library, like QuickBox2D
  3. Write our own framework with Box2D integrated into it

The first option was lucrative, as it would save a lot of effort. I tried to set up a simple physics demo with these engines and quickly strike out Flixel and FlashPunk, as they are more suitable for simple platform games and don’t work well with physics simulation like Box2D. PushButton was a serious contender, and it even has Box2D built into it – however the interface for it is not very easy to use, and it require having a physics component attached to every game object. After digging into the source I also discovered that the collision system is far from optimized and uses an older version of Box2D so I decided to drop it as well.

Option #2 was using QuickBox2D – very easy to use but way too generic to be used in an actual game. It did find a lot of good ideas inside the source code, like the way they build physics bodies based on shapes.

We ended up with the the last option, and I took a shot at writing my own framework. Taking a cue from libraries like Corona and QuickBox2D, I designed a simple interface that couples a display objects with a physical body. After spending some time with excellent tutorials by Todd Kerpelman, Allan Bishop and Emanuele Feronato, I managed to get a grasp on the basics of Box2D and write a simple engine that would form the core of our game framework. It also helped that by that time I was familiar with the way that the other frameworks integrated Box2D so I had plenty of references.
This effort resulted in our homegrown framework  – a game framework with a physics subsystem, that encapsulates all Box2D functionality as well as an actor system similar to the one used in engines like Unreal3.

Architecture: Composition vs Inheritance

Engine architecture is typically based on one of two patterns to define the different game objects: inheritance or composition. Some engines use composition (like PushButton Engine), some use inheritance (Flixel) and others, like Unreal3 use a blend of the two.  We had to pick a side.
We chose to rely on inheritance rather than composition, simply because it suited our needs – we kept the hierarchy simple and composition would take too much time to implement. The base class for any game object is the Actor class, and the subclasses override specific functionality to define their own behavior.
Here is a snippet of the base actor class:

	public class Actor
	{
		protected var _body:b2Body;
		protected var _geom:DisplayObject;
 
		public function get body():b2Body { return _body; }
		public function get geom():DisplayObject { return _geom; }
 
		public function Actor(disp:DisplayObject, b:b2Body=null)
		{
			_geom = disp;
 
			if (b) {
			    _body = b;
			    _body.SetUserData(this);
			}
		}
 
		public function updateNow():void
		{
			updatePosition();
			childUpdate();
		}
 
		public function destroy():void  {}
 
		protected function updatePosition():void  {}
 
		// Called when collision occured
		public  function hit(force:Number, actorB:Actor):void {}
	}

Assets: Vector vs Bitmap

Another early decision we made is to try to optimize for mobile, so it would be easier to port the game to mobile platforms later. Even though the framework supports any display object as the visual element, we opted to use bitmaps over vectors and spritesheets over movie clips. This actually made it much easier to handle the art pipeline – bitmaps get loaded dynamically on game setup and do not require embedding or rebuilding when updated. Performance wise, spritesheets make sense since they render faster – by blitting the frame and avoiding the overhead of timeline in movie clips. The faster rendering is due to the face that a movieclip frame (or a shape) is drawn (and rasterized) on every frame in the game loop, while a bitmap is only blitted once and then get cached and used on subsequent frames without rasterizing.
Also, we only used a limited number of frames per asset in the game so the memory usage is kept on check.

Engine First, Game Later

This may sound trivial, but too often ignored: avoiding tight coupling between engine (framework) and the game specific code is not only a best practice, but also a big time saver. Once the scope of development has switched from the framework to the game, we were able to focus on the game code almost exclusively. Tasks become much clearer and easier to implement that way, especially under pressure of a very short schedule. Also the game code is often coupled with specific assets, and involves close collaboration with the artist that creates them, so there is minimal down time for the artist since they don’t need to wait for the coder to implement the infrastructure.

Level Editing Tool

Perhaps the biggest win for us was the fact that we made our own level design tool in advance. These kind of platform game requires a lot of time and effort to build a level, and we approached the problem from two aspects- design time and load time.

First we created a script for Flash CS4 (using JSFL) that exports all instances on the stage to an XML file, in the form of a list of objects with type, name and position. Then, we wrote a level loader into the game framework to read the level XML, create the game objects and place them on the game screen. This was simple and crude but extremely effective – any of us could edit a level in a matter of minutes and creating a new one in an hour or two.

What Went Wrong

Finalizing Game idea

Up until the last moment before the jam we weren’t able to nail down a clear idea for the game and how to make it fun. We had to fill in the blanks as we go, often while coding – that impacted the final product as it often feels like something is missing. Maybe we would add more in future versions.

Content and Production Value

For a game created in such a short schedule you really need to prepare goo concept art and visual style guide well in advance. Like every other game out there, content is king – highly polished visuals are extremely important to give the game high production value. Our visuals fell behind and did not meet our initial expectations, leaving the game without anything that stands out of the ordinary.

Conclusion

Pileup was a lot of fun to create. It may not stand out and is not very original, but we learned a lot while making it. The production process is compressed to a few days and the stakes are high, and we managed to reach the finish line with a complete game. Lots of features did not make it to this release, so hopefully we would be able to include them future updates.

Game Facts

Development Team: Two coders and two artists

Tools used
Adobe Flash Builder 4.5, Adobe Flash CS4, Photoshop CS4, SVN

3rd Party libraries
Greensock TweenLite, AS3 Signals, Box2D 2.1a (Boris the brave AS3 port)

Source 3600 lines of code in 44 classes
Build Size Binary SWF file: 112k, Total Assets: 6 MB