Work / Charades / Wiki / Concepts
screenshot-seam
Conceptverified 2026-10-30
screenshot-seam
A capture build is this app with a few files swapped, so store screenshots can be captured
from the running app rather than drawn. Under EXPO_PUBLIC_SCREENSHOT_MODE=1,
metro.config.js resolves @/a/b to src/a/b.screenshot.ts wherever that file exists. The
flag is set by scripts/build-screenshot-* and nowhere else.
App code holds no flag and no capture branch, so a store binary contains nothing of what
a capture build runs. It used to: the app read a SCREENSHOT_MODE boolean in five places and
the seeded game shipped in every store binary, dead. App Review rejects that pattern under
guideline 5.6 (features "hidden during the review process"). src/config/seams.test.ts
asserts the flag is in no eas.json, app.config.ts or .env*, that no app file reads it or
imports a capture-only file, and that the swap does what it says.
The state lives in src/lib/screenshot-fixture.ts. Two files are swapped:
| Swapped file | What a capture build changes |
|---|---|
config/seams.ts → seams.screenshot.ts |
ROUND_START: seeding movieResults also derives the score, renders the streak badge, and makes GameScreen skip the 3-2-1 overlay |
STARTING_PACKS: three packs picked, every paid pack owned |
|
FIRST_HISTORY: so the history screen is a list, not its empty state |
|
startingPrices: RevenueCat refuses a Test Store key in Release, so prices would otherwise render empty |
|
STORAGE_ID: a separate MMKV id; sharing one let a capture run's fake week survive into a normal build |
|
lib/movie.ts → movie.screenshot.ts |
the deck: the Fisher-Yates shuffle is the only true randomness |
A new source of difference is a new export in seams.ts and its twin in
seams.screenshot.ts, never a branch in app code. Import a swapped module as @/…, never
by a relative path: the swap matches on that spelling.
goldie reinstalls the app with cleared data before every flow, so none of this can be seeded by hand once; it has to reassert on every cold launch.
The fixture owns every paid pack, so no price or padlock reaches the store artwork. Capturing:
.context/ops/runbooks/store-listing.md.