Skip to content

Claude/eager cray 2n42az - #4

Open
matthewcodergamer wants to merge 6 commits into
weliveinhell:masterfrom
matthewcodergamer:claude/eager-cray-2n42az
Open

matthewcodergamer wants to merge 6 commits into
weliveinhell:masterfrom
matthewcodergamer:claude/eager-cray-2n42az

Conversation

@matthewcodergamer

Copy link
Copy Markdown

No description provided.

The web build could not start on an iPhone, and even where it started
there was no way to move: iOS has no keyboard and no Pointer Lock.

Startup blockers:

- INITIAL_MEMORY=2047mb is a single upfront WebAssembly.Memory
  reservation that mobile Safari refuses outright. Start at 512mb and
  grow to the same 2047mb ceiling instead. Memory limits and the thread
  pool size are now overridable via EM_* environment variables.
- PTHREAD_POOL_SIZE=8 with POOL_SIZE_STRICT=2 hard-aborts on a device
  with fewer cores. Size the pool from navigator.hardwareConcurrency and
  downgrade strictness to a warning so extra threads spawn on demand.
- The page must be cross-origin isolated for SharedArrayBuffer, and
  nothing in the tree provided those headers. Add serve.py (a dev server
  that sends COOP/COEP and the right MIME types) and a _headers file for
  static hosts, plus per-server config in README-hosting.md.

Input and presentation:

- shell.html had no viewport meta at all, so iPhone Safari laid the page
  out at 980px and every touch coordinate reaching the engine was wrong.
  Add the viewport and web-app meta tags, suppress pinch/double-tap zoom,
  rubber-band scrolling and the long-press callout, handle safe-area
  insets and orientation changes, and size the canvas to a pixel budget
  rather than an iPhone's native 3x grid.
- Gate startup behind a "Tap to play" overlay. iOS only allows starting
  an AudioContext, entering fullscreen or locking orientation inside a
  real user gesture, so main() is held on a run dependency until then.
- Detect touch devices and pass +touch_enable 1, so the engine's existing
  on-screen controls come up. They default to off everywhere but Android,
  which is why there was no way to move. Also pass a device-appropriate
  -w/-h and +mat_picmip 2.
- Report failures on screen. A phone has no console, so unsupported
  browsers, missing cross-origin isolation, out-of-memory aborts and lost
  GL contexts now explain themselves instead of leaving a black page.
- iPhone Safari has no Element.requestFullscreen; hide the button there
  and point at Add to Home Screen, which does give a fullscreen window.

Bugs found along the way:

- A failed map chunk download left the engine thread parked forever in
  memory.atomic.wait32, because only the success path stored and notified
  the lock. Release it on failure too. A 404 was worse than a hang: it
  fired onload, and the error page was parsed as chunk data. Check the
  status and bounds-check every entry.
- touch.cpp built a zero-quad mesh from texture id 0 whenever no touch
  texture made it into the atlas, which is exactly what happens when the
  packed game data has no vgui/touch materials. Skip the atlas pass.
- touch.cpp cleared an stbrp_rect array using sizeof(stbrp_node), leaving
  each entry half initialised, and kept a stale touchTextureID after
  deleting the texture.
- An Error() call was missing the argument for its %s.
- Only request pointer lock where the browser actually supports it.
- repackage.js missed loose materials/vgui/touch/*.vtf, so touch buttons
  drew with the missing-material texture even when the files were there.

Note: not build-tested. No emsdk in this environment, so the C++ changes
are unverified by a compiler; the JS/HTML was exercised against a DOM
harness covering iPhone, Android, desktop and each failure mode.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qy5DKdwTqGQqScWvJyNcft
The CI artifact was the engine and nothing else, so "download release.zip
and open it" could never work: there is no game data in it, and opening
the page over file:// or any host that does not send COOP/COEP leaves it
without SharedArrayBuffer.

- Add fetch_chunks.py, which downloads the packed map chunks into
  <bundle>/chunks. It reads the map list out of pre.js rather than
  keeping a second copy that can drift.
- Ship serve.py, _headers, fetch_chunks.py and pre.js inside the bundle
  so the artifact is self-contained.
- Generate an index.html that points at hl2_launcher.html, so opening the
  bundle root works.
- Document the actual path from a push to a running game: download the
  artifact, fetch the chunks, serve it cross-origin isolated. Call out
  that GitHub Pages cannot host this, since it cannot set headers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qy5DKdwTqGQqScWvJyNcft
… worker

GitHub Pages cannot send Cross-Origin-Opener-Policy or
Cross-Origin-Embedder-Policy, so it could not host a threaded build at
all: no SharedArrayBuffer, no startup. A service worker can add those
headers to responses as they come in, which makes the page cross-origin
isolated on a host that has no header control.

- Add coi-serviceworker.js and load it from shell.html's <head>. The
  first visit registers it and reloads once; after that the page is
  isolated. It also sets Cross-Origin-Resource-Policy on what it passes
  through, so game data served from another origin is not rejected.
- Refuse to reload unless the attempt can be recorded in sessionStorage.
  Reading it throws in Safari private browsing, and a reload that cannot
  be remembered repeats forever. Both reload paths now go through one
  guarded helper, and the page reports why it gave up.
- Teach the capability gate the difference between "not isolated" and
  "isolation is one reload away", so a pending service worker shows
  progress instead of a fatal error, and a failed one says why.
- Add a Deploy to GitHub Pages workflow. It builds, optionally pulls the
  chunks when a CHUNKS_BASE_URL variable is set, and fails with a clear
  message if the site exceeds the 1GB Pages limit instead of letting the
  deploy fail on its own.
- Make the chunk location configurable with ?chunks=<url> or
  window.CHUNK_BASE_URL, since GitHub blocks files over 100MB and caps a
  Pages site at 1GB, which the full Portal data does not fit under. The
  engine can now be on Pages with the data hosted anywhere.
- Drop a .nojekyll into the bundle so Pages does not strip _headers.

Verified with a harness covering both halves of the worker: header
injection preserves body and content-type, only-if-cached passes through,
and every reload path stops after one attempt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qy5DKdwTqGQqScWvJyNcft
`zip -r out.zip *` skips dotfiles, so .nojekyll never made it into
release.zip. Anyone unzipping the artifact to deploy GitHub Pages by hand
would get a site where Jekyll strips files beginning with an underscore.
Zipping "." instead picks them up.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qy5DKdwTqGQqScWvJyNcft
iPhone Safari kills the page while compiling the largest side module,
so the size of each .so is the number that matters. Print them in CI
so changes to the link flags can be compared without a device.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qy5DKdwTqGQqScWvJyNcft
SIDE_MODULE=1 exports every symbol and therefore keeps every function
in each of the 24 side modules. The tree already compiles with
-fvisibility=hidden and marks its genuine exports DLL_EXPORT, which is
exactly the contract SIDE_MODULE=2 honours, so wasm-ld can now
garbage-collect unreferenced code per module.

iPhone Safari kills the page while compiling the largest module, so
the amount of code it has to compile is the constraint. CI prints the
per-module sizes to measure the effect.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qy5DKdwTqGQqScWvJyNcft
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.

2 participants