Tests for store image rules and iPad wiring; skill and README: iPad, sources, checks

This commit is contained in:
CRTkafa 2026-10-10 21:54:47 +08:00
parent aecdcb1c50
commit df1a757a8b
3 changed files with 271 additions and 6 deletions

View file

@ -14,11 +14,26 @@ iOS Simulator capture needs macOS + Xcode (`xcrun`); Android capture needs `adb`
|---|---|---|
| ios69 | 1320 x 2868 | App Store 6.9" (`APP_IPHONE_67`), required |
| ios65 | 1284 x 2778 | App Store 6.5" (`APP_IPHONE_65`) |
| ipad13 | 2064 x 2752 | App Store 13" iPad (`APP_IPAD_PRO_3GEN_129`), required when the app runs on iPad; only with `apple.ipad: true` |
| play | 1080 x 1920 | Play phone (2-8, ratio at most 2:1) |
| tab7 | 1080 x 1920 | Play 7" tablet (tablet frames) |
| tab10 | 1440 x 2560 | Play 10" tablet |
| feature | 1024 x 500 | Play feature graphic (required) |
Sources (re-check before a release; Apple renames display classes often):
- Apple "Screenshot specifications": https://developer.apple.com/help/app-store-connect/reference/app-information/screenshot-specifications
(13" iPad: 2064 x 2752 or 2048 x 2732, landscape too, "Required if app runs on iPad"; 1-10 per size; JPEG / PNG,
no alpha or transparency).
- ASC API `ScreenshotDisplayType`: https://developer.apple.com/documentation/appstoreconnectapi/screenshotdisplaytype
(there is no "13 inch" value: the 13" iPad set is `APP_IPAD_PRO_3GEN_129`).
- Play graphics: https://support.google.com/googleplay/android-developer/answer/9866151 (screenshots 320-3840 px, at
most 2:1, JPEG or 24-bit PNG, 8 MB; feature graphic 1024 x 500).
**iPad.** Set `apple.ipad: true` only if the app runs on iPad (iPhone-only apps skip the iPad set). Then the default
sizes include `ipad13` (3:4 layout), `apple screenshots` uploads it, `validate` requires it, and tablet frames default
to the 13" iPad screen (1032 x 1352 CSS px @2x below a 24 px bar), so an `iPad Pro 13-inch` / `iPad Air 13-inch`
simulator screenshot fits after the bar is cropped. Play tablet sizes (tab7 / tab10) reuse the same tablet frames.
## 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).
@ -30,15 +45,21 @@ iOS Simulator capture needs macOS + Xcode (`xcrun`); Android capture needs `adb`
- `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).
`-AppleLanguages` / `-AppleLocale`; status bar is forced to 9:41, full battery. After a cold boot the app is
launched once and given `ios.warmupMs` (default 8000) before the first shot; without it the first frame of a
fresh simulator is often blank. A simulator storebound boots is shut down afterwards (`--keep-booted` keeps it).
For iPad shots set `ios.devices.tablet` (e.g. "iPad Pro 13-inch (M5)") and `device: 'tablet' | 'both'` per shot.
- `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.
`cropTop` rows (the status bar) so they fit the template: by default the frame's bar share per device class
(162 px on a 6.9" iPhone, 48 px on a 13" iPad with `apple.ipad`); set `cropTop: 120` or `{ phone, tablet }` for
other devices, and `shots.phone` / `shots.tablet` to that device's screen in points. Capture warns when a frame's
aspect does not match. Give the game time to load: `delayMs` (simulator / emulator; 2500 default is short for a
cold start) or `waitFor` (web).
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.
@ -49,7 +70,11 @@ iOS Simulator capture needs macOS + Xcode (`xcrun`); Android capture needs `adb`
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. **Check.** `storebound shots check` (read-only, exit 1 on errors): sizes, alpha, counts, text overflow.
8. **Check.** `storebound shots check` (read-only, exit 1 on errors): pixel sizes (Apple: a listed size, portrait or
landscape; Play screenshots 320-3840 px at most 2:1; feature graphic exactly 1024 x 500), alpha, Play JPEG /
24-bit PNG and 8 MB, counts per set (Apple 1-10, Play 2-8), text overflow flags (warnings). `--variants` also checks
A/B variant folders. `storebound validate` runs the same checks on the renders folder and lists errors as
blockers next to the store state (`--no-local` skips them).
9. **Upload.** `storebound play images` and `storebound apple screenshots` (both idempotent, background + log).
## Gotchas