Posted on by

google-play-storeAt the Google I/O conference last May, Google announced Google Play game services and began offering online game support similar to Apple’s GameCenter.

Corona Labs, working with Google, demonstrated live apps at Google I/O using these game services. And now, following on the heels of this demo, we’ve rolled out the first version of Google Play game services support in Corona SDK. At this time, the plugin supports leaderboards and achievements on Android, but we’re actively adding more features and we’ll soon offer iOS support as well.


Google Setup

If you’ve already implemented Apple’s GameCenter using Corona’s gameNetwork API, you only need to make a few changes to implement the Google Play leaderboard and achievement services. There are just a couple things to be aware of:

  1. Set up the Google Play game services independent of the apps you’ve installed.
  2. Link your apps to the service following the six basic setup steps outlined below. Google provides a walkthrough on setting up your game here. IMPORTANT: make sure that you follow c. Specify client ID settings — and particularly steps 2-5 — before you click on the “Create client” button.

Once you click on the little game controller icon, you’ll see a popup form that asks for the name of your game and the category. There will be two tabs:

  • “I don’t use any Google APIs in my game yet.”
  • “I already use Google APIs in my game.”

Select the first option (default) and then specify the name of your game. It doesn’t need to match any existing or future game — you’re just naming the service at this time. Next, select the category and click “Continue”.

1. Configure Game Details

First and foremost, record the long number next to the name you entered. This is your game’s App ID which you’ll need later. You can also change the name/category and add the following:

  • a description
  • a 512 × 512 PNG icon
  • a 1024 × 500 JPEG feature graphic

2. Link the App

Here you can link up the name of the game that will support Google Play game services (GPGS for shorthand in this tutorial) and specify its Package name. Unless your game will reside solely on Google Play, you should set anti-piracy off.

NOTE: this step will take you through the process to create OAuth2 login credentials for the linked app. It’s very important that you follow these steps carefully, including the steps to get the SHA1 Keystore signature. If you don’t do this, you won’t be able to connect to the service (and you cannot edit it later to fix it).

3. Set Achievements

You will need to enter at least five achievements before you can publish, so plan accordingly. Like many other services, you have 1000 points to allocate among your various achievements. You’ll get an ID string for each achievement which you’ll reference later in your app. Two additional aspects are a 512×512 icon and an achievement description which you may not have if you’ve used only GameCenter. You can test the app without these two items, but you’ll need them before publishing to market.

4. Configure Leaderboards

For leaderboards, you just need to fill out the basic information, i.e. whether you want a “high” or “low” system. Because the GPGS SDK automatically creates daily, weekly, and all-time versions of every leaderboard, there’s no need to create separate leaderboards for each time frame.

5. Set Test Accounts

You may add test accounts on this screen. Note that your developer account is already included.

6. Publish!

Before you publish, you’ll be notified if anything needs to be fixed. If everything is correct and in place, you can publish your service. Please note that once published, you can not delete the service, nor can you edit any field with a “padlock” icon beside it.


Corona Setup

Now, let’s initiate Google Play game services in Corona…

Note: You must use a release build of your Android application, not a debug build.  Please make sure to use a release keystore!!!

1. Build Settings

Before you start coding the actual functionality, add the following code to your build.settings file and specify the App ID you received from the Google. Don’t forget to include the Corona plugin as well!

android = 
{
   googlePlayGamesAppId = "29844238489347"  --long App ID number (use yours!)
},

plugins =
{
   --key is the name passed to the Lua "require()"
   ["CoronaProvider.gameNetwork.google"] =
   {
      --required!
      publisherId = "com.coronalabs",
   },
},

2. Login and Event Handlers

Somewhere convenient — perhaps within main.lua — require the gameNetwork module. Then, set up some event listeners to initialize Google Play game services. Unlike Apple’s GameCenter, which automatically logs the player in during the gameNetwork.init() call, you have to explicitly log in the player with GPGS.

local gameNetwork = require( "gameNetwork" )
local playerName

local function loadLocalPlayerCallback( event )
   playerName = event.data.alias
   saveSettings()  --save player data locally using your own "saveSettings()" function
end

local function gameNetworkLoginCallback( event )
   gameNetwork.request( "loadLocalPlayer", { listener=loadLocalPlayerCallback } )
   return true
end

local function gpgsInitCallback( event )
   gameNetwork.request( "login", { userInitiated=true, listener=gameNetworkLoginCallback } )
end

local function gameNetworkSetup()
   if ( system.getInfo("platformName") == "Android" ) then
      gameNetwork.init( "google", gpgsInitCallback )
   else
      gameNetwork.init( "gamecenter", gameNetworkLoginCallback )
   end
end

------HANDLE SYSTEM EVENTS------
local function systemEvents( event )
   print("systemEvent " .. event.type)
   if ( event.type == "applicationSuspend" ) then
      print( "suspending..........................." )
   elseif ( event.type == "applicationResume" ) then
      print( "resuming............................." )
   elseif ( event.type == "applicationExit" ) then
      print( "exiting.............................." )
   elseif ( event.type == "applicationStart" ) then
      gameNetworkSetup()  --login to the network here
   end
   return true
end

Runtime:addEventListener( "system", systemEvents )

This may appear confusing at a glance, so let’s follow through it step by step. Since this routine is structured using basic Lua scoping methods, the flow actually goes bottom-to-top.

  1. In the gameNetworkSetup() function, we initialize the gameNetwork library. Here, we check the system platform to determine the appropriate provider. As mentioned above, GameCenter does not require a separate login call, so the event listener can jump directly to the gameNetworkLoginCallback() function. In the case of GPGS, however, we need to run an “intermediate” function to handle the initiation, as illustrated with the gpgsInitCallback() function. This intermediate function uses gameNetwork.request() to initiate GPGS and, assuming it’s successful, it passes the flow onward to the gameNetworkLoginCallback() function.
  2. Once the proper service is initiated, we use gameNetwork.request() again to log in the player locally. Assuming this is successful, the loadLocalPlayerCallback() function is called. The event table of this function contains a data table which in turn contains information such as the player “alias” (event.data.alias) or the player’s network ID (event.data.playerID). At this stage, it may be useful to save this player data locally to a text/JSON file or a SQLite database.

Using Leaderboards

The following example shows how simple it is to display leaderboards. Staying true to the cross-platform design standard above, this code is compatible with both GPGS and GameCenter.

local function showLeaderboards( event )
   if ( system.getInfo("platformName") == "Android" ) then
      gameNetwork.show( "leaderboards" )
   else
      gameNetwork.show( "leaderboards", { leaderboard = {timeScope="AllTime"} } )
   end
   return true
end

Note that while both platforms use the gameNetwork.show() API to display the leaderboards, the timeScope parameter is not yet supported for GPGS. This feature may be implemented in the near future, however.

Managing Leaderboards

Adding scores to a leaderboard is straightforward using Corona’s gameNetwork.request() API:

local function postScoreSubmit( event )
   --whatever code you need following a score submission...
   return true
end

local myScore = 100

--for GameCenter, default to the leaderboard name from iTunes Connect
local myCategory = "com.yourname.yourgame.highscores"

if ( system.getInfo( "platformName" ) == "Android" ) then
   --for GPGS, reset "myCategory" to the string provided from the leaderboard setup in Google
   myCategory = "CgkJtbq23agVEAIQAQ"
end

gameNetwork.request( "setHighScore",
{
   localPlayerScore = { category=myCategory, value=tonumber(myScore) },
   listener = postScoreSubmit
} )

Showing Achievements

The following example shows how to display achievements. This time, there’s no code difference between GPGS and GameCenter — just call gameNetwork.show() with the sole parameter of “achievements”.

local function showAchievements( event )
   gameNetwork.show( "achievements" )
   return true
end

Managing Achievements

GPGS makes it easy to manage (unlock) achievements:

--for GameCenter, default to the achievement name from iTunes Connect
local myAchievement = "com.yourname.yourapp.achivementname"

if ( system.getInfo("platformName") == "Android" ) then
   --for GPGS, reset "myAchievement" to the string provided from the achievement setup in Google
   myAchievement = "CgkIsqa23agVEAIQAg"
end

gameNetwork.request( "unlockAchievement",
{
   achievement = { identifier=myAchievement, percentComplete=100, showsCompletionBanner=true },
   listener = achievementRequestCallback
} )

For Google Play game services, the “unlockAchievement” request doesn’t support percentComplete or showsCompletionBanner, both of which are required for GameCenter. Internally, GPGS supports a “counter” which can be incremented but not decremented; this feature is not yet supported in Corona, but it may be in the near future. At this time, it doesn’t hurt to pass the GameCenter-specific values to GPGS to keep your code base the same on both platforms.


That should provide you enough code to get going with Google Play game services. We are adding multiplayer support on Android right now and once that is done will start work on iOS support. Once these items are done, we’ll follow up with a tutorial that covers all those elements.


Posted by . Thanks for reading...

42 Responses to “Tutorial: Introducing Google Play Game Services”

    • Moksh Jawa

      If a device has Google Play on it, GPGS will work. A kindle doesn’t come preloaded with Google Play but it is possible to load Google Play onto the Kindle.

      Reply
        • sangam kumar

          thank you for this tutorial, i m getting an issue at the time of login. when login page of GPGS opened then all credentials done, but at last when i click on SignIn button, after then login faild eror gives.
          i used all credentials like- ApplicationID, package name, game name from GPGS console,and used released keystore for build apk.

          but i have doubt, the ApplicationID, package name, and SHA1 has been created on other system by my Senior team member, and now i m using those ApplicationID, and Package name in my own system to build the App for android where i created my own release keystore and alias.

          is the problem due to creating GPGS AppID on other system and making build(developing code) on other system ???? its high priority issue for me.

          Reply
  1. David Handy

    “At this time, it doesn’t hurt to pass the GameCenter-specific values to GPGS to keep your code base the same on both platforms.”
    Does this mean that if percentComplete is less than 100, the GPGS plugin will just hide the request? If the attribute is just ignored, then it definitely does hurt to pass that value…

    I’d like to test it myself, but I can’t seem to get the “resetAchievements” request to work.

    Reply
  2. Adi

    Hi,

    I’m currently using GC iOS and Parse for android. I’m looking into changing to GPGS and wondered if the method to request for leaderboards is similar to GC.
    i’m no showing the native leaderboard popup (using gameNetwork.show). instead I request gameNetwork.request( “loadScores”..) and then gameNetwork.request( “loadPlayers”..) to pupolate my own table.
    will it work similarly for GPGS or do we need to have a different set of calls to get this info?

    Reply
  3. Scott

    I recently implemented achievements and leaderboards through GPGS for Android. In the developers console, GPGS states that you can use their Leaderboards and Achievements on iOS also. I would like to do this for my game instead of the iOS Game Center for a truly Global Leaderboard. Does Corona have it setup to use GPGS for iOS yet or do I have to stick with Game Center for iOS?

    I was thinking that their would only need to be something added to the build.settings for this to work.

    Reply
    • Rob Miracle

      We don’t support GPGS on iOS yet. We have to get Graphics 2.0 and some other important products out the door, then we can come back and re-address it in the future.

      Reply
      • Scott

        Okay thank you Rob, I have another question. What other elements on top of (playerID and alias) are in the table returned from loadLocalPlayerCallback()?

        Reply
      • Scott

        I know iOS Game Center includes loadPlayerPhoto(), and I’ve been trying to use this for GPGS without any luck… Is there any way to show the Users Profile Picture through the GPGS yet?

        Reply
    • sangam kumar

      how did u worked on Leaderboard by using GPGS for android? when i login then it ask for email Id after then it shows some credentials. but it does not show any welcome screen. and directly come on main screen of Game.

      Reply
  4. greg

    Hi Rob – I have a few questions & would love to get your guidance:

    Q1 – Does the the code above got logic flaw in the “gpgsInitCallback” callback? I ask this as I’m having problems getting things working and I note when I print the event which I receive back I have an error. So in this case the handler should not continue to login no?

    I/Corona ( 7347): androidInit_Callback
    I/Corona ( 7347): {
    I/Corona ( 7347): type = “init”,
    I/Corona ( 7347): name = “init”,
    I/Corona ( 7347): errorCode = 1,
    I/Corona ( 7347): errorMessage = “Service Missing”,
    I/Corona ( 7347): data = false,
    I/Corona ( 7347): isError = true
    I/Corona ( 7347): }

    Q2 – What would you recommend in main.lua regarding performing the google license check as well as Game Services setup? Can they occur in parallel? (currently my google license check just proceeds in the background whilst the game keeps loading/working)

    Q3 – What’s the minimum requirement to run on an Android device to get game services working? I’m new to Android and just trying to work out what Google apps needs to be installed exactly before a Corona app with game services will work.

    thanks
    Greg

    Reply
  5. greg

    update – just bought a new Android device to test (vs the old device I had) and game services just seem to work on it, so perhaps on the older devices you had to manually download google apps yourself first? So

    re my Q1 – perhaps one should ideally be checking to handle the case where on an older phone game services may not be on the device, and detecting this before proceeding?

    Reply
    • Rob Miracle

      Some older devices do not have Google Play. It may have the previous incarnation of the store on it, or not at all. But you’re right, the code above probably doesn’t test for every condition. You probably should add logic to test for that case.

      My Android-fu isn’t as strong as it should be so I’m not sure about the licensing question. If it’s working for you, I’d leave it alone.

      Q3, as far as I know, the device needs to have Google Play installed and the user needs to be logged into Google Play with a valid account.

      Reply
    • Nijel

      Hi
      I have tried your code and it all works well except when I display the leaderboard there are no scores showing

      Does anyone know if there has to be a minimum amount of scores or users before the board displays because
      When I submit a score the postScoreSubmit is definately been called

      If there is a min number of scores before the board displays then a lot of people could be tearing their hair out
      when trying to develop and not knowing why the score is not showing on the leaderboard

      Reply
      • Debi12

        Same here. On my Android device (SGS3) the leaderboard won’t show up.

        2. Is there a way to check the user is currently logged in?

        Thank you!
        Debi

        Reply
      • Upita

        Nigel – I am having the same issue. Players are able to log into game services, as well as show the leaderboard. However, no scores are being posted. The leaderboard simply says “There are no public high scores for this game”.

        I am following the code described in “Managing Leaderboards” to update the scores. Were you able to find an answer to this question?

        Reply
  6. Pablo Isidro

    Same here! I followed the code with print statements and the code calls:
    gameNetwork.show( “leaderboards” )

    but nothing happens.

    Is there any way to know what happens, or to return some information about the error?

    Reply
  7. Andrew

    Having used methods suggested in other corona tutorials on saving my high score with the mydata.lua modules and the score.lua modue provided by corona, i have no idea how and where to implement the google play games services in my game.

    For example where do i load the score to gpgs? Which module? Where do i add al the functions mentioned in this tutorial?

    Any help would be greatly appreciated, if someone could contact me, because i find myself confused by this tutorial.
    Thanks in advance

    Reply
    • Rob Miracle

      GPGS and Apple GameCenter basically allow you to share a player’s high score (and achievements) with the world. To use these services, you must first “init” them. This generally is done in your main.lua when the app starts up. Then once you know your high score, you would then call the appropriate API for the service to register/record the score. I would wait until the game is over, you are showing the high score to the user and call the code to save the score at that point. You could even put a button where the user could decide to choose to save the score or not.

      Then there are actions to show your leaderboards. You generally give the user a button to show the leaderboards on screens that are convenient (Main menu, end of game, etc.)

      Reply
  8. Abdulaziz

    Rob,

    Maybe it is a good idea to include that GPGS does not work with debug key.. I struggled in that issue for long.

    Regards
    Abdulaziz

    Reply
    • Rob Miracle

      Generally since you have to submit your app at least in Alpha form to the store, that sort of implies that you need a release key, but I’ll add a note.

      Rob

      Reply
  9. Jason

    I keep getting attempt to call field ‘show’ (a nil value) also for request also.

    This is how I am calling showleaderboard

    –[ Listeners when game is ending]
    function EndgameListeners(action)

    if(action == ‘add’) then

    exitgameBtn:addEventListener(‘tap’, OnExit)
    restartgameBtn:addEventListener(‘tap’, OnReload)
    leaderboardBtn:addEventListener(‘tap’, showLeaderboards)

    else

    exitgameBtn:removeEventListener(‘tap’, OnExit)
    restartgameBtn:removeEventListener(‘tap’, OnReload)
    leaderboardBtn:removeEventListener(‘tap’, showLeaderboards)
    end
    end

    –[ uses when tap on leaderboard button]
    function showLeaderboards:tap(e)
    if ( system.getInfo(“platformName”) == “Android” ) then
    gameNetwork.show( “leaderboards” )
    else
    gameNetwork.show( “leaderboards”, { leaderboard = {timeScope=”AllTime”} } )
    end
    return true
    end

    Reply
    • Rob Miracle

      The blog comments are not a good place to try and trouble shoot code problems. Please post this request in the forums where you will have more people look at your issue and code can be formatted better.

      Rob

      Reply
  10. Nick White

    I just added this code to my app. It works great! I am so stoked!! Thank you so much for this tutorial!

    For all of you that can’t get the code to work… you are doing it wrong and you need to re-read the entire tutorial out-load to yourself.

    Reply
    • Rob Miracle

      Perhaps you could ask for help in the forums. You will get access to a wider audience of people who’ve used the service and can help than here.

      Rob

      Reply
  11. Jaemok

    unlockAchievement counter, is it implemented yet?

    I want to apply incremental achievements to my game both GPGS and iOS GameCenter.

    But if Corona Lab did not implemented unlockAchievement counter for GPGS yet, and have no short-term plan, I have to make it non-incremental achievement.

    Reply
  12. jilvir

    I am new in Corona and my subscription is PRO I build my first game perfectly based on what I want. now its ready and all are ready including the account in Google Play/Store. can any body help me how to publish it to Google Play? its only a free game. based on I read the instruction about building is should be “Publish” not a “Debug” but I did not see this option when building…

    Reply

Leave a Reply

  • (Will Not Be Published)