Posted on by

Since the Game Center feature is just an extension of the existing gameNetwork API, there’s no need to go over every single available request you can send to Game Center—you can view the updated gameNetwork init(), request(), and show() documentation for that.

So instead, I’ll give you a quick overview of what you need to do on the “Apple side” of things (iTunes Connect), the Corona “setup” info, as well as the special considerations that need to be taken to ensure everything works properly in your app.

iTunes Connect

Link: Visit the iTunes Connect Portal

The steps you’re required to take on Apple’s side of things are pretty straightforward, so I won’t need to go too in-depth with this section. In short, you’ll need to create Leaderboards (high score boards) and Achievements for the apps you want to enable Game Center features, and also make note of the individual Leaderboard and Achievement ID’s you’ve assigned to each one.

  1. Click the ‘Manage Your Applications’ link.
  2. Click your app’s icon.
  3. On the right, click ‘Manage Game Center’ button (blue).
  4. Click the ‘Enable’ button.
  5. Click ‘Edit’ under the Leaderboard and Achievements sections.
  6. Add Leaderboards and Achievements.
  7. Make note of each ‘Leaderboard ID’ and ‘Achievement ID’.

Of course, if you don’t want to have Achievements (or a Leaderboard) in your game, you can skip those sections. It’s recommended you add something, or your Game Center implementation might be a little bland to say the least.

System Events and initCallback

Normally, gameNetwork.init() is called at the beginning of main.lua, and is never touched again for the lifetime of your app’s runtime. With Game Center, there are two main differences in regards to gameNetwork.init().

The first difference is, because Game Center is a system-wide process in iOS, users are logged out of GameCenter (for your app) every time your app is suspended (e.g. the user presses the ‘Home’ button or switches to a different app). Therefore, you’ll want to call gameNetwork.init() every time your app receives an “applicationStart” system event.

The second difference between other providers is that with Game Center, you can specify an initCallback function that is called once the init request has completed (which gives you a chance do something when the user logs in, declines, or if the they are offline and can’t access Game Center features).

Here’s an example of how you might use gameNetwork.init() when using Game Center as a network provider:

local gameNetwork = require "gameNetwork"
local loggedIntoGC = false

-- called after the "init" request has completed
local function initCallback( event )
    if event.data then
        loggedIntoGC = true
        native.showAlert( "Success!", "User has logged into Game Center", { "OK" } )
    else
        loggedIntoGC = false
        native.showAlert( "Fail", "User is not logged into Game Center", { "OK" } )
    end
end

-- function to listen for system events
local function onSystemEvent( event ) 
    if event.type == "applicationStart" then
        gameNetwork.init( "gamecenter", initCallback )
        return true
    end
end
Runtime:addEventListener( "system", onSystemEvent )

In your initCallback listener function, the event table includes a single property, event.data, which is set to true upon successful Game Center login, and is nil if user was not logged in. The primary use-case for this is to avoid calling gameNetwork.request() in situations where the user is not logged in. For more information, see the updated gameNetwork.init() documentation.

Game Center Requests

When using Game Center as your provider, the following strings can be used in conjunction with gameNetwork.request():

  • setHighScore
  • loadScores
  • loadLocalPlayer
  • loadPlayers
  • loadFriends
  • loadAchievements
  • unlockAchievement
  • resetAchievements
  • loadAchievementDescriptions
  • loadFriendRequestMaxNumberOfRecipients
  • loadLeaderboardCategories
  • loadPlayerPhoto
  • loadAchievementImage
  • loadPlaceholderCompletedAchievementImage
  • loadIncompleteAchievementImage

Please see the gameNetwork.request() API documentation to see the different kinds of data that needs to be passed with each of the above requests. Most of the above requests allow you to specify a listener which is where you’ll receive requested data. The most confusing aspect of Game Center requests is knowing what data is returned to your callback listener through the event table. As a reminder, this information can always be found in the gameNetwork.request() API documentation page and also on the individual class reference pages within the Official Game Kit Documentation. If all else fails, you could always encode the event table into a JSON string and display it on your device’s screen through a native alert. Here’s an example of how you might do that in conjunction with a “loadFriends” request:

local gameNetwork = require "gameNetwork"
local json = require "json"

-- callback listener for Game Center requests
local function requestCallback( event )
    if event.type == "loadFriends" then
        local data = json.encode( event.data )

        -- show encoded json string via native alert
        native.showAlert( "event.data", data, { "OK" } )
    end
end

gameNetwork.request( "loadFriends", { listener=requestCallback } )

Posted by . Thanks for reading...

34 Responses to “Tutorial: Game Center Integration (iOS)”

  1. Peter9221

    I’m confused on one thing: What do I need to put in build.settings to enable BOTH Gamecenter and Openeint separately?

    Reply
  2. peter9221

    I see that you said that you include
    components = { “openfeint” }
    in build.settings, but is that for both GC and OF, just GC within OF?

    Reply
  3. Jonathan Beebe

    @Peter9221: You have two three options when it comes to OpenFeint and Game Center:

    1. Standalone GameCenter
    2. Standalone OpenFeint
    3. Standalone OpenFeint (with included GameCenter features)

    For the first option, you’ll include the empty components table in your build.settings.

    For the second and third option, you’ll include “openfeint” as the only item in build.settings (see example in article above).

    With the third option, you’ll call gameNetwork.init( “openfeint” ) and all of your gameNetwork requests will be to OpenFeint. OpenFeint has integrated Game Center features that allow you to submit to both OpenFeint and Game Center when it comes to setting a new high score or unlocking an achievement (but the requests will go through OpenFeint).

    You cannot init both OpenFeint and Game Center as a *standalone* provider in your app. If you want both of them, you have to go with the third option in the list (which provides only a very limited Game Center implementation).

    Reply
  4. ewing

    Since Game Center is already built-in to all iOS devices, we don’t make you specify it as a “component”. It is always there regardless if you use it or not.

    OpenFeint is a large 3rd party framework which adds several megabytes to your build. We originally tried to be smart about whether we included it by detecting if you did “require(‘gameNetwork’)” in your code. But this won’t work anymore since we can’t tell if you are using OpenFeint or Game Center from this. So we need you to tell us explicitly now in your build.settings what you really want.

    Reply
  5. Kiel McDonald

    Thanks for the info, looking forward to adding this to my current project!

    Are there any plans to extend Game Center support to include the turn based items released in iOS 5?

    Reply
  6. Alan / Falcon

    This is fantastic! Thanks Ansca, and thanks for the tutorial Jon! I have an implementation question and I’m not sure if this is the best place to ask, but I’ll try it:

    I originally submitted my game to Apple using a wildcard App ID. It’s my understanding that I can’t use GameCenter with an app using the wildcard. Will Apple allow my update to use a different App ID for the same app so that I can add Game Center?

    Reply
  7. Chevol

    How do we show the leaderboards? I am trying to call it from a button event and the call I am using is:
    gameNetwork.show( “leaderboards”, { listener=dismissCallback } )

    This shoud work correct?

    Reply
  8. Chevol

    Nm I think the call actually is:
    gameNetwork.show( “leaderboards”, { leaderboard = {category=”com.appledts.GKTapper.aggregate”, timeScope=”Week”}, listener=dismissCallback } )

    Reply
  9. Jonathan Beebe

    @Alan / Falcon: You can build using a different provisioning profile (that doesn’t use a wildcard), but in either case, your bundle ID should actually be the same. As long as the provisioning profile you created is using the same bundle ID as what you have in iTunes Connect, then everything will be fine.

    Reply
  10. Can

    is gamecenter supports by default offline achivement saves and submits when becomes online?

    Reply
  11. Can

    OpenFeint is a large 3rd party framework which adds several megabytes to your build. We originally tried to be smart about whether we included it by detecting if you did “require(‘gameNetwork’)” in your code. But this won’t work anymore since we can’t tell if you are using OpenFeint or Game Center from this. So we need you to tell us explicitly now in your build.settings what you really want.

    This is not working in last build: 2012.726
    I didnt include components=openfient but my app has OF bundle files in it. (~300files / 2mb)

    Reply
  12. ewing

    Can: If you don’t put the components line in your build.settings, we revert to our old behavior which will always include OpenFeint if you have require(‘gameNetwork’) in your code.

    Reply
  13. Shehab

    Hey Jonathan,

    I’m currently using only game center and insured that build.settings is set correctly, as well as made sure my user is logged in before posting.

    When I set a highscore, my callback listener gets fired correctly, and when I JSON encode my event.data I see that there indeed has been a score submission.

    The problem is that when I check the leader board on game center, I see that I am ranked, BUT, no scores are visible. I get nothing but “No Scores” for all tabs (Today, This Week and All Time).

    Is there anything else I need to be doing? Is there a certain naming convention?

    P.S: When I hard coded Apple’s GK Tapper Bundle ID I was able to see actual scores.

    Reply
  14. Jonathan Beebe

    @Shehab: Ensure you are using a non-wildcard provisioning profile that uses the same bundleId that your app is set up to use in iTunes Connect. Also ensure that the leaderboardId in the ‘category’ parameter matches the leaderboardId of one of your leaderboards for your app (also created in iTunes Connect).

    Reply
    • Jayden

      Gerald did you find an answer to this? I’m also looking for Corona’s support of Game Center’s turn-based features.

      Reply
  15. Luciane

    Can I test my not-yet-submitted-to-the-appstore app with Game Center in ad-hoc disti only using its leaderboard following these steps? or do I nedd to do something else?

    Reply
  16. Jos

    I was quite excited to see Game Center support for Corona. I was wondering if there will be any support for its turn-based game API? This is a huge boon of the 5.x API, in that devs no longer need to run their own servers to support turn based games.

    Reply
  17. robol921

    Is it possible to change the language of Game Center Popup? (Title, button, and tap to rate) I have seen it in other games but not sure how to make it in Corona.

    Reply
  18. John

    Does gameNetwork.show(“leaderboards”) display a list of all my leaderboards that the user can select? My app will have a few different leaderboards. Same with achievements.

    Reply
  19. Nikolai

    Hi, I just finishing my first app for iPhone and using corona sdk doind it. I already implemented gamecenter support througth openfeint, so all data goes to game center too, througth openfeint function calls.

    But in the some games I saw what you can select between game center and openfeint and depending on this selection show dashboard of the game center or openfeint if user press on some button.

    Or in Slam Dunk app in options screen we have openfeint dashboard, gamecenter achievements, gamecenter leaderboards at one time, and it works.

    How it is possible? If you called gameNetwork.init() and passed openfeint how you can show the gamecenter leaderboards and achievements after that? I tried calling gameNetwork.init() once again with different parameter but it doesn’t work.

    Can you help me with this?

    Reply
  20. don

    I’m trying to run the GKTapper example in build 799, and for some reason it’s not able to connect to the network on the device. I’m just building with team provisioning profile and running it. Am I missing some step?

    Also, if I try to replicate the steps with ‘com.appledts.GKTapper’ as my bundle id, do I actually have to setup the achievements in iTunes Connect and create a bundle id to match in my provisioning portal?

    Reply
  21. don

    If a player doesn’t have a GameCenter account is there a way to launch it so the player can create a new account?

    Reply
  22. All

    Nice work!

    Now, when I prepare my own Leaderboards and Achievements What do I have to change?

    Should I change just this line in Build.settings file:

    CFBundleIdentifier = “com.appledts.GKTapper”,

    To something like

    CFBundleIdentifier = “com.appledts.MyGameName”,
    ?

    Is there any thing else????

    Reply
  23. Mike Kelly

    I downloaded your example file, Jonathan, but when I click on Submit High Score or Show Leaderboards, it keeps telling me “GameCenter Offline Please check your internet connection.” is it supposed to work out of the box? thanks!

    Reply
  24. Greg

    Is highest score per level supported directly? Doesn’t seem to be…

    If not explicitly supported is the a technique people use to do per level highest scoreboard?

    Reply

Leave a Reply

  • (Will Not Be Published)