npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@byvik/capacitor-play-games

v0.1.1

Published

Google Play Games Services v2 for Capacitor: sign-in, leaderboards, achievements and cloud saved games.

Readme

@byvik/capacitor-play-games

Google Play Games Services v2 for Capacitor: sign-in, leaderboards, achievements and cloud saved games.

  • Built on play-services-games-v2, the SDK Google currently supports. No GoogleApiClient, no legacy Google Sign-In.
  • Saved games (snapshots), so a player's progress follows their Google account across devices and reinstalls.
  • Leaderboard standing: the player's rank and the number of scores in one call.
  • Android only. On iOS and web every method rejects, so guard calls with Capacitor.getPlatform() === 'android'.

Tested on a physical device (Android 12) against a real Play Games Services project: sign-in, player, score submission, standing, achievements, saved games and Google's leaderboard and achievement screens.

Install

npm install @byvik/capacitor-play-games
npx cap sync

Requires Capacitor 8.

Setup

  1. In the Play Console, open your game and go to Play Games Services → Setup and management → Configuration. Create the project and add an Android credential for every key that signs your app: the debug key, your upload key and the Play App Signing key. A missing SHA-1 is the usual reason sign-in fails with errorCode: 10.

  2. Copy the Project ID shown at the top of that page into android/app/src/main/res/values/strings.xml:

    <string name="game_services_project_id" translatable="false">123456789012</string>
  3. Reference it inside <application> in android/app/src/main/AndroidManifest.xml:

    <meta-data
        android:name="com.google.android.gms.games.APP_ID"
        android:value="@string/game_services_project_id" />
  4. To use saveGame and loadGame, turn on Saved Games in the same configuration page.

While the game is unpublished, only accounts listed under Testers can sign in.

Variables

Set these in android/variables.gradle to override the defaults:

  • playServicesGamesV2Version: version of com.google.android.gms:play-services-games-v2 (default: 20.1.2)

Usage

import { PlayGames } from '@byvik/capacitor-play-games';

// On launch: the SDK has already tried a silent sign-in.
const { isAuthenticated } = await PlayGames.isAuthenticated();

// From a "Sign in" button:
const result = await PlayGames.signIn();
if (!result.isAuthenticated) {
  console.warn('Not signed in', result.errorCode, result.errorMessage);
}

// Leaderboards
await PlayGames.submitScore({ leaderboardId: 'CgkI...', score: 4200 });
await PlayGames.showLeaderboard({ leaderboardId: 'CgkI...', timeSpan: 'daily' });
const { rank, numScores } = await PlayGames.getLeaderboardStanding({
  leaderboardId: 'CgkI...',
  timeSpan: 'daily',
});

// Achievements
await PlayGames.unlockAchievement({ achievementId: 'CgkI...' });
await PlayGames.setAchievementSteps({ achievementId: 'CgkI...', steps: 37 });
await PlayGames.showAchievements();

// Saved games
await PlayGames.saveGame({ name: 'progress', data: JSON.stringify(save) });
const { data } = await PlayGames.loadGame({ name: 'progress' });
if (data !== null) {
  const cloudSave = JSON.parse(data);
}

Errors

isAuthenticated() and signIn() never reject; they resolve with isAuthenticated: false. Every other method rejects when Play Games reports a failure, and the error's code is the Google API status code as a string.

API

isAuthenticated()

isAuthenticated() => Promise<AuthResult>

Whether a player is signed in. Shows no UI and never rejects.

The SDK tries a silent sign-in when the app starts, so this is the call to make before drawing anything that depends on the session.

Returns: Promise<AuthResult>

Since: 0.1.0


signIn()

signIn() => Promise<AuthResult>

Ask the player to sign in. This is the only call that shows Google's sign-in UI, so make it from a button the player pressed. Never rejects: a cancelled or failed sign-in resolves with isAuthenticated: false.

Returns: Promise<AuthResult>

Since: 0.1.0


getCurrentPlayer()

getCurrentPlayer() => Promise<Player>

The signed-in player. Rejects when nobody is signed in.

Returns: Promise<Player>

Since: 0.1.0


openPlayGamesApp()

openPlayGamesApp() => Promise<void>

Open the Play Games app, or its store listing when it is not installed.

Useful when signIn() cannot succeed because the device has no Google account or the player has no Play Games profile: both are created there.

Since: 0.1.0


submitScore(...)

submitScore(options: SubmitScoreOptions) => Promise<void>

Submit a score to a leaderboard.

| Param | Type | | ------------- | ----------------------------------------------------------------- | | options | SubmitScoreOptions |

Since: 0.1.0


getLeaderboardStanding(...)

getLeaderboardStanding(options: LeaderboardStandingOptions) => Promise<LeaderboardStanding>

The player's rank and score, and the number of scores in the leaderboard, read together for one time span and collection.

| Param | Type | | ------------- | --------------------------------------------------------------------------------- | | options | LeaderboardStandingOptions |

Returns: Promise<LeaderboardStanding>

Since: 0.1.0


showLeaderboard(...)

showLeaderboard(options: LeaderboardOptions) => Promise<void>

Open Google's UI for one leaderboard. Resolves when the UI opens.

| Param | Type | | ------------- | ----------------------------------------------------------------- | | options | LeaderboardOptions |

Since: 0.1.0


showAllLeaderboards()

showAllLeaderboards() => Promise<void>

Open Google's UI listing every leaderboard of the game.

Since: 0.1.0


unlockAchievement(...)

unlockAchievement(options: AchievementOptions) => Promise<void>

Unlock an achievement. Queued by the SDK when offline.

| Param | Type | | ------------- | ----------------------------------------------------------------- | | options | AchievementOptions |

Since: 0.1.0


revealAchievement(...)

revealAchievement(options: AchievementOptions) => Promise<void>

Reveal a hidden achievement. Queued by the SDK when offline.

| Param | Type | | ------------- | ----------------------------------------------------------------- | | options | AchievementOptions |

Since: 0.1.0


incrementAchievement(...)

incrementAchievement(options: AchievementStepsOptions) => Promise<void>

Add steps to an incremental achievement. Queued by the SDK when offline.

| Param | Type | | ------------- | --------------------------------------------------------------------------- | | options | AchievementStepsOptions |

Since: 0.1.0


setAchievementSteps(...)

setAchievementSteps(options: AchievementStepsOptions) => Promise<void>

Set the absolute progress of an incremental achievement. Play ignores a value lower than the one it already has, which makes this the safe choice when your own save holds the real counter.

| Param | Type | | ------------- | --------------------------------------------------------------------------- | | options | AchievementStepsOptions |

Since: 0.1.0


showAchievements()

showAchievements() => Promise<void>

Open Google's achievements UI. Resolves when the UI opens.

Since: 0.1.0


saveGame(...)

saveGame(options: SaveGameOptions) => Promise<void>

Write a saved game to the player's Google account, creating it if needed. Conflicts between devices are resolved by keeping the most recently modified copy.

| Param | Type | | ------------- | ----------------------------------------------------------- | | options | SaveGameOptions |

Since: 0.1.0


loadGame(...)

loadGame(options: LoadGameOptions) => Promise<LoadGameResult>

Read a saved game. Resolves with data: null when it does not exist and rejects when it could not be read.

| Param | Type | | ------------- | ----------------------------------------------------------- | | options | LoadGameOptions |

Returns: Promise<LoadGameResult>

Since: 0.1.0


Interfaces

AuthResult

| Prop | Type | Description | Since | | --------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- | | isAuthenticated | boolean | Whether a player is signed in to Play Games Services. | 0.1.0 | | errorCode | number | Google API status code. Only present when the SDK reported an error. 10 (DEVELOPER_ERROR) means the app is misconfigured: the SHA-1 of this build or its package name is missing from the OAuth credentials in the Play Console. 16 and 12501 mean the player cancelled. | 0.1.0 | | errorMessage | string | Error message from the SDK. Only present when the SDK reported an error. | 0.1.0 |

Player

| Prop | Type | Description | Since | | ----------------- | ------------------- | ------------------------------------------------ | ----- | | playerId | string | | 0.1.0 | | displayName | string | The name the player shows in Play Games. | 0.1.0 | | title | string | The player's Play Games title, if they have one. | 0.1.0 |

SubmitScoreOptions

| Prop | Type | Description | Default | Since | | ------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ----- | | leaderboardId | string | | | 0.1.0 | | score | number | Raw score, an integer. For time leaderboards it is in milliseconds and for currency leaderboards in 1/1,000,000ths of the main unit. | | 0.1.0 | | immediate | boolean | Wait for the server to confirm the score. With false the SDK queues the score, even offline, and the call resolves straight away. With true the call resolves once the server has the score and rejects when it cannot be reached; use it when you read the standing right after submitting. | false | 0.1.0 |

LeaderboardStanding

| Prop | Type | Description | Since | | --------------- | --------------------------- | --------------------------------------------------------------------------------------------- | ----- | | rank | number | null | The player's rank, or null when unknown (for example, no score in this time span). | 0.1.0 | | score | number | null | The player's raw score, or null when unknown. | 0.1.0 | | numScores | number | null | How many scores the leaderboard has in this time span and collection, or null when unknown. | 0.1.0 |

LeaderboardStandingOptions

| Prop | Type | Description | Default | Since | | ----------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- | | forceReload | boolean | Skip the local cache and ask the server. The cached number of scores can be stale, but Google rate-limits forced reloads: keep it for moments when fresh data matters. | false | 0.1.0 |

LeaderboardOptions

| Prop | Type | Description | Default | Since | | ------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ----- | | leaderboardId | string | | | 0.1.0 | | timeSpan | LeaderboardTimeSpan | | 'allTime' | 0.1.0 | | collection | LeaderboardCollection | 'friends' needs the player's permission to read their friends list. Until they have granted it, getLeaderboardStanding rejects with code '26703' (CONSENT_REQUIRED). | 'public' | 0.1.0 |

AchievementOptions

| Prop | Type | Since | | ------------------- | ------------------- | ----- | | achievementId | string | 0.1.0 |

AchievementStepsOptions

| Prop | Type | Since | | ------------------- | ------------------- | ----- | | achievementId | string | 0.1.0 | | steps | number | 0.1.0 |

SaveGameOptions

| Prop | Type | Description | Since | | ----------------- | ------------------- | --------------------------------------------------------------------------------------------------- | ----- | | name | string | Unique name of the saved game: 1 to 100 characters from a-z, A-Z, 0-9, -, ., _ and ~. | 0.1.0 | | data | string | The contents, stored as UTF-8. Play allows up to 3 MB per saved game. | 0.1.0 | | description | string | Description shown in the Play Games saved games UI. | 0.1.0 |

LoadGameResult

| Prop | Type | Description | Since | | ---------- | --------------------------- | ----------------------------------------------------------------------- | ----- | | data | string | null | The saved contents, or null when no saved game with that name exists. | 0.1.0 |

LoadGameOptions

| Prop | Type | Since | | ---------- | ------------------- | ----- | | name | string | 0.1.0 |

Type Aliases

LeaderboardTimeSpan

'daily' | 'weekly' | 'allTime'

LeaderboardCollection

'public' | 'friends'

License

MIT