Apr
18

Continuous Integration in Flash and the Feature Switchboard Paul

Actionscript, Flash, Workflow

Recently, I worked on a large-scale game that had to be deployed to production in stages. First came the core gameplay experience, followed by a series of updates over the next few months that added bells and whistles. After the initial deployment it became obvious that bugs would need to be fixed and deployed to production while development continued on new features. This post explores how to continually integrate high priority changes in to your production projects while concurrently developing new features that are not available to the user until you turn them on.

Until they’re ready, these new features should only be available on development servers (a dev server for internal development and a staging server for client review), but bug fixes should ideally be pushed to production as soon as they are confirmed fixed. How can we fix bugs and develop new features in the same codebase without revealing our awesome but not yet completed pieces of the project. With a team of developers on a regular application we could use the standard continuous integration development model. Individual developers branch the code in to ‘feature branches’ and then merge those branches back to the trunk when features were complete. Bug fixes continue in the trunk and the feature branches never touch the trunk until they’re ready.

However, because .fla files are (currently) a binary file format, they are impossible to merge, so creating a branch for feature development while maintaining a branch for bug fixes is out when your bug fixes or new features involve mucking around in asset files. The solution is to use feature switches.

In essence, feature switches are checks that look at what server the code is running on and determine if a given feature should be enabled. This allows you to develop new features and restrict access to them so that features are visible only in the environments you want. You can fix bugs in the main codebase as well as develop new features protected by a feature switch, and then deploy the whole package knowing that the features in development will be hidden on production servers until you’re ready to turn them on.

Feature management is performed by the FeatureSwitchboard, which is pretty straight forward. First you must initialize the switch manager with the allowed servers and the permission level:

FeatureSwitchboard.addServer("dev.breaktrycatch.com", RuntimeEnvironment.DEV);
FeatureSwitchboard.addServer("stage.breaktrycatch.com", RuntimeEnvironment.STAGE);
FeatureSwitchboard.addServer("www.breaktrycatch.com", RuntimeEnvironment.LIVE);

Note that you don’t need to specify the full domain name. This prevents the runtime environment from becoming unknown if you wish to move your SWF between folders or subdomains on your server.

Once you’ve configured your allowed servers, all you need to do is set the current environment URL. This can be determined using stage.loaderInfo.url:

FeatureSwitchboard.setEnvironment(stage.loaderInfo.url);

The last configuration step is to create a list of features to use with the switchboard. I usually create a class called Features that contains a static variable for each feature.

public class Features
{
	public static const AWESOME_NEW_FEATURE : int = STAGE;
}

And then finally place a check where the feature will eventually appear:

 if(FeatureSwitchboard.isFeatureEnabled(Features.AWESOME_NEW_FEATURE))
{
	// make it happen.
}

Since the ‘awesome new feature’ has a permissions level of STAGE, it will be enabled locally, on the dev server and on the staging server but not on production. You could also adapt this approach to enable features for specific users, allowing you to beta test a new feature with a group of users before allowing all users access to it.

Conveniently, using feature switches also solves another problem we’ve been having. On previous games we’ve been noticing many tracking calls coming from servers we don’t own. Its unfortunate, but people had ripped our games and posted them on their own sites without permission. When calling set environment we can check if the server is in the list of allowed servers and if not we can throw an error and halt execution. While this isn’t foolproof, so far we’ve had no more trouble with our games being ripped and posted elsewhere.

Finally, using the Feature Switchboard in conjunction with dtrace(), etrace() and qtrace() allows you to configure different tracing behaviour based on the server the site is deployed to. You can use a tool like FlashTracer or Vizzy to view your traces on your development server and automatically have those traces turned off when you deploy to production servers. This can yield some nice speedups, especially if the user is using the Debug version of the Flash Player.

Download the Feature Switchboard and try it out on your own projects.

This idea isn’t new; the guys over at the Flickr Dev Blog have written about this technique and how they use it themselves. So while I dont want to take credit for the idea, it is particularly well suited to Flash, and has worked out very well in the past.

This entry was posted on Sunday, April 18th, 2010 at 11:46 am and is filed under Actionscript, Flash, Workflow. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.