Skip to content

Research Brief Matpipe

LopeKinz edited this page Oct 1, 2026 · 2 revisions

Identity

Worker w-matpipe-a1; task matpipe; research/implement. Read .agent-cache/WORKER.md. Bus: python "%USERPROFILE%/.claude/skills/agent-cache-orchestrator/scripts/acbus.py" Parallel: w-meshfmt-a1, w-cmfmt-a1, w-entitypipe-a1, w-mapmanifest-a1. You own surfaces: material -> image -> texdb, end to end.

Objective

Close the visual loop: put a texture we authored onto a surface in a TNC map. 1462 image and 388 material entries per map, and the lookup key that used to block this was solved today.

Answer and deliver:

  1. The material payload format - how a material names its images and which slot is the albedo/diffuse.
  2. The TNC image payload (.bimage, BIM\x0e): can we author one, and in which pixel formats? Round-trip a retail image first.
  3. The full chain: author an image, write the matching .texdb rows, bind it through a material, so a named surface in a map would use our pixels.

What is already solved - do not redo it

  • The TexDB key is solved and master-verified today: key = ((entry+0x60 & 0x0FFF_FFFF_FFFF_FFFF) << 4) | (mip_base - mip_level), 25930/25930 across all 28 .texdb. The asset NAME does not enter the key. Read re_probes/agent_reports/texdbkey.md in full before you start - it also decoded the .bimage mip table (header 0x32 bytes, then 32-byte records: level, 0, w, h, raw_size, streamed/inline, stored_size, offset), and it establishes that MountDatabase checks only the magic and that a new chunk_N.resources auto-mounts its chunk_N.texdb.
  • Crucially it also says: entry+0x60 for images is assigned by the build tool and no reader recomputes it, so we may choose it freely - and 570 retail hashes are shared between image names, i.e. the engine itself deduplicates. Reusing a retail key gives retail pixels; own pixels need own texdb rows, written SORTED or the binary search fails.
  • Container writing is finished: wolfsdk/idclwrite.py, byte-exact round-trip.
  • Part 1 image code exists and is read-only for you: wolfsdk/bim.py, wolfsdk/image.py (BIM decode/encode, PNG in/out), tools/probe_texdb.py, tools/verify_image.py. Part 1 is BIM of a different version - check, do not assume.

Sources / starting points

  • re_probes/runtime_87400/module.bin - read-only capture of the RUNNING, unpacked executable (file offset == RVA, sections in manifest.json). The image/material loaders are in there; today's five wins all came from reading loaders rather than sweeping data.
  • docs/texdb.md, docs/virtualtextures.md, docs/ui-assets.md (part 1 image replacement already works there, image-export/image-import).
  • Retail corpus READ ONLY: /steamapps/common/Wolfenstein.II.The.New.Colossus
  • capstone 5.0.7 vendored: PYTHONPATH=re_probes/python_deps

Ownership

tools/probe_matpipe.py (new), re_probes/matpipe/ (new dir), re_probes/agent_reports/matpipe.md (new). Everything else read-only, including other workers' tools and dirs.

Forbidden / do not touch

No game launch, no process attach, no writes under the Steam install or "%USERPROFILE%/Saved Games". Do not edit wolfsdk/, docs/, config.json, tools/probe_texdbkey.py or any other worker's file. No pip install.

Hard constraints

Python 3.11, stdlib only (plus vendored capstone for disassembly). Reuse wolfsdk/oodle.py. No new image library - if a block-compressed format needs an encoder we do not have, say so rather than adding a dependency.

Acceptance criteria

  • material parser with a byte-exact round-trip, n/n over at least 200 retail materials across 3 archives.
  • image payload round-trip, n/n over at least 200 retail images, and the mip table cross-checked against the sizes the .texdb actually stores.
  • End-to-end demo: an authored image (a flat, unmistakable colour is ideal - it is obvious on screen and trivially verifiable) plus its texdb rows plus a material that points at it, all inside a container that passes probe_datahash n/n and probe_idclhash OK.
  • Negative controls: unsorted texdb rows, a key with the top nibble left unmasked, and a mip count that disagrees with the bimage header must each be caught by your checker.

Verification expectations

Nothing offline shows that a pixel reaches the screen. Say "structurally valid by these checks, rendering unconfirmed". Keep "the lookup will find our block" and "the GPU will decode it" strictly apart - the second depends on the pixel format, which is NOT yet established (texdbkey.md says so explicitly).

Failure honesty

If the pixel format turns out to be a block-compressed form we cannot encode without a new dependency, that is the answer: report which formats appear, with counts, and whether any uncompressed form is accepted. Part 1 has exactly this limitation documented - do not repeat its mistake of shipping an encoder whose output nobody ever looked at.

Coordination / deliverable

Checkpoint at milestones. Publish a bus fact when the image round-trip works - w-meshfmt-a1 needs materials for any authored geometry. Concise German report in re_probes/agent_reports/matpipe.md. Finish the bus task.

Clone this wiki locally