feat(doctor): the one host prerequisite the Asset Bridge added (Asset Bridge cutover, 4 of 5) #26

Merged
whitlocktech merged 2 commits from edge into main 2026-09-14 23:11:55 +00:00
Member

Step 4 of 5 of the Asset Bridge edge → main cutover (docs/link/v8.md §16 row 9b).

This repo was not in the 9b row, and had to be

The plan named four repos for the cutover — link, servuo-plugins, module-uo, website.
installer's edge carries phase 9a's doctor check (#25), and docs' SHARD_PREREQS.md on
main already says that check exists — it has said so since phase 1, before anything built it.
Leaving this repo out of the cutover leaves an operator-facing doc on main describing a check that
is not in any released binary. Org lead's call, 2026-09-14: five repos.

What the check is

ServUO targets net48, so a Linux shard host runs it under Mono, and Mono's System.Drawing is a
thin layer over libgdiplus — which §4.2 of the Asset Bridge design puts squarely in the decode
path. Without it a Linux host cannot read a sprite at all.

  • Linux only. There is no row on Windows or macOS rather than a row saying "not applicable" —
    a Windows host has genuinely nothing to check, and a checklist that pads itself with
    non-applicable rows on three quarters of its hosts teaches operators to skim it.
  • A , not a . Names and the spawn atlas have no pixels in them, so a host without
    libgdiplus still gets the cliloc table and the whole spawn atlas over the bridge; it is the art
    families that go dark. The note carries both package manager lines.
  • Detection is ldconfig -p plus the five real install paths across Debian/Ubuntu/Fedora/RHEL and
    /usr/local.

Worth recording alongside it: https://github.com/mono/libgdiplus was archived in March 2025
read-only and unmaintained upstream, though distros still package and patch it. That is the
long-term argument for moving off System.Drawing, and it is why phase 4's UOP animation reader was
written without it.

Bundle pairing already enforces §15's protocol contract, so nothing else here needed to move.

Verification

  • cargo fmt --check — clean
  • cargo clippy --all-targets -- -D warnings — clean
  • cargo test149 passed, 0 failed (140 + 9)

After the merge

Releases are cut from main on every push, so this publishes an installer release. That is the
point of including it: the check only reaches an operator as a released binary.

AI disclosure

Authored with Claude Code (Claude Opus 5). Commits carry the Co-Authored-By trailer.

🤖 Generated with Claude Code

https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4

Step **4 of 5** of the Asset Bridge `edge → main` cutover (`docs/link/v8.md` §16 row 9b). ## This repo was not in the 9b row, and had to be The plan named four repos for the cutover — `link`, `servuo-plugins`, `module-uo`, `website`. `installer`'s `edge` carries phase 9a's `doctor` check (#25), and `docs`' `SHARD_PREREQS.md` on `main` **already says that check exists** — it has said so since phase 1, before anything built it. Leaving this repo out of the cutover leaves an operator-facing doc on `main` describing a check that is not in any released binary. Org lead's call, 2026-09-14: five repos. ## What the check is ServUO targets `net48`, so a Linux shard host runs it under Mono, and Mono's `System.Drawing` is a thin layer over **libgdiplus** — which §4.2 of the Asset Bridge design puts squarely in the decode path. Without it a Linux host cannot read a sprite at all. - **Linux only.** There is no row on Windows or macOS rather than a row saying "not applicable" — a Windows host has genuinely nothing to check, and a checklist that pads itself with non-applicable rows on three quarters of its hosts teaches operators to skim it. - **A `⚠`, not a `✗`.** Names and the spawn atlas have no pixels in them, so a host without libgdiplus still gets the cliloc table and the whole spawn atlas over the bridge; it is the art families that go dark. The note carries both package manager lines. - Detection is `ldconfig -p` plus the five real install paths across Debian/Ubuntu/Fedora/RHEL and `/usr/local`. Worth recording alongside it: **<https://github.com/mono/libgdiplus> was archived in March 2025** — read-only and unmaintained upstream, though distros still package and patch it. That is the long-term argument for moving off `System.Drawing`, and it is why phase 4's UOP animation reader was written without it. Bundle pairing already enforces §15's protocol contract, so nothing else here needed to move. ## Verification - `cargo fmt --check` — clean - `cargo clippy --all-targets -- -D warnings` — clean - `cargo test` — **149 passed, 0 failed** (140 + 9) ## After the merge Releases are cut from `main` on every push, so this publishes an installer release. That is the point of including it: the check only reaches an operator as a released binary. ## AI disclosure Authored with Claude Code (Claude Opus 5). Commits carry the `Co-Authored-By` trailer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
wtclaude added 2 commits 2026-09-14 22:57:41 +00:00
feat(doctor): the one host prerequisite the Asset Bridge added (Phase 9a)
All checks were successful
PR Checks / rust-gates (pull_request) Successful in 1m39s
ead105d5bf
`libgdiplus`, on Linux hosts only. ServUO targets net48, so on Linux it runs
under Mono, and Mono's `System.Drawing` is a thin layer over that library -- which
sits in the DECODE path, not merely the encode: `Ultima.Frame` writes ARGB1555
through a LockBits pointer, so without it the shard cannot read one sprite out of
the operator's UO client.

docs/link/v8.md §17.2 took all three answers to this rather than one -- the
prerequisite in SHARD_PREREQS.md, a named NO_IMAGING status instead of an error,
and a `doctor` check. The first two shipped in phase 1. This is the third, and
SHARD_PREREQS.md has been claiming it existed since then.

Three things about the row are deliberate:

- **Linux only, and absent elsewhere.** A Windows host ships System.Drawing with
  .NET Framework and has nothing to check, so there is no row rather than a row
  saying "not applicable" on three quarters of the hosts that run this.
- **A warning, never a failure.** Names and the shard's own spawn files have no
  pixels in them, so a host without this library still runs a useful bridge, and
  `doctor`'s exit code -- which monitoring reads -- must not go red over one
  absent feature.
- **`ldconfig -p` first, paths second.** The loader's own cache is the same
  question Mono asks at runtime, so a distro that puts the file somewhere unusual
  answers correctly; the path probe is the fallback for a slim container with no
  ldconfig, and a missing ldconfig degrades to it rather than taking doctor down.

The verdict is split from the detection so the mark and the wording are testable
on a host that has the library and one that does not; all three tests are
Linux-gated, which is where CI runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4
Reviewed-on: #25
whitlocktech approved these changes 2026-09-14 23:11:48 +00:00
whitlocktech merged commit f865660c7c into main 2026-09-14 23:11:55 +00:00
Sign in to join this conversation.
No description provided.