docs: game-services skill (Game Center + Play Games Services step by step), pitfall 86, commands, CHANGELOG Unreleased; adapters regenerated

This commit is contained in:
CRTkafa 2026-10-21 05:12:44 +07:00
parent 22286c7e02
commit 93d7f8a5fc
8 changed files with 104 additions and 0 deletions

View file

@ -0,0 +1,77 @@
---
name: game-services
description: Set up Game Center (App Store) and Play Games Services (Google Play) for a mobile game from one config section - the App ID GAME_CENTER capability, Game Center on for the app and the version, the com.apple.developer.game-center entitlement, leaderboards and achievements with localizations (storebound apple game-center, upsert by vendor id), the Play Games Services project, Android credential with the app signing SHA-1, web OAuth client and publish (console plan play-games-services), the games_APP_ID resource, and leaderboards / achievements through the Games Configuration API (storebound play games). Use when a game adds leaderboards, achievements or platform sign-in, when Game Center sign-in fails, or PGS sign-in fails with a missing APP_ID or a SHA-1 mismatch.
---
# Game Center and Play Games Services
One `games` section in `storebound.config.ts` drives both stores. The leaderboards and achievements are ONE shared
list: each item has your `id` (the App Store vendor identifier) and texts per config language; Play generates its own
ids, which you add as `playId` once they exist (until then storebound matches Play items by the default-language
name).
```ts
games: {
gameCenter: true, // App ID capability + Game Center for the app and the version
playGames: { appId: '123456789012' }, // the PGS project id (games_APP_ID); set it after step P1
leaderboards: [
{ id: 'com.example.game.highscore', sort: 'high', format: 'INTEGER', // Apple formatter names
locales: { en: { name: 'High score', suffix: ' points' }, tr: { name: 'En yüksek skor' } } },
],
achievements: [
{ id: 'com.example.game.first-win', points: 10, locales: { en: { name: 'First win', description: 'Win a round.' } } },
{ id: 'com.example.game.secret', points: 20, hidden: true, steps: 3, // steps: incremental on Play only
locales: { en: { name: 'Secret', description: 'Find the secret room.', earned: 'You found it.' } } },
],
},
```
Limits checked by `storebound check`: Game Center names at most 32 characters, points 0-100 each and 1000 in total;
Play points a multiple of 5, 1000 in total, at most 200 achievements, and at least 5 before Play publishes the games
project. `platforms: ['ios']` keeps an item on one store.
## Game Center (App Store Connect API)
1. `games.gameCenter: true`, then `storebound apple signing ensure --dry` and without `--dry`: GAME_CENTER is added
to the App ID (it never removes a capability). It reads the App ID back; the list can lag (pitfalls).
2. The Xcode target needs the entitlement: Signing & Capabilities > + Game Center, which writes
`com.apple.developer.game-center` into the `.entitlements` file named by `CODE_SIGN_ENTITLEMENTS`. `storebound check`
and `validate` compare entitlement, App ID and config, and the uploaded IPA's entitlements.
3. `storebound apple game-center --dry`: the plan (Game Center detail for the app, the editable version's switch,
every leaderboard / achievement / localization: create, update or keep). Then without `--dry` (asks first): it
creates through `POST /v1/gameCenterDetails`, `POST /v1/gameCenterAppVersions`, `/v1/gameCenterLeaderboards`,
`/v1/gameCenterAchievements` and their localizations, PATCHes only what differs, and reads everything back.
4. Images (leaderboard / achievement artwork, 512 or 1024 px) are optional for the API and stay in App Store
Connect for now. Leaderboards and achievements go to review with the next app version: the owner's Submit for
review (`storebound apple submit`).
5. `storebound apple game-center status` (MCP `apple_game_center_status`) shows the state at any time.
## Play Games Services
P1. `storebound console plan play-games-services --json` (MCP `console_plan`): the agent drives Play Console and the
Google Cloud console with its own browser tool: create the games project, the Android credential (package name +
the **App signing key** SHA-1 from Play app signing; the API gives only SHA-256, so read it on that page), the web
OAuth client only when a game server exchanges server auth codes (ask the owner), the properties. The agent
never presses **Publish**: that is the owner's button.
P2. Put the project id into `games.playGames.appId` and the "Get resources" XML into
`android/app/src/main/res/values/games-ids.xml`; the manifest needs
`<meta-data android:name="com.google.android.gms.games.APP_ID" android:value="@string/game_services_project_id"/>`
and the app module `com.google.android.gms:play-services-games-v2`. `storebound scan`, `check` and `validate` check
all three and that the id matches the config.
P3. `storebound play games --dry`, then without `--dry`: inserts / updates the drafts through the Games Configuration
API (`achievementConfigurations`, `leaderboardConfigurations`). It prints each new Play id: add it as `playId`.
P4. Testers (Play Games Services > Testers) are the owner's to add. The owner presses Publish; then
`storebound console verify play-games-services --from-text -` with the page text.
## Declarations
A Game Center or PGS player id is a **User ID**: App Privacy > Identifiers > User ID (`appPrivacy.types.USER_ID`,
App Functionality, linked) and Play Data safety > Personal info > User IDs (`dataSafety.data.PSL_USER_ACCOUNT`,
collected for app functionality). `check` warns when they are missing; ask the owner whether the id is shared. If the
game has its own accounts on top, the account-deletion skill applies; the platform account itself is deleted by Apple
or Google, not by the game.
## Desktop
App info > Game services: both stores side by side (enabled, capability, entitlement, project id, counts vs the
config, pending changes), Sync buttons (dry run, then the native confirm dialog) and the PGS setup plan.

View file

@ -1076,3 +1076,14 @@ that fails without the fix (see CONTRIBUTING.md).
line: "--version <x.y.z> is required (storebound apple status shows the editable version)".
- **Guard:** `findReviewContact` / `noContactMessage` in `cli/lib/credentials.ts`, `Args.required` in
`cli/lib/args.ts` (listing, privacy-manifest, adhoc export, edit, resubmit); `tests/console-guardrails-1021.test.ts`.
## 88. Game Center and Play Games Services: ids, SHA-1 and the deprecated enabled-versions route
- **Symptom:** Play Games sign-in fails on store installs while debug builds work (the Android credential has the
upload key's SHA-1, not the App signing key's); sign-in fails at once with no APP_ID (the Gradle dependency is there,
the manifest meta-data or games-ids.xml is not); Game Center items created twice by a re-run; a tool reading
`/v1/apps/{id}/gameCenterEnabledVersions`, which the API marks deprecated.
- **Do:** one `games` section (game-services skill). Game Center items are matched by vendor identifier (`id`), Play
items by `playId` or the default-language name (Play generates ids). Read the SHA-1 on Play Console > App integrity >
Play app signing (the Play API has only SHA-256, `generatedapks.list`). Version switch: `gameCenterAppVersions`.
- **Guard:** `cli/lib/game-services.ts` (validateGames, planGameCenter, planPlayGames, pgsFindings, gcFindings),
`storebound scan` rule `pgs.manifest` / `pgs.app-id`, `cli/play/games.ts` (no 5xx retry of an insert),
`tests/game-services.test.ts`.