store-screenshots skill: capture sources, dry run, shots check

This commit is contained in:
CRTkafa 2026-10-10 21:28:40 +08:00
parent 4356395087
commit 4755ab4e30

View file

@ -1,12 +1,13 @@
---
name: store-screenshots
description: Produce store screenshots and the Play feature graphic for a mobile game in every required size and many languages - capture raw frames from the running game with playwright, write per-language marketing copy (incl. RTL Arabic and CJK fonts), render captioned scenes with device frames, JPEG copies for Play, and upload to both stores. Use when the user needs App Store / Google Play screenshots, preview images, a feature graphic, localized screenshot captions, or screenshot sizes.
description: Produce store screenshots and the Play feature graphic for a mobile game in every required size and many languages - capture raw frames from the running game (web build via playwright, iOS Simulator via simctl, Android emulator or device via adb, or a folder of frames from any engine), write per-language marketing copy (incl. RTL Arabic and CJK fonts), render captioned scenes with device frames, JPEG copies for Play, and upload to both stores. Use when the user needs App Store / Google Play screenshots, preview images, a feature graphic, localized screenshot captions, or screenshot sizes.
---
# Store screenshots
CLI: `storebound` (or `bunx storebound` in a project that has it, or `bun <toolchain>/cli/index.ts`). Needs `ffmpeg`, and `playwright` in the project
(`bun add -d playwright`; it uses Playwright's Chromium or an installed Google Chrome).
(`bun add -d playwright`; it uses Playwright's Chromium or an installed Google Chrome) for rendering and web capture.
iOS Simulator capture needs macOS + Xcode (`xcrun`); Android capture needs `adb` (platform-tools).
## Sizes (what each store wants)
| size key | pixels | where |
@ -21,9 +22,23 @@ CLI: `storebound` (or `bunx storebound` in a project that has it, or `bun <toolc
## Steps
1. **Game switches.** Give the game URL params for screenshots: language, fixed seed, no ads / analytics / purchase
UI, skip tutorial, jump to a level, freeze at a moment. Frames must show real gameplay (store rule).
2. **Capture.** Configure `shots.capture` (baseUrl, query with `{lang}`, shots: path / waitFor / eval / delayMs /
device). Start the game (production build preview), then `storebound shots capture --lang en` (phone 440 x 902 @3x
and tablet 800 x 1240 @2x by default; the template draws the status bar above). Frames are local, not committed.
2. **Capture.** Configure `shots.capture` with a `source` (or pass `--source`), then
`storebound shots capture --lang en --dry` to see the plan, and without `--dry` to capture. Frames land in
`<shots.frames>/<lang>/<phone|tablet>/<shot>.png`, local, not committed.
- `web` (default): `baseUrl`, `query` with `{lang}`, shots: `path` / `waitFor` / `eval` / `delayMs` / `device`.
Phone 440 x 902 @3x and tablet 800 x 1240 @2x by default; the template draws the status bar above.
- `ios-sim` (Unity, Godot, Flutter, native, Capacitor: any Simulator build): `ios.device` (simulator name or UDID,
e.g. a 6.9" iPhone), `ios.bundleId`, optional `ios.app` (.app to install), `ios.args`. Per shot: `args` (launch
arguments, read them with UserDefaults / your engine) and / or `url` (deep link). Language goes in as
`-AppleLanguages` / `-AppleLocale`; status bar is forced to 9:41, full battery. A simulator storebound boots is
shut down afterwards (`--keep-booted` keeps it).
- `android-emu`: `android.package`, optional `serial`, `activity`, `apk`. Per shot: `url` (VIEW intent) and / or
typed `extras`. Demo-mode status bar; per-app language on Android 13+ (older: pass `{lang}` in an extra).
Nothing is wiped or rebooted.
- `folder`: frames made any other way; `shots capture` (and `shots check`) only verify that every frame the scenes
use exists with the right aspect ratio and resolution.
`{lang}`, `{locale}`, `{shot}` are replaced in args, extras and URLs. Simulator / emulator screenshots lose
`cropTop` rows (the status bar; default about 5.6 % of the height) so they fit the template.
3. **Copy.** `store/shots/copy.json`: per language, per scene: `eyebrow`, `title` [white line, gold line], `sub`,
`badges` [[big, small]]. Short and true (only claim what is in the game); about 15 Latin characters per title line.
Natural marketing tone per language, not literal translation; use the game's own terms.
@ -34,7 +49,8 @@ CLI: `storebound` (or `bunx storebound` in a project that has it, or `bun <toolc
6. **Render.** `storebound shots render --lang en` first, review `store/renders/en/sheet.png` (contact sheet), then
all languages in the background: `storebound shots render > .storebound/render.log 2>&1 &`.
7. **JPEG for Play.** `storebound shots jpeg` (q92, about 4x smaller than PNG; App Store stays PNG).
8. **Upload.** `storebound play images` and `storebound apple screenshots` (both idempotent, background + log).
8. **Check.** `storebound shots check` (read-only, exit 1 on errors): sizes, alpha, counts, text overflow.
9. **Upload.** `storebound play images` and `storebound apple screenshots` (both idempotent, background + log).
## Gotchas
- Output is 24-bit RGB PNG: Play rejects alpha / palette PNGs, Apple rejects alpha.