Optimizing Your Game To Run On Facebook.com

Overview

Facebook offers several features designed to let your game shine in your players' browsers, allowing you to gracefully handle a wide range of window sizes, enable your players' and your game's use of Facebook features during play, and accept interactions from Facebook without disrupting your game.

Layout Optimization

Fluid Layout allows you to expand the size of your game to match the player’s browser dimensions. When enabled, it allows the iframe containing your game to fill the entire available width and/or height of browser window.

How your app content fills the available space for your Facebook Web Game and without fluid width and height.

In order to enable Fluid Layout you will first need to configure the settings for your app within the App Dashboard. Navigate to the Settings page for your app and locate the App on Facebook section, which will look like the image below.

Fluid Layout settings found inside the App Dashboard.

Fixed Width

Setting fixed width to No will set the width of the iframe that contains your game to 100%. Your content will then be left-aligned and the iframe will resize to fill the page if players change the width of their browser windows.

Setting fixed width to Yes will force the iframe to use a width of 760px. By default, the <body> element of the iframe in most browsers has margin:8px, so unless you override that, you will have 744 pixels for content.

Fixed Height

Setting fixed height to No will set the height of the iframe that contains your app to 100%. If the browser window is resized, the iframe will resize too, and there will be a scrollbar if your content exceeds the available height.

Setting fixed height to Yes will force the iframe to use a height value which you specify, in pixels, as an additional setting on the App Dashboard.

Fluid Layout

Once you have enabled fluid width and height by setting the fixed settings to No, you will then need to develop your app to support variable dimensions as well as dynamic resizing, as a viewer can resize their browser at any time.

Your app should scale to use all available screen space and, if necessary, listen for the JavaScript window.onresize event to adjust its layout dynamically. In many cases HTML and CSS can handle a dynamic layout without the need of JavaScript, but if you've specified element sizes in absolute units, you may need to run code during a window.onresize event. To prevent flickering or excessive re-layout, it may be advisable to only run the resize handler 30-60 times per second, or when the size change exceeds some threshold.

HTML example

For an HTML app, set the height and width of the app's parent element to 100%. If you need to reorient any UI elements within your HTML app, you can do so via the window.onresize event as with any normal HTML page.

The example code below defines a <div> HTML element, sets the background color to blue and fills the available browser dimensions. It will listen for the window.onresize event and print out the current <div> dimensions if the browser is resized.

<html>
  <head>
    <title>Fluid Layout HTML Example</title>
  </head>
  <body style="margin:0; padding:0; border:0; background-color:#000000">
    <div id="allContent" style="background-color: #0000FF; height:100%">
      <div id="output" style="color: #FFFFFF;" />
    </div>
    <script src="http://connect.facebook.net/en_US/all.js"></script>
    <script type="text/javascript">
      FB.init({appId : 'APP ID',});
      function echoSize() {
        document.getElementById('output').innerHTML ="HTML Content Width: " + window.innerWidth +" Height: " + window.innerHeight;
        console.log(window.innerWidth + ' x ' + window.innerHeight);
      }
      echoSize();
      window.onresize = echoSize;
    </script>
  </body>
</html>

Handling Fluid Layouts in Flash

If you are building a Flash app, you will need to set the initial dimensions of your <object> tag to 100% for both height and width. This will allow your Flash client to fill the entire space it has available. Next, your ActionScript code will need to listen for, and handle, the Event.RESIZE event for the stage object. This event is dispatched every time the player changes the size of the swf; use it to layout your UI elements accordingly.

Handling Dialog and Menu Popups in Flash or Other Plugins

It is possible that, while your Flash or other plugin-based game is running, the player will interact with UI elements that are part of Facebook, which will sometimes cause your game to become obscured. Sometimes, this will happen because of an action your game takes (like invoking the Login dialog), and sometimes, it will happen because the player interacts with Facebook elements around your game (like a Messenger window).

To gracefully handle this, you may want to create a dynamic screenshot of your app, then replace the <object> element with this image. You will need to make that replacement within 200ms. This allows Dialogs to display correctly and creates a more pleasing user experience.

The best way to do this is to create a function in your Flash code that takes a screenshot, as a JPEG or other compact format for your graphics style, then Base64 encodes that string, then pauses your game. Expose that function (perhaps calling it something like exportScreenshot) to JavaScript as appropriate (in Flash, for example, you'll use the flash.external.ExternalInterface.addCallback function). Also, expose a function that resumes your game once it regains focus.

Then, in your JavaScript code, write a listener function to be called when your game loses or regains focus, and register it with the Facebook environment by passing it to FB.init() as the hideFlashCallback parameter. The listener will be passed a parameters dictionary which will contain a key called state, which will be set to opened if you should be hiding your game. In that case, the listener should call the Flash app's exportScreenshot method, use the Base64-encoded image data to create a data URL, and make that the src of an img element; it should move your app's containing element offscreen using the

FB.Canvas.hideFlashElement

method in the JS SDK, and replace it with that img. If the parameters dictionary passed to the listener does not have state: "opened" then, instead, bring your Flash app back onscreen using

FB.Canvas.showFlashElement

.

You may want to export a screenshot that you have altered by sampling it down to 1/4 size (which will display as a blurry image) or by darkening its color, so it appears to have faded into the background. This will make it clearer to the player that the focus is off the game and on whatever UI element has popped over it.

Avoiding Reloads By Setting a urlhandler

The JavaScript SDK method FB.Canvas.setUrlHandler() registers a callback which allows your game to gracefully handle situations where a person clicks on a link somewhere in the Facebook chrome which would normally cause your game to be reloaded. Examples include:

  • All ticker stories
  • Bookmarks
  • Requests from the bookmarks drop-down list
  • Request Notifications stories.

When a person clicks on a ticker story about their friend getting an achievement in your game, for example, by default their browser would be sent to the URL of that achievement. Your game can choose to instead register a callback to display the achievement within the application.

The callback will be called with a field that contains the path of the URL, relative to you application's Facebook Web Games URL; for example, if the URL that would have been loaded was

http://apps.facebook.com/yourgameXYZ/achievements/cheevo1.php
  ?fb_source=canvas_ticker
  &fb_ticker_mod=achievement
  &fb_action_types=games.achieves

your callback will be called with a parameter that is a dictionary like

{ 
  path: "/achievements/cheevo1.php?fb_source=canvas_ticker&fb_ticker_mod= achievement&fb_action_types=games.achieves" 
}

Note that each call to FB.Canvas.setUrlHandler() replaces the previously set callback, if one had been set. Also, only links pointing to your game on Facebook (i.e. starting with apps.facebook.com/your_app/ will be sent for inline processing.

Handling WebGL in Unsupported Browsers

If your Facebook Web Game game uses WebGL, set WebGL to Yes in your app settings under Facebook Web Games. This enables Facebook to optimize the WebGL experience for players.

Players using a browser that does not support WebGL will see the following page when attempting to access your game. The page displays links to WebGL compatible web browsers and (if your game is available on Facebook Gameroom) a link to the Gameroom client.

If you do not wish to redirect players to this page you can disable the redirection by setting Override WebGL Unsupported Experience to Yes. If you do this you must handle the experience for browsers that do not support WebGL in your game.