Skip to content

Make Duo DS an installable PWA with an Aleph Void icon, and run the threaded core - #2

Merged
nstarke merged 2 commits into
mainfrom
claude/eloquent-brahmagupta-k1aod9
Oct 28, 2026
Merged

nstarke merged 2 commits into
mainfrom
claude/eloquent-brahmagupta-k1aod9

Conversation

@nick-alephvoid

Copy link
Copy Markdown

What this adds

Installable app

  • duo/manifest.webmanifest: name "Duo DS", fullscreen display, any orientation, dark background/theme colour, icons.
  • duo.html links the manifest, an SVG/PNG favicon and the Apple touch icon, and sets the home-screen title.

App icon

The Aleph Void mark (ℵ₀) in white on a two-tone Nintendo-red clamshell, with a dark hinge line across the middle.

  • icon.svg uses glyph outlines taken from FreeSerif, which matches the aleph in the GitHub avatar, so it doesn't depend on any font.
  • PNGs: icon-192, icon-512, icon-maskable-512 (logo kept inside the maskable safe zone), apple-touch-icon (180, opaque) and favicon-32.

Service worker (duo/sw.js)

  • Caches the app shell for offline use. Pages and scripts load network-first with a cache fallback; the large .data core files load cache-first and refresh in the background.
  • Adds Cross-Origin-Opener-Policy / Cross-Origin-Embedder-Policy headers. GitHub Pages can't send these itself, and they're what makes the page cross-origin isolated so SharedArrayBuffer is available.
  • On the first visit the page reloads once when the worker takes over, so it becomes isolated.

Performance

The live site is already a release build: minified emulator.min.js and the prebuilt optimized melonDS core. When the page is cross-origin isolated it now:

  • loads the multi-threaded melonDS build (melonds-thread-wasm.data, which the deploy already copies), and
  • enables melonDS's Threaded Software Renderer, which moves DS 3D rendering off the main emulation thread.

Add ?threads=0 to the URL to force the single-threaded build and compare on a device.

⚠️ One workflow line needed

The service worker must be served from the site root to control the page. My credentials can't edit workflow files, so please add this line to the "Assemble site" step in .github/workflows/duo-pages.yml, right after cp -r duo _site/duo:

          cp duo/sw.js _site/sw.js

Without it, the app still installs from the manifest, but there is no offline support and no threaded core (the page falls back to single-threaded as it does today).

Testing

Headless Chromium, mobile viewport, site assembled the same way as the deploy workflow plus the line above:

  • First visit reloads once, then crossOriginIsolated === true and SharedArrayBuffer is available.
  • The manifest parses with no errors, and Chrome reports no installability errors.
  • Loading a homebrew .nds requests melonds-thread-wasm.data, EJS_threads is on, the threaded renderer is enabled, and the game renders across the fold as before.
  • After going offline, reloading still serves the app from cache.

Not yet tested on a real iPhone. Safari supports cross-origin isolation and WebAssembly threads, but the actual speedup on an iPhone 16 needs checking on the device. Note that iOS Low Power Mode also caps frame rate.

Assisted-by: claude-opus-5-5


Generated by Claude Code

claude and others added 2 commits October 28, 2026 02:09
- Add a web app manifest so the page can be installed to the home screen
  and runs fullscreen.
- Add app icons built from the Aleph Void aleph-null mark on a red
  clamshell with a hinge line. The glyphs are FreeSerif outlines, so the
  SVG needs no font. PNGs cover 192/512, maskable, Apple touch and
  favicon sizes.
- Add a service worker that caches the app for offline use (network
  first, cores served cache first) and adds COOP/COEP headers. Pages
  can't set those headers itself, and cross-origin isolation is what
  allows SharedArrayBuffer.
- With isolation available, load the multi-threaded melonDS build and
  enable its threaded software renderer. ?threads=0 forces the
  single-threaded build for comparison.

The service worker has to be served from the site root. The deploy
workflow needs one added line to copy it there.

Assisted-by: claude-opus-5-5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013mySqFhLDykUTkvwZ3ZBZ4
Assisted-by: claude-opus-5-5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nstarke
nstarke merged commit 0d0b240 into main Oct 28, 2026
2 checks passed
@nstarke
nstarke deleted the claude/eloquent-brahmagupta-k1aod9 branch October 28, 2026 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants