# ScummVM adventure port

**Status:** Phase 0 complete and Phase 1 adapter started. Engine pinned; data-free
Emscripten build verified for two engine families; shared adapter, detection
generator, engine session, and bring-your-own-data host implemented; adapter and
session pass the shared conformance suite. Test-channel catalog records and
packaging are scaffolded but nothing is deployed.
**Roadmap:** [`ROADMAP.md`](ROADMAP.md)
**Feasibility:** [`docs/engineering/SCUMMVM_ADVENTURE_PORT_FEASIBILITY.md`](../../docs/engineering/SCUMMVM_ADVENTURE_PORT_FEASIBILITY.md)
**Phase 0 audit:** [`docs/engineering/SCUMMVM_PHASE0_AUDIT.md`](../../docs/engineering/SCUMMVM_PHASE0_AUDIT.md)

ScummVM is a multi-engine adventure interpreter, so this port is structured as
**one `portId` (`scummvm`) hosting many `gameId`s**, sharing a single pinned
engine artifact. The first targets are:

| Game | `gameId` | Engine | ScummVM game ID |
| --- | --- | --- | --- |
| The Secret of Monkey Island | `monkeyisland` | `scumm` (SCUMM v5) | `monkey` |
| Space Quest III: The Pirates of Pestulon | `spacequest3` | `sci` (SCI0) | `sq3` |
| Monkey Island 2: LeChuck's Revenge | `monkeyisland2` | `scumm` (SCUMM v5) | `monkey2` |

## Layout

```text
ports/scummvm/
  upstream.lock.json             # pinned tag/commit/archive/file hashes (empty patch stack)
  engine/sdl3.pc                 # shim: the Emscripten SDL3 port ships no .pc
  adapter/
    adapter.js                   # GameAdapter factory for every scummvm gameId
    scummvm-install.js           # partial-hash profiles, validation, pure-JS MD5
    generated-detection.json     # profiles generated from the pinned tables
    scummvm-fixture.js           # data-free synthetic fixtures
    adapter.test.cjs             # shared conformance + unit tests
  platform/
    scummvm-input.js             # action -> key / pointer mapping
    scummvm-session.js           # ScummvmWasmSession (EngineSession)
    scummvm-storage-provider.js  # browser IndexedDB StorageProvider
    unzip.js                     # bounded ZIP reader for BYOD import
    scummvm-session.test.cjs
    scummvm-integration.test.cjs # SessionHost + adapter end to end
  platform-host/
    index.html, host.css, host.js, manifest.json   # BYOD import + launch host
  scripts/
    resolve-upstream.mjs         # clone at the pinned tag and fail closed
    build-wasm.sh                # data-free Emscripten build (sci + scumm)
    gen-detection.mjs            # emit adapter profiles from the pinned tables
    package-runtime.mjs          # assemble the test-channel routes + source
  ROADMAP.md
```

## Build

```bash
node ports/scummvm/scripts/resolve-upstream.mjs
node ports/scummvm/scripts/gen-detection.mjs
bash ports/scummvm/scripts/build-wasm.sh
```

Requires the repository's pinned Emscripten SDK (`clients/web/.cache/emsdk-sdk`),
plus GNU make and `pkg-config` on `PATH`. The verified Phase 0 build produced a
data-free `scummvm.js` + `scummvm.wasm` restricted to the `sci` and `scumm`
engines; see [`upstream.lock.json`](upstream.lock.json) for artifact hashes.

## Tests

```bash
node --test ports/scummvm
```

Covers the shared adapter conformance suite for all three games, partial-hash
profile recognition (including the verified Phase 0 data when the ignored cache
is present), the engine session input/save behaviour, and a `SessionHost`
end-to-end launch/flush/checkpoint.

## Runtime seam (Phase 0 findings)

- The engine's compiled `DATA_PATH` is `/data`, served by the emscripten HTTP
  filesystem with a per-directory `index.json` (the upstream
  `dists/emscripten/build-make_http_index.py` format). No game data is preloaded.
- The launcher is bypassed with a `scummvm.ini` game domain (`path`, `gameid`,
  `engineid`) and launching the target by name.
- ScummVM's custom Emscripten shell pre-js overrides `Module.arguments` from the
  URL **hash**, so a host page passes CLI arguments as `#target` or
  `#--opt%20value`.

## Not yet done

Touch shell, settings surface, full in-engine save restore, packaging, notices,
legal review, third-party inventory, and catalog entries. See
[`ROADMAP.md`](ROADMAP.md).
