Tutorial: Sharing shared objects between games/applications

This topic came up some days ago with a lot of interesting possibilities especially for flash games. One shared object holding several variables you can load from every game. What could that mean? A regular player of your games gets secret levels, special items or skills for playing a game more often. Or let the player compare his actual score to the scores he achieved in other games you made, if these are comparable. Or an adventurelike game where one has to solve puzzles in external games or where achievements in other games control the plot.

Alright, enough of the dreaming, let’s go to where the action is:

The sending application

Make youself familiar with Saving and Loading in Flash by reading this tutorial or this tutorial. Thanks to Michael and Emanuele for this. You should also bookmark their blogs, these guys are doing great stuff. Inspirado!

Today we are going to create a simple one-screen application which generates a score that is saved to a local shared object. The fla’s name is SharedObjectTutorial.fla with DocumentClass1.as as the document class. The important parts of the DocumentClass:

package
{
  import flash.display.MovieClip;
  import flash.text.TextField;
  import flash.ui.Mouse;
  import flash.events.MouseEvent;
  import flash.utils.Timer;
  import flash.events.TimerEvent;
  import flash.net.SharedObject;
  import flash.system.Security;

Since Flash 7, shared objects are stored with a complete URL of the application. With the import of flash.system.Security we have the possbility of switching to the version 6 mode. Back then only the last two components of a URL was used so subdomains did save their shared objects to the same place. That was example.com, games.example.com and forum.example.com all used the storage of example.com.

  public class DocumentClass1 extends MovieClip
  {
    public var sharedObject:SharedObject;
    public var score:Number = 0;
    public var gameTimer:Timer;
    public function DocumentClass1()
    {
      Security.exactSettings = false;

As stated, with Security.exactSetting set to false we can save all data to one place.

      loadSave();

A function is called that takes care of all the loading and saving.

    }
    public function loadSave()
    {
      sharedObject = SharedObject.getLocal( "kegogrogscores", "/" );

getLocal creates and reads a shared object, the slash is import because without every swf would create its own path to the file sharedObject.data.gameName01_gamePlayed = 1; that is the way of assigning variables to data in the shared object, in this case we’ll tell that this game is played on this computer.

      if( sharedObject.data.gameName01_scoreName01 == null || score > sharedObject.data.gameName01_scoreName01)
      {
        sharedObject.data.gameName01_scoreName01 = score;
      }

When saving from more than one game to file, make sure the names are not the same, otherwise you could overwrite your precious savegame.
If the local object holds no information or the the actual value is greater than the saved value this path will assign numbers to the variables we try to get from the harddrive.

      savedScore.text = sharedObject.data.gameName01_scoreName01.toString();
      scoreDisplay.text = score.toString();

Just two textfields showing information.

      sharedObject.flush();
    }
  }
}

With flush() information is saved to the disk. Otherwise the local object is updated only on closing the application. Complete missing here is a game code. But that is not a part of this tut. Here is a flash movie based on the above approach:

As a result you now have a shared object on your harddrive (in case your flash players security settings allowed). It contains two values, one states that this gae is played, the other tells the highscore. Phew! You can test this by making some score and refreshing the page. The highscore should be there now.

The receiving application

At this point the second file is nearly a copy of the first.

package
{
  import flash.display.MovieClip;
  import flash.net.SharedObject;
  import flash.text.TextField;
  import flash.system.Security;
  import flash.display.SimpleButton;
  import flash.ui.Mouse;
  import flash.events.MouseEvent;
  public class DocumentClass2 extends MovieClip
  {
    public var sharedObject:SharedObject;
    public function DocumentClass2()
    {
      Security.exactSettings = false;
      loadScore();
      clearButton.addEventListener(MouseEvent.CLICK, clearButtonHandler);
      loadButton.addEventListener(MouseEvent.CLICK, loadButtonHandler);
    }
    public function loadScore()
    {
      sharedObject = null;

Setting the variable to null is neccessary to really refresh its value, otherwise the parallel reload would not be possible.

      sharedObject = SharedObject.getLocal( "kegogrogscores", "/" );

Getting the shared object.

      if( sharedObject.data.gameName01_gamePlayed == null )

Checking if the game was played.

      {
        regBon.text = "no";
      }
      else if ( sharedObject.data.gameName01_gamePlayed == 1 )
      {
        regBon.text = "yes";
      }
      if( sharedObject.data.gameName01_scoreName01 == null )
      {
        sharedObject.data.gameName01_scoreName01 = 0;

If there is no score just set it zero.

      }
      scoreBon.text = sharedObject.data.gameName01_scoreName01.toString();
      }
    public function clearButtonHandler(event:MouseEvent)
    {
      sharedObject = SharedObject.getLocal( "kegogrogscores", "/" );
      sharedObject.clear();

Deleting the shared object, we’ll talk about that later.

      loadScore();
    }
    public function loadButtonHandler(event:MouseEvent)
    {
      loadScore();

Calling the loading function.

    }
  }
}

[kml_flashembed fversion=”9.0.0″ movie=”/wp-content/uploads/2009/06/sharedobjecttutorial2.swf” targetclass=”flashmovie” useexpressinstall=”true” publishmethod=”static” width=”550″ height=”400″]
[/kml_flashembed]

You can now go back up and raise the highscore, then come back, click LOAD and the new highscore should show! To the the cleared highscore in the first application you need to refresh the page. I didn’t just implement the test (nulling the shared object before flushing), but it’s no problem for you anymore to do this.

Talking about sharedObject.clear(): This really deletes the file, so if there are more games saved in this slot, nothing will exist afterwards. A better approach here is to set values back to zero. If you followed a strict naming convention there should be no problem assigning new values.

ONE THING: To load data from a local object, this object must not come from another URL.


That’s it for the moment. Now it’s time for development. Here is the source.

It’s caturday, so drink up me hearties, yo ho!

This entry was posted in game development and tagged , , , , , . Bookmark the permalink.
Be Sociable, Share!

3 Responses to Tutorial: Sharing shared objects between games/applications

  1. MichaelJW says:

    Wow, neat. I wonder, though… you said “To load data from a local object, this object must not come from another URL.” — does that mean you might run in to problems trying this on portals where you have no control over where the SWF is kept?

  2. Musquetan says:

    What I found was, that getLocal can’t get around the sandbox boundaries. That means the minimum path (using getLocal(“sharedObjectName”, “localPath”) with “localPath” “/”) to the object path always begins with the URL the movie runs on at the moment of ‘flushing’.
    Let’s assume the movie is called example.swf, creates examplesave.sol and runs on http://games.example.com/: Without a localPath set, the sol would be saved in ‘…\#SharedObjects\SomeString\games.example.com\example.swf\examplesave.sol’. But even with “/” as localPath it’s saved in ‘…\games.example.com\examplesave.sol’.
    That okay if all of the games are saved on the same portal, because you can give the same path for you games with localPath “/mygames” to be save from sameSavegameNameAsAnotherDeveloper.sol issues.
    Even a persistent remote object doesn’t seem like a good workaround. Maybe, with SharedObject.onSync event handler we can get the transition from one place to local to another or something like that. I’m still researching on that.

    edit:

    This blog post’s comments say that it was possible before F8. Gah!

  3. MichaelJW says:

    Interesting. Argh, sucks that they removed the functionality with Flash 8. I guess you could use Nonoba, but it’d be really nice to store this in the SharedObject itself ;/

Leave a Reply

Your email address will not be published.