feat(asset-bridge): the transport, and the 357 wrong pictures it found #28
Reference in New Issue
Block a user
No description provided.
Delete Branch "feat/asset-bridge-p1"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Asset Bridge phase 1 (docs/link/v8.md §16). Sidecar half: RunicGateway/link#41.
Docs half: RunicGateway/docs#236.
The transport for protocol 8, plus phase 0's validator promoted into the overlay
and extended to animations — which is where the interesting part is.
357 of the 1,144 "decodable" bodies are wrong pictures, on a STOCK client
Phase 0 measured the art path and left the animation half unbuilt. It has the same
defect, and it is worse:
GetAnimationdecodes throughnew MemoryStream(m_StreamBuffer, false)— the whole shared buffer, not thelengthbytes just read into it — so a truncated or absent record does not even hitend-of-stream. It sails on into the previous animation's bytes.
Measured directly, because no count could tell:
lookup 22638982, length 0) straight after…The catalogue is 787 bodies, not 1,144. Importing the other 357 would have written
duplicate creature portraits into the site showing whichever body the walk decoded
before them.
The record walk refused 0 real bodies on the stock client — the false-refusal
measurement §4.5 says the boundary depends on.
And four of the twelve player bodies, not six
§5.2 listed the elf ghosts (607, 608) as decoding. Their index entry is
length 0;what came back was the elf female at her exact dimensions, because 606 is what the
walk decoded immediately before. Confirmed the same way — 607 after the dragon is
the dragon. Phase 4's UOP decoder now covers eight ids rather than six.
What is here
overlay/Scripts/Custom/Bridge/BridgeAssets.cs— the plane. Accepts on the Corethread, hands off to a dedicated asset worker, returns immediately. Three rules, all
answering a specific failure:
bridge.busy(425).Emit's queue is boundedin lines, so 10,000 queued 200 KB replies is 2 GB of shard memory; the bound that
holds is flow control, on the side where the memory is.
AssetBatchBytes, 512 KiB) under the sidecar's new 1 MiB cap. Thefactor of two is load-bearing: a page always admits its first item, so it may
overshoot by one, and the headroom is what makes that land on the wire.
reqId, no answer. An uncorrelated frame is an eventby definition, and §3.1 is why none of this may be one.
PageBuilder— one paging envelope (more/cursor/cut) for all five familiesthat will page, defined before the first one needs it.
cutmatters: "short page" hasthree meanings and only
endmeans finished.assets.sources— stage 1 of the import gate, its first user.BridgeAssetValidator.cs— promoted fromtools/, plusResolveAnimation(thenever-sweep-file-types rule as code, with no loop and no fallback),
AnimationRecordSaneand the frame walk.EXTRACTOR_VERSION,overlay.tomlprotocol 7 → 8,AssetsEnabled.Hashing had to come off the request path
§6's gate is (size, mtime) first, hash only when those differ. The first call has nothing
cached, so that still means hashing 1.06 GB — inside the sidecar's 10 s reply timeout it
does not fit. So hashes are computed on their own thread (deliberately not the single-slot
worker, which would answer every status poll
bridge.busyfor the whole pass) and thereply carries
hashing/complete.Measured on the real rig: first call instant with
sha256: null, second call 44 mswith every hash present.
Verified on the wire, not just compiled
Real ServUO 57.4 + the real sidecar + the real client.
GET /assets/sources→ 200,X-UOLink-Version: 8,imaging: {ok: true}, and §4.6's diagnostic firing on a liveclient:
artDataFile: artlegacymul.uop, withart.mulandartidx.mulboth carryingshadowedBy. Live events kept flowing through the new capped reader with no warnings.Not exercised live: the disabled-plane 403 and the busy 425 (both unit-tested on the
sidecar side; the shard halves are a config read and a lock).
🤖 Generated with Claude Code
https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4