From d07772a3d85c1b6a0f5295629fc298c5696b8e6e Mon Sep 17 00:00:00 2001 From: wtclaude Date: Thu, 10 Sep 2026 18:50:45 -0500 Subject: [PATCH] docs(modules): the cliloc conversion step IS avoidable now (phase 2 debt) SCHEMA.md's cliloc section still described the pre-protocol-8 world, two phases after phase 2 changed it. Three sentences said the same false thing, so fixing only the flagged one would have left the section arguing with itself: - "Sourced from files the operator supplies" -- the BASE comes from the shard on any install with uo-link configured; only the overlays are the filesystem's, and that asymmetry has a reason worth stating (ServUO has no server-side notion of a custom cliloc, so there is nothing to ask for). - "A base (the converted client table)" -- not converted any more. - "The conversion step is not avoidable ... so the shard cannot supply names on our behalf" -- it does supply them. Phase 2 ported UOFiddler's Mythic decompressor into the overlay precisely so nobody converts anything. Rewritten to say what is true and why the file path still exists (deprecated, not removed, so an existing install keeps working), plus the two things a reader of this table actually needs: `shard_cliloc_meta.payload` keeps the base's fingerprint under `base` SEPARATELY from the overlay hashes -- because on the bridge the old `clilocs.plain` label is supposed to disappear and one flat hash map would read that upgrade as a vanished source -- and boot does not import on the bridge path at all. Each claim checked against the code rather than from memory: shardClilocs.model.js:307 (`base: fingerprint`), :438-440 (refreshOnBoot returns `skipped` on the bridge), clilocSource.js:333 (`missingOverlays`). Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4 --- modules/uo/SCHEMA.md | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/modules/uo/SCHEMA.md b/modules/uo/SCHEMA.md index 5b9955c..7007dae 100644 --- a/modules/uo/SCHEMA.md +++ b/modules/uo/SCHEMA.md @@ -245,29 +245,49 @@ marketplace listing — but with no table to resolve it against, the character s | Table | Shape | |---|---| | `shard_clilocs` | `number` INT PK, `flag`, `text` TEXT | -| `shard_cliloc_meta` | Singleton (`id = 1`), `payload` JSON (source file, sha256, count, `parserVersion`), `imported_at` | +| `shard_cliloc_meta` | Singleton (`id = 1`), `payload` JSON (`source` — `bridge` or `file` — the base's fingerprint under `base`, the overlay `hashes`, per-source counts, `parserVersion`), `imported_at` | Import-owned and all-or-nothing in one transaction, same contract as the atlas — including **`DELETE`, not `TRUNCATE`**, for the same reason. -**Sourced from files the operator supplies**, at a path from the `cliloc_client_path` setting falling -back to `UO_CLIENT_PATH`. Nothing client-derived is committed: UO's strings are EA's, exactly as the -creature sprites are. A shard with nothing configured is fully supported — names render as ids. Full -design and operator guide: [`CLILOCS.md`](../../website/CLILOCS.md). +**The base table comes from the SHARD** on any install with uo-link configured (Protocol 8, phase 2): +it reads its own client's compressed `Cliloc.enu` and serves the table paged over the bridge, so +nothing is converted and nothing is copied to the web host. Without a shard link it falls back to a +converted file on disk at a path from the `cliloc_client_path` setting, then `UO_CLIENT_PATH` — the +pre-protocol-8 pipeline, deprecated rather than removed so an existing install keeps working. + +**Overlays are always the filesystem's**, either way: ServUO has no server-side notion of a custom +cliloc, so `custom/` is the only place shard-added ids exist and there is nothing on the shard to ask +for. That gap is in the *game*, not in this pipeline. + +Nothing client-derived is committed: UO's strings are EA's, exactly as the creature sprites are. A +shard with nothing configured is fully supported — names render as ids. Full design and operator +guide: [`CLILOCS.md`](../../website/CLILOCS.md). **It reads a SET of sources, not one file**, because shards edit items and add new ones and those -carry cliloc ids no stock client table has. A base (the converted client table) plus every overlay -under `custom/` are re-read on every boot and hash-gated **together**, exactly as the atlas re-reads +carry cliloc ids no stock client table has. A base (from the shard, or a converted file) plus every +overlay under `custom/` are hash-gated **together**, exactly as the atlas re-reads `Regions.xml` + `Locations/*.xml` + `Spawns/*.xml` + `ChampionSpawns.xml`. Later sources win, so an overlay both adds ids and overrides stock ones, and adding one custom item never means re-exporting a 5 MB client file. Scale, measured on the live shard: its script tree references 16,434 cliloc ids and only 37 are absent from stock — tens of entries against a 67k base, which is why this is an overlay and not a second table. -The conversion step is not avoidable: **every current client ships its cliloc files compressed** -(first DWORD's high byte `0x8E`), and ServUO's own bundled `Ultima.StringList` cannot read that -either — so the shard cannot supply names on our behalf. The plain layout and a delimited text export -are both accepted, sniffed by header rather than extension. +**The conversion step used to be unavoidable, and is not any more.** Every current client ships its +cliloc files compressed (first DWORD's high byte `0x8E`) and ServUO's own bundled +`Ultima.StringList` cannot read that either — which is why, for two protocol versions, the operator +had to install UOFiddler, build a converter against its `Ultima.dll` and copy a 5 MB file to the web +host. Protocol 8 phase 2 ported the Mythic decompressor into the overlay, so **the shard reads its +own client and supplies the names**. The file half survives only as the fallback above, where the +plain layout and a delimited text export are both accepted, sniffed by header rather than extension. + +Two consequences for what this table holds. `shard_cliloc_meta.payload` carries the base's +fingerprint under `meta.base` (the shard's file size, mtime, hash and `EXTRACTOR_VERSION`) separately +from the overlay hashes, because on the bridge the old `clilocs.plain` label is *supposed* to +disappear and a single hash map would read that upgrade as a vanished source. And **boot does not +import on the bridge path**: a file could be re-hashed locally on every restart, but asking the shard +would put a sidecar round trip in the boot sequence for a table that changes only when an operator +patches their client. Importing is an admin action. Three decisions worth stating: