Archive for the 'Programming' Category


An Interesting Theory of Code Stability 3

Michael Feathers recounted a conference run-in with one of the original XP and TDD practitioners:

John Nolan gave his developers a challenge: write OO code with no getters. Whenever possible, tell another object to do something rather than ask. In the process of doing this, they noticed that their code became supple and easy to change. They also noticed that the fake objects that they were writing were highly repetitive, so they came up with the idea of a mocking framework that would allow them to set expectations on objects — mock objects.

That’s a fascinating suggestion, writing OO code with no getters. To think of it in object terms, that means that you create objects that don’t have information extracted from them, they’re only asked to do things. If you take his statement literally and to the extreme, you have the scenario where you don’t know the state of a separate object you can only tell it to do things and hope it does them (you can’t confirm it because there’s no gettable state!). Hmm… that sounds familiar.

I think event-driven programming achieves the goal of “writing OO code with no getters.” It has the added bonus of being dynamically (and anonymously) coupled at runtime. And, in fact, I’ve found event-driven code to be the least brittle. Definitely more complicated in some scenarios (usually trivial cases, while being less complicated for the non-trivial cases), but always more stable, higher quality, fewer bugs.

AS3 has a particularly beautiful event model. When an object dispatches an event the listeners for that event are called immediately (inside of the dispatch function) as opposed to being queued and processed at a later point in time. Callbacks, basically. But at the same time you have to write them as if they occur asynchronously.

I’m not sure the point I’m trying to make… other than to say that event-driven programming is less fragile?

Functional Programming in AS3 1

I’ve never done a lot of functional programming. Sure, I did a bit of required Scheme in my Programming Languages class in college. Didn’t do anything real though — well, maybe a bit of decent AI stuff, but no actual apps. The point is, I’ve never really worked extensively with functional programming largely because the languages/tools I’ve been working with haven’t been purely functional.

Well, apparently I’ve just been missing it in AS3. It was staring me plainly in the face but hadn’t really thought about it in those terms. Bruce Eckel did, though. He shows how we can use the various Array methods (and add some of our own since Array is dynamic) to work functionally. There’s some very clever stuff in there, particularly the in-line functions that leverage closures to return results to the calling method… very clever use of AS3.

There is quite a bit of noise in the article related to his working with Flex Builder and writing the MXML to display the results of his tests. He also has a very — aheminteresting code style that I wouldn’t suggest anyone follow if you plan on sharing with other AS3 coders. I’m referring to his mixing of MXML and AS3 (and I’m not talking mx:Script blocks, either). First time I’ve ever seen that…

This is why I use Flash. 1

Peter Christensen explains why I feel no shame for moving from the world of cutting-edge console games to web-based Flash games.

Are magic MVC frameworks really helping me? 2

As a preface, please read this about “magic” code.

It wasn’t that long ago that I gushed about Cake. But after doing some development with it (beta sites for Mockingbird), and after recently working on our current site (which runs on top of Pligg, kinda), I’ve started to kinda think, “hey, what are these guys actually doing for me?”

First, I am still baffled that with all of the auto-sniffing-magic that these frameworks (Rails, et al) do I still have to describe by database schema in two places. I mean, come on, Microsoft solved this problem in .NET. Sure, they do it through code-generation (XML database schema creates the actual underlying database as well as generating all of the C# classes used to interact with it in a completely typed, validated way). But with Cake (and with Rails, AFAIK) I have to go off and do DB admin creating tables and indices and such, and then I have to come and create some parallel classes in the framework. Sure, I don’t have to specify the individual fields, it’ll automatically attempt to map unknown properties for me… unless I want to build-in validation, or relationships, or serialization… you know, trivial little things that only serious webapps would need… ahem. Sure.

Second, I’m just terrified by the amount of decision-making that is made each time “through” the framework when one of my pages is served up. Sure, op-code caching alleviates some of this, but really, should I be executing 10x the necessary amount of code to save me from having to write out a dozen lines of completely self-explanatory, easy-peasy lines of code?

Maybe I’m missing something… maybe these guys are doing a lot of stuff for me I’m not realizing. But I get the itch’n feeling that they’re really just providing a different syntax (with some defaults that make building a bare bones blog in 15 minutes a snap) on bits that are already there, at a lower level.

Routing — mod_rewrite/.htaccess is the only routing tool you need. I almost guarantee you’re not doing anything in your webapp that requires some kind of routing logic that can’t be handled elegantly with mod_rewrite/.htaccess.

Controller — this is the PHP file that your mod_rewrite directs queries to. All you need to do is practice some self-control and keep all of the aesthetic bits out of this PHP file. Just do the work, the logic of the user’s request. When you done all your work, just pass the results off to the view.

View — go download Smarty. Just use it. Flickr uses it and they get more traffic than you ever will. It’s a templating engine designed with the viewpoint that the template should *only* be the view and that the designer and programmer are at least independent tasks if not entirely different individuals.

Model — I was very frustrated with Cake when I tried to combine it with Pligg. Pligg had a particular table/field naming scheme, and Cake had a similar (but different enough) scheme. There was no combination of tweaking that would get one to be compatible with the other. Writing the necessary SQL queries to bridge the gap manually was trivial. And I knew them all along – in fact, I used them when debugging the naming scheme in an attempt to work backwards. :) Just grab ezSQL, that’s as simplified and automatic as your database interaction should be, because the database is critical (and powerful) if you don’t discount it as just a big property list.

Helpers, Components, Behaviors &mash; these frameworks all have a bunch of additional “utility” features that basically just make life easier as a webapp developer. These could be worth it, if they’re you’re particular flavor. But I bet for each one there’s a strong, healthier open-source version that does more.

Maybe I should put my money where my mouth is? Maybe so. How cleanly could I build a webapp without a framework (and without implicitly building one myself)? In other words, have we heaped one abstraction too many on the pile?

Magic Thinking 0

Code on the Road: No Magic

Amen, brother.

The Craft of Gamemaking 6

I presented this evening at the ACC. I think it went well. I’m definitely out of practice. The slides probably won’t be interesting without the talking, but in case anyone is curious: The Craft of Gamemaking.

If you saw the presentation, I’d love to hear from you in the comment section.

Dynamic code loading in ActionScript3 3

In my post regarding using PHP for Code Generation, Cyrus Lum asked the following question:

I was wondering about being able to load .as3 code snippets or classes at run time - Let’s say a user can download the swf, then through sockets, I can deliver a section of the code as a bytearray that would allow the swf to function.

This is definitely doable, though I’ve not done in exactly the way requested (via ByteArray via sockets). The Flex Framework provides a Module API that does exactly this, and if you Google around a bit you’ll find the Module API’s original author’s blog where he outlines his early experiments in building the API. Basically, you compile your “plugin” object as a stand-alone ActionScript project, producing an SWF. You then load that SWF with the Loader class (which accepts a URLRequest for the SWF, or a ByteArray for the bytes you pull from a socket). Once you have the SWF, you simply cast it to some known class and begin working with it.

The Module API has a Module class as the container for your plugin. Using MXML, the user creates a class that inherits from Module. The Module API loads the SWF and casts the object to a Module (which inherits from UIComponent, which inherits from Sprite, which is what any SWF that you compile from AS3 turns into). The Module API assumes your module is a component, so it places it on the stage somewhere, but you wouldn’t have to do that (thanks to the AS3 DisplayObject API).

Using PHP for Code Generation 2

I’ve been using PHP lately to write the server-side of our product. One of the nice mechanics of PHP is that a PHP file is actually a text file that is output as it is read and the PHP code is simply escaped/executed… in other words, PHP is a templating language. While that’s not news for most folks, it hadn’t really hit home with me that because PHP is a templating language its an excellent tool to use for doing code generation. So, if its good enough for generating HTML pages then its certainly good enough for generating ActionScript source files! ;-)

A month or so ago I went looking for a command-line tool to take a list of assets (PNGs, MP3s) and make an SWF library out of them. My first stop was the excellent Swfmill. Unfortunately for me, Swfmill only supports up to version 8, and I’m using 9, and the last thing I wanted was to have to cross between AS’s two virtual machines just for loading assets.

I posed the question to the excellent Flexcoders group. I promptly got a suggestion from Alex Hurai (member of the Flex team at Adobe) that I could just do a bit of codegen to create an AS class full of embedded assets (using Flex’s embed metadata). So that’s what I did!

I’ll post the code sometime this weekend, once I’ve tested it completely and cleaned it up a bit, but it seems to work. I did a bit of reading on how the module loading code for Flex was written to give me a solid basis for how to handle things. Basically, I generate a class that implements my own IAssetLibrary interface, which is basically an interface that provides methods for querying and retrieving the embedded assets. The PHP codegen simply scans a specified directory, grabs the appropriate filenames, and populates a standard AS3 class. It then populates a few arrays (mapping filenames to embedded asset classes) and its done.

The way PHP-on-the-command-line works this just all spews out to stdout, so I just wrapped it all up in batch file that pipes things to .as file, then calls mxmlc (ActionScript3/Flex compiler) on that .as file. The result (after a very long time … mxmlc is dog slow because it has to fire up the Java VM, etc.) is a SWF with a single class in it, a Sprite (because root classes in an SWF have to inherit from Sprite or MovieClip) that implements the IAssetLibrary interface. I can then use the Flash API’s Loader class to load the SWF, cast it to IAssetLibrary, then retrieve my assets by filename!

The big reason for doing this is that our current build loads each asset individually from a URL (like a web browser rendering a webpage). This was entirely by-design (modeled after a web browser), but in practice (after many months of design revisions) we no longer require that degree of flexibility. And it comes with a cost: the current build makes 228 separates GETs to our server to gather all the assets, most of which are in the 5-10k ballpark. That’s a lot of network overhead. And code overhead, in both my code to manager all those requests and the Flash Player dealing with all those async calls.

And magically, an SWF compresses PNGs/MP3s smaller than just the raw files (elimination of redundant headers or something, I’m not sure)… the total weight of all the assets is 300k smaller (6.5MB compared to 6.8MB).

Pixel-Perfect Collision Detection in ActionScript3 21

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. }

Flex rhymes with… 6

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.

Next Page »