feat: gump art reader + backpack container background (#19) #38

Merged
marco merged 3 commits from feat/gump-art into main 2026-07-18 04:41:07 +02:00
Owner

Partially addresses #19 (Phase A + a first Phase B/C pass).

Summary

Real UO gump art, starting with the backpack container background.

  • GumpMulReader decodes legacy gumpidx.mul/gumpart.mul (extra=(w<<16)|h; per-row DWORD lookups; (colour, count) RLE; ARGB1555 with transparent runs; no hue). Unit-tested against synthetic bytes (multi-row RLE — transparent run = alpha 0, coloured run = opaque — and null on an empty/absent entry).
  • gumps extractor command: gumps <client> [out] --range/--ids dumps gumps to PNG (discovery), or --map name=id packs them. Verified against the real client: 0x003C decodes to the UO backpack (230×204) — confirmed by eye.
  • Pack + client: the shipping pack includes gump/container_backpack; the client loads gump/ textures and InventoryPanel draws the real backpack art behind the grid, falling back to the plain panel when the pack is absent (repo stays shippable).

Gumps are pure client presentation — no protocol, no server, no authoritative state.

Scope / honest notes

  • Only the backpack id (0x003C) is confirmed and shipped. 0x07D0 turned out to be a decorative dragon frame, not the paperdoll — excluded. Finding the paperdoll frame + buttons (and a faithful UO layout — UO's paperdoll is a separate window; the backpack shows free-positioned items, not a grid) is the extend step; the gumps dump command is the tool (dumped PNGs can be inspected to identify ids).
  • The backpack art is currently stretched to the existing panel rect — a layout/coordinate polish pass follows once ids are confirmed.
  • The real targeting cursor gump is a separate follow-up (depends on #37; noted there).

How it was tested

GumpMulReader unit tests (synthetic multi-row RLE + null cases); dump verified against ~/Games/UO (0x003C = backpack, correct dimensions, visually the UO backpack). 209 tests green, zero warnings, CSharpier clean. assets.isoa repacked (38 anims).

Needs your eyes (GUI)

Open the inventory (I): the backpack should show the real UO backpack art behind the slots (with no pack, the plain panel). Tell me and I'll dump/identify the paperdoll frame + buttons next.

Checklist

  • just lint clean · [x] just test green (209) · [x] whole solution builds, 0 warnings · [x] multi-platform preserved · [x] tests added
Partially addresses #19 (Phase A + a first Phase B/C pass). ## Summary Real UO **gump art**, starting with the backpack container background. - **`GumpMulReader`** decodes legacy `gumpidx.mul`/`gumpart.mul` (`extra=(w<<16)|h`; per-row DWORD lookups; `(colour, count)` RLE; ARGB1555 with transparent runs; no hue). Unit-tested against **synthetic bytes** (multi-row RLE — transparent run = alpha 0, coloured run = opaque — and null on an empty/absent entry). - **`gumps` extractor command**: `gumps <client> [out] --range/--ids` dumps gumps to PNG (discovery), or `--map name=id` packs them. **Verified against the real client**: `0x003C` decodes to the UO backpack (230×204) — confirmed by eye. - **Pack + client**: the shipping pack includes `gump/container_backpack`; the client loads `gump/` textures and `InventoryPanel` draws the **real backpack art** behind the grid, **falling back** to the plain panel when the pack is absent (repo stays shippable). Gumps are pure **client presentation** — no protocol, no server, no authoritative state. ## Scope / honest notes - Only the **backpack** id (`0x003C`) is confirmed and shipped. `0x07D0` turned out to be a decorative dragon frame, **not** the paperdoll — excluded. Finding the paperdoll frame + buttons (and a faithful UO layout — UO's paperdoll is a separate window; the backpack shows free-positioned items, not a grid) is the **extend step**; the `gumps` dump command is the tool (dumped PNGs can be inspected to identify ids). - The backpack art is currently stretched to the existing panel rect — a layout/coordinate polish pass follows once ids are confirmed. - The real **targeting cursor** gump is a separate follow-up (depends on #37; noted there). ## How it was tested `GumpMulReader` unit tests (synthetic multi-row RLE + null cases); dump verified against `~/Games/UO` (0x003C = backpack, correct dimensions, visually the UO backpack). **209 tests green**, zero warnings, CSharpier clean. `assets.isoa` repacked (38 anims). ## Needs your eyes (GUI) Open the inventory (I): the backpack should show the **real UO backpack art** behind the slots (with no pack, the plain panel). Tell me and I'll dump/identify the paperdoll frame + buttons next. ## Checklist - [x] `just lint` clean · [x] `just test` green (209) · [x] whole solution builds, 0 warnings · [x] multi-platform preserved · [x] tests added
feat: gump art reader + backpack container background (#19)
All checks were successful
ci / Lint & Test (pull_request) Successful in 1m52s
839cc0c916
Phase A: GumpMulReader decodes legacy gumpidx/gumpart.mul (extra=(w<<16)|h,
per-row DWORD lookups, (colour,count) RLE, ARGB1555 with transparent runs),
unit-tested against synthetic bytes (multi-row RLE + null on empty/absent). An
AssetExtractor `gumps` command dumps gumps to PNG (discovery) or packs them via
--map. Verified against the real client: 0x003C decodes to the UO backpack.

Phase B/C (first pass): the pack build includes gump/container_backpack (0x003C,
the one confirmed id); the client loads gump/ textures and InventoryPanel renders
the real backpack art behind the grid, falling back to the plain panel when the
pack is absent. Gumps are pure client presentation — no protocol/server change.

Finding the remaining ids (paperdoll frame, buttons) + a faithful UO layout are
the extend step; the `gumps` dump command is the tool for it.
revert(client): drop the naive backpack-gump background
Some checks failed
ci / Lint & Test (pull_request) Failing after 2m13s
ffd519f214
Rendering the backpack gump stretched behind the opaque slot grid looked wrong —
the grid-on-backpack hybrid is the wrong shape (UO's backpack shows free-positioned
items; the paperdoll is a separate window). Back to the clean functional panel.
The gump reader/dump/pack pipeline and the loaded gump textures stay — an authentic
UO inventory/paperdoll UI is a dedicated follow-up.
feat(editor): preserve frame anchor on replace so gumps import correctly
All checks were successful
ci / Lint & Test (pull_request) Successful in 1m38s
f41e6cf08f
The asset editor already lists/previews/saves gump entries (single-frame
animations). The one gap: Replace-from-PNG hardcoded a bottom-centre anchor (the
actor default), which corrupted a gump's top-left anchor (and statics'/land's
centre). Keep the existing frame's anchor on replace instead — correct for every
category (gumps, statics, land, actors) with no per-category guessing. Docs updated.
marco merged commit 639c9292dd into main 2026-07-18 04:41:07 +02:00
marco deleted branch feat/gump-art 2026-07-18 04:41:07 +02:00
Sign in to join this conversation.
No reviewers
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!38
No description provided.