All work and no Google Play

If there was one thing missing from CerberusX, it was Google Play services. It already has a module for Game Center on IOS, but nothing for Android. This meant tracking high scores on Android was local to your app only.

Google Play Game Services would allow an interactive online experience for Android users.

This weekend I decided to sit down and write a module for Google Play Games Services so that I can plugin online leader boards and achievements into my CerberusX Android games.

Writing the external module

Lets start with a simple template

gameservices.cxs
Strict

#If TARGET="android"
Import "native/gameservices.android.java"
#Else
#Error "Google Play Game Services currently only available for android"
#Endif

Extern

Class GameService Extends Null="gms"
end

native/gameservices.android.java
class gms {
  private Activity _activity;
  private Context _context;

  public GGgms(){
    _activity=BBAndroidGame.AndroidGame().GetActivity();
    _context=_activity.getApplicationContext();
  }
}

The above code doesnt do anything yet, but will form the base of the GameService class.

Google Play Game Services

We need to reference the google play game service library and the auth library so that it gets added to Gradle for compile time. CerberusX already has a way to add to the Manifest and Gradle files. The current version of the libraries is 15.0.1
#ANDROID_LIBRARY_REFERENCE_1="compile fileTree(dir: 'libs', include: ['*.jar'])"
#ANDROID_LIBRARY_REFERENCE_2="compile 'com.google.android.gms:play-services-games:15.0.1','com.google.android.gms:play-services-auth:15.0.1'"

Application ID reference

The application ID from the Google Play Game service needs adding to the res/values/ids.xml file

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_id">[APP_ID]</string>
</resources>

Currently this cant be done programatically in CerberusX or JAVA. This file will need to be created and placed in the gradle template build folder so that it is added every compile time.

Signing in

Initially this took a while due to permissions in the Developer console. Things that need setting up first.
  • An APK uploaded without a dev signing key
  • APK published into alpha, beta or full release. This requires some store assets creating too.
  • Tester emails (including your own)
Information about the signing in process is here

gameservices.cxs
Class GameService Extends Null="gms"
  Method SignIn:Void()
End

native/gameservices.android.java
class gms {
  private Activity _activity;
  private Context _context;

  // Client used to sign in with Google APIs
  private GoogleSignInClient mGoogleSignInClient;

  public gms(){
    _activity=BBAndroidGame.AndroidGame().GetActivity();
    _context=_activity.getApplicationContext();
    mGoogleSignInClient = GoogleSignIn.getClient(_activity, new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build());
  }

  public void SignIn() {
      _activity.startActivityForResult(mGoogleSignInClient.getSignInIntent(), RC_SIGN_IN);
    }
}

Leaderboards

Part of the game service is to create Leaderboard tables and submit highscores. Information about Leaderboards can be found here

Lets update our code by adding 2 methods. One for showing leader boards and the other for submitting a score

gameservices.cxs
Class GameService Extends Null="gms"
  Method SignIn:Void()

  Method ShowLeaderboard:Void(leaderboard_id:String)
  Method SubmitLeaderboardScore:Void(leaderboard_id:String, score:Int)
End

native/gameservices.android.java
class gms {
  private Activity _activity;
  private Context _context;

  // Client used to sign in with Google APIs
  private GoogleSignInClient mGoogleSignInClient;

  public gms(){
    _activity=BBAndroidGame.AndroidGame().GetActivity();
    _context=_activity.getApplicationContext();
    mGoogleSignInClient = GoogleSignIn.getClient(_activity, new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build());
  }

  public void SubmitLeaderboardScore(String leaderboard_id, Integer score) {
      Games.getLeaderboardsClient(_activity, GoogleSignIn.getLastSignedInAccount(_activity)).submitScore(leaderboard_id, score);
  }

  public void ShowLeaderboard(String leaderboard_id) {
      Games.getLeaderboardsClient(_activity, GoogleSignIn.getLastSignedInAccount(_activity))
            .getLeaderboardIntent(leaderboard_id)
            .addOnSuccessListener(new OnSuccessListener<Intent>() {
                @Override
                public void onSuccess(Intent intent) {
                    _activity.startActivityForResult(intent, RC_LEADERBOARD_UI);
                }
            });
  }
}

Achievements

In much of the same way, achievements can be added very quickly. More info about achievements is here

gameservices.cxs
Class GameService Extends Null="gms"
  Method SignIn:Void()

  Method SubmitLeaderboardScore:Void(leaderboard_id:String, score:Int)
  Method ShowLeaderboard:Void(leaderboard_id:String)

  Method UnlockAchievement:Void(id:String)
  Method ShowAchievements:Void()
End

native/gameservices.android.java
  public void UnlockAchievement(String achievement_id) {
      Games.getAchievementsClient(_activity, GoogleSignIn.getLastSignedInAccount(_activity)).unlock(achievement_id);
  }

  public void ShowAchievements() {
        Games.getAchievementsClient(_activity, GoogleSignIn.getLastSignedInAccount(_activity))
                .getAchievementsIntent()
                .addOnSuccessListener(new OnSuccessListener<Intent>() {
                    @Override
                    public void onSuccess(Intent intent) {
                        _activity.startActivityForResult(intent, RC_ACHIEVEMENT_UI);
                    }
                });
  }

Results

Above is a sample of how I created the Google Play module. it can also be a uaed as a guide on how to create other external modules.

Release v1.0.0

The above is an example of the code for this module.The first final release of this module can be downloaded from [here] 

Comments