# OpenQ4 WebAssembly port

This directory contains the browser platform work for OpenQ4. The first
milestone is an assetless OpenQ4 client reaching its event loop and WebGL
context. The playable milestones then add, in order:

1. OpenQ4 SP linked for WebAssembly with the D3Wasm GLES/WebGL renderer.
2. Revisioned, chunked PK4 import into origin-private browser storage.
3. OpenQ4 MP client networking over binary WebSocket to the gateway UDP bridge.
4. Touch/gamepad input, save persistence and production shell integration.

SP and MP use separate OpenQ4 WebAssembly main modules and separate GameLib
WebAssembly side modules. Selecting a mode reloads the page with the matching
pair. The loader verifies the selected side module against the manifest,
stages it under `/baseoq4` in WasmFS, and the engine loads it through the same
`dlopen`/`GetGameAPI` boundary used by native OpenQ4.

`tools/build-wasm.sh --clean --jobs 4` is the canonical build. It authenticates and
materializes the pinned OpenQ4 and OpenQ4-GameLibs inputs into `build/wasm-src` (the
public source offer uses a separately pinned, sanitized OpenQ4 export), applies the
tracked native/Web patch series, and configures two isolated Meson build directories.
The script rejects a compile graph where the SP artifact does not
use `src/game`, where the MP artifact does not use `src/mpgame` with
`GAME_MPAPI`, where the engines are not Emscripten `MAIN_MODULE`s, where the
GameLibs are not `SIDE_MODULE`s exporting `GetGameAPI`, or where the SP and MP
side modules are identical.

A successful build publishes only these frozen build artifacts; each retains its
applicable license:

```text
engine/openq4-sp.mjs
engine/openq4-sp.wasm
engine/openq4-mp.mjs
engine/openq4-mp.wasm
engine/game-sp_wasm.wasm
engine/game-mp_wasm.wasm
engine/engine-manifest.json
engine/build-info.txt
engine/SHA256SUMS
```

The manifest maps `singleplayer` to the SP artifact and both `multiplayer` and
`replay` to the MP artifact and matching MP GameLib. It records content hashes
for every script, engine WASM, and GameLib side module. Intermediate source and
object trees stay under ignored `build/` paths.

OpenQ4 and OpenQ4-GameLibs retain their respective upstream licenses. Keeping
the Emscripten modules dynamically separated mirrors the native architecture;
it does not by itself determine license compatibility or redistribution rights.

The public site must not contain retail PK4s or unproven upstream media. Its shared
`fs_cdpath` contains only deterministic self-authored CC0 minimal runtime packs and
approved CC0 addons. Full content resolves through `fs_basepath` from a
player-supplied GOG/Steam installation. Local E2E may use the owner's verified GOG
copy under `assets-src/gog`.
