Max Did It
Coding
,Sun
2 Comments
Tagged , ,

Hitting a Dead End with Facebook and Flash

I have made good progress the last couple of days. I learned a lot, and I got a lot of classes and neat features done. Too bad I won’t be able to use any of them in my upcoming game.

I managed to create a working implementation of the Facebook Connect button in Flash. And I would have gotten away with it, too, if it wasn’t for Flash’s meddling security features.

Dead End

©2004-2012 ~NoxxStock

The work I got done will not go to waste. I’m sure I will be able to reuse most parts of it in the future. But for now, I have to admit that I’ve hit a dead end. This is what happened:

The Idea

I am currently working on a game called Satellite, a physics based game for Flash. I want the game to feature unlockable tiers of levels. At first, only a handful of levels are available. You have to finish at least a couple of them to unlock the next batch. Those levels unlock the next tier, and so on.

Of course it’s important for this feature that your progress in the game will be saved, unless you want to start all over again every time you load the game. Saving your progress locally is no problem, this can be done with Flash’s SharedObject functionality. SharedObjects are also known as Flash cookies, and while they have a bad reputation, many flash games use them to simply save progress locally.

But what if you have unlocked a couple of levels on your PC at work (during lunch break, of course), and want to continue where you left off at home? For this, the data would have to be stored in a remote database. And to retrieve your data later, and only your data, you would need to identify yourself in some way.

I’m sure implementing a naive user data base which only stores and checks a user name and a password could be done in short time. But if you want to do it properly, you suddenly have a lot of issues at your hands like

  • security,
  • encryption and
  • convenience functionality, for example resetting your password if you forgot it.

Implementing, and more importantly, maintaining all that is not making any sense for a single developer/game designer like me.

So my idea was: Why not use an already existing user database where most people who would play my game are already registered?

Facebook Connect Wouldn’t it be convenient for everybody if I offered the players to use Facebook Connect to log into my game, if they want to? That way, I could identify them, store their game data based on that, and maybe implement one or two neat viral features.

And wouldn’t you know it, there is an official Actionscript library for the Facebook Platform API. I like it when a plan comes together!

Facebook Actionscript API

Facebook Actionscript APIThe Facebook Actionscript API has been created by Terralever, Adobe and gskinner.com and promises to support easy communication with Facebooks OpenGraph API.

The first thing I noticed is that there are three versions of the library. One web version, one desktop version and one mobile version. Which already struck me as a little weird. Why not make a fully featured web version and just use that in Air and on mobile devices?

Looking into Adobe’s tutorials for the library reveals that the desktop and mobile versions of the library display native OS dialogues for the Facebook login screens and messages. Have they developed the separate versions to provide better integration with the UI of the native system the app is running on?

I downloaded the web version of the Actionscript Facebook API and I was quickly disappointed. I started my game in the IDE and the first thing I saw when trying to connect with Facebook was this error:

Error #2067: The ExternalInterface is not available in
this container.

It seems that the library tries to use Javascript. Further studying the API reveals that the library itself does not communicate with Facebook, but relays all the commands via the ExternalInterface to the Facebook JavaScript SDK running on the page outside the Flash container. Provided that the Facebook JavaScript SDK happens to be loaded and running on the page my game appears on.

Which is a problem for me. It’s no problem to load the SDK on my own page, but once the game is finished, I want to post it on portals like Newgrounds and Kongregate and I can’t rely on all of them to provide the JavaScript functions I need.

Also, when testing the library on my own site I had trouble getting it to run. The communication between the Facebook JavaScript SDK and the Actionscript counterpart seemed rocky, with callbacks not being called and other weird behaviour.

Finding a Workaround

But I don’t give up that easily. There must be a way to implement the functionality of the Facebook JavaScript API in Flash, right? Digging around a litte netted this article in the Facebook documentation.

By navigating to the URL described in the article, the user can send his login data and give the necessary permissions. If everything works out, the user will be redirected to a page the application can specify. Facebook will add a certain parameter to the URL which can be used as a token to access data on Facebook’s OpenGraph.

Usually this process is done directly in the browser. But I was confident I could recreate the handshake in Flash.

However, I needed to be able to read that last URL that the user is redirected to to retrieve the access token. Facebook is using the 302 HTTP header to redirect the user, which contains the adress it points to, including any parameters.

Usually, you won’t see the header data if you use classes like URLLoader to access websites, but luckily, the as3httpclient library reimplements the HTTP protocol and gives you low level access to the data which is sent and received.

The Catch

So, I have performed a lot of trial and error, learned a couple of things about HTTP and browser cookies, I even dabbled a little in parsing and displaying HTML to be able to show any error messages returned by Facebook.

Long story short:

It works!

I got it to run. I have written a Flash application that will contact the above mentioned Facebook URL, lets you input your login data, handles your input in Facebook’s permission dialogue and at the end retrieves the access token. So, it works, but…

…only if you execute the SWF as a file on your local machine.

As soon as I upload it to a webspace and run it in my browser, this one little security feature of the Flash Player kicks in which I totally forgot about. If the Flash Player tries to contact a server via Sockets the server needs to provide a file saying that that’s okay for the the player to do. You need to do that even if you could contact the same webserver with the same URL in the same browser that loaded the Flash file.

And the problem is, of course, that as3httpclientlib uses XMLSockets to communicate with websites, and Facebook doesn’t provide said policy file.

Wich is probably the same reason why the web version of the Facebook Actionscript API works the way it does. Too bad that didn’t raise any red flags for me back when I saw it. Now I feel more like this:

Genius Meme

As mentioned, I’ve learned a lot while doing this. But I will have to go another route with some of the features I had planned for my game.

Comments

2 Comments have been posted so far - Leave a Comment

Alexander Rotter
Alexander Rotter
,Tue

Tough luck with the FB API. :( But have you considered using conditional compilation and the various portal APIs (Armorgames, Kongregate, etc) for storing game progress and save games?

Afaik pretty much every one of the big Flash game portals provides some API functions for centralized login and save games, and with conditional compilation and a centralized wrapper class you could build portal specific versions of your games with imo not too much effort.

Reply

Max Knoblich
Max Knoblich
,Wed

That's a very good tip, thank you! I will look into it!


Leave A Comment

Your email address will not be published. Required fields are marked *

Connect with Facebook

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>