[rust] T6-2: Rust CODE panel (Compile/Run/Stop) inside the normal game UI, wired to al serve #38

Closed
opened 2026-09-22 21:09:14 +02:00 by sleepy · 1 comment
Owner

Goal

The end state is to play the game in the normal UI while writing Rust instead of JS (sleepy). The /rust-code page (T4-3) is a working PoC but a separate page; the real goal is a Rust CODE panel inside the normal game UI.

Model (why a separate process is correct, not a bug)

JS CODE evals in the browser page context. Rust CODE is a separate process that logs into the server on its own socket and drives the character (T3-4/T4-1). So: the browser is the viewer, the Rust process is the operator — the user watches the character move in the normal UI while the Rust loop (via al serve) drives it. Two clients on one character is the documented local behavior (see rust/dev/LOCAL.md).

Design (guidance, not a mandate)

  • The normal UI's CODE panel is .codeui, opened by toggle_code() (js/functions.js:2124) from the CODE button (htmls/index.html:201); it currently hosts the JS CodeMirror editor (the legacy flow — leave it working).
  • Add a Rust tab/section to that panel (or a second entry) that reuses the htmls/rust_code.html editor + log-pane logic and talks to al serve on 127.0.0.1:8192: Compile → POST /compile, Run → POST /run, Stop → POST /stop, log pane polls GET /status. The auth token never passes through the browser (al serve holds the creds, same as T4-3). al serve binds 127.0.0.1 only.
  • Reuse, don't fork: the Rust panel is the same client as /rust-code, embedded.

Acceptance

  • In the normal game UI (signed in as a local char), the Rust panel compiles, runs, and stops a crate that drives the signed-in character; the log pane streams the run; the character's movement is visible in the normal view.
  • The legacy JS CODE editor still works unchanged.
  • No Rust source or credential passes through the backend or the browser token.

File by orchestrator, 2026-09-22. Follows T4-3 (/rust-code PoC, main cc30aee).

## Goal The end state is to **play the game in the normal UI while writing Rust instead of JS** (sleepy). The `/rust-code` page (T4-3) is a working PoC but a *separate page*; the real goal is a Rust CODE panel **inside the normal game UI**. ## Model (why a separate process is correct, not a bug) JS CODE `eval`s in the browser page context. Rust CODE is a **separate process** that logs into the server on its own socket and drives the character (T3-4/T4-1). So: the **browser is the viewer**, the **Rust process is the operator** — the user watches the character move in the normal UI while the Rust loop (via `al serve`) drives it. Two clients on one character is the documented local behavior (see `rust/dev/LOCAL.md`). ## Design (guidance, not a mandate) - The normal UI's CODE panel is `.codeui`, opened by `toggle_code()` (`js/functions.js:2124`) from the `CODE` button (`htmls/index.html:201`); it currently hosts the JS CodeMirror editor (the legacy flow — **leave it working**). - Add a **Rust** tab/section to that panel (or a second entry) that reuses the `htmls/rust_code.html` editor + log-pane logic and talks to `al serve` on 127.0.0.1:8192: Compile → `POST /compile`, Run → `POST /run`, Stop → `POST /stop`, log pane polls `GET /status`. The **auth token never passes through the browser** (al serve holds the creds, same as T4-3). `al serve` binds 127.0.0.1 only. - Reuse, don't fork: the Rust panel is the same client as `/rust-code`, embedded. ## Acceptance - In the normal game UI (signed in as a local char), the Rust panel compiles, runs, and stops a crate that drives the signed-in character; the log pane streams the run; the character's movement is visible in the normal view. - The legacy JS CODE editor still works unchanged. - No Rust source or credential passes through the backend or the browser token. _File by orchestrator, 2026-09-22. Follows T4-3 (/rust-code PoC, main cc30aee)._
Author
Owner

T6-2 is implemented, tested and verified live in a real browser; PR #39 (task/38-in-game-rust-panel → main, mergeable) carries it, so I am leaving this issue for you to close on merge rather than closing it myself.

Acceptance, each one observed rather than inferred (full log in rust/PROGRESS.md, 2026-09-24 12:00):

  • JS/RUST tabs in the CODE panel — toggle_code() now opens a three-element .codeui group: tab strip, legacy #codeui, #rustcodeui. The JS editor is untouched and still engages (CodeMirror alive at 1118 chars, a snippet ran, runner frame up).
  • Rust pane mounts lazily — 0 requests to al serve at page load, no panel in the DOM at all; it appears on the first RUST click and stops polling when its tab or CODE closes.
  • ?serve= resolves correctly — endpoint chosen in the browser (data-endpoint → ?serve= → localStorage → window.AL_SERVE_DEFAULT_ENDPOINT → 127.0.0.1:8192); the game page renders no endpoint, no crate list and no source. The live run caught a real bug here (bb4b06a): js/game.js history.replaceStates the URL to /character/<name>/in/… on load, so location.search was empty by the time the lazy mount read it, and the panel silently polled the default :8192 — a different al serve, allow-list and character. Now the query is captured at script load.
  • Compile / Run / Stop of examples/hello against a local al serve (:8212, --creds rust/dev/.local): Finished release profile in 2.85s → Running · pid 2630111 · restarts 0 → the log pane streamed x 2.4 y -21.2 → x -11.0 y 98.1 → x -24.3 y 217.3 → stopped · clean exit (code 0), /status back to running:false pid:null.
  • the character visibly moved in the game UI — the browser played UserTesting and watched Rusty through the game's own observer (observe_character): (-20.7,185) moving=true → (-24.3,217.3) with the camera following; the server's store moved him 240 px, arrived=true. Two distinct characters on purpose: the server refuses a second live login for a character it still holds (msince(last_sync) < 120 → ex("ingame"), node/server.js:10911).

Two things from the pass worth your attention, both in the last PR comment:

  1. POST /compile writes its body to src/main.rs before cargo runs and refuses nothing, so an empty editor truncates the crate — that is T4-3's contract (#16), fixed in the client (ab0fd65) and still open in the endpoint. Companion fix in control.rs::compile whenever you want it.
  2. hello's toward-origin walk jails the character from some spawn points (and from jail every leg answers new_map), which is #17's jail-safe travel work, not a panel bug. It cost this verification two wasted runs.

Tests: panel suites 38/38, full node --test node/test/ 211/211, cargo fmt --check clean.

T6-2 is implemented, tested and verified live in a real browser; PR **#39** (`task/38-in-game-rust-panel` → `main`, mergeable) carries it, so I am leaving this issue for you to close on merge rather than closing it myself. Acceptance, each one observed rather than inferred (full log in `rust/PROGRESS.md`, 2026-09-24 12:00): - **JS/RUST tabs in the CODE panel** — `toggle_code()` now opens a three-element `.codeui` group: tab strip, legacy `#codeui`, `#rustcodeui`. The JS editor is untouched and still engages (CodeMirror alive at 1118 chars, a snippet ran, runner frame up). - **Rust pane mounts lazily** — 0 requests to `al serve` at page load, no panel in the DOM at all; it appears on the first RUST click and stops polling when its tab or CODE closes. - **`?serve=` resolves correctly** — endpoint chosen in the browser (`data-endpoint` → `?serve=` → localStorage → `window.AL_SERVE_DEFAULT_ENDPOINT` → `127.0.0.1:8192`); the game page renders no endpoint, no crate list and no source. The live run caught a real bug here (`bb4b06a`): `js/game.js` `history.replaceState`s the URL to `/character/<name>/in/…` on load, so `location.search` was empty by the time the lazy mount read it, and the panel silently polled the *default* :8192 — a different `al serve`, allow-list and character. Now the query is captured at script load. - **Compile / Run / Stop of `examples/hello` against a local `al serve`** (:8212, `--creds rust/dev/.local`): `Finished `release` profile in 2.85s` → `Running · pid 2630111 · restarts 0` → the log pane streamed `x 2.4 y -21.2` → `x -11.0 y 98.1` → `x -24.3 y 217.3` → `stopped · clean exit (code 0)`, `/status` back to `running:false pid:null`. - **the character visibly moved in the game UI** — the browser played UserTesting and watched Rusty through the game's own observer (`observe_character`): `(-20.7,185) moving=true` → `(-24.3,217.3)` with the camera following; the server's store moved him 240 px, `arrived=true`. Two distinct characters on purpose: the server refuses a second live login for a character it still holds (`msince(last_sync) < 120 → ex("ingame")`, `node/server.js:10911`). Two things from the pass worth your attention, both in the last PR comment: 1. `POST /compile` writes its body to `src/main.rs` *before* cargo runs and refuses nothing, so an empty editor truncates the crate — that is T4-3's contract (#16), fixed in the client (`ab0fd65`) and still open in the endpoint. Companion fix in `control.rs::compile` whenever you want it. 2. `hello`'s toward-origin walk jails the character from some spawn points (and from jail every leg answers `new_map`), which is #17's jail-safe travel work, not a panel bug. It cost this verification two wasted runs. Tests: panel suites 38/38, full `node --test node/test/` 211/211, `cargo fmt --check` clean.
Sign in to join this conversation.
No labels
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
sleepy/adventureland_mongodb#38
No description provided.