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

@ -94,6 +94,7 @@ need to ...", do it instead, unless it is one of the owner steps in point 2.
- `skills/build-and-sign/SKILL.md`: Sign, build and upload a mobile app or game from the terminal
- `skills/console-autofill/SKILL.md`: Fill App Store Connect and Google Play Console forms that have no API (New App, App Privacy, Play Create app, IARC content rating, every Play App content card, Play Store settings category, first production release countries and send-for-review). Agent-first by default
- `skills/export-compliance/SKILL.md`: Answer App Store export compliance (encryption) for a mobile app or game correctly
- `skills/game-services/SKILL.md`: Set up Game Center (App Store) and Play Games Services (Google Play) for a mobile game from one config section
- `skills/listing-localization/SKILL.md`: Translate the store listing of a mobile app or game into more languages
- `skills/migrate-from-fastlane/SKILL.md`: Move a mobile app or game from fastlane (deliver, supply, snapshot / screengrab, Appfile, Deliverfile) to storebound with `storebound import fastlane`
- `skills/play-first-release/SKILL.md`: Step-by-step first (and later) Google Play release of a mobile app or game

View file

@ -96,6 +96,7 @@ need to ...", do it instead, unless it is one of the owner steps in point 2.
| `build-and-sign` | Sign, build and upload a mobile app or game from the terminal |
| `console-autofill` | Fill App Store Connect and Google Play Console forms that have no API (New App, App Privacy, Play Create app, IARC content rating, every Play App content card, Play Store settings category, first production release countries and send-for-review). Agent-first by default |
| `export-compliance` | Answer App Store export compliance (encryption) for a mobile app or game correctly |
| `game-services` | Set up Game Center (App Store) and Play Games Services (Google Play) for a mobile game from one config section |
| `listing-localization` | Translate the store listing of a mobile app or game into more languages |
| `migrate-from-fastlane` | Move a mobile app or game from fastlane (deliver, supply, snapshot / screengrab, Appfile, Deliverfile) to storebound with `storebound import fastlane` |
| `play-first-release` | Step-by-step first (and later) Google Play release of a mobile app or game |

View file

@ -95,6 +95,7 @@ need to ...", do it instead, unless it is one of the owner steps in point 2.
- `skills/build-and-sign/SKILL.md`: Sign, build and upload a mobile app or game from the terminal
- `skills/console-autofill/SKILL.md`: Fill App Store Connect and Google Play Console forms that have no API (New App, App Privacy, Play Create app, IARC content rating, every Play App content card, Play Store settings category, first production release countries and send-for-review). Agent-first by default
- `skills/export-compliance/SKILL.md`: Answer App Store export compliance (encryption) for a mobile app or game correctly
- `skills/game-services/SKILL.md`: Set up Game Center (App Store) and Play Games Services (Google Play) for a mobile game from one config section
- `skills/listing-localization/SKILL.md`: Translate the store listing of a mobile app or game into more languages
- `skills/migrate-from-fastlane/SKILL.md`: Move a mobile app or game from fastlane (deliver, supply, snapshot / screengrab, Appfile, Deliverfile) to storebound with `storebound import fastlane`
- `skills/play-first-release/SKILL.md`: Step-by-step first (and later) Google Play release of a mobile app or game

View file

@ -33,6 +33,15 @@
every command with its window place and methods; 92 commands, 88 covered, 4 not for the desktop (`mcp`, `serve`,
`desktop`, `api`). `tests/desktop-coverage.test.ts` fails when a command has no place, names a method the window
never calls, or is marked not-for-desktop without being on the short list.
- **Game Center and Play Games Services.** A `games` config section (switches per store and one shared list of
leaderboards and achievements). `storebound apple game-center` switches Game Center on for the app and the version
and upserts leaderboards, achievements and their localizations by vendor id; `apple signing ensure` adds the
GAME_CENTER capability. `storebound play games` upserts the Play drafts through the Games Configuration API, and
`console plan play-games-services` walks an agent through the games project, the Android credential with the app
signing SHA-1, the web OAuth client and the owner's Publish. `scan`, `check` and `validate` compare the entitlement,
the App ID and the config, the games_APP_ID resource with the Gradle dependency and the config, and remind the User
ID declarations; `games status`, four MCP tools and a Game services card in the desktop's App info tab. Skill
game-services, pitfall 88.
## 0.8.21 · 2026-10-20

View file

@ -95,6 +95,7 @@ need to ...", do it instead, unless it is one of the owner steps in point 2.
| `build-and-sign` | Sign, build and upload a mobile app or game from the terminal |
| `console-autofill` | Fill App Store Connect and Google Play Console forms that have no API (New App, App Privacy, Play Create app, IARC content rating, every Play App content card, Play Store settings category, first production release countries and send-for-review). Agent-first by default |
| `export-compliance` | Answer App Store export compliance (encryption) for a mobile app or game correctly |
| `game-services` | Set up Game Center (App Store) and Play Games Services (Google Play) for a mobile game from one config section |
| `listing-localization` | Translate the store listing of a mobile app or game into more languages |
| `migrate-from-fastlane` | Move a mobile app or game from fastlane (deliver, supply, snapshot / screengrab, Appfile, Deliverfile) to storebound with `storebound import fastlane` |
| `play-first-release` | Step-by-step first (and later) Google Play release of a mobile app or game |

View file

@ -50,6 +50,7 @@ run in the background with a log (`storebound shots render > .storebound/render.
| `play images [--variant b]` | API | icon, feature graphic, phone / 7" / 10" screenshots, one edit per language |
| `play products` | API | one-time products: regional prices from `convertRegionPrices` + your overrides, activate |
| `play subscriptions [--csv]` | API | subscriptions: listings + benefits, one auto-renewing base plan, regional prices, intro and extra offers, activate (plan first, asks) |
| `play games [status]` | API | Play Games Services leaderboards and achievements from `games` (Games Configuration API; drafts, the owner publishes); the setup is `console plan play-games-services`; dry first, asks |
| `play data-safety` | API | Data safety form (CSV import); `--csv` writes the file |
| `play build [--version-code N] [--flavor f]` | local + API read | `build.prebuild` first (Capacitor: web build + cap sync; stale copied web assets stop the build), then Gradle `bundleRelease` (Flutter `flutter build appbundle`; Capacitor, React Native, Unity export found) with the next free versionCode and the upload key from env / `.storebound` (passed through the environment, never argv); AAB checked and copied to `build/android/` |
| `play upload [<aab>] --track internal\|alpha\|beta` | API | AAB to a testing track with release notes; versionCode checked first; `--dry` is read-only, a real run asks |
@ -83,6 +84,8 @@ run in the background with a log (`storebound shots render > .storebound/render.
| `apple subscriptions [--csv] [--codes]` | API | groups, subscriptions, levels, localizations, availability, equalized prices + overrides + CSV (scheduled changes), introductory and promotional offers, offer code campaigns, review screenshots (plan first, asks; custom codes only with `--codes`) |
| `apple appinfo` | API | categories, age rating, content rights, Free, territories; plan first (old -> new), only changes are sent |
| `apple review-details` | API | App Review contact, demo account (from `.storebound/`, masked), notes (+ sign-in steps, where account deletion is) |
| `apple game-center [status]` | API | Game Center from `games`: the app's Game Center detail, the version switch, leaderboards and achievements with localizations (upsert by vendor id, read back; nothing submitted); dry first, asks |
| `games status [--json]` | API, read-only | Game Center and Play Games Services on both stores: capability, entitlement, games_APP_ID, counts vs the config, pending changes, console links |
| `apple encryption` | API | export compliance answer from `apple.usesNonExemptEncryption` (never guessed) |
| `apple release --phased on\|pause\|resume\|complete`, `--manual-release` | API | phased release, release an approved version (resume / complete / release ask first) |
| `apple signing status` | API, read-only | bundle id capabilities, distribution certificates (with / without a private key on this Mac), App Store profiles per bundle id, installed or not |

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`.