Archive for March, 2010|Monthly archive page

Cross-domain import loading

I hit a wall while trying to get the “WMYT: A Stitch in Time” game demo setup online. I had (correctly) anticipated that the demo would get heavy traffic upon release, so I wanted to host the game’s 9Mb worth of media out on the Amazon cloud, then just load the game’s 100Kb shell application from my server. Great… all I needed to do was get all the cross-domain restrictions worked out.

I started by adding lots of Security.allowDomain() calls into all my SWF media. No luck. The Lassie engine relies on library sharing between SWFs, and try as I might – I could not get the SWFs to authorize that level of access using just allowDomain() (maybe I was missing something…). Either way, I moved on and found a cross-domain loading feature that I’d never used before: import loading. Wow, it’s really handy.

The premise of import loading is very simple: you’re loading media from another domain into the current security sandbox, at which time the loaded media can be accessed as though it were available on the local file system. No symmetrical Security.allowDomain() calls are required between media files, so this is super clean and easy to set up. Just have a Flash Loader object perform an import load, and you’re off to the races. Here’s how to do it:

First, let’s assume that we’ll be working with the following servers: – this server hosts all of the external media that we’ll be loading. – this is where our application will be running at.

1) Set up a cross-domain policy file on your media server.

This policy file must be called “crossdomain.xml” and must reside in the media server’s web root (ie: the policy file URL would need to be “”). This policy file specifies what domains may access files on this server. The content of the cross-domain XML should be this:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "">
 <site-control permitted-cross-domain-policies="master-only"/>
 <allow-access-from domain=""/>
 <allow-access-from domain=""/>

2) Configure an import load

Now that you have a cross domain policy file that will allow your application to access files on the media server, you can import load from the media server by doing this:

var $loader:Loader = new Loader();
var $context:LoaderContext = new LoaderContext(true, null, SecurityDomain.currentDomain);
var $request:URLRequest = new URLRequest("");
$loader.load($request, $context);

The trick here is to use a LoaderContext object that specifies the current security domain as the sandbox to load the external media into. Specifying “SecurityDomain.currentDomain” brings the external media into the local sandbox. Once you’ve done that, neither the loader nor the loadee file need any further security scripting to work together (such as allowDomain() calls).

“A Stitch in Time” demo has been released

After many long months and a lot of hard work, Matt Kempke and I have finally launched the demo game of “What Makes You Tick: A Stitch in Time”. This is the first game released with Lassie Shepherd, and showcases most of the engine’s multimedia capabilities. For those who remember and love classic adventure games… enjoy!

Creating Day and Night

The demo of “What Makes You Tick – A Stitch in Time” is releasing soon (March 18th), so it seems as good a time as any to discuss some aspects of what’s on the way. So, one of the big features of Stitch is that we built the world to be playable at both day and night, with player-controls for switching between the two. While this feature was one of the most painful aspects of game production, it was ultimately one of the most rewarding as well.

Day and night at the Ravenhollow docks.

I believe it was Matt (my partner on Stitch, and inspired by his childhood of playing Zelda games) who initially proposed the idea of time changes during an early brainstorming session. While I didn’t object to the idea from a tech standpoint, I also didn’t really expect to go through with it… In my experience, massive labor-intensive features generally have a way of working themselves out of a product. Only later did I realize my oversight: massive features only work themselves out of client projects where the client doesn’t want to pay for a grandiose vision. Unfortunately, features do not work themselves out of your own projects unless you heart-wrenchingly cut them (hence the reason we are each our own worst clients!). While I remained leery of the idea, Matt wrote it into his first draft of the script and it became a lock-in. However, that’s not to say that we didn’t make ANY cuts. Matt’s first version of the script actually included three times of day: sunrise, daytime, and night. Wow – that would have been a ton of work (I emphasize that now that we’ve implemented ONLY day and night). Thankfully, it was a pretty easy decision to cut back to just the two; mainly because:

  1. We were concerned with making the world so faceted that the player would miss connections between the different times of day. We decided that a player would have plenty to figure out with only two times to work between.
  2. After some early artwork tests, it became clear that the original idea of rendering all scenes as daytime and then just adding color overlays for the alternate times was not going to work. The artwork looked very flat, so we were going to need to render every lighting scheme as a custom painting (and two paintings for each room was enough!).

So after the day/night concept was locked in, it was time to think through the technical solution. One “easy” idea that was quickly thrown out was to create two separate instances of the world: one in daytime, one at night. While the idea seemed lucrative because of its simplicity (just swap the player into the same point of the other world instance, right?), it just didn’t make sense. We had a ton of puzzles planned, and while some puzzles were unique to day and night, the majority would be universal between times. That meant that all universal puzzles would need to be coded, tested, and debugged twice (once for each world instance)… and that doesn’t even take dialogue into account. The world is full of dialogue responses, so each world instance would need to be edited and maintained separately. Finally, multiply this scenario by roughly 20 rooms and you’ve got an extremely formidable challenge. So, that got me thinking of sneaky alternatives to pull off day and night without the development overhead.

This led me to build a layer setting within the Lassie engine called “frameOffset”. The concept is pretty simple: Lassie assigns a MovieClip as the image of each layer within a room, then tells that clip to go to a frame based on the layer’s current display state. Adding a “frameOffset” basically tells the layer to figure out which frame it should display, then go to that target frame +X. This allowed us to start building all graphics with day and night states, where the night graphic was placed on a timeline frame immediately following its daytime counterpart. At night, all dynamic layers receive a frameOffset of “1”, which causes them to go to the frame after their baseline daytime state. Suddenly, this process became a whole lot more manageable: create all rooms once, then just track whether their graphics should be skinned as day or night. Of course, we still needed to add lots of conditional logic to control puzzle behavior between day and night, but that was a minor endeavor compared to what it would have taken to maintain separate world instances.

Overall, time-of-day was a tough process that made for twice the art production, extra programming, and a general feeling of exponential complexity. I’ll admit, I had a moment of weakness where I tried to narrow the scope of day and night down to just work within the center of Ravenhollow (about 3 scenes). However, Matt never budged on keeping the whole world playable in both times of day, and he was right. It IS better this way. We think our fans will really enjoy act 2 of Stitch (the largest act), where day and night is fully utilized. While we’ll be introducing the time switching scenario in act 1 (the demo area), the process will be linear so that the world state only changes once. However, in act 2 the player gets complete control of the clock!