Play Games Services for C++

The Google Play games Services C++ SDK provides a C++ API for use with Google Play Game services, and is meant for developers who have an existing C++ implementation of their game.

Currently, the SDK implements the following services:

  • Authorization
  • Achievements
  • Leaderboards
  • Events
  • Saved Games
  • Nearby Connections (Android only)
  • Player Statistics

Concepts

At a high level, you use the SDK by following these steps:

  1. Set up a platform configuration for Android.
  2. Use a GameServices::Builder to configure and construct a GameServices object. The GameServices object automatically attempts to sign in, and returns the result via an OnAuthActionFinished() callback. Take note of the result returned by the callback. If the automatic sign-in attempt failed, you can display a button to let users sign in.
  3. After receiving the OnAuthActionFinished() result, you can use the GameServices object and its child Managers to make Play Games services calls, including:

    • Sign in (after authorization fails): StartAuthorizationUI()
    • Unlock achievements: Achievements().Unlock()
    • Show achievements using built-in UI: Achievements().ShowAllUI()
    • Submit a high score: Leaderboards().SubmitScore()
    • Sign out: SignOut()
  4. When you are done using the GameServices object, reset or destroy it.

At a more detailed level:

  1. Initialize a platform configuration: This is an object that contains platform-specific initialization information. On Android, the platform configuration contains the Java VM and a pointer to the current Activity:

    // In android_main(), create a platform configuration
    // and bind the object activity.
    // Alternately, attach the activity in JNI_Onload().
    gpg::AndroidPlatformConfiguration platform_configuration;
    platform_configuration.SetActivity(state->activity->clazz);
    
  2. Construct a GameServices object: This object is the main entry point for Google Play games Services functionality. GameServices instances are created with GameServices::Builder.

    In most implementations, a given GameServices object will persist as long as your C environment does; you do not need to reinitialize it when your Android Activity pauses and resumes.

    // Creates a GameServices object that has lambda callbacks.
    game_services_ = gpg::GameServices::Builder()
            .SetDefaultOnLog(gpg::LogLevel::VERBOSE)
            .SetOnAuthActionStarted([started_callback](gpg::AuthOperation op) {
                is_auth_in_progress_ = true;
                started_callback(op);
            })
            .SetOnAuthActionFinished([finished_callback](gpg::AuthOperation op,
                                                         gpg::AuthStatus status) {
                LOGI("Sign in finished with a result of %d", status);
                is_auth_in_progress_ = false;
                finished_callback(op, status);
            })
            .Create(pc);
    
  3. Use the Manager classes to manage your GameServices object. Managers are accessed from a GameServices instance and group related functionality together. Examples of these include the Achievement and Leaderboard Managers. They contain no user-visible state themselves. Managers are returned by reference, and the containing GameServices instance controls their lifecycle. Your client should never hold onto a Manager reference. Instead, your client should hold on to the GameServices instance.

    Managers return data via immutable value type objects. These values reflect a consistent view of the underlying data at the point in time when the query was made.

    // Submit a high score
    game_services_->Leaderboards().SubmitScore(leaderboard_id, score);
    
    // Show the default Achievements UI
    game_services_->Achievements().ShowAllUI();
    
  4. When you are finished using the GameServices object, clean up by calling reset() on the unique_ptr that owns it, or by letting the unique_ptr automatically destroy it when going out of scope.

Threading model

Unless otherwise noted, all GameServices and Manager methods have thread-safe, asynchronous implementations. They can be called on any thread without external locking, and will execute in an order consistent with their invocation order.

Accessor methods (those that read state) come in two major variants. The first type of method (with names like FetchProperty()) asynchronously supplies its results to a provided callback; the second (with names like FetchPropertyBlocking()) synchronously returns its results to the calling thread.

// Blocking callback
gpg::AchievementManager::FetchAllResponse fetchResponse =
        game_services_->Achievements().FetchAllBlocking(std::chrono::milliseconds(1000));

// Non-blocking callback
game_services_->Achievements().FetchAll(gpg::DataSource::CACHE_OR_NETWORK,
    [] (gpg::AchievementManager::FetchAllResponse response) {
    LogI("Achievement response status: %d", response.status);});

All user callbacks are invoked on a dedicated callback thread. This thread is potentially distinct from any platform concept of a "main thread" or "UI thread". You should also try to ensure that user callbacks execute quickly; a stalled callback thread may cause user-visible issues (for example, delayed completion of a sign-out request).

Platform-specific information

To get started using the Play Games C++ SDK on Android, continue to the quickstart guide.

Further reading

Be sure to read the class documentation that comes in the Google Play Game services C++ SDK for further details, and check out the samples that demonstrate how to use the SDK.

If your game uses a backend server, see Enabling Server-Side Access to Google Play Games Services.