diff --git a/.gitignore b/.gitignore
index 173ad59..24cbabf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,6 @@ android/local.properties
# editor leftovers
*.swp
*~
+
+# python leftovers
+__pycache__/
diff --git a/RELEASING.md b/RELEASING.md
index be3fbef..e749d2d 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -110,10 +110,22 @@ Separate from all of the above, and manual: upload the six files in
## If the screenshots need redoing
-`fastlane/metadata/android/en-US/images/phoneScreenshots/` holds five shots at
-1170×2532. They are generated from `public_html/index.html` itself with headless
-Chromium, not taken on a phone, so they can be regenerated exactly. Two traps if
-you do it by hand:
+```bash
+python3 tools/screenshots.py
+```
+
+That rewrites all five in
+`fastlane/metadata/android/en-US/images/phoneScreenshots/` at 1170×2532. They
+are rendered from `public_html/index.html` with headless Chromium, not taken on
+a phone, so they reproduce exactly — anything that changes the look of the app
+is a reason to re-run it.
+
+The script sets each scene by seeding `localStorage` before the app boots, so
+the app renders its own saved state rather than having the DOM poked from
+outside. Editing a scene means editing the `SCENES` table at the top.
+
+Three traps, all of which fail quietly, and all of which the script already
+handles — they are written down here because they cost an afternoon each:
- The capture lands whenever the virtual-time budget runs out, not when your
script finishes — so freeze the render loop (`requestAnimationFrame = () => 0`)
@@ -121,6 +133,10 @@ you do it by hand:
- CSS transitions don't advance under `--virtual-time-budget`, so a panel caught
mid-transition photographs in its *old* colour. Disable transitions in the
screenshot build.
+- Snap-confined Chromium cannot write into hidden directories — not `~/.cache`,
+ not any dot-directory, not the private `/tmp` it is handed. It fails with a
+ bare "Permission denied" and no hint as to why. Both the HTML it reads and the
+ PNG it writes have to sit in a plainly-named directory.
## Reference
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
index 4710270..030022a 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
index 9fa02ab..e6c0b56 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
index d0ce49e..a3c2a6e 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
index 59e40ad..31e197c 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png
index 4512acd..ea064ec 100644
Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png differ
diff --git a/public_html/index.html b/public_html/index.html
index 33c02db..362cd1e 100644
--- a/public_html/index.html
+++ b/public_html/index.html
@@ -14,16 +14,18 @@
+
+"""
+
+
+def find_chromium():
+ for name in CHROMIUM:
+ path = shutil.which(name)
+ if path:
+ return path
+ sys.exit("no chromium found; tried: " + ", ".join(CHROMIUM))
+
+
+def build_page(scene, source):
+ """A copy of the app with the scene seeded and the render loop pinned."""
+ seed = {
+ "bg.points": str(scene["cfg"]["points"]),
+ "bg.base": str(scene["cfg"]["base"]),
+ "bg.delay": str(scene["cfg"]["delay"]),
+ "bg.theme": scene["cfg"].get("theme", "sage"),
+ "bg.sound": "1",
+ }
+ if scene["game"] is not None:
+ seed["bg.game"] = json.dumps(dict(v=1, **scene["game"]))
+
+ html = source.replace("", SEED % json.dumps(seed) + "", 1)
+ html = html.replace("