UPDATE

Since this has become one of our more popular pages I just wanted to update it to say that UPSAT has now launched! If you find this page useful or just want to see some of the cool things we did with OpenFeint, including custom notifications, then please consider supporting us by getting the full version of UPSAT and by following us on Facebook or Twitter!

UPDATE

So you have an amazing Android game and you’ve decided you want to join the 21st century and add social connectivity? Well kudos and welcome to the party!

If you’re reading this then you’re probably at least somewhat interested in OpenFeint and what is entailed in getting this working with your game. The good news is it’s actually really easy. The bad news, since OpenFeint is relatively new on Android, the documentation can be a bit lacking which makes the task SEEM very daunting. I have to admit that I was a little bit nervous about doing this before I started, but in the end it only took me around 5 hours. So, if you have any coding skills whatsoever (unlike myself) then you could probably get it done in less. I’ve decided to write this little tutorial to help future users who find themselves running into the same problems as I did and to begin chipping away at the community support void that OpenFeint for Android is currently experiencing.

IMPLEMENTATION SPECIFICS

Since my game was created using the Android SurfaceView class and not OpenGL, I can’t attest as to the viability of this tutorial in other situations. That being said, the fundamentals should still be the same for any multi-thread gaming environment. At it’s core, Android is just Activities and Views, and both GLSurfaceView and SurfaceView classes are just views that operate on separate threads. So if you’re using something besides the regular SurfaceView class, don’t stop reading, this information could still prove useful. I’m running Windows 7 and using Eclipse 3.7.0. I’m going to focus on Step 4 of the getting started with OpenFeint tutorial from the developer support site, as steps 1-3 are essentially repeated here.We’re also going to assume you already have your project in Eclipse.

GETTING STARTED: IMPORTING OPENFEINT

I’m going to go ahead and skip steps 1-4 on this page because it’s all pretty self explanatory. If you can’t figure that out then I don’t think any number of tutorials will help you. So our first task is actually getting OpenFeint imported into your workspace. You’ll want to make sure you download and extract the OF SDK to somewhere convenient. I put mine in the same location as my Android SDK. To import the API’s follow these steps

  1. Right-click on your project in the project or package explorer
  2. Click Import.
  3. On the following screen select General and then click Existing Projects into Workspace..
  4. Click Next.

    OpenFeint tutorial Import Window

  5. Click on Select Root Directory and then Browse
  6. Browse to the directory in which the OpenFeintAPI and GameFeed libraries are stored.
  7. Click OK.

    OpenFeint Tutorial Import Projects

  8. Click the checkboxes for GameFeed and OpenFeintAPI. If you’ve already imported the projects they will be grayed out as is shown here
  9. Select Copy projects into workspace
  10. Click Finish.

OpenFeint Tutorial Projects Imported

You should now see the two projects in your package/project explorer. If they are not there, try deleting them out of your workspace through Windows Explorer and then following the steps above. If your images don’t look exactly like mine, that’s ok. I have some of my files in SVN repositories so they display a little differently.

BUILDING AND SETTING UP THE PROJECT

Next we need to verify that the projects have been built and that both projects are classified as libraries. This part seems to be the main area of confusion and I had the most trouble here. From reading other forums, it seems as though, depending on how you perform the import, the files may automatically be classified as libraries, in which case your project would be fine. If this doesn’t happen then you will start seeing errors as you actually implement the API into your code. It’s best just to perform these quick verification steps to be safe.

  1. In the top menu bar, select Project and then check to see if Build Automatically is selected. If it is, go to the next step. If it’s not, then select Build All and then select Build Automatically 

    OpenFeint Tutorial Build Projects

  2. Right click on the OpenFeintAPI project in the project explorer and select Properties
  3. In the window that appears select Android and then make sure Target is set to Android 1.6 and Is Library is selected as well. I had issues with the project being set to anything besides 1.6, but if it works for you then that’s fine too.

    OpenFeint Tutorial Properties Setting

  4. Click OK
  5. Follow steps 2 -4 for the GameFeed project in the project explorer
  6. Right click on your game project in the project explorer and select Properties
  7. On the Android tab make sure Is Library is NOT selected.
  8. Click Add and then select both the GameFeed and OpenFeintAPI projects and select OK. You should now see the two references with green check marks.
  9. Click OK to close the window.

Your project is now set up and you’re ready to begin coding. At this point you shouldn’t have any errors. If you do then please retry all the steps and if you are still having issues feel free to comment here and I will try to help you out.

INITIALIZING OPENFEINT IN YOUR GAME

“Ladies and Gentleman, Boys and Girls…. It’s time for the MAAAAAAIIIINNNNN Event!” This is the part you’ve no doubt been waiting for. Before we get started I want to take a minute to explain my setup and how I’ll be implementing the code. Simplifying greatly, my project consists of one Activity (AndroidGame) which is the UI thread and one SurfaceView( Screen) which is the worker thread where I perform all my game logic and rendering. Through some trial and error coding, I found that the OpenFeint methods have to be called from within an Activity class or context and not a view (or SurfaceView for that matter). This means that as far as I know, the calls must be made from the UI thread. I also found some apparent errors in the code given on the OpenFeint developers site and will point these out to you.

The first few steps for editing the Android Manifest file are pretty straightforward:

  1. Edit the AndroidManifest.xml file in your project:
    • Add the following activities inside your <application>tag:
      <activity android:name="com.openfeint.internal.ui.IntroFlow"    android:label="IntroFlow"    android:configChanges="orientation|keyboardHidden"    android:theme="@style/OFNestedWindow"/> <activity    android:name="com.openfeint.api.ui.Dashboard"    android:label="Dashboard"    android:configChanges="orientation|keyboardHidden"    android:theme="@style/OFNestedWindow"/>  <activity android:name="com.openfeint.internal.ui.Settings"    android:label="Settings"    android:configChanges="orientation|keyboardHidden"    android:theme="@style/OFNestedWindow"/>  <activity android:name="com.openfeint.internal.ui.NativeBrowser"    android:label="NativeBrowser"    android:configChanges="orientation|keyboardHidden"    android:theme="@style/OFNestedWindow"/>
    • Add the following permissions to AndroidManifest.xml outside of your tag:
       <uses-permission android:name="android.permission.INTERNET" />
    • To grant OpenFeint the ability to save data in the /sdcard/, which is faster and uses less of the user’s built-in flash memory, add the following to the AndroidManifest.xml:
       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    • To allow OpenFeint to retrieve the logged-in user’s email address from Phone SDK version 5 or above so that the user does not have to type the email address in when creating an account, add the following to the AndroidManifest.xml:
      <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    • To allow OpenFeint to detect network connectivity state, which will allow it to notify the user when they can’t login (instead of taking many seconds to time out), add the following to the AndroidManifest.xml:
      <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  2. Refresh (File->Refresh) the project so that the items you added appear.

If you’ve successfully completed everything, then your Manifest file should build with no errors. If you get an error with the “@style/OFNestedWindow” line, then you need to go back and make sure that the OpenFeint API’s are both libraries and that they are both referenced in your project.  Next we need to set up the variables that let the OpenFeint network know what game this is. You’ll do this in the main Activity of your game wherever the OnCreate() method is called. You’ll want to define these as variables outside of the onCreate() method and then use them to instantiate the settings.

  1. Import the following packages into your file:
    import com.openfeint.api.OpenFeint;  import com.openfeint.api.OpenFeintDelegate;  import com.openfeint.api.OpenFeintSettings;  import com.openfeint.api.resource.Achievement;  import com.openfeint.api.resource.Leaderboard;  import com.openfeint.api.resource.Score;  import com.openfeint.api.ui.Dashboard;  import android.widget.Toast;
  2. Define  the following variables in the class definition replacing the words in quotes with the values as defined on the OpenFeint developer site:
    static final String gameName = "Name of your application";  static final String gameID = "gameID";  static final String gameKey = "gameKey";  static final String gameSecret = "gameSecret";
  3. Use these variables to construct the settings object in the OnCreate() method:
    OpenFeintSettings settings =    new OpenFeintSettings(gameName, gameKey, gameSecret, gameID);
  4. Initialize OpenFeint by calling the following method:
    OpenFeint.initialize(this, settings, new OpenFeintDelegate() {});

    The openfeint support states that this must be called in the OnCreate() method, but in reality the only requirement is that it is called after creating settings and before calling any other OpenFeint methods. It is therefore a good idea to call this as soon as possible because OpenFeint will need to connect to it’s network before you can do anything else. If you’re using a loading screen it may be a good idea to call this just before that screen to give OpenFeint time to connect while your game is loading resources.

    Here is how I implemented all of the above:

    public abstract class AndroidGame extends Activity implements Game {      AndroidFastRenderView renderView;      Graphics graphics;      Audio audio;      Input input;      FileIO fileIO;      Screen screen;      WakeLock wakeLock;      static final String gameName = "UPSAT";      static final String gameID = "391633";      static final String gameKey = "abcdefghijklmnop";      static final String gameSecret = "ajlassdkgjhdsgo944098shdkghsodg890sdjhg";        @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          OpenFeintSettings settings =                    new OpenFeintSettings(gameName, gameKey, gameSecret, gameID);          OpenFeint.initialize(this, settings, new OpenFeintDelegate() {});
  5. Run your game!

If you’ve done everything right then the first time you run your game you should see something like this:

OpenFeint Tutorial Initialized

OpenFeint Tutorial Initialized

CONGRATULATIONS! You have now successfully implemented online connectivity into your game. Every time you log in after this you will no longer see this screen and instead will see a pop-up saying welcome back.

IMPLEMENTING OPENFEINT FEATURES

Now we get to the fun stuff. Yes you have online functionality, but unfortunately you have no way to get to it. We need to add code into our game to unlock achievements, post high scores, and then open the dashboard so the user can edit their profile, sign on/off, and of course, be social!

Since all of my game logic is performed in the SurfaceView thread, I needed to have an easy way to make OpenFeint calls on the UI thread. The easiest way for me to do this was to create several public methods in my AndroidGame activity that could be called from the SurfaceView when OpenFeint activities needed to occur. This also makes implementation into an existing game a breeze because it keeps all the lengthy OpenFeint calls to leaderboards and achievements in one place and then all I need to do is add one line of code throughout the game when necessary.

We’ll start with the dashboard because that is the easiest thing to implement.

  1. Add the following line to the code in your main Activity where you’d like to call the dashboard:
    Dashboard.open();

BOOM! That’s it! It’s that easy. I was amazed too. 17 simple characters and your players will be socializing like it’s their job. From the dashboard the players can check their wall, meet up with friends, and check their achievements and leaderboards. It’s pretty awesome.

My code looked something like this once it was wrapped in a method in my AndroidGame activity:

public void openDashboard(){          Dashboard.open();      }

And then the call from anywhere on my SurfaceView thread becomes:

game.openDashboard();

Where “game” is an instance of my AndroidGame class.

Next up is the second easiest thing; posting a score to the leaderboards.

  1. Add the following snippet to the code in your main Activity where you’d like to post a score:
    long scoreValue = longScoreValue;  Score s = new Score(scoreValue, null); // Second parameter is null to indicate that custom display text is not used.  Leaderboard l = new Leaderboard("leaderboardID");  s.submitTo(l, new Score.SubmitToCB() {    @Override public void onSuccess(boolean newHighScore) { 		// sweet, score was posted      MyClass.this.setResult(Activity.RESULT_OK);      MyClass.this.finish();    }    @Override public void onFailure(String exceptionMessage) {      Toast.makeText(MyClass.this, "Error (" + exceptionMessage + ") posting score.", Toast.LENGTH_SHORT).show();      MyClass.this.setResult(Activity.RESULT_CANCELED);      MyClass.this.finish();    }  });
  2. Replace “longScoreValue” with the players score you’d like to post
  3. Replace “leaderboardID” with the number of a leaderboard you created on the OpenFeint developer website
  4. Replace “MyClass” with the name of the Activity containing the code

This one is a bit trickier and I came across an issue here with the “MyClass.this.finish();” command. This is a call to close the Activity. Now I don’t understand why this was included in here, but chances are if you’re implementing this into an already created game, then you have some other method that will close the activity when it is ready. Deleting these two lines will do no harm and my implementation works fine:

public void postLeaderboard(int score){          long scoreValue = (long) score;          Score s = new Score(scoreValue, null); // Second parameter is null to indicate that custom display text is not used.          Leaderboard l = new Leaderboard("977406");          s.submitTo(l, new Score.SubmitToCB() {            @Override public void onSuccess(boolean newHighScore) {         // sweet, score was posted              AndroidGame.this.setResult(Activity.RESULT_OK);            }            @Override public void onFailure(String exceptionMessage) {              Toast.makeText(AndroidGame.this, "Error (" + exceptionMessage + ") posting score.", Toast.LENGTH_SHORT).show();              AndroidGame.this.setResult(Activity.RESULT_CANCELED);            }          });      }

As you can see I’ve wrapped the code in a method in my AndroidGame activity again and passed in an int score variable which I then convert to a long as it is required by the OpenFeint code. I can then call this method from the SurfaceView thread as follows:

game.postLeaderboard(gameStatus.overallScore);

If a new highscore is indeed achieved then a neat message pops up alerting the user as follows:

OpenFeint High Score Message in UPSAT

We have yet to rearrange any of our UI or fix things up aesthetically, but because this is all contained within the OpenFeint library, it is possible to reformat these message to make them fit the style of your game.

Finally, the trickiest thing to figure out was posting an Achievement. Although the code itself is very similar to the previous example, I believe I found a typo in the online support which made this quite frustrating. The code below originally did not call for a boolean in the arguments of the OnSuccess() class. I spent some time trying to figure out where this boolean was supposed to come from and what it was referencing, but in the end I just decided to throw in a generic boolean variable and everything works smoothly now. The corrected implementation is used here.

  1. Add the following snippet to the code in your main Activity where you’d like to post an achievement:
    new Achievement("achievementID").unlock(new Achievement.UnlockCB () {    @Override public void onSuccess(boolean bool) {      MyClass.this.setResult(Activity.RESULT_OK);      MyClass.this.finish();    }    @Override public void onFailure(String exceptionMessage) {      Toast.makeText( MyClass.this, "Error (" + exceptionMessage + ") unlocking achievement.",Toast.LENGTH_SHORT).show();      MyClass.this.setResult(Activity.RESULT_CANCELED);      MyClass.this.finish();    }  });
  2. Replace “achievementID” with the number of an achievement you created on the OpenFeint developer website
  3. Replace “MyClass” with the name of the Activity containing the code

Again, you can choose to delete the two “finish()” lines if you do not want the activity to end after posting the achievement. My implementation is as follows:

public void postAchievement(int ID){          new Achievement(String.valueOf(ID)).unlock(new Achievement.UnlockCB () {                @Override public void onSuccess(boolean bool) {                  AndroidGame.this.setResult(Activity.RESULT_OK);                }                @Override public void onFailure(String exceptionMessage) {                  Toast.makeText( AndroidGame.this, "Error (" + exceptionMessage + ") unlocking achievement.",Toast.LENGTH_SHORT).show();                  AndroidGame.this.setResult(Activity.RESULT_CANCELED);                }              });      }

I’ve also wrapped this code in a method in the AndroidGame activity which takes an int ID as an argument to tell us which Achievement to unlock. I then call the following code whenever I decide that an achievement has been unlocked:

game.postAchievement(1348322);

Where the number is the achievement id from the OpenFeint developer site. If you’ve done it correctly then you should see a pop-up like this when the achievement is unlocked:

OpenFeint Tutorial Achievement Unlocked UPSAT

CLOSING ARGUMENTS

That’s it. If you’ve made it this far then hopefully you now have a fully working implementation of OpenFeint. Also, you must REALLY like to read. There is still a little bit more to do with GameFeed and editing the theme of the popups, but I’ll leave that for another day. This wall of text will crumble under it’s own weight if I add any more. All in all I found the integration of OpenFeint into our game to be EXTREMELY easy and even – GASP – enjoyable! I hope you found this post informative and that you’ll consider sticking around and reading some of the other stuff we have here about designing our game. If you come across any other questions then please feel free to comment here or on facebook or twitter!

 

    • Akash says:


      I’m getting error when I write SimpleAudioEngine::SharedEngine->openDashBoard, i.e. when I’m trying to call OpenFeint from the surface view…. Can anybody help me!

  1. Randy says:


    Dude!!!!!!!

    You are awesome! I spent a few hours troubleshooting this before I came across your page. Thank you, thank you, thank you… thank you! It worked like a charm.

    Funny thing, looking at your eclipse projects it looks like you and I used the same Android book (Beginning Android 4 Games). Small world.

    • Chris says:


      They were definitely great books! We actually based our engine around that, albeit with some major tweaks, but in the end it came out great. There’s a whole bunch of information on this subject in our beginning blog posts from back when we were just getting started. You should check out UPSAT in the marketplace. There’s a free version and the OpenFeint enabled version is only $1.

  2. Umang Kamboj says:


    hey can we add a leader board as a table in our application if yes than how.So, as to show the top scorers and scores of the game. say (top 25)
    and other GUI component as in i-center for ios.
    I want them for android.

    • Chris says:


      Although we didn’t do this in our game it should be relatively easy. OF has a bunch of abstract callback functions you can override to get access to various information from the dashboard. We did this for our achievements because we wanted the notifications to pop up in our UI.

      You’d need to override the Class Leaderboard.GetScoresCB which is in the Package com.openfeint.api.resource . The onSuccess method of that function will be called with the list of scores as an argument once it has been successfully downloaded.

  3. ptk says:


    Awesome, you guys rock!!

    Thanks,
    smooth, persistently non overwhelming article..:)
    I guess, not a better tutorial available for OF integration.

    One Question btw,
    did u find the OF integration helpful substantially in neways with experience/downloads/monetary benefits from ur games?
    On behalf on everyone, If any suggestions/experience/DosAndDonts regarding it, please do post or send and email.

    Looking forward to more discussions with your team.

    • Chris says:


      If I’m being honest, I have been extremely disappointed with OF and more than likely will not use them for our next game. Their servers are ALWAYS slow and it leads to people thinking that it is a problem with our game when really their servers are just too busy to handle all the demand so they respond with a 502 error. Also, the lack of documentation and support for Android is EXTREMELY frustrating. I spent months in a back and forth conversation with their support team troubleshooting an issue using custom acceptance screens, and at the end of the day it turned out to be an issue on their end. To make it worse, the final answer from them was, “We’re sorry, but this feature is simply broken and won’t be fixed any time soon.” At that point we were a couple weeks from launch and it was too late to turn back so we just rolled with it with the hope that it would be fixed eventually. As of now it still hasn’t.

      As far as increased downloads and monetary benefits goes, we’ve seen no difference. I’ve spoken with several people at OF about getting our game promoted or featured, and they said that unfortunately they do not offer these tools for Android. They only choose to feature whatever games they want. They asked that I send them a free version for them to try (which I did), but I never heard back from them afterwards. Also, their in game announcements and social sharing features are NOT available for Android, despite what their website says. I brought that to their attention and they said they would remove that from the website, but they never did. This was a feature I was really looking forward to as it would allow players to easily spread the word about the game and allow me to communicate with them about new updates, but it isn’t happening.

      So overall, I’d say OF just simply isn’t worth your time. I’m not sure what’s out there that’s any better, but if you do some looking I think you could find better stuff.

      • Matt says:


        Hey guys. There’s a pretty solid alternative to OF out there called Swarm (aka SwarmConnect) that runs fast, offers more customization, and has a staff that cares about support. Anywho, might be worth checking out :). Honest Disclaimer: I’m one of the founders and developers from Swarm.

    • Chris says:


      We’re glad you found this helpful! I know it was something that really frustrated me, so that’s why I decided I needed to help others out. I’ve done a LOT more OF stuff since then (including custom achievements, notices, and intro flow) so if you need any help with that I’d be glad to assist. If you have a twitter or facebook follow us and we’ll be sure to check out your game when it’s done! Ours will be out in less than 2 weeks!

  4. Tim says:


    BUILDING AND SETTING UP THE PROJECT > Steps 6 through 9 was what I was totally missing in my project’s config. I kept getting OFNestedWindow resource not found errors. This helped!!! Thanks for posting!!!