# Minesweeper Minesweeper X, running under wine on a headless X display, streamed into an Officer panel. It is a game. It is also the smallest honest proof that Officer can put an arbitrary X11 program in a panel — a framebuffer, a process on it, a VNC server reading it, a client in the browser — and it is the first plugin to use the platform's per-plugin websocket relay. ## What it needs Six host binaries, declared in `manifest.ts` and checked before install: `wine`, `Xvfb`, `x11vnc`, `xdotool`, `xdpyinfo`, `winetricks`. The awkward one is wine. Minesweeper X is a **32-bit** PE (machine `0x014c`, Visual Basic 6), so the host needs i386 multiarch and a `win32` prefix. A 64-bit-only wine cannot load it, and the failure is a bare `Bad EXE format`. On Debian or Ubuntu: ``` sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine wine32:i386 xvfb x11vnc x11-utils xdotool winetricks ``` ## The game [Minesweeper X](https://minesweepergame.com/download/minesweeper-x.zip) — the competition build, with timing and replay extras. `game/Minesweeper X.exe` is committed; it is 68 KB and it is the thing being run rather than state produced by running it. | | | | --- | --- | | zip sha256 | `21089193924919ef876a5b464f06bed9cc149867c51e40c259288ebe623014f0` | | exe sha256 | `e414c207adaa14999b0464c3d0a701f20ed11282d5ed0f84b27b62d25389f661` | The download needs a browser `User-Agent`; the site answers `403` to curl's default. ## Where its state lives `DATA_PATH/minesweeper/` — never in this directory, which `plugins:update` will `git pull` over. - `prefix/` — the wine prefix, ~600 MB, built on first `POST /start`. Deleting it is the standard fix for a wedged wine, and it is safe: the next start rebuilds it. - `run/` — pid state, logs, and `vnc.sock`. **Mode 0700, and that is load-bearing.** ## Two things worth knowing before you change anything **x11vnc has no password, and that is correct.** It binds a unix socket inside `run/`, not a port. The kernel refuses every other account before x11vnc is asked anything, so a password would be a second lock on a door only one person can reach. The version this replaced bound `127.0.0.1:5907` with `-nopw`, which is a different claim entirely — every local account could open it and take the display. **The wine prefix is confined to `C:` on every start.** A fresh prefix maps the whole filesystem to `Z:` and symlinks the profile into the real home, and Minesweeper X has Open and Save dialogs for its replays. That is why this was an ungrantable `execution` capability in the platform. `sidecar/prefix.ts` closes it instead, which is what makes the plugin's permission safe to grant. Wine restores `z:` whenever it updates a prefix, so the confinement is re-asserted rather than done once. ## Contract ``` GET /api/minesweeper/status { installed, running, window, error? } POST /api/minesweeper/start idempotent; builds the prefix on a cold install (minutes) POST /api/minesweeper/stop /api/plugin-ws/minesweeper the display, as RFB ``` ## Where this came from Built first as a standalone directory, `officer-dev/wine-minesweeper`, and folded in here when it became a plugin. Two things from that work are worth keeping, because both are judgement calls somebody will otherwise make again from scratch. **Wine came from Ubuntu noble, not the WineHQ repository.** The distribution package is older — 9.0 — and that is fine for a 2017 VB6 application. The alternative was adding a third-party apt source, with its key and its update cadence, to a machine that runs a bitcoin wallet and a mail store, for a game of Minesweeper. If a future version genuinely needs newer wine, that trade is worth revisiting; until then it is not. **Enabling i386 pulled four krb5 libraries forward** within noble-updates. That was checked before installing rather than after: nothing moved near libc, systemd, openssl or postgres. Worth re-checking on any host where `dpkg --add-architecture i386` is new, since it is the one step here that changes how the whole machine resolves packages and is never undone by uninstalling the plugin. ### The original verification baseline From the standalone build, on Ubuntu noble with wine 9.0. Useful as a comparison when something feels wrong rather than as a test to run: - The game launches in about a second and draws the classic beginner board at **152x214**. - A synthetic `xdotool` click opens a region and starts the timer — so **input reaches the game**, which is the part that matters for a playable stream and the part a screenshot cannot tell you. - x11vnc completes an **RFB 003.008** handshake and reports an 800x600 32bpp framebuffer. - Cold start, display through to game window, in under two seconds. That excludes building the prefix, which happens once and takes minutes. The shell prototype that ran all this (`bin/session.sh`) is not kept. Everything it knew — waiting for a usable display rather than a live pid, parking the window at the origin, and clearing the whole wine process family on stop — is in `sidecar/session.ts`, with the reasoning attached to the code that depends on it.