Debug harness: loopback socket to pilot the client (screenshots + scripted checks) #122

Closed
opened 2026-07-21 23:08:00 +02:00 by marco · 0 comments
Owner

What

A DEBUG-only control channel on the client so the character can be piloted programmatically — for scripted checks and, above all, so the assistant can drive the client, exercise a visible feature and capture screenshots to attach to PRs.

Design (agreed)

  • DEBUG-only (#if DEBUG) — never compiled into a Release build. No backdoor.
  • Loopback TCP, line protocol. Binds 127.0.0.1 only. One command per line, each gets a OK ... / ERR ... response — drivable from a shell with nc / /dev/tcp. Request→response so a screenshot command ACKs only once the PNG is written (no read race).
  • Server-authoritative. The harness injects the same client intents as human input (MoveRequest, Say, …) and captures the framebuffer. It never fabricates server state; the server validates every action as usual.
  • Thread-safe. The socket listener runs off-thread; commands are queued and drained on the game's main loop; screenshot + intent injection happen on the main thread (needs GraphicsDevice).

MVP commands

login <user> (drives the login screen to reach in-world), goto <x> <y> / move <dir>, say <text>, open bag|doll|admin, screenshot <path>, status (self position / visible entities), hud on|off, help.

Also

Update the PR template + CLAUDE.md working agreement: for a visible change, the screenshot is produced by the assistant piloting the client via this harness (exercising the feature and attaching the shots + the steps run), not by the human.

Definition of Done

  • In a DEBUG client, connecting to 127.0.0.1:<port> and sending logingotoscreenshot <path> produces a PNG that shows the in-world scene at that position.
  • The screenshot command responds only after the file is written.
  • Every gameplay command results in the corresponding client intent reaching the server (verifiable: the move/say is reflected server-side), i.e. no state is faked client-side.
  • A Release build exposes no socket / debug listener (verifiable: the type is compiled out).
  • Command parsing is unit-tested (Client.Core).
  • The PR template + CLAUDE.md state the assistant-piloted screenshot process.

Scope refinement (validated by dry-running #121 + #117)

The harness needs synthetic input injection (mouse + keyboard), not just game-intent injection — otherwise it can drive gameplay but not the UI (gumps/chat), which is half our features. Full command set:

  • High-level: login <user>, goto <x> <y>, move <dir>, say <text>, open bag|doll|admin, screenshot <path>, status, help.
  • Input injection: click <x> <y>, rightclick <x> <y>, drag <x1> <y1> <x2> <y2>, type <text>, key <k> — overlays a synthetic InputState so gumps/chat react exactly as to a real mouse/keyboard.

Out of scope: hover effects and scroll-wheel injection (not needed for screenshots).

## What A **DEBUG-only** control channel on the client so the character can be piloted programmatically — for scripted checks and, above all, so the assistant can drive the client, exercise a visible feature and **capture screenshots to attach to PRs**. ## Design (agreed) - **DEBUG-only** (`#if DEBUG`) — never compiled into a Release build. No backdoor. - **Loopback TCP, line protocol.** Binds `127.0.0.1` only. One command per line, each gets a `OK ...` / `ERR ...` response — drivable from a shell with `nc` / `/dev/tcp`. Request→response so a `screenshot` command ACKs only once the PNG is written (no read race). - **Server-authoritative.** The harness injects the *same client intents* as human input (`MoveRequest`, `Say`, …) and captures the framebuffer. It never fabricates server state; the server validates every action as usual. - **Thread-safe.** The socket listener runs off-thread; commands are queued and drained on the game's main loop; screenshot + intent injection happen on the main thread (needs `GraphicsDevice`). ### MVP commands `login <user>` (drives the login screen to reach in-world), `goto <x> <y>` / `move <dir>`, `say <text>`, `open bag|doll|admin`, `screenshot <path>`, `status` (self position / visible entities), `hud on|off`, `help`. ## Also Update the PR template + `CLAUDE.md` working agreement: for a visible change, the screenshot is produced by the assistant **piloting the client via this harness** (exercising the feature and attaching the shots + the steps run), not by the human. ## Definition of Done - In a **DEBUG** client, connecting to `127.0.0.1:<port>` and sending `login` → `goto` → `screenshot <path>` produces a PNG that shows the in-world scene at that position. - The screenshot command responds only **after** the file is written. - Every gameplay command results in the corresponding client intent reaching the server (verifiable: the move/say is reflected server-side), i.e. no state is faked client-side. - A **Release** build exposes **no** socket / debug listener (verifiable: the type is compiled out). - Command parsing is unit-tested (Client.Core). - The PR template + `CLAUDE.md` state the assistant-piloted screenshot process. --- ### Scope refinement (validated by dry-running #121 + #117) The harness needs **synthetic input injection** (mouse + keyboard), not just game-intent injection — otherwise it can drive gameplay but not the UI (gumps/chat), which is half our features. Full command set: - **High-level:** `login <user>`, `goto <x> <y>`, `move <dir>`, `say <text>`, `open bag|doll|admin`, `screenshot <path>`, `status`, `help`. - **Input injection:** `click <x> <y>`, `rightclick <x> <y>`, `drag <x1> <y1> <x2> <y2>`, `type <text>`, `key <k>` — overlays a synthetic `InputState` so gumps/chat react exactly as to a real mouse/keyboard. **Out of scope:** hover effects and scroll-wheel injection (not needed for screenshots).
marco closed this issue 2026-07-22 06:00:56 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marco/IsoMmo#122
No description provided.