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

@idleflowgames/capacitor-play-games

v0.1.1

Published

Capacitor 8 plugin for Google Play Games Services (Android) and Apple GameKit (iOS): sign-in, achievements, leaderboards, and saved games.

Readme

@idleflowgames/capacitor-play-games

Capacitor 8 plugin for platform games services: Google Play Games Services (PGS v2) on Android and Apple GameKit / Game Center on iOS, with a safe no-op fallback on web. One TypeScript API covers sign-in, achievements, leaderboards, and saved games across both platforms.

Install

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

Supported platforms

| Platform | Backing API | Notes | | -------- | ---------------------------------------------------- | ----------------------------------------------------------- | | Android | Google Play Games Services v2 (play-services-games-v2) | Requires PGS configured in the Google Play Console. | | iOS | Apple GameKit / Game Center | Requires the Game Center capability + App Store Connect setup. | | Web | none | Every method resolves to a safe default (signed out, empty). |

Platform setup

Achievement and leaderboard ids are yours: the plugin takes opaque id strings and passes them straight through to the platform. Create them in the Google Play Console (Android) and App Store Connect / Game Center (iOS), then pass the matching id at each call site. The two platforms issue different ids for the same logical achievement, so keep a per-platform map in your app.

Android

Configure Play Games Services v2 in the Google Play Console, then wire your project id into Android resources and the app manifest (see Google's Play Games Services docs):

<!-- android/app/src/main/res/values/games-ids.xml -->
<resources>
  <string name="game_services_project_id" translatable="false">YOUR_PGS_PROJECT_ID</string>
</resources>
<!-- 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" />

google-services.json is not required for PGS v2 on its own; it is only needed if you also wire Firebase.

iOS

Enable the Game Center capability on your app target in Xcode and create the app's achievements / leaderboards in App Store Connect. The system presents the Game Center sign-in UI.

If your app shows an App Tracking Transparency (ATT) prompt, request it before calling initialize(). iOS suppresses an ATT prompt shown while Game Center's "Welcome back" banner is on screen, and initialize() is what can trigger that banner.

Usage

import { PlayGames } from "@idleflowgames/capacitor-play-games";

await PlayGames.initialize();

const { signedIn } = await PlayGames.signIn(); // silent by default
if (!signedIn) {
  // Force the interactive flow from an explicit user gesture:
  await PlayGames.signIn({ silent: false });
}

await PlayGames.unlockAchievement({ id: platformAchievementId });
await PlayGames.submitScore({ leaderboardId: platformLeaderboardId, score: 1234 });

// Cross-device saves:
await PlayGames.saveSnapshot({ name: "main", data: JSON.stringify(state) });
const { snapshot } = await PlayGames.loadSnapshot({ name: "main" });

// React to system-driven sign-in changes (e.g. signed out via Settings):
await PlayGames.addListener("signInStateChanged", ({ signedIn }) => {
  // update UI
});

On web every method resolves to a safe default, so gate feature usage behind isSignedIn() rather than platform checks.

API

initialize()

initialize() => Promise<void>

Initialize the native games SDK. Idempotent.

On Android this triggers PlayGamesSdk.initialize; on iOS it installs the GameKit authentication handler. Call once, after any App Tracking Transparency prompt has resolved, before the other methods.

Since: 0.1.0


signIn(...)

signIn(opts?: { silent?: boolean | undefined; } | undefined) => Promise<SignInResult>

Sign in to the platform games service.

silent (default true) attempts auto sign-in with no UI; on most devices this succeeds if the player has previously authenticated this game. Pass silent: false to force the full interactive flow, and only in response to an explicit user gesture.

| Param | Type | | ---------- | ---------------------------------- | | opts | { silent?: boolean; } |

Returns: Promise<SignInResult>

Since: 0.1.0


isSignedIn()

isSignedIn() => Promise<{ signedIn: boolean; }>

Whether a player is currently signed in.

Returns: Promise<{ signedIn: boolean; }>

Since: 0.1.0


getPlayer()

getPlayer() => Promise<PlayerInfo>

Get the signed-in player's profile.

On Android and iOS this rejects when no player is signed in. On web (the no-op fallback) it resolves an empty profile (playerId: "").

Returns: Promise<PlayerInfo>

Since: 0.1.0


unlockAchievement(...)

unlockAchievement(opts: { id: string; }) => Promise<void>

Unlock an achievement by its platform id (Play Console achievement id on Android, App Store Connect / Game Center id on iOS).

| Param | Type | | ---------- | ---------------------------- | | opts | { id: string; } |

Since: 0.1.0


incrementAchievement(...)

incrementAchievement(opts: { id: string; steps: number; }) => Promise<void>

Increment a partial (incremental) achievement.

steps is interpreted differently per platform: on Android (PGS) it is a discrete step count toward the achievement's Play Console step total; on iOS (GameKit) it is added to percentComplete as percentage points. Compute a platform-appropriate value (e.g. via Capacitor.getPlatform()) so progress matches on both stores.

| Param | Type | | ---------- | ------------------------------------------- | | opts | { id: string; steps: number; } |

Since: 0.1.0


showAchievements()

showAchievements() => Promise<void>

Show the platform's native achievements UI.

Since: 0.1.0


submitScore(...)

submitScore(opts: { leaderboardId: string; score: number; }) => Promise<void>

Submit a score to a leaderboard by its platform id.

| Param | Type | | ---------- | ------------------------------------------------------ | | opts | { leaderboardId: string; score: number; } |

Since: 0.1.0


showLeaderboard(...)

showLeaderboard(opts: { leaderboardId: string; }) => Promise<void>

Show the native UI for a single leaderboard.

| Param | Type | | ---------- | --------------------------------------- | | opts | { leaderboardId: string; } |

Since: 0.1.0


showAllLeaderboards()

showAllLeaderboards() => Promise<void>

Show the native all-leaderboards UI.

Since: 0.1.0


loadSnapshot(...)

loadSnapshot(opts: { name: string; }) => Promise<{ snapshot: Snapshot | null; }>

Load a saved-game snapshot by its stable name. Resolves { snapshot: null } when no snapshot exists for that name.

| Param | Type | | ---------- | ------------------------------ | | opts | { name: string; } |

Returns: Promise<{ snapshot: Snapshot | null; }>

Since: 0.1.0


saveSnapshot(...)

saveSnapshot(opts: { name: string; data: string; description?: string; }) => Promise<void>

Create or overwrite a saved-game snapshot. Conflicts are auto-resolved by most-recently-modified (last write wins), with no merge.

| Param | Type | | ---------- | ------------------------------------------------------------------ | | opts | { name: string; data: string; description?: string; } |

Since: 0.1.0


listSnapshots()

listSnapshots() => Promise<{ snapshots: SnapshotMeta[]; }>

List metadata for all of the player's snapshots.

Returns: Promise<{ snapshots: SnapshotMeta[]; }>

Since: 0.1.0


deleteSnapshot(...)

deleteSnapshot(opts: { name: string; }) => Promise<void>

Delete a saved-game snapshot by its stable name.

| Param | Type | | ---------- | ------------------------------ | | opts | { name: string; } |

Since: 0.1.0


addListener('signInStateChanged', ...)

addListener(event: "signInStateChanged", listener: (e: SignInStateChangedEvent) => void) => Promise<PluginListenerHandle>

Listen for sign-in state changes: an interactive sign-in completing, or the player signing out of the platform service system-wide.

| Param | Type | | -------------- | --------------------------------------------------------------------- | | event | 'signInStateChanged' | | listener | (e: SignInResult) => void |

Returns: Promise<PluginListenerHandle>

Since: 0.1.0


removeAllListeners()

removeAllListeners() => Promise<void>

Remove all listeners registered through this plugin.

Since: 0.1.0


Interfaces

SignInResult

Result of a sign-in attempt, or the payload of a sign-in state change.

| Prop | Type | Description | | -------------- | ------------------------------------------------- | --------------------------------------------------------- | | signedIn | boolean | Whether the player is currently authenticated. | | player | PlayerInfo | The player profile, present only when signedIn is true. |

PlayerInfo

A signed-in player's public profile.

| Prop | Type | Description | | ----------------- | ------------------- | ----------------------------------------------------------------------------- | | playerId | string | Stable, platform-assigned player id (PGS player id / GameKit gamePlayerID). | | displayName | string | Display name as shown in Google Play Games / Game Center. | | avatarUrl | string | URL of the player's avatar image, when the platform exposes one. |

Snapshot

A saved-game snapshot together with its serialized payload.

| Prop | Type | Description | | ----------------- | ------------------- | ----------------------------------------------------------------------- | | name | string | Stable unique name the snapshot was saved under. | | description | string | Human-readable description stored with the snapshot. | | modifiedAt | number | Last-modified time, in epoch milliseconds. | | data | string | The serialized save payload as a UTF-8 string (encode binary yourself). |

SnapshotMeta

Snapshot metadata without the payload, as returned by listSnapshots.

| Prop | Type | Description | | ----------------- | ------------------- | ---------------------------------------------------- | | name | string | Stable unique name of the snapshot. | | description | string | Human-readable description stored with the snapshot. | | modifiedAt | number | Last-modified time, in epoch milliseconds. |

PluginListenerHandle

| Prop | Type | | ------------ | ----------------------------------------- | | remove | () => Promise<void> |

Type Aliases

SignInStateChangedEvent

Payload of the signInStateChanged event.

SignInResult

Development

pnpm install
pnpm verify      # lint + typecheck + build + pack check

The TypeScript bridge is built to dist/ (ESM + CJS + types). The native sources under android/ and ios/ ship in the package and are wired up by npx cap sync.

License

MIT © Idle Flow Games