05.07.09
On Cinco De Mayo, Taco Del Mar held their "5-Pounder Burrito Challenge". Basically, if you down the $17.99 5-pound Mondo burrito in 30 minutes or less, you'll get $20 in Taco Del Mar gift certificates, a shirt, and a major stomachache for the next week, er, I mean fame and fortune. We talked our IT guy, Joe, into doing it, and here's the result:
04.14.09
We recently launched a cool adaptation of RPS-101 on Facebook. It's built in Silverlight and it's loads of fun turning up some pretty funny results. Of course when you get an app out into the wild it's nice to know what's going on with it.
Our custom tracking tool was integrated into the app with our new feature set. The new features include graphs, user-agent details, and a custom gameplay stats module. But we decided to go one-up on those features and build a custom Silverlight suite to track penetration and new installs.
There's some contention about Scott Guthrie's "one in four" so the first number we're after is penetration before they come to our app. The second number is "what happens next" - when presented with the prompt to install Silverlight are users likely to take action and install it?
Tim Sneath detailed the Silverlight install experience guidelines in his blog. It outlines the best-practices around the install experience. It appears from the documentation that it's possible for a seamless installation experience inside of Internet Explorer but most browsers require a restart after the plug-in is installed.
Unfortunately it's a little outdated (Oct 2007) and fails to detect Silverlight correctly in non-IE browsers breaking the code around their seamless experience for everyone else. The premise is simple, though, prompt the user for a download and then set a timeout to repeatedly check for plug-in availability. When it comes online replace the <div> contents with the Silverlight object tag.
So we did some research around the install experience and used a simplified check to see if the browser has Silverlight 2.0 available:
function isSilverlightInstalled()
{
var isSilverlightInstalled = false;
try {
try {
var slControl = new ActiveXObject('AgControl.AgControl');
isSilverlightInstalled = true;
}
catch (e) {
if ( navigator.plugins["Silverlight Plug-In"] ) {
isSilverlightInstalled = true;
}
}
}
catch (e) { }
return isSilverlightInstalled;
};This simple function (from the JavaScript files in the experience guidelines) worked for us. Whenever the client hits the Silverlight page the JavaScript simply posts back the availability of the Silverlight client. Because our Dormouse platform seamlessly handles stateful users we're able to keep track of install statistics and adoption across sessions.
$(document).ready(function () {
if ( !isSilverlightInstalled() ) {
postBackSilverlight(0);
} else {
postBackSilverlight(1);
}
});
function postBackSilverlight(installed_val) {
var restURL = getRootIFrame() + "/postBackSilverlight";
$.get(
restURL,
{
installed: installed_val,
nt: theTime.getTime()
},
function(data){}
);
}The stateful user on the Dormouse platform keeps track of Silverlight installation status. If it's the first time Silverlight status has even been posted back then we post a message to our Zabra REST service indicating pre-install conditions and save the information on the User objects. When these are summed up we get "Pre-App Silverlight Penetration" statistics.
If a user has doesn't have Silverlight they'll take one of two actions - install Silverlight and come back or bounce from the app and not return. Whenever a user comes back to the app with the plug-in newly installed we post a new message to Zabra "SilverlightInstalledAfterApp" which tells us that someone installed Silverlight and came back. The difference between the total Users who are "Not Installed" and "Installed After App" users will leave us with our bounce number.
This works great on our Zabra system and seamlessly integrates into our Dormouse platform. Want to implement it yourself? All you need is a way to track user data across a few sessions. You might store their Silverlight status in a cookie, SharedObject, PHP session, or CMS system. Here's some pseudocode to keep track of Silverlight installs:
postBackSilverlight(user, silverlightinstalled) {
if(user.silverlightinstalled has been set) {
if(user.silverlightinstalled equals false) {
if(silverlightinstalled equals true) {
statistics.post("new silverlight install");
}
}
} else {
if(silverlightinstalled) {
statistics.post("silverlight installed before app");
} else {
statistics.post("silverlight not installed before app");
}
}
}We've passed these into some nice charts that let our clients keep tabs on user adoption both before their app and after hitting the installation user experience. Hopefully Silverlight will hit a critical mass where adoption is no longer a concern. For now we're all keeping our eyes on the future of a really promising technology.
03.31.09
In our efforts to find a more comfortable collaboration and streamlined flow from Design to Development while working on Silverlight projects, we started brainstorming ideas to keep our chops up to date. We decided we wanted to create a Silverlight 2.0 game that could be deployed on Facebook, as that would allow us to explore new territory (being there aren’t a ton of Silverlight Facebook apps available) as well as contribute to the cause of evangelizing its adoption.
Of course internal projects are great vehicles for advancement, but we also wanted to get this out fast! So, we decided to leverage concept and art from existing resources in order to put it in 5th gear. Being avid readers of The Stranger | SLOG we had previously been amused and impressed with an article on a 101-hand gesture game based on Rock Paper Scissors. But, imagining the complexity involved in remembering all those hand gestures and what beats what or the awkward inaction of trying to play it on the computer together with someone, made it a picture perfect candidate for a Facebook game! The asynchronicity allows for breathing room in computer game play and makes receiving the results that more fun!
We worked together with the creator of the game to bring his concept to life using our design and development talents and released RoshamBOOM! within just a few weeks — the speed of which could not have been possible without the versatility of our Social Networking Platform, Dormouse. I would say this was the most fun I’ve had developing a game, and undoubtedly one darn fun game to play! Check it out: http://apps.facebook.com/roshamboom
Currently, only the Challenge and Outcome pages are in Silverlight, but we plan to integrate all pages in subsequent releases. Last but not least, we can’t forget props to the originator, David C. Lovelace.
03.04.09
Have you ever had the need to make a line of code wait a second before executing? How did you go about trying to make that happen? Well, I for one did a Google search and came up with something using setInterval (AS 2.0), or using setTimeout (AS 3.0). Â Either solution will work, and probably looked something like this:
var wait1 = setTimeout(callback1, 3000);
function callback1():void {
trace("Wait 1");
};
The code above told Flash to wait three seconds before calling callback1, which traces "Wait 1". Â So, what if you needed to make two lines, or two blocks, or multiple blocks of code, you might have something that looked like this:
var wait1 = setTimeout(callback1, 1000);
function callback1():void {
trace("Wait 1");
};var wait2 = setTimeout(callback2, 2000);
function callback2():void {
trace("Wait 2");
};var wait3 = setTimeout(callback3, 3000);
function callback3():void {
trace("Wait 3");
};
Notice you have to manually add up the time delay to get the individual callbacks to fire at the right time. Â So, it'd be a great inconvenience if you needed to adjust the delay for wait 1, since you'll need to adjust the wait time for wait 2 and 3 as well. Â Plus, it's a hideous looking block of code. Â So, out of the goodness of our hearts, and for the benefit of all developerkind, we, Plexipixel, are going to make public one of the most useful utilities in our library, our Script class.
(Okay, it's not really for the benefit of mankind, or out of the goodness of our hearts, it's more like we wanted to drive some web traffic to our blog. Â So, thanks for visiting! Â Now, buy something, thank you.)
You can download the source code with examples here. Â The following code will do that same thing as the code above:
var cs:Script = new Script;
cs.call(this, function() {
trace("Start Script");
});
cs.wait(1.0);
cs.call(this, function () {
trace("Wait 1");
});
cs.wait(1.0);
cs.call(this, function() {
trace("Wait 2");
});
cs.wait(1.0);
cs.call(this, function() {
trace("Wait 3");
});
cs.start();
Besides being easier to read, you don't have to add up time. Â For space constraints I won't reprint the Script class itself here, but I will run through how to use it.
After you've imported the Script class and instantiated a Script object, you use wait, to add a wait, it takes time in seconds, so, half second would be 0.5.  Use call to call a function.  call takes two parameters, the first tells Script the scope of the function to be called.  The second parameter is the function to call, in the example above I used an inline function.  To call a function do the following:
var cs:Script = new Script;
cs.call(this, testFunction1);
cs.start();
function testFunction1():void {
trace("testFunction1 called");
}
So, what if you wanted the your application to wait for an indefinite time, like waiting for a MovieClipLoader to load something? Â We have that covered too:
var cs:Script = new Script;
var i:Number = 0;
cs.call(this, function() {
trace("i " + i);
i++;
if (i < 10) return false;
trace("Done");
});cs.start();
If you manually include a return false in your application it'll force the Script class to loop indefinitely, until you stop sending false, or send it a true.
Anyway, we hope you find this little utility helpful in your Actionscript endeavors.
Allen is a Flash Developer here at Plexipixel. When not hard at work, he enjoys long walks on the beach (no, not really), and journaling by the fireside (definitely not).
02.19.09
We were in need of a demo reel while the real one is being worked on, the closest thing we had was a slideshow that was part of a booth display, it was done in a hurry, with the intent of being shown on a local computer, and not over the web, composed of a player SWF externally loading multiple SWFs, varying between 40KB and 5MB, and of varying run time, totaling 35MB. To get it running smoothly for the web was going to be a challenge without completely redoing it.Â
To get the show on the web quickly, we first looked into converting the slideshow into either a FLV or QuickTime movie, to take advantage of the built in streaming abilities of the respective players. Even though the resulting movie ended up being smaller, the picture quality was unacceptable. The next step was to look into optimizing the player for web playback. Â
As a slideshow, there shouldn’t be any breaks in between the different SWFs, but with the player in it’s current state, the next SWF doesn’t get loaded until it is needed, which works in a local environment since loading a SWF is nearly instantaneous off a hard drive, but over the net, to say there’s a delay is an understatement. It’s obvious some sort of loader is needed.Â
We started with a simple loader that basically loads one SWF ahead of the currently playing SWF, it worked well enough for small SWFs, but when we hit the megabyters (SWFs of 1+ megabyte in size), we simply ran out of time before the next one is done loading. There were also instances where the next SWF is small and the current SWF is long in time, so we ended up with a lot of wasted time. So, we decided to get fancy and created what we’d like to call an “idle loader”.Â
The “idle loader” basically takes advantage of the Flash cache by loading additional SWF off stage whenever the next SWF is done loading and the current SWF is still playing, the “idle” part of “idle loader”. This loading scheme worked mostly, but had problems when multiple megabyters are queued up in a row. And code-wise, it felt needlessly complex, trying to balance what’s off-stage, dumping it, and loading it on-stage when needed. We’ve strayed from using a preloader because we wanted the experience to start right away, but at this point, looks like we’ll have to use a preloader.Â
We couldn’t just do a regular preloader and load all 35MB worth of SWFs at the start, because the wait time would be obscene even on a Comcastic® connection. We could just arbitrarily pick a number of SWFs to load, but it’s just not ideal since connection variances amongst our users. We have to get fancy once again, and create a semi-intelligent preloader, if we were to name it, it’d be called IntelliLoader®, but since Microsoft has the whole Intelli-Something cornered, we’ll just call it Steve®.Â
The first step to making Steve® intelligent would be finding out how fast the user’s internet connection is, similar to Netflix. At the start of every Netflix streaming movie, it pops up this little dialog that tells you it’s measuring your connection speed. Steve® measures the user’s internet connection speed by loading the first five SWFs, it starts a timer when the first SWF starts loading, and it adds up the individual SWF sizes while they’re loaded, at the end of the fifth SWF it does a quick totalBytesLoaded divided by totalLoadTime, to get a KB/s number. This bit of testing not only gets us the user’s connection speed but effectively preloads 5 SWFs without the user knowing it. Steve® is a clever lad.Â
Now that we know how fast the user’s connection speed is, we’ll need to figure out how many SWFs to preload for the internet speed. With the help of Firefox Throttle  and some manual testing, we came up with four speed tiers to account for, <50 KB/s (Tier1), 51-100 KB/s (Tier2), 101-150 KB/s (Tier3), and >151 KB/s (Tier4). With some more manual testing we’ve determined Tier1 needs about a 12 SWFs head start, Tier2 about 6, Tier3 4, Tier4 0. We ended up trimming it back to 10/4/3/0, just because 12 is a long wait.Â
So from here on, we added a loading indicator, status messages stating we’re buffering x of y, and percentage loaded of current SWF, so the user’s not in the dark about what’s happening, being verbose, Steve® is very talkative. Of course with this system there’s really not much you can do if the user’s connection slows down, so the buffering message will also pop whenever the user runs out of loaded SWFs.Â
And, there you have it, that’s how our current demo reel came about, and the birth of Steve®. You can see Steve® in action here: http://www.plexipixel.com/portfolio/roadshow/.Â
Â
 ![]()
Epilogue
Okay, if you’ve been keeping up, you’re probably thinking why don’t you just find out the total file size of all the SWFs and do some divisions from there, and you’ll know exactly how much to preload? The short answer is, Steve® is not that smart, the long answer? It’s the next step for Steve®. The concept is simple enough, create a loop to start loading the SWFs, grab totalFrames, grab the file size, then dump it. With the information gathered we can use some fancy math and figure out how much to load to keep in front of play head. The honest answer? We just thought of it, we’ll upgrade Steve® when we get a chance.Â
Allen is a Flash Developer here at Plexipixel. Â He enjoys long walks on the beach (no, not really), and journaling by the fireside (definitely not) when not at work battling the Adobe Flash IDE.
02.10.09
Since we recently helped design the Hexic and Sudoku games for Zune, we decided to take a deeper dive into XNA during some downtime after the holidays. If I were to describe XNA in one word, the word would be “easy”. In four words, “easy like Sunday morning”.  I’m not saying any one-eyed chimp will be able to crank out games, but it is very easy to get started, and it’s all free.Â
To get started head over to http://creators.xna.com/, sign up, if you don’t have Visual C# 2008, you can grab the free Express edition, then download and install Microsoft XNA Game Studio 3.0, choose a tutorial, and you’re ready to go. Every step of  the way is explained in detail.Â
After working with Flash and ActionScript for so long, it’s kind of a relief to be working in a development environment that has so few bugs. Intellisense works beautifully in Visual Studios, showing you every member, method, function, option, and grandma available, and in detail. There is also real-time debugging if you leave the “Error List” open.  It is so anal-retentive it will even tell you if a function is not being used. The scrollbars work properly, they don’t spaz out if you use the mouse wheel. I think the neatest thing about it is that it’s easy to convert a project from PC, to Xbox360, and to Zune.Â
It’s not perfect though, the help files are overly complex, the search function is useless, it was easier to just do a Google search most of the time. If the studio were to move to XNA, we would have to drastically alter our process. A lot of the UI stuff designers can do in Flash will have to be done completely in code, there’d be no tweaking by thee pixel pushers, me mateys, yaarrgh.Â
Anyway, Microsoft really made it easy for people to get started developing in XNA, this is just a really quick and brief rundown of what it is, for more information, please go to:Â http://creators.xna.com/. And here's more information on the Hexic and Sudoku games we did for Zune.
![]()
![]()
01.26.09
The greatest “eureka” moment I’ve had on the road to becoming a more productive developer was the discovery of open source libraries. Much in the same way that the introduction to and ultimate understanding of the usage of functions, objects, methods and inheritance in my web apps is helping move me away from bloated, redundant code, finding out that I don’t have to reinvent the wheel every time I need to implement a common feature has been a huge timesaver.
The reality of developing a web application is that many of the features clients are looking for are often ubiquitous across the web. The desire to reduce time wasted on rewriting the same code over and over again has driven developers from around the world to create flexible, often cross-browser solutions that have been contributed to and refined by the open source community-at-large. Common items include text field autocomplete, embedding .swf’s, and toggling visibility of objects on the front end as well as abstracting database queries and templating systems on the back end.
Here’s a few that we used recently for our MSN Games social networking project:
- jQuery (javascript)
We needed to create a “friend picker” on Myspace, so we built a web service that queries the Myspace API that returns an array (“user name” => “Myspace user id”) which is passed into an autocomplete plugin for jQuery. - SWFObject 2 (javascript)
Lightweight javascript for embedding SWF’s. Handles all of the cross browser issues and gracefully degrades if the user has javascript disabled or hasn’t installed the Flash plug-in. - ADODB (PHP)
This database abstraction library takes care of a lot of the meat and potatoes of pulling data from your database. - Smarty Template Engine (PHP)
All of our HTML was spit out from the Smarty engine. We were able to render different display elements for Myspace or Facebook from within the same template using Smarty conditional statements.
01.14.09
Â
We had the pleasure of working on some significant Silverlight projects over the last year, one of which included building a plug-in to Microsoft Expression Encoder.
Â
The project in a nutshell was creating a Silverlight 2.0 video/audio player that synced with PowerPoint slides and visual chapter points. Imagine a live presentation in which a speaker is showing PowerPoint slides and the cue cards they hold in hand are the chapter points to be discussed. Now imagine an online version of this presentation in which the speaker was pre-recorded and their cue cards exposed alongside the PowerPoint slides they are referencing – this is what we built.
A list of chapter points as well as thumbnails of PowerPoint slides and other supporting media are available for the viewer to navigate forward and backward in the presentation, in addition to the normal player controls on the video/audio itself. Any of the three navigation areas selected will sync the others to the correct point in the presentation. Pretty cool!
Â
Another cool part of this project was making it so the presentation could be assembled and output from Expression Encoder. We built a plug-in that enabled the user to associate chapter point text and other visual media with markers in the video/audio and then export it to the Silverlight Presentation template we created, which could either be hosted online or run locally via an EXE.
Â
It was a fun and invaluable experience, but still a rough ride. The project spanned 3 iterations of Silverlight releases (Alpha 1.1, Beta 1, and Beta 2), which continually required updates to the code and the use of preview versions of both Expression Blend and Encoder. And unfortunately there was not much in the way of support in the skinning department for Expression Blend just yet.
Â
Luckily with the release of Silverlight 2, came many improvements to Expression Blend, adding support for the new Visual State Manager which allows designers to create interactive mouse states (without needing to know any code!), by way of editing the default templates for existing controls. This, paired with the ability to access static resources through the VSM, paved way for our next project in creating skins for the Silverlight 2 .NET control set.  For this project we were tasked with building specific UI themes for the Silverlight toolkit, which released on CodePlex in December (see Whistler Blue, Bureau Blue & Black).Â
Â
Having a more stable version of Blend to work with - thanks to SP1, helped immensely but there was still the hurdle of getting designers used to the VSM interface and template structures. Other internal struggles consisted of:
Â
·        Maximizing the use of shared static resources without compromising the design or simplifying it to the point of banality.
·        Walking the line of VSM animations versus layered assets and how to structure the control templates using the least amount of XAML.
·        Cleanup of code added by Blend (collapsing lines where possible and removing unnecessary default properties).
·        Managing workflow from design to development for cleanup and consolidation into ISM framework, while maintaining continual design updates.
Â
This was the biggest learning experience of all, because it involved a steady flow from design to development, and there didn’t seem to be an efficient way to handle recurring updates without continually redoing dev work. The most plausible solution would have been for everyone to work from one XAML file containing all controls, merging updates in source control, but having all controls laid out in one file caused a HUGE update lag within Expression Blend’s interface. Even editing XAML directly was experiencing lag, making it impossible to work that way. Instead we had to separate each control to a different project and continually clean and consolidate them with each update for delivery.
Â
Maybe in the near future this problem will have surfaced enough to find a fix, we can only hope! There is definitely one thing we’re looking forward to in 2009 with the release of Silverlight 3 – 3D support and GPU hardware acceleration! Let the games begin!Â
Â
01.02.09
Objected oriented patterns have perks. Luckily I don't need to evangelize this to most of the audience. When you can take a concept and execute it in a matter of moments it makes brainstorming and iteration so much more potent.
Getting applications up on social network sites (SNS) is on everybody's mind. How do you get an app up there and how do you make it viral enough to get your message out there? It's an important question to ask yourself. Beyond the implementation of an app are you adding anything to the site's user experience?
We were approached by MSN Games with interest in making two of their most popular games available on social network sites for users all over the web - not just their user base on games.msn.com. They hand us two games that we know are winners and we help them transition them to the social network space. This is the kind of end-to-end experience we provide all of our customers.
The social network space is a constantly evolving thing. The platforms, the user attitudes, the technologies are all in flux. That's where proven object oriented methodologies come in. We implemented a very common pattern for our social apps: the Model-View-Controller. This proven separation helped us rapidly launch the games for Facebook - even while major platform changes were taking place.
When Facebook decided to change the implementation of an FBML control we simply update our templates in the View. If they changed the Facebook REST API we could quickly adapt our Model to load the new information into our user objects. Our controllers covered a few surfaces, from the game play in Flash to web page input on the canvas or profile pages.
This quick adaption helped us build and debug the apps with minimum time lost to refactoring. Of course the platform is quickly evolving as users respond to privacy changes, new profile layouts, boxes, tabs, invites... It's almost never ending. That's why it was important for us to abstract our logic and data from our layout. We'd simply build up new features to easily integrate into Facebook's new platform.
These new features ensure that we provide our customers with all the integration and exposure that's available and gives users the best experience when playing and sharing the games. When users can truly express themselves to their friends using your application they've become social.
Want to try them out? Check out Hexic and Chess on Facebook now.
06.26.08
We had some downtime in between projects several weeks back and decided to get social with social networking. Since most of the studio is on Facebook, we decided to develop a Facebook application. It’s a simple whack-a-mole type game with a table of your friend’s high scores.
WHAT WE LEARNED:
- Facebook, besides being the number two social networking site, is also the creator of a small army of Facebook branded programming languages. HTML? They’ve got that, but it’s called FBML. SQL? They’ve got that too, FQL. JavaScript? FBJS. And so on.
- Facebook documentation, while complete, is really quirky. It’ll list all the parameters of a function, but doesn’t list what order it should go in. Nor do they provide a sample call. (http://developers.facebook.com/documentation.php?v=1.0&method=friends.areFriends).
- A “multi-friend selector” has a built in skip button that cannot be optioned out, so when placed in certain context really confuses the user. It’s a known issue, and Facebook “won’t fix”.
- The “profile page” is the page most users see, it’s the one where it has the user’s feeds, list of the user’s friends, and the applications the user’s installed. The “canvas page” is the application’s page. There’s also a “Page page”, which is page specific for groups or companies (http://www.facebook.com/pages/Plexipixel-Inc/22585493640).
- A Facebook “session key” is a unique key based on the currently logged in user. An “infinite session key” is like a regular session key, except it doesn’t expire. A session key is essentially what logs you in or keeps you logged in on Facebook.
- Facebook caches everything. The first time you run your application on the canvas page, Facebook, like a good hamster, pulls everything from your server that’s used: images, SWF’s, Virgin Mary statues, even output from PHP files. We think they do this for performance reasons. Instead of having the data for the page come from various uncontrolled servers, it’ll come from either one of their servers or several servers under their control, so pages will load in a consistent manner, unlike MySpace.
SOME PROBLEMS WE FACED
- Because of this hamster-like need to cache things, it leads to problems when the data you want is dynamic, such as a table of high scores. They provide a command to force a refresh of the cache (
$facebook->api_client->fbml_refreshRefUrl('yourUrlHere’);), which works great on the canvas page, but, unfortunately does not get called when it’s placed on the profile page, for probably the same reason as above.- Take the refresh cache command and the set profile FBML command and put them on a PHP page.
- Get an infinite session key.
- Then use some kind of scheduler, like a CRON job, along with your infinite session key (so, you can access Facebook without logging in), then call it at some interval.
- There is no default “Add to Profile” option on the Invite Friend Notification, so if you didn’t know about it, you’ll be sending an “invite friend” request with only an “Ignore” option. This is by far the most frustrating thing, because, one, it makes you look really stupid. And two, Facebook, what could you possibly think a user wants to do when they click on “Invite a Friend to [app name]”? Send them a cookie?
Our Fix:
There are several ways of getting around this, and they’re all variations on a basic theme:
So, when we ran our update script the first time, it worked, until we went to a test account and found out that we’ve updated our test user’s score table with the scores of our friends, not the test user’s friends. And the reason for that is the Facebook function that returns a list of your friends is not based off your user ID, but rather based off of your session key. When we ran the update script instead of placing a table of the user’s friend’s scores, we placed a table of MY friend’s scores, ON EVERYBODY’S PROFILE PAGE.
Our Fix:
Make sure to add the “Add to Profile” option!
Overall, we learned a lot from our first look into the world of coding Facebook apps. Keep an eye out for more tips and tricks as we continue to explore the possibilities of social networking applications!
