Skip to main content

Android

Prerequisites

Before integrating GooglePGS, note that while GooglePGS works with any Player Network login channel, it is recommended (but not required) to configure Google login (INTLGoogle channel) first, as the cross-device sync feature is designed for the Google ecosystem. For the INTLGoogle setup, follow the Google Android login guide.

Additionally, ensure the following PGS-specific prerequisites are met:

  1. A Web client ID (server client ID) from the Google Cloud ConsoleAPIs & Services → Credentials. This will be used as GOOGLEPGS_SERVER_PROJECT_ID.
  2. Google Play Games Services enabled for your app in the Google Play Console under Play Games Services → Setup and management.
  3. The INTLGooglePGS plugin added to your project.

For detailed step-by-step instructions on obtaining the Web Client ID and enabling Google Play Games Services, see the Google Android login guide.

Google Play Games Services Integration

Google Play Games Services (GooglePGS) enables PGS sign-in, cross-device login state synchronization, and access to PGS features such as achievements. It is recommended for games that need to sync login state between Android devices and Google Play Games on PC, or that want to use PGS achievements.

Integrating GooglePGS requires the INTLGooglePGS plugin. While GooglePGS works with any login channel, it is typically used alongside INTLGoogle — the cross-device sync feature is designed for the Google ecosystem, where both the Android device and Google Play Games on PC share the same Google account.

Step 1: Configure the SDK for GooglePGS

  1. Add the following configuration in the INTLConfig.ini file:

    INTLConfig.ini
    [Android LifeCycle]
    LIFECYCLE = GooglePGS
    [GooglePGS]
    GOOGLEPGS_SERVER_PROJECT_ID = {INTL_GOOGLEPGS_SERVER_PROJECT_ID}
    GOOGLEPGS_ENABLE_PGS = 1
    GOOGLEPGS_ENABLE_SYNC = 0
    GOOGLEPGS_AUTO_ACTIVATE = 1
    GOOGLEPGS_LOGIN_WITH_PGS_ON_MOBILE = 0
    • Replace {INTL_GOOGLEPGS_SERVER_PROJECT_ID} with the Web client ID.
      This is the client ID of the web application in the Credentials section of the API OAuth configuration process, also referred to as the server client ID in the API OAuth 2.5 configuration process.
    • GOOGLEPGS_ENABLE_PGS controls whether the client-side PGS flow is enabled, including PGS initialization, login, and the welcome bubble. Set GOOGLEPGS_ENABLE_PGS = 1 to enable.
note

Starting from V1.31, GOOGLEPGS_ENABLE_PGS only controls the client-side PGS flow. The backend sync behavior is now controlled separately by GOOGLEPGS_ENABLE_SYNC.

  • GOOGLEPGS_ENABLE_SYNC controls whether the SDK syncs the player's OpenID with their PGS Player ID on the Player Network backend. This binding enables cross-device auto-login via PGS — when a player logs in on Device A, Device B can automatically find the associated OpenID through the PGS Player ID. Set GOOGLEPGS_ENABLE_SYNC = 1 to enable. Default is 0 (disabled).
tip

If your game does not need cross-device login recovery via PGS, you can leave GOOGLEPGS_ENABLE_SYNC = 0. This is the recommended setting for games that do not have an independent PGS channel configured in the Player Network Console.

  • GOOGLEPGS_AUTO_ACTIVATE controls whether the SDK automatically triggers PGS initialization (non-force) after a successful login. Default is 1 (enabled — same as pre-V1.32 behavior). Set to 0 if the game wants to control PGS initialization timing manually — for example, to avoid PGS prompts during a new-user tutorial. When disabled, the game must call ActivatePGSService at the appropriate time.

  • GOOGLEPGS_LOGIN_WITH_PGS_ON_MOBILE controls whether PGS-based auto-login is allowed on mobile devices. The default value is 0, meaning PGS auto-login only works on Google Play Games on PC. Set to 1 to also enable PGS auto-login on Android mobile devices.

  1. Define manifestPlaceholders in the gradle file, replacing {INTL_GOOGLEPGS_APPID} with the Google Play Games Services App ID.
mainTemplate.gradle
android {
defaultConfig {
manifestPlaceholders = ["GOOGLEPGS_APPID":"{INTL_GOOGLEPGS_APPID}"]
}
}

[Optional] Step 2: Enable cross-device auto-login

After a player has logged in on an Android device (via any channel such as Google), you can sync the login state to Google Play Games on PC via GooglePGS. Both the Android device and Google Play Games on PC must be logged in to the same Google account.

note

This step requires GOOGLEPGS_ENABLE_SYNC = 1 in Step 1. Without it, the OpenID–PGS Player ID binding is never created, and cross-device auto-login will not work.

note

On Google Play Games on PC, the SDK automatically uses the PGS login flow when AutoLogin() is called — if no local auth result is found, the SDK attempts to recover the player's session via their PGS Player ID.

INTLAPI.AutoLogin();

[Optional] Step 3: Manually trigger PGS login

After a successful login through another channel (e.g., Google), the SDK automatically triggers a non-force PGS sign-in in the background. In this automatic flow, the SDK initializes PGS and shows the PGS welcome popup. It then checks the player's PGS authentication state:

  • If already authenticated: The SDK proceeds to request a server-side auth code for PGS identity binding.
  • If not authenticated: The SDK silently skips PGS login without showing the sign-in UI to the player.
note

On the very first app launch on a device with a Google account, PGS v2 may display a login or profile creation prompt as part of its own platform onboarding. This is triggered by PGS initialization (PlayGamesSdk.initialize()), not by the SDK's signIn() call, and is outside the SDK's control. On subsequent launches, PGS either silently authenticates (if the player previously completed login) or remains unauthenticated without showing any UI. If there is no Google account on the device, this prompt does not appear even on the first launch.

If you need to explicitly trigger PGS login from the game side (for example, to let the player link their PGS identity), you can call the ActivatePGSService API. This API is Android only and accepts a forceSignIn parameter:

  • ActivatePGSService(true)Force sign-in (default). If PGS is not authenticated, the SDK invokes signIn() which presents the Google PGS sign-in UI to the player.
  • ActivatePGSService(false)Non-force sign-in. Same behavior as the automatic flow: if PGS is not authenticated, the SDK silently skips without showing any UI.

When called, the SDK will:

  1. Run pre-checks: verify that GOOGLEPGS_ENABLE_PGS = 1, the activity is valid, and Google Play Services is available. If any check fails, an error is returned through the auth result callback.
  2. Initialize PGS and check if the player is already authenticated with PGS:
    • If already authenticated: The SDK proceeds to request a server-side auth code for PGS identity binding.
    • If not authenticated (force): The SDK invokes signIn() which presents the Google PGS sign-in UI to the player. If the player completes login successfully, the SDK proceeds to request the auth code. If the player dismisses the UI or login fails, an error is returned through the auth result callback.
    • If not authenticated (non-force): The SDK silently skips PGS login without showing any UI, and returns an error through the auth result callback.
note

The PGS identity binding (OpenID ↔ PGS Player ID) is only sent to the Player Network backend when GOOGLEPGS_ENABLE_SYNC = 1. Without it, ActivatePGSService authenticates PGS but does not create the cross-device binding.

Starting from V1.32, if GOOGLEPGS_AUTO_ACTIVATE = 0, the SDK will not automatically initialize PGS after login. The game should call ActivatePGSService at the desired time:

  • ActivatePGSService(false) — triggers the same non-force flow as the automatic path (shows welcome bubble, silently skips if not authenticated).
  • ActivatePGSService(true) — force sign-in, shows the PGS login UI if not authenticated.
// Non-force: same as automatic flow
INTLAPI.ActivatePGSService(false);

// Force: shows PGS sign-in UI if not authenticated
INTLAPI.ActivatePGSService(true);
Image: PGS welcome bubble

Image: PGS welcome bubble displayed after successful PGS initialization

Image: PGS sign-in UI

Image: PGS sign-in UI shown when the player is not yet authenticated

Acceptance testing

Verify the following scenarios after completing the PGS integration:

  1. PGS auto-initialization: After login, confirm the PGS welcome bubble appears (when GOOGLEPGS_ENABLE_PGS = 1 and GOOGLEPGS_AUTO_ACTIVATE = 1).
  2. Cross-device sync: Log in on an Android device with GOOGLEPGS_ENABLE_SYNC = 1, then launch the game on Google Play Games on PC with the same Google account — the player should be automatically logged in without re-entering credentials.
  3. Manual PGS login: Call ActivatePGSService(true) and confirm the PGS sign-in UI appears when the player is not yet authenticated.

GooglePGS Configuration Reference

ConfigurationDefault valueDescription
GOOGLEPGS_SERVER_PROJECT_IDWeb client ID (server client ID) from Google Cloud Console OAuth credentials. Required.
GOOGLEPGS_ENABLE_PGS0Enables the client-side PGS flow (initialization, login, welcome bubble).
GOOGLEPGS_ENABLE_SYNC0Syncs the player's OpenID with their PGS Player ID on the Player Network backend for cross-device auto-login.
GOOGLEPGS_AUTO_ACTIVATE1Controls whether the SDK automatically triggers PGS initialization after a successful login. Set to 0 to control timing manually.
GOOGLEPGS_LOGIN_WITH_PGS_ON_MOBILE0Allows PGS-based auto-login on mobile devices (not just Google Play Games on PC).

Google PGS Achievements

The Player Network SDK provides an Achievement module that integrates with Google Play Games Services achievement feature. This allows games to unlock achievements, increment progress, and display the native achievements UI.

note

Starting from V1.32.01, all achievement APIs use the immediate (server-confirmed) variant. The callback RetCode reflects the actual server result, and IncrementAchievement returns {"newly_unlocked": true/false} in ExtraJson. Error handling was also standardized: RetCode now uses standard INTL error codes (e.g., NEED_LOGIN, INVALID_ARGUMENT) instead of returning UNKNOWN with custom codes in ThirdCode. In versions earlier than V1.32.01, only UnlockAchievement, IncrementAchievement, and ShowAchievements were available, and UnlockAchievement and IncrementAchievement used fire-and-forget calls — the callback returned success immediately without confirming the operation completed on the server.

Prerequisites

  1. Complete the GooglePGS configuration above with GOOGLEPGS_ENABLE_PGS = 1.
  2. Configure achievements in the Google Play Console under Play Games Services > Setup and management > Achievements.
  3. PGS must be authenticated before calling any achievement API. If PGS is not authenticated, the API will return a NEED_LOGIN error via callback. The SDK automatically authenticates PGS after a successful login when GOOGLEPGS_ENABLE_PGS = 1, or you can manually trigger it via ActivatePGSService.

Register Achievement Callback

Register a callback to receive achievement operation results.

// Add achievement callback
INTLAPI.AddAchievementResultObserver(OnAchievementResult);

// Remove achievement callback
INTLAPI.RemoveAchievementResultObserver(OnAchievementResult);

// Handle achievement result
public void OnAchievementResult(INTLAchievementResult ret)
{
Debug.Log($"Achievement MethodID: {ret.MethodId}, RetCode: {ret.RetCode}");
}

Unlock Achievement

Unlock a standard (non-incremental) achievement by its ID. If the achievement is already unlocked, the call succeeds without changing its state.

The result is returned through the achievement callback with MethodId = 2701. No ExtraJson is returned.

INTLAPI.UnlockAchievement("GooglePGS", "achievement_id_here");

Increment Achievement Progress

For incremental achievements, increment the progress by a specified number of steps. The numSteps parameter must be greater than 0. If the new total reaches or exceeds the achievement's required steps, the achievement is unlocked.

The result is returned through the achievement callback with MethodId = 2702. The ExtraJson field contains {"newly_unlocked": true/false}, indicating whether this call caused the achievement to be unlocked.

INTLAPI.IncrementAchievement("GooglePGS", "achievement_id_here", 1);

Show Achievements UI

Display the native Google Play Games achievements overlay. The overlay is shown as a separate activity on top of the game.

The result is returned through the achievement callback with MethodId = 2703. No ExtraJson is returned.

INTLAPI.ShowAchievementsUI("GooglePGS");
Image: PGS achievements overlay

Image: Native Google Play Games achievements overlay displayed on top of the game

Query Achievement List

Available in V1.32.01 and above. Query all achievements for the current player, including their state (UNLOCKED, REVEALED, HIDDEN), type (STANDARD, INCREMENTAL), step progress, and name. Pass {"force_reload": true} in extraJson to bypass the local cache and force a fresh load from the server.

The result is returned through the achievement callback with MethodId = 2704. The ExtraJson field contains a JSON object with the following structure:

{
"achievements": [
{
"id": "achievement_id",
"state": "UNLOCKED", // UNLOCKED | REVEALED | HIDDEN
"type": "STANDARD", // STANDARD | INCREMENTAL
"current_steps": 5, // Only for INCREMENTAL
"total_steps": 10, // Only for INCREMENTAL
"last_updated_timestamp": 1234567890,
"name": "Achievement Name"
}
],
"is_stale": false // Whether the data came from cache
}
// Use cache (default)
INTLAPI.QueryAchievementList("GooglePGS");

// Force reload from server
INTLAPI.QueryAchievementList("GooglePGS", "{\"force_reload\": true}");

Set Achievement Steps

Available in V1.32.01 and above. Set an incremental achievement's completed steps to at least a target value. Unlike IncrementAchievement which adds steps, this API sets the progress directly — if the current steps are already equal to or greater than the target, the achievement remains unchanged. If the target reaches or exceeds the total steps, the achievement is unlocked.

The result is returned through the achievement callback with MethodId = 2705. The ExtraJson field contains {"newly_unlocked": true/false}, indicating whether this call caused the achievement to be unlocked.

INTLAPI.SetAchievementSteps("GooglePGS", "achievement_id_here", 5);

Reveal Achievement

Available in V1.32.01 and above. Reveal a hidden achievement to the player. Once revealed, the achievement becomes visible in the achievements UI but remains unlocked until the player completes its requirements.

The result is returned through the achievement callback with MethodId = 2706.

INTLAPI.RevealAchievement("GooglePGS", "achievement_id_here");

Achievement API Reference

APIParametersDescription
UnlockAchievementchannel, achievementId, extraJson (optional)Unlock a standard achievement.
IncrementAchievementchannel, achievementId, numSteps (Unity) / Progress (UE), extraJson (optional)Increments progress of an incremental achievement.
ShowAchievementsUIchannel, extraJson (optional)Displays the native achievements UI overlay.
QueryAchievementListchannel, extraJson (optional)Queries all achievements and their current status.
SetAchievementStepschannel, achievementId, numSteps (Unity) / Progress (UE), extraJson (optional)Sets an incremental achievement's steps to a target value.
RevealAchievementchannel, achievementId, extraJson (optional)Reveals a hidden achievement to the player.
AddAchievementResultObserver (Unity)callbackRegisters a callback for achievement results.
RemoveAchievementResultObserver (Unity)callbackRemoves a previously registered achievement callback.
SetAchievementResultObserver (UE)FINTLAchievementEvent&Registers a delegate for achievement results.
GetAchievementResultObserver (UE)Returns the delegate object; call .Clear() to remove.

Achievement Result Data

The INTLAchievementResult (Unity) / FINTLAchievementResult (UE) contains:

FieldTypeDescription
MethodIdintThe method that triggered this result (2701=Unlock, 2702=Increment, 2703=ShowUI, 2704=QueryList, 2705=SetSteps, 2706=Reveal).
RetCodeintResult code. 0 indicates success.
SubRetCodeintSecondary result code (available since V1.28).
RetMsgstringResult message.
ThirdCodeintRaw Google Play Games Services status code. Only populated when RetCode is 9999 (THIRD), meaning the error originated from PGS. See GamesClientStatusCodes.
ThirdMsgstringHuman-readable PGS status string when ThirdCode is set, or error detail message.
ExtraJsonstringAdditional result data (JSON format). See individual API sections for details.
PlatformstringThe achievement provider name, e.g., "GooglePGS".
SeqIdstringSequence ID for the request.

Acceptance testing

Verify the following scenarios after completing the achievement integration:

Image: PGS achievements: unlocked vs revealed

Image: PGS achievements UI showing (top to bottom) a standard locked achievement, an incremental locked achievement, and a hidden achievement

  1. Unlock achievement: Call UnlockAchievement on a standard achievement and verify the callback returns MethodId = 2701 with RetCode = 0. Confirm the achievement is unlocked in the achievements UI.
  2. Increment achievement: Call IncrementAchievement on an incremental achievement and verify the callback returns MethodId = 2702 with RetCode = 0. Check that ExtraJson contains {"newly_unlocked": true/false}.
  3. Show achievements UI: Call ShowAchievementsUI and verify the callback returns MethodId = 2703 with RetCode = 0. Confirm the native Google Play Games achievements overlay is displayed.
  4. Query achievement list: Call QueryAchievementList and verify the achievement callback returns MethodId = 2704 with RetCode = 0. Check that ExtraJson contains an achievements array with valid state, type, and step data.
  5. Set achievement steps: Call SetAchievementSteps on an incremental achievement and verify the callback returns MethodId = 2705 with RetCode = 0. Check that ExtraJson contains {"newly_unlocked": true/false}.
  6. Reveal achievement: Call RevealAchievement on a hidden achievement and verify the callback returns MethodId = 2706 with RetCode = 0. Confirm the achievement becomes visible in the achievements UI.

Troubleshooting

This section shares common issues identified during the integration and testing of Google Play Games Services, along with guidance on how to verify and resolve them.

PGS integration issues

  1. Verify the PGS configuration and signing certificate

    Confirm that Play Games Services is associated with the correct OAuth client. The associated OAuth client must contain:

    • The package name of the application being tested
    • The SHA-1 certificate fingerprint used to sign the application distributed through Google Play

    If Google Play App Signing is enabled, verify the app signing certificate rather than only the development or upload certificate.

    If the OAuth client uses a different package name or SHA-1 fingerprint, PGS backend requests may fail despite the UI indicating that they were successful. For example, the login toast may still appear and the achievement may still seem to unlock with the unlock toast showing; however, the achievement may eventually fail to synchronize correctly and may even revert to a locked state. This error might not be visible in the game or INTL SDK logs.

    For more information, see Play Games Services credentials.

  2. Verify that the account is a PGS testing user

    Before the PGS configuration and achievements are published, confirm that the Google account used for testing has been added as an authorized PGS tester.

    Also confirm that:

    • The account used by Google Play Games is the account added to the tester list.
    • The account has access to the applicable testing release.
    • The installed build belongs to the expected package and PGS project.
    • The correct account is selected if multiple Google accounts are present on the device.

Achievement issues

  1. Wait and observe

    Achievement updates may not appear immediately in the Google Play Games UI or across game sessions. After calling an achievement API, wait for the update to propagate, then refresh or restart the relevant session before concluding that the operation failed.

    Avoid repeatedly submitting the same operation while waiting for the previous update to appear.

  2. Verify the achievement ID

    Confirm that the achievement_id exactly matches the value in Google Play Console. Achievement IDs are case-sensitive and should always be copied directly from the console rather than entered manually.

    For example, an ID containing uppercase I characters may be misread as containing lowercase l characters:

    Correct:   CgkI_***********I****
    Incorrect: Cgkl_***********l****

    Also check for:

    • Leading or trailing whitespace
    • Changed letter casing
    • Letters confused with visually similar numbers
    • An ID copied from a different PGS project or application
  3. Check the achievement publishing status

    Draft achievements can be used to test achievement operations, callbacks, progress updates, and unlock behavior. However, unlocking a draft achievement does not award XP.

    Keep achievements in draft status during development so that their unlock state can be reset for repeated testing. Do not publish achievements solely to validate XP before the game and its PGS integration are ready for production.

tip

When reporting a PGS issue, provide the complete relevant IDs (such as the achievement ID) as plain text in a private debugging channel, together with the application package name, build source, signing-certificate SHA-1 fingerprint, and tester status. Do not provide IDs only through screenshots.