diff --git a/link/v8.md b/link/v8.md index 9c02333..2964ad7 100644 --- a/link/v8.md +++ b/link/v8.md @@ -1,7 +1,13 @@ -# Protocol 8 — Client assets over the bridge +# Asset Bridge (Protocol 8) — client assets without UOFiddler + +**Call it the Asset Bridge.** That is the name for this work everywhere — commits, PR titles, +branches (`feat/asset-bridge-p`), and conversation. The protocol number is **8** and this file is +`docs/link/v8.md`. **Status:** Design of record. Approved in principle 2026-09-09 (architecture, asset scope, -built-in cliloc decoder, atlas cleanup); §17 lists what is still open. +built-in cliloc decoder, atlas cleanup); refined 2026-09-10 (one direction not five, ServUO's own +decoders, the UOP reader for player bodies, the libgdiplus requirement). §17 lists what is still +open. **Supersedes the manual half of:** [`../website/UOFIDDLER.md`](../website/UOFIDDLER.md), [`../website/CLILOCS.md`](../website/CLILOCS.md) §Converting, [`../website/SPAWN_ATLAS.md`](../website/SPAWN_ATLAS.md) §Artwork and §Configuring the tree. @@ -181,8 +187,8 @@ Three costs come with it, all known and none of them blocking: not merely accepted: §4.3 adds a decoder for it**, because it is the player character and the scope says player models. 2. **`System.Drawing` is a hard dependency, in the decode and not just the encode.** `Frame` - writes ARGB1555 straight through a `LockBits` pointer, so a Linux/Mono shard needs libgdiplus - to read a sprite at all. See §17. + writes ARGB1555 straight through a `LockBits` pointer, so a Linux shard needs **libgdiplus** to + read a sprite at all. That is a stated prerequisite — §4.4. 3. **We inherit whatever `Ultima` a given ServUO vendors**, which can change under a shard upgrade. `EXTRACTOR_VERSION` (§7) is the mitigation: it already counts as drift, so a shard whose library changed re-derives on the next import. @@ -217,6 +223,47 @@ silently puts a spider on the gargoyle page, and no error is raised anywhere. A correct behaviour; a plausible wrong picture is the failure this protocol most needs to avoid, because nothing downstream can detect it. +### 4.4 Requirement: a Linux shard host needs libgdiplus + +**Stated prerequisite, not a soft recommendation.** ServUO targets `net48`, so on Linux it runs under +Mono, and Mono's `System.Drawing` is a thin layer over **libgdiplus**. §4.2 put `System.Drawing` in +the decode path, so without that library a Linux shard cannot extract art at all — the cliloc table +(§9) and the atlas files (§10) are unaffected, since neither touches pixels. + +**Windows shard hosts need nothing.** `System.Drawing` ships with .NET Framework. This is a +Linux-only prerequisite and most shards will never read this section. + +| Host | Get it with | +|---|---| +| Debian / Ubuntu | `sudo apt-get install libgdiplus` — in Debian since bullseye (6.0.4) and bookworm/trixie (6.1), and in Ubuntu universe | +| Fedora / RHEL | `sudo dnf install libgdiplus` (EPEL or the Mono repository) | +| Docker | `RUN apt-get update && apt-get install -y libgdiplus` in the shard image | +| Alpine, or a distro with no package | Build from source — see the repository below. This is the awkward case and is worth avoiding by choosing a Debian-based image | + +Upstream is , with the Mono project's own page at +. + +**One thing to know before depending on it: that repository was archived in March 2025 and is +read-only.** Distributions still package and patch it, so `apt-get install libgdiplus` is a normal, +supported thing to do today — but upstream is not maintained. It is the strongest long-term argument +for eventually moving extraction off `System.Drawing`, and phase 4's UOP reader (§4.3) is written +without it precisely so that door stays open. It does not change the decision now. + +**How its absence must present.** Never a stack trace and never a 500. Missing libgdiplus is a +named, actionable outcome in the same family as the cliloc reader's `COMPRESSED`: + +``` +status: unavailable +code: NO_IMAGING +reason: This shard host cannot render images — Mono's System.Drawing needs libgdiplus. + Install it (apt-get install libgdiplus) and re-run the import. Cliloc and + atlas import are unaffected. +``` + +The installer's `doctor` checks for it and reports it alongside its other host checks, so an +operator learns about this while setting the shard up rather than from an empty bestiary weeks +later. + --- ## 5. Addressing: one key for every asset @@ -556,8 +603,8 @@ disagree, so a split bump means the next bundle silently fails to compose. | `link/` | Six command families forwarded, the REST surface, **the inbound line cap (§3.3)**, `PROTOCOL_VERSION` | | `module-uo/` | Client calls, asset store, the atlas source backend (§10), cliloc ingest, admin surface | | `website/` | None expected — `ctx.uploads` already suffices (§12) | -| `docs/` | This file; rewrite `CLILOCS.md` §Converting and `SPAWN_ATLAS.md` §Artwork + §Configuring; **delete `UOFIDDLER.md`** | -| `installer/` | None expected; the bundle pairing already enforces §15 | +| `docs/` | This file; rewrite `CLILOCS.md` §Converting and `SPAWN_ATLAS.md` §Artwork + §Configuring; **delete `UOFIDDLER.md`**; add the libgdiplus prerequisite to `SHARD_PREREQS.md` (§4.4) | +| `installer/` | A `doctor` check for libgdiplus on Linux hosts (§4.4). Bundle pairing already enforces §15 | | `android-app/` | Consumes images by URL; no parity gate expected until a screen shows one | | `integration-kit/` | A chapter note only — this is UO-specific and teaches nothing about the module contract | @@ -592,18 +639,19 @@ because §4.3's whole point is that this failure mode produces confident, wrong --- -## 17. Decisions still open +## 17. Decisions + +Items 1–3 are settled and recorded here because each one changes numbers elsewhere in the document. +**Item 4 is the only thing still open, and it does not block starting.** 1. **§4: settled 2026-09-10 — call ServUO's vendored `Ultima`,** with one exception added the same day: **§4.3's UOP animation decoder**, scoped to the player bodies the legacy path cannot reach and to nothing else (phase 4). The crash is confined to the `hasExtra: true` branch that only `Gumps` reaches, and nothing here calls `Gumps`. -2. **§17.1's consequence: Linux/Mono shards.** §4.2 item 2 leaves `System.Drawing` in the decode - path, so a non-Windows shard needs **libgdiplus** installed or art extraction fails there. Three - ways to answer it, and this is the one real question left: document it as a prerequisite in - `SHARD_PREREQS.md` and let it fail loudly; have the installer's `doctor` detect and report it; - or fall back to no-art on that platform with a status the panel explains. Phase 0 should - establish which failure it actually is before we pick. +2. **§4.4: settled 2026-09-10 — libgdiplus is a stated requirement** on Linux shard hosts, with + all three answers taken rather than one: it goes in `SHARD_PREREQS.md`, the installer's `doctor` + checks it, and its absence degrades to a named `NO_IMAGING` status instead of an error. Windows + hosts are unaffected. 3. **§5.1/§5.2: direction — settled 2026-09-10.** Player character bodies use index 0, everything else index 1, direction is not in the key, and the player-body set is enumerated from `Race.AllRaces` rather than hardcoded. Nothing outstanding; recorded here because it changes