Game Dev


25
Sep 07

If a game can make us cry, then why can’t it make us kill?

Another suit (from Jack Thompson) against Take-Two/Rockstar regarding GTA and a murder. The standard “informed” rebuttal: games don’t make people killers… if he didn’t have access to guns… it’s the parent’s responsibility… he was a 13yrold playing a 17+ M rated game…

The problem: arguing that he’s a 13yrold playing a 17yrold’s game kinda concedes the point that the game may have caused the problem. While that may be possible, I kinda doubt it…

Another problem: arguing that playing a game can’t have a negative impact on you (can’t make you a killer) kinda goes against the assertion that games are art and can have impacts on the audience, express emotion, etc.

We can’t have our cake and eat it, too: games either have emotional/psychological impacts or they don’t. And if they do, the question is whether the game in particular has a positive or negative one (or if its even related to the case). Of course games have emotional impacts. The best ones aim for it. That does not mean they bear responsibility for its audience’s actions.

Games, like all media, broaden the consumer’s palette of experience. It’s experience-by-proxy. I wasn’t alive during WWII, but I feel as though I have some degree (incredibly slight, to be sure) of experiential understanding of it due to movies like Saving Private Ryan, Schindler’s List, or video games like Medal of Honor. We have to admit, though, that 2 hours of Saving Private Ryan delivers a far deeper emotional impact than 20 hours of Medal of Honor.

Of course, most video game players focus on the mechanics, with the thematic elements being secondary. Thematic elements become repetitive. Much like a movie may revolve around its characters and their development, a game revolves around the mechanics and their application.

Of course, someone predisposed toward violence or who is desensitized to it or amoral for whatever reason may focus on the thematic elements. In fact, they may be attracted to the game because of the thematic elements, as opposed to the mechanics. And if they play obsessively, it may be a kind of “wallowing” in the themes, as opposed to “exercising” the mechanics.

Porn is an apt comparison, a slightly more socially acceptable pursuit that most males will (hopefully) have more experience with than violence. It’s base, just like violence, and is considered a socially undesirable (if not wholly unacceptable) recourse for certain “urges”. One can probably see the distinction between viewing porn “to get your rocks off” as opposed to becoming obsessed and entrenched in it. There’s a difference between getting aroused by hearing a woman moaning as she’s brought to (a likely faked) climax and being aroused by the male-dominating, misogynistic “fake rape” that can be found in some dark corners. It may be a thin line from some perspectives, and their may be no distinction in the eyes of others, but I’d guess most guys can see the difference.

The same applies to video games… the vast majority of the consumers are relishing the mechanics primarily and the themes secondarily. It’s not the life of a real mob assassin that we’re enjoying thematically, it’s the idealized, sanitized version. And we know it’s different. Hell, a 13yrold should know its different. If he can’t make that distinction, then there’s something wrong. A parent shouldn’t be oblivious to that.

So the parents do bare some responsibility, not so much for the child’s actions, but for the contributing factors to those actions. Now, if Rockstar was advertising GTA during Saturday morning cartoons, including it in cereal boxes, and distributing demos at elementary schools, then they’d be doing something wrong (though still not *responsible* for the actions of the players). But rating a game as M, selling it for $60 for a $200 game machine puts reasonable barriers to entry up, particularly for a 13yrold.

In other words, I’ve got absolutely no problem with the existence of pornography. I would absolutely have a problem with my 13yrdold son watching pornography. But if I bought it for him, and let him watch it, could I really turn around and sue Vivid when he got a girl pregnant? Could I honestly blame the makers of the porn for that?

Please note my comparison between porn and video games: the comparison is apt because in the eyes of those defaming video games they are on equal footing, yet they would never think of suing the porn makers (or maybe they would, but no lawyer would give them the time of day ’cause they’d lose). They are not the same thing, though. Porn is like a documentary: it is real people having real sex. GTA is crudely modeled and animated, very clearly not real people doing very clearly not real things (like running from one end of a city to another, and dying, and being resurrected, and getting hit by cars and not getting hurt, etc…).

So, the next time you witness a “games don’t kill people, people kill people” kind of debate, be clear about the point you’re arguing. Don’t diminish games by arguing they don’t have the emotive substance to effect their audience. Its a double-edged sword that we must be quite careful in wielding.


25
Jun 07

Pixel-Perfect Collision Detection in ActionScript3

UPDATE: Check out the most recent update to this post.

The Flash Player provides vector-perfect collision detection with the hitTest() method. The drawback of this method is that if you use Bitmaps it sees just the bounding-box of the Bitmap, i.e. it ignores alpha. This is pretty frustrating when it comes to a sprite-based game.

A bit of digging on the web found a quick and simple solution from Andre Michelle [.zip]. A slightly more robust version was written for AS2 by Grant Skinner, then ported to AS3 by Boulevart. I grabbed their version to start with...

First, I cleaned up the code and commented it. It's pretty straightforward: you render two display objects to separate color channels, combine the color channels, then search the resulting image for any overlapping color (the previous two sites have deeper explanations).

I found two problems with the code. First, it unions the bounding boxes of the two display objects. This is unnecessary, we only care about the pixels in the intersecting rectangle. And since performance hit of this technique grows with the size of the overlap, this is a critical optimization (you're allocating significantly less BitmapData each test).

Second, the code doesn't account for a display list of any complexity: it assumes the two display objects have the same parent (and are thus in the same coordinate space), and it assumes the display objects do not have any scale or rotation (it only considers linear transformation, i.e. the objects' positions). I fixed both of these.

So, the new code will determine if two DisplayObjects are visibly overlapping with pixel precision. Enjoy!

Actionscript:
  1. package
  2. {
  3.     import flash.display.BitmapData;
  4.     import flash.display.BitmapDataChannel;
  5.     import flash.display.BlendMode;
  6.     import flash.display.DisplayObject;
  7.     import flash.display.DisplayObjectContainer;
  8.     import flash.geom.Matrix;
  9.     import flash.geom.Point;
  10.     import flash.geom.Rectangle;
  11.    
  12.     public class PixelPerfectCollisionDetection
  13.     {
  14.         /** Get the collision rectangle between two display objects. **/
  15.         public static function getCollisionRect(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Rectangle
  16.         {
  17.             // get bounding boxes in common parent's coordinate space
  18.             var rect1:Rectangle = target1.getBounds(commonParent);
  19.             var rect2:Rectangle = target2.getBounds(commonParent);
  20.            
  21.             // find the intersection of the two bounding boxes
  22.             var intersectionRect:Rectangle = rect1.intersection(rect2);
  23.            
  24.             if (intersectionRect.size.length> 0)
  25.             {
  26.                 if (pixelPrecise)
  27.                 {
  28.                     // size of rect needs to integer size for bitmap data
  29.                     intersectionRect.width = Math.ceil(intersectionRect.width);
  30.                     intersectionRect.height = Math.ceil(intersectionRect.height);
  31.                    
  32.                     // get the alpha maps for the display objects
  33.                     var alpha1:BitmapData = getAlphaMap(target1, intersectionRect, BitmapDataChannel.RED, commonParent);
  34.                     var alpha2:BitmapData = getAlphaMap(target2, intersectionRect, BitmapDataChannel.GREEN, commonParent);
  35.                    
  36.                     // combine the alpha maps
  37.                     alpha1.draw(alpha2, null, null, BlendMode.LIGHTEN);
  38.                    
  39.                     // calculate the search color
  40.                     var searchColor:uint;
  41.                     if (tolerance <= 0)
  42.                     {
  43.                         searchColor = 0x010100;
  44.                     }
  45.                     else
  46.                     {
  47.                         if (tolerance> 1) tolerance = 1;
  48.                         var byte:int = Math.round(tolerance * 255);
  49.                         searchColor = (byte <<16) | (byte <<8) | 0;
  50.                     }
  51.  
  52.                     // find color
  53.                     var collisionRect:Rectangle = alpha1.getColorBoundsRect(searchColor, searchColor);
  54.                     collisionRect.x += intersectionRect.x;
  55.                     collisionRect.y += intersectionRect.y;
  56.                    
  57.                     return collisionRect;
  58.                 }
  59.                 else
  60.                 {
  61.                     return intersectionRect;
  62.                 }
  63.             }
  64.             else
  65.             {
  66.                 // no intersection
  67.                 return null;
  68.             }
  69.         }
  70.        
  71.         /** Gets the alpha map of the display object and places it in the specified channel. **/
  72.         private static function getAlphaMap(target:DisplayObject, rect:Rectangle, channel:uint, commonParent:DisplayObjectContainer):BitmapData
  73.         {
  74.             // calculate the transform for the display object relative to the common parent
  75.             var parentXformInvert:Matrix = commonParent.transform.concatenatedMatrix.clone();
  76.             parentXformInvert.invert();
  77.             var targetXform:Matrix = target.transform.concatenatedMatrix.clone();
  78.             targetXform.concat(parentXformInvert);
  79.            
  80.             // translate the target into the rect's space
  81.             targetXform.translate(-rect.x, -rect.y);
  82.            
  83.             // draw the target and extract its alpha channel into a color channel
  84.             var bitmapData:BitmapData = new BitmapData(rect.width, rect.height, true, 0);
  85.             bitmapData.draw(target, targetXform);
  86.             var alphaChannel:BitmapData = new BitmapData(rect.width, rect.height, false, 0);
  87.             alphaChannel.copyChannel(bitmapData, bitmapData.rect, new Point(0, 0), BitmapDataChannel.ALPHA, channel);
  88.            
  89.             return alphaChannel;
  90.         }
  91.  
  92.         /** Get the center of the collision's bounding box. **/
  93.         public static function getCollisionPoint(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Point
  94.         {
  95.             var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance);
  96.        
  97.             if (collisionRect != null && collisionRect.size.length> 0)
  98.             {
  99.                 var x:Number = (collisionRect.left + collisionRect.right) / 2;
  100.                 var y:Number = (collisionRect.top + collisionRect.bottom) / 2;
  101.        
  102.                 return new Point(x, y);
  103.             }
  104.        
  105.             return null;
  106.         }
  107.        
  108.         /** Are the two display objects colliding (overlapping)? **/
  109.         public static function isColliding(target1:DisplayObject, target2:DisplayObject, commonParent:DisplayObjectContainer, pixelPrecise:Boolean = false, tolerance:Number = 0):Boolean
  110.         {
  111.             var collisionRect:Rectangle = getCollisionRect(target1, target2, commonParent, pixelPrecise, tolerance);
  112.        
  113.             if (collisionRect != null && collisionRect.size.length> 0) return true;
  114.             else return false;
  115.         }
  116.     }
  117. }


18
Jan 07

Flex rhymes with…

Have I mentioned how much I like Flex? The ActionScript3 (EMCAScript/JavaScript) language is a pleasure to program in (garbage collected, dynamic *and* static typing, single-inheritance class hierarchies and built in XML (E4X) manipulation). Flex Builder 2 (which is Eclipse) is a spectacular IDE (trumping, dare I say, VS.NET 2003, my prior fave, but only with Visual Assist -- Visual Assist still trumps all). And the inclusion of declarative (MXML) programming hits a perfect sweet spot in my long time HTML coder's heart. It just seems perfect.

You know, kinda like exactly what I said would be the perfect game development environment back in March 2006. I sung the praises of the mindshift in software development brought on my "web 2.0" where production-quality development truly is agile: they divide the problem into structure, behavior and styling. Of course. The Holy Trinity of Interaction. You find it time and time again when you dissect anything one would describe as interactive: model-view-controller, input-process-output, listen-think-speak... structure, behavior and styling.

To recap: structure defines the layout of things, their relationships, both spatially and conceptually; behavior consumes the structure, plays on the structure like monkeybars, moves through it. And styling determines how the structure is presented, provides feedback, expresses.

In practical software development terms, I've discovered that means one needs a declarative language (MXML), an imperative language (ActionScript3), and support for skinning and/or style sheets (Flash, CSS). Flex bundles all three together.

Of course, it has a good application framework provided out of the box (that's free, in fact, along with the compiler... you just pay if you want the IDE, which is Eclipse, so you're actually just paying for the visual MXML editor, which is probably worth it, but certainly not required if you're patient or are experience with HTML/CSS). I can't imagine if there was a gamedev framework for it... that'd be sweet. ;-)

Chalk up one for Adobe (via Macromedia): Adobe Flex 2 is the finest software development kits -- nay, platform! -- that I've ever had the pleasure of dealing with. And this coming from a guy who's spent the last five years convincing game studios to adopt a commercial SDK (RenderWare), so I can smell my own kind... and I don't smell Flex at all! Clean as a whistle...

I think they will seriously give C#.NET a run for its money. Sure, C#.NET is probably faster on a Windows box, no doubt about that... but is it that much faster? And .NET certainly doesn't have the Flash graphics engine backing it up (your toolchain is already finished!). And it only really works on MS devices. And you have to download and install (and in Vista, enter an admin password!) because its a native EXE with all of the potential problems.

While Flash... well, Flash is ubiquitous. Hell, it's more standardized across user machines than Java or web browser and most certainly operating system. And your input, output and everything in-between is identical on whatever platform your user is using.

And, and, and... it's all sorts of integrated with and designed to a leverage the always-on-net-connection world that many, many of us live in.

Go now, you can buy it off the shelf. I did. Best $500 I've spent in a long time. No regrets.


13
Dec 06

Austin, Texas

I'm now firmly back in Austin, Texas. Feels good to be here. Warm weather, breakfast tacos, NPR, pancakes and all of the local businesses... it certainly feels like home. Of course, there is still a mountain of boxes to unpack (amazingly, unpacking boxes goes pretty slow with a six-month old and a new startup!). Oh, and Christmas shopping... So, I'm really looking forward to getting to the other side of the holidays so life can somewhat return to a normal pace... ;-)

People are asking what I'm working on, and I've given some veiled hints. And there are a few folks I've actually explained it to offline. The reactions have all been positive -- dare I say, excited -- so far. Of course, my powers of persuasion are legendary (why do you think EA acquired Criterion? ;-)).

Here's the big, big, big picture goal: to make game making a purely creative process, to eliminate the drudgery of engineering that it currently requires. If technical neophytes can create web pages and edit videos, then why can't they make games? Because we're special? I don't think so. Because it's interactive? Folks get board games, and when they were kids, they certainly made up alot of games on their own. So, as educated adults who can use a computer well enough to surf the web and download music to their iPods, how come they can't make a PacMan clone?

It's time to stop approaching the problem from the engineeer's perspective, which is exactly what XNA does... it's an SDK. It's not the YouTube of video games... it's the RenderWare of hobbyist programmers! Not a bad thing, not an unwanted thing, but not everything it could be!

It's time to throw off the shackles and storm the gates... the audience will only grow in relationship to the number of creators, and the number of creators will only grow if we mature the tools and lower the barrier of entry. Anyone can pick up a paintbrush... anyone can make a game.


11
Nov 06

So, now what?

So, now what? That's the question many folks have been asking me over the last few weeks, since I announced my departure from EA. I've had to be understandably coy about the whole thing as to not ruffle any feathers at the mothership... I've got enough going on with an international move and such to not have to fight one last political battle.

International move, you say? Yes, we (me, the misses, the baby girl) currently live in Vancouver (well, Burnaby, but that's besides the point). A week from now, we'll live in... well, in limbo, as it takes a while for all of our belongings to make the long trek from Vancouver to Austin, Texas. We'll hang around our parents' homes in Northwest Arkansas, enjoy Thanksgiving (American-style), and introduce our baby girl to all of her uncles, aunts and cousins. Two weeks from now, we'll be sitting in our new home in Austin, unpacking what I'm sure will be several million cardboard boxes (now, where's my crowbar...).

So, that's the physical "now, what?" over the short term. But what's really going to happen? What are my next steps professionally?

Well, it's still a little too early too say. It's not that I don't know... I've known for nearly six months! But, due to my employment contract with EA, I was unable to act on my plans for world domination. It'd be no good if I went and created the "next great IP" and it defaulted to the folks who paid my bills, now would it? Thus, these next few weeks will see the creation, tangibly in copyrightable form, lots of IP.

What is this IP, you ask? Well... I can't say now. I've spoken to some offline about it, to make sure I'm not crazy, and responses seem to favorably indicate that, at least in respect to this idea, I am not crazy. In fact, it sounds as if I may be providing an honest-to-goodness service for my fellow developers.

Service, you say? Games aren't services! No they're not. I am not making a game. You are. We all are. Have fun!


19
Oct 06

Movement Mechanics in “The Legend of Zelda”

Let's start our deconstruction with the most basic feature of the player's character, Link: his movement. Link's movement displays a surprising amount of subtlety. If you play The Legend of Zelda for a while, you'll notice that Link doesn't ever get hung up on obstacles due to unexpected collisions, nor do you ever just miss a bad guy by a pixel or two when attacking him. Yet at the same time, you'll notice that Link moves fluidly through the gameworld; even tough the environment is tile-based, you can tap the directional pad and link will move a single pixel in that direction. If you're moving to the left and decide to go up, down or right, Link instantly moves in that other direction when you change directions on the gamepad.

What's happening here is a very neat trick. While Link can move a single pixel at a time, in any direction, the longer he continously moves in any direction the more he gravitates toward aligning himself with the underlying grid of the screen. The tile grid for LoZ is 16 tiles wide by 14 tiles high (including 3 tiles for the status display at the top of the screen). Each tile is 16x16 pixels. Link operates on a half-tile grid, though (32x28 tiles, 8x8 pixels each). As Link moves, if he's not currently aligned with the half-tile grid, he is adjusted, one pixel at a time, toward the closest correction. As a result, if Link is 4 pixels off alignment he'll line back up with the grid after moving 4 pixels.

In case that description doesn't make sense, here's an exercise to help demosntrate the technique:

Assume Link is basically in the center of the screen, lined-up with a tile. In other words, Link occupies a whole tile, just as he would in a strictly tile-based game (like a traditional boardgame or wargame). If you tap on the directional pad to the left, Link will move one pixel to the left. If you tap again, he'll move another pixel to the left. This is pixel-fine control, which makes Link's movement feel fluid.

Now, if you hold the directional pad to the left, Link will move continously. As soon as you let up, he stops. If you hold left then immediately reverse to hold right, he instantly changes direction (as he does for up and down as well). This is basically lag-free, which makes Link's movement feel responsive.

Okay, return back to Link sitting squarely on a tile. If you tap left twice he'll be two pixels over the left edge of his starting tile. Now press up four times. You'll notice that after each press Link will move up one pixel. But, he'll also move to the right one pixel, either the first two times you pressed up or the first and third times you pressed up (I don't have the game in front of me and I can't remember the rate at which it corrects). So, even though you never press right on the gamepad, Link has now returned to the same horizontal position as he was when he started (before you moved him left two pixels). This is the built-in correction.

What does this correction do for you?

The correction prevents the subtle but annoying problem wherein the player would "snag" on the corners of objects that he anticipated passing by. The more the player moves contiously the more aligned Link becomes, which has the same effect as speed-sensitive steering in a car.

The correction also has benefits for attacking as well. When Link attacks (with his sword, for example), the "kill zone" lies in the tile(s) immediately along his facing direction. Since enemies align along a similar half-grid as Link, the correction serves to line up Link with his enemies (as opposed to missing the enemy by a few frustrating pixels).

Observant readers will observe (as they are known to do) that this "feature" doesn't appear in the SNES sequel, The Legend of Zelda: A Link to the Past . Even though the gameworld is still tile-based, player (and enemy/NPC) movement is not strictly aligned on any grid. We get the same corrections though, but using different mechanisms.

Movement is corrected by "rounding" the corners of most things Link can collide with. Thus, when he encounters them the "physics" of the game deflects him at a 45-degree angle along his direction of movement (e.g., if he was moving north/up and encountered a corner he would move northwest/east until he passed the corner).

Attacking is corrected in a similarly interesting way. Instead of Link's sword having a killzone along a straight line down his facing direction, his sword "swipes" in a large arc, an arc that happens to be pretty close to full two "tiles" in the gameworld (one directly in front and half above and half below). This allows the player to attack while slightly mis-aligned with an enemy and still land a blow.

The result for both actions in both games is the same: the player's desire is successfully expressed in the gameworld, regardless of the potentially pedantic ways of the computer.


18
Oct 06

Deconstructing “The Legend of Zelda”

It's no secret that the Legend of Zelda (NES) was a watershed game. The game still has an open-world feel that titles to this day fall on their face trying to emulate, even in this post-GTA design world. This was the first game I ever played that truly was open in the sense that I could go anywhere in the game and basically approach (or avoid) any obstacle as I saw fit. The game also fits the bill as the prototypical example of an action-adventure video game, and the series (with a few minor exceptions) has continued that tradition since.

What is there to learn from a game that originally released in 1986? Twenty years later, there are still design subtleties in LoZ that are overlooked. The game is a perfect example of simple mechanics played out on a vast and varied playing field. From a complexity perspective, the game represents something achievable by any single individual given today's technology and tools, yet we have the efforts of huge teams with comparitively bottomless budgets failing to capture the subtle qualities that simply make this game work.

In what I hope to be an insightful series of essays, I'll be deconstructing the elements that I feel make LoZ a relative Citizen Kane of the genre, and see how those successes can translate to useful lessons in today's games.

As a bit of a preface, let's look at the game's premise and detail the overall mechanics of LoZ. The premise follows the classic Hero's Journey, with Link (the player-controlled character, who was so-named because Miyamoto saw him as the player's "link" into the game world) out to save Princess Zelda from the evil clutches of Ganon. To achieve this goal, Link must acquire the objects of mythical power (the tri-force) and the one weapon that can kill the ultimate evil (the master sword). To this end, Link travels to many different locales (deserts, forests, mountains, dungeons), doing battle with many monsters and finding many unique weapons.

The mechanics are straightforward. Link is represented onscreen in an top-down view. The player has direct control over Link: the directions on the gamepad (left, right, up, down) correspond to movement onscreen (west, east, north, south, respectively). The A & B buttons are mapped to various actions, usually one of which is mapped to Link's sword while the other is mapped to a special weapon or inventory item. There's no jumping. To pick-up an item, Link simply collides with it.

The gameworld is divided into two sections: the Overworld and the Underworld. The Overworld is composed of mountains, trees, bushes, rivers, lakes, rocks, etc., what you'd expect from a classic outdoor adventure landscape. The Underworld is represented by dungeons whose entrances are hidden throughout the Overworld. Each dungeon (of which there are 9) is self-contained with one entrance/exit, each one containing a boss monster and usually an item of significance near their end. The dungeons don't have to be visited in any particular order, but some of them have accessibility barriers that require attaining items of significance from other dungeons in order to be successful. The final dungeon is home to Ganon, whose defeat is the final goal of the game.

The gameworld is viewed one screenful-at-a-time. When Link hits the edge of the screen (or a doorway on the edge of the screen when in the dungeons) the game "pauses" momentarily while the view shifts/slides to the new screen, at which point player-control resumes. Each "screen" is usually transient, with enemies regenerating and other elements "resetting" when a player exits then returns to a screen. Enemies cannot pursue Link out of one screen and into another, nor can Link attack from one screen into another. Thus, each screen represents a self-contained segment of gameplay, rarely dependent on what came before it.

Enemies are generally very "stupid" and normally just follow set movement patterns. Outside of bosses, few of the enemies actually pursue the player, and most are killed in one or two hits from the player's sword. Most enemies attack the player with "contact damage," though some launch projectiles along whatever direction they are facing. Often, enemies leave behind some kind of reward on their death, usually a coin (or "rupee"), heart (representation of Link's life or hit points) or other refillable items (arrows, bombs, keys).

Of course, all of this is probably not news to anyone reading this, as I would hope everyone is familiar with this classic. It can be easily located in ROM form to play in your favorite NES emulator, or you can grab the version for the GBA (the re-released NES classics). I have both, in fact!

Our first topic (which will be posted either later tonight or tomorrow night) will be some observations on the movement and attack mechanics of Link.


10
Oct 06

GTD, an agile software dev process?

Can we apply David Allen's Getting Things Done process to software development? If it can organize the hectic life of a Fortune 500 CEO, couldn't it help out the lowly software developer? A recent blog post from a coder in the Google trenches, "Good Agile, Bad Agile" suggests to me, "yes."

This morning, I read a post over at King Lud IC that seems to indicate I'm not the only one who read "Good Agile, Bad Agile" and thought, "hey, this could apply to gamedev!" Of course, there are already folks applying the Agile process to gamedev (notably, the folks over at High Moon Studios). From the sounds of it, they're happy and successful. But, I know Clint (High Moon CTO) and Noel personally, and those are two guys who I'd expect could make any process successful. They're dedicated, meticulous, and above all clever. How about the rest of us?

Like many web professionals and software developers, I've been lured by the cult of personal productivity. It's rather ironic, then, that I'm also infamously considered a procrastinator and referred to by my parents (when speaking to their friends) as "extermely laidback." Of course, I own up to both of those descriptions. Perhaps they're the underlying motivation for my constant pursuit of a "better system"?

I've found Getting Things Done (or GTD as its referred to by those in the trade) to be an ideal system. It has some basic rules, some lose theory around those rules, and a whole ecosystem of software and blogposts guiding anyone wishing to embark on the journey. For purposes of this discussion, here are the basic tennets (cribbed from the 43Folders linke above):

  • Identify all oustanding issues (close all open loops).
  • Get rid of everything that doesn't need your attention right now (delegate, defer, delete).
  • Create a central repository for everything that works for you.
  • Put stuff in the right place, consistently.
  • Work based on time, effort and context (do the right thing at the right time at the right place).
  • Repeat, and refactor mercilessly.

So, how do we apply these tennets of GTD to the software development process? Or more interestingly for the readers of this dear site, how do we apply this to game development (thinking of the indies)?

Identify all oustanding issues (close all open loops).

I find this one to be the most satisfying, the most fun. It's the carrot that really gets the process moving along. It's brainstorming, but with more depth and detail. You'll want to make an exhaustive list of all design features, technology hurdles and content requirements. Don't stop and do anything, and don't spend too much time thinking. The goal is to make as complete a document (list) as possible of what needs to be done. Try to be as specific as possible, but don't worry too much about the granularity (as that will solve itself later). You should be telling yourself, "if I don't write this down then it's basically like it doesn't exist." Make your thoughts tangible, or they'll never happen.

Get rid of everything that doesn't need your attention right now (delegate, defer, delete).

The three D's: delegate, defer, delete. There are lots of details you won't have to worry about. If you just starting your design for a new game then don't fret over how you're going to collect credit card payments when its finished. You can worry about that if and when you finish the project. If you're the programmer and you're not quite sure how the artists are going to produce all the content for the game, stop, delegate that to the artist and have them worry about that. This is all in an effort to save you from the fourth D, distraction.

Create a central repository for everything that works for you.

I'm using activeCollab, a web-based project management app (a free, self-hosted competitor to Basecamp). Basecamp is a great option as well. Large organizations often use Microsoft Project. I'm sure there are other options as well. A simple to-do list could work as well, but the less structured it is the more onus is on you, the user, to keep things organized and useful. The critically important thing is that the repository is something that you'll use, and use often and regularly. As a result, I'd suggest using a piece of software that you're in love with, if possible, and you want to have an unreasonable desire to go and use it at every chance (to close those open loops).

Put stuff in the right place, consistently.

If you think of a new idea, put it in the repository. If you run across a bug, put it in the repository. Whatever you do, don't have multiple places for these things to be kept; keep it all in one, centralized spot. Don't keep a notepad on your desk and promise yourself you'll type the stuff up in a few hours or at the end of the day. Do it now. The advantage is that you get these "open loops" out of your brain so that your brain can be used for more productive things. Computers are great at "remembering" things, let them do the grunt work.

There's one exception to this: the two-minute rule. If you can act on something in less than two minutes, then do it. The overhead of "using the system" isn't worth it for something so small. Two minutes isn't an absolute, but don't stretch the exception too far or you defeat the purpose of the rule (as you start to get distracted!).

Work based on time, effort and context (do the right thing at the right time at the right place).

Multitasking is trivial with modern computers. While context-switching is one of the most expensive "atomic" operations a computer can perform, it still is well under a second. For people, on the other hand, context-switching is expensive, very expensive. It breaks "flow." So, instead of just plowing through your lists of tasks in the order they come, divide them into "contexts" that dictate when the appropriate time is to work on them. This is particularly useful for the one-man-gamedev-shop where you wear the hat of programmer/artist/designer/producer. I'd recommend having contexts like: Photoshop, Websurfing/Research, Visual Studio, Level Editor. When you're in a specific context, look to that "list" to see what you should do next.

Also, if your "master list" tracks such useful information such as estimated time required for a task, use that information to as a secondary criteria for context. Have 15 minutes while you wait for some software to download? Do a little websurfing/research. An hour while your significant other is getting ready for work in the morning? Finish the icon for your application in Photoshop.

Iterate and refactor mercilessly.

Consistency in applying these policies is what makes them successful. Refactoring is also a big win.

Now, I don't mean refactoring in the software sense. I mean refactoring the process. Part of the advantage of the simple process and the whole GTD system is its kind of introspective nature, where GTD practicioners are always looking for ways to refine and enhance the GTD system while still embracing the fundamentals of GTD.

But there's an even more particular way in which you should apply the ideal of "iterate and refactor." In the case of your master list, you'll inevitably have items on it that the GTD crowd calls "projects." Projects are tasks that are in fact meta-tasks, something like "Organize the Closet" which aren't really directly actionable. When you hit upon a "project" in your list, you need to look at it and determine what the "next action" is, i.e. what can you do tangibly to move this forward.

In fact, GTD has "reviewing" as an important element of its process. One should regularly (daily, twice-daily) review all of the meta-level stuff, like projects, and determine where they stand (completion, timing, etc.) and populate their master to-do list accordingly. Again, this is an aspect of the "refactoring."

Well... there's a ton more I could write on GTD-as-software-process, and I certainly plan to do that. This post is somewhat vague in areas, a bit hand-wavy in others... it's my first shot at getting these ideas down, but I'll definitely revisit it in the future.


10
Oct 06

Stuck in Limbo

I'm looking forward to getting stuck in Limbo. He's looking for C++ programmers, but I was first struck with how perfectly this game could be done in Flash. With Flash's new filters and improved performance, I'd guess he could get the exact same results, cross-platform and with a lot less development pain than C++.

It's a great example, though, of the kind of results we'll see as more people with classic art and graphic design backgrounds (with a sprinkling of programming experience) are brought into the gamedev fold. The in-development footage on his sight is hauntingly beautiful, and an inspiration to say the least. Makes me remember those first few hours playing Out of this World, still one of the few games to deliver so much on so little.

Speaking of Out of this World, I've always thought it'd be awesome to see that game remade in Flash (it's largely rotoscoped with a vector-like graphic style, very applicable to Flash development). Hell, if it fit on a 1.44MB floppy and ran on a 286, surely it can run full-speed in Flash on a modern day machine? Those are the kind of side-scrollers people need to be making... there's a lot of life left in that very simple mechanic! (And the side-scroller view? Well, that aesthetic has worked for "comics" for a hundred years.)


15
Sep 06

Perfect and Simple

TonyPa first came to my attention with his impressive tutorials on tile-based games in Flash. Later, I discovered his games page, which includes a maddening simple and addictive game called "Gear Taker." If you go to his site, click on "games" then click on the first game in the list "GEARTAKER" that'll lead you to it (sorry, no direct links available). This is the finest example of a "one button game." To play the game only requires pressing a single button (the left mouse button, of course). Yet with only that one means of input the gameplay is as addictive as any good game of Tetris or Bejeweled. And the aesthetics... well, the visuals are black-n-white, stick figures and gears (as simple as it gets), and the music has a single sample played at various pitches and tempos. And while the aesthetics perfectly understate the simple design, the music perfectly understates the incredible tension induced as your hapless stick figure flies across the screen.

Two words: perfectly simple. TonyPa, your creation serves as an inspiration to the rest of us. Thank god I don't have this on my mobile phone.

I would only add one option, an advanced mode for the masochists that involves timing. But it's probably for the safety of the masses that he didn't include something such as that.

My best score is between 2500 and 3000, around level 6 or 7. Good luck!