# Master of Magic port

Bring *Master of Magic* (1994, Simtex) to the Ultimatum platform through the
[**ReMoM**](https://github.com/jbalcomb/ReMoM) C reconstruction, targeting the
desktop browser and iPad (iPad Safari; native iPad is a later, separate option).

**Status:** Phase 1. The adapter, engine-session bridge, browser session path,
touch-first shell, and a bring-your-own-data test route are runtime-verified. A
test-channel route is packaged and deployed to
`https://test.ultimatumproject.com/masterofmagic/`. See [`ROADMAP.md`](ROADMAP.md)
and the [feasibility document](../../docs/engineering/MASTER_OF_MAGIC_PORT_FEASIBILITY.md).

> **Licensing note.** ReMoM declares no license and is a
> disassembly/reassembly of the original v1.31 executable, so there's no
> redistribution grant to lean on. Keep it to the test channel / local demos
> rather than a public release unless the author's asked. The repository contains
> no original game data.

## Engine

ReMoM is C (C++17 for tests only) with CMake and a backend-neutral platform
contract at `platform/include/Platform.h`. It ships `sdl2`, `sdl3`, native
`win32`, and `headless` backends, and a scripted `HeMoM` scenario runner. It has
**no Emscripten/web target**, which is the decisive technical gap for this port.

Pin and hashes: [`upstream.lock.json`](upstream.lock.json).

## Resolve the engine

```sh
node ports/masterofmagic/scripts/resolve-upstream.mjs
```

This clones the pinned commit into `.cache/ports/masterofmagic/src` (ignored) and
verifies the commit and identifying-file hashes, then applies the patch stack.

## Game data

ReMoM is **engine-only** and requires an original Master of Magic **v1.31**
installation: all `.LBX` files plus `CONFIG.MOM` (optional). Supported editions
are bring-your-own-data. The engine embeds its own 101-file v1.31 `.LBX`
SHA-256 manifest; the port will cross-check independently captured hashes during
Phase 0.

## Known limitations

- **Tactical combat is not implemented in ReMoM yet.** The upstream
  [`doc/__TODO-Combat.md`](https://github.com/jbalcomb/ReMoM/blob/main/doc/__TODO-Combat.md)
  notes that the combat screen, map-build, unit-action, and draw subsystems are
  largely unreconstructed. Entering a battle shows a black screen with the
  combat music. This is an engine gap, not a port bug.

## Build

Toolchain: the repository's pinned Emscripten SDK (6.0.9), CMake 4.4.3, Ninja
1.13.2 under `clients/web/.cache`. Configure `.cache/ports/masterofmagic/build-wasm`
with `-DDISABLE_AUDIO=OFF` (SDL_mixer is linked for sound effects) and build the
`ReMoM` target. Artifact hashes are recorded in [`upstream.lock.json`](upstream.lock.json).

Audio: the web build enables SDL_mixer for sound effects (VOC->WAV). The
Emscripten SDL_mixer port has **no MIDI backend** (`MIDI support not available`),
so the engine hands its converted XMI->MIDI bytes to the host, which plays them
with a prototype WebAudio synth (`platform/remom-midi.js`).

## Platform integration

The port registers through the shared platform SDK:

- `adapter/adapter.js` — `GameAdapter` (descriptor, detection, exact-hash
  validation, mounts, render plan, actions, settings, save descriptor) plus a
  conformance fixture.
- `adapter/mom-install.js` and `adapter/lbx-manifest-v131.js` — recognition
  helpers and the reviewed v1.31 `.LBX` SHA-256 table.
- `platform/remom-engine-session.js` — browser `EngineSession` bridge: snapshot,
  semantic intent → SDL key/mouse translation, and `SAVE*.GAM` capture for the
  platform `SaveStore`.
- `platform/remom-storage-provider.js`, `platform/unzip.js`, and
  `platform/remom-midi.js` — IndexedDB install storage, ZIP import, and the
  prototype WebAudio MIDI synth.
- `platform-host/` and `scripts/qa-session-cdp.py` — a QA host that drives the
  real session path (launch → intents → checkpoint → restore) in headless
  Chrome over CDP.

```sh
node --test ports/masterofmagic/adapter/adapter.test.cjs ports/masterofmagic/platform/remom-engine-session.test.cjs
python3 ports/masterofmagic/scripts/qa-session-cdp.py
```

This includes the shared `runAdapterConformance` suite and the end-to-end
session-path check (`SESSION PATH: PASS`).
