A manifest and icons rendered from icon.svg make the app installable. The native build emits a service worker that precaches exactly the built files and passes everything else to the network, so ROMs never reach its cache. New versions wait for the player's Update, which saves before reloading. Savegames offers installation, iPhone steps and persistent storage, and a full disk gets its own save error. Acceptance on physical iPhone and Android devices remains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
37 lines
1.3 KiB
JavaScript
37 lines
1.3 KiB
JavaScript
// Renders public/icon.svg into the PNG icons the manifest and iOS need.
|
||
// Run after changing the SVG: node scripts/make-icons.mjs
|
||
import { readFileSync } from "node:fs";
|
||
import { chromium } from "@playwright/test";
|
||
|
||
const svg = readFileSync("public/icon.svg", "utf8");
|
||
// The maskable icon keeps the artwork inside the central safe zone (80 %).
|
||
const icons = [
|
||
{ file: "public/icon-192.png", size: 192, inset: 0 },
|
||
{ file: "public/icon-512.png", size: 512, inset: 0 },
|
||
{
|
||
file: "public/icon-maskable-512.png",
|
||
size: 512,
|
||
inset: 0.1,
|
||
background: "#102b2a",
|
||
},
|
||
{
|
||
file: "public/apple-touch-icon.png",
|
||
size: 180,
|
||
inset: 0.06,
|
||
background: "#102b2a",
|
||
},
|
||
];
|
||
|
||
const browser = await chromium.launch();
|
||
const page = await browser.newPage();
|
||
for (const { file, size, inset, background } of icons) {
|
||
await page.setViewportSize({ width: size, height: size });
|
||
const pad = size * inset;
|
||
await page.setContent(
|
||
`<body style="margin:0;background:${background ?? "transparent"}"><div style="padding:${pad}px;width:${size - 2 * pad}px;height:${size - 2 * pad}px">${svg.replace("<svg ", '<svg width="100%" height="100%" ')}</div></body>`,
|
||
);
|
||
await page.screenshot({ path: file, omitBackground: !background });
|
||
console.log(`${file} ${size}×${size}`);
|
||
}
|
||
await browser.close();
|