shots: Mac App Store screenshots (mac size, APP_DESKTOP to the macOS version), a landscape layout (Mac window or bare; Mac, Play Chromebook, Play tablets), safe margins in every template checked by shots check from the render's layout boxes, a contact sheet timeout that scales with images, sizes and load; pitfall 80

This commit is contained in:
CRTkafa 2026-10-20 03:29:19 +07:00
parent 30488c512d
commit e59539fec8
26 changed files with 532 additions and 67 deletions

View file

@ -978,3 +978,19 @@ that fails without the fix (see CONTRIBUTING.md).
every version; validate and release status warn about another platform's editable or rejected version.
- **Guard:** `cli/apple/platform.ts` (`pickPlatform`, `parsePlatform`), `tests/apple-platforms.test.ts` (fake App Store
Connect: iOS 0.8.7 live, macOS 0.8.7 rejected in UNRESOLVED_ISSUES).
## 80. Screenshot text and logo hugging the edges; a Mac app with no screenshots; sheet.png timing out
- **Symptom:** a game's hero logo and titles touched the left / right / top edge of the screenshots (the stores crop
and round the corners, it reads cramped); a game with a macOS version had no Mac screenshots (storebound had no Mac
size); `shots render` stopped with "sheet.png ... Timeout 30000ms" on a project with 9 sizes.
- **Cause:** the templates padded the text by 5 % and drew the logo 86 % wide with a negative top margin, nothing
measured it; the size table only knew iPhone, iPad and Play; the contact sheet used the same flat 30 s wait as one
screenshot while decoding every image of the language.
- **Do:** keep the 7 % / 5 % safe margins (`shots check` code `margin` fails anything under 6 % / 4 %, measured from the
page's layout boxes in report.json); set `apple.mac: true` for a Mac app (`mac` size, 16:10, `APP_DESKTOP`, uploaded
with `apple screenshots --platform macos`) and capture landscape frames; the sheet's wait now scales with images,
sizes and load and logs a heartbeat (or use `--no-sheet`).
- **Guard:** `marginViolations` / `SAFE_MARGIN` and `renderDims` in `cli/shots/lib.ts`, `marginIssues` in
`cli/shots/report.ts`, `IMAGE_SPECS.mac` and `macNote` in `cli/shots/spec.ts`, `MAC_DISPLAY` in
`cli/apple/screenshots.ts`, `sheetTimeoutMs`; `tests/mac-landscape.test.ts`, `tests/browser/landscape.browser.ts`,
the macOS case in `tests/idempotency.test.ts`.

View file

@ -36,9 +36,11 @@ or uploaded as another size. `store/renders` can be large (hundreds of MB) and n
| iphone-duo-outer | 1398 x 2034 (or 2034 x 1398) | App Store "iPhone Duo" outer display; optional, only with `apple.iphoneDuo: true` (tablet frames) |
| iphone-duo-inner | 2007 x 2853 (or 2853 x 2007) | App Store "iPhone Duo" inner display; same switch |
| 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` |
| mac | 2880 x 1800 (also 2560 x 1600, 1440 x 900, 1280 x 800) | Mac App Store (`APP_DESKTOP`), 16:10 landscape only; only with `apple.mac: true`, uploaded to the macOS version |
| play | 1080 x 1920 | Play phone (2-8, ratio at most 2:1) |
| tab7 | 1080 x 1920 | Play 7" tablet (tablet frames, Android tablet body); optional, see `play.tablets` |
| tab10 | 1440 x 2560 | Play 10" tablet; optional, see `play.tablets` |
| chromebook | 1920 x 1080 | Play Chromebook screenshots (landscape layout); only with `play.chromebook: true`; console only (no API image type) |
| feature | 1024 x 500 | Play feature graphic (required) |
Sources (re-check before a release; Apple renames display classes often):
@ -75,7 +77,30 @@ console's iPhone Duo tab until then (one constant, `IPHONE_DUO_DISPLAY` in `cli/
the enum has them). No Duo app preview sizes are published. Google Play has no foldable slot: foldables show the
7" / 10" tablet sets below.
**Play tablets are optional.** Play requires the 512 x 512 icon, the 1024 x 500 feature graphic and at least 2
**Mac App Store.** Apple's Screenshot specifications (checked 2026-10-20) list four 16:10 Mac sizes: 1280 x 800,
1440 x 900, 2560 x 1600 and 2880 x 1800, PNG / JPEG without alpha, 1-10. `apple.mac: true` adds the `mac` size key
(2880 x 1800): `shots render` lays it out in landscape, `shots check` accepts exactly those four sizes (no portrait, no
alpha) and requires the set, and `apple screenshots --platform macos` uploads it as `APP_DESKTOP` to the macOS
version (versions are per platform, pitfall 79; the iOS run uploads the iOS sets only and says where the Mac set
goes). `validate` prints an info note when the app has a macOS version but no Mac screenshots. Frames: landscape
captures in `<frames>/<lang>/landscape/<name>.png`, `shots.landscape.size` CSS px (default 1440 x 900 @2x).
**Landscape layout (Mac, Chromebook, Play tablets).** Copy in a column on one side (`shots.landscape.side`, default
left), the scene's first frame on the other. `shots.landscape.frame`: `'window'` draws a Mac window (title bar with
the three buttons, the default for `mac`), `'none'` the bare frame with rounded corners (the default for Play sizes).
Both templates (game and app) have it. Play: `play.chromebook: true` renders the `chromebook` size (1920 x 1080; the
Play API has no Chromebook image type, so `play images` prints the Main store listing deep link instead of
uploading), and `shots.landscape.playTablets: true` renders tab7 / tab10 in landscape (1920 x 1080 / 2560 x 1440),
which Play's tablet slots accept. Badges are not drawn in landscape.
**Safe margins (every template, every size, both stores).** Text and logo keep about 7 % of the width left and right
and 5 % of the height at the top; the logo scales to fit inside. Each render records the layout boxes of the logo,
eyebrow, title lines and subtitle (and the feature graphic's logo or name) in `report.json`, and `shots check` fails
any box closer than 6 % of the width to the left / right edge or 4 % of the height to the top (code `margin`). The
measurement comes from the page's own layout, not from a pixel scan. Renders from older templates fail it: render
again.
**Play tablets are optional.****Play tablets are optional.** Play requires the 512 x 512 icon, the 1024 x 500 feature graphic and at least 2
screenshots (answer 9866151 above); 7" / 10" tablet screenshots are optional, but without them the app is not eligible
for tablet featuring. `play.tablets` decides: unset = true when tablet renders (tab7/ or tab10/) already exist, else
false; `false` = `shots render`, `shots check`, `shots gallery`, `validate` and `play images` never ask for them;
@ -238,6 +263,9 @@ Screenshots". Optional: without these assets the App Store uses in-app events, a
many languages takes minutes: in a terminal prefer `storebound shots render > .storebound/render.log 2>&1 &`.
## Gotchas
- `shots render`'s contact sheet (`sheet.png`) waits for every image to decode: its timeout grows with the images and
sizes on the sheet and with the machine's load (`max(1-min, 5-min load) / cores`, 1-5x), with a "still loading" line
every 15 s. A timeout names the sheet, the budget and the page errors. `--no-sheet` skips it.
- Output is 24-bit RGB PNG: Play rejects alpha / palette PNGs, Apple rejects alpha.
- Arabic: `rtl: true` on the language; numbers stay LTR inside RTL text automatically.
- Japanese breaks by phrase, Korean at spaces; long words shrink the line rather than wrap.