docs(issues): #37 — Investigation 2 narrows bug to SubPalette coverage gaps
Five parallel agents + dat probes ruled out: - byte-level decode primitive (matches ACViewer) - polygon emission (no ST_DOUBLE / Surface.Type & 6 issues) - per-PART texture-override scoping (correctly per-MeshRef'd) - SubPalette indexing convention (full-size 2048 palettes, *8 wire un-pack is single-applied) Smoking gun: for +Acdream the server sends 10 SubPaletteSwap ranges that overlay palette indices [0..320), [576..1024), [1392..1488), [1728..1920). The complement — [320..576), [1024..1392), [1488..1728), [1920..2048) — is NOT overlaid. Base palette 0x0400007E at those indices has red/skin tones. Coat texture UVs sampling those non-overlaid indices render as visible "skin stub at top of coat". Either ACE sends incomplete SubPaletteSwap data, or retail does extra client-side ClothingTable computation we (and ACE) don't. Diagnostic harness now lives at tools/InspectCoatTex/Program.cs; GameWindow's DUMP_CLOTHING also probes runtime SubPalette dat sizes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a3f53c2644
commit
5937ebe1c5
3 changed files with 368 additions and 16 deletions
|
|
@ -310,22 +310,35 @@ What we confirmed (data is correct):
|
|||
matches ACME's `StaticObjectManager.cs:256-258` and retail decomp's
|
||||
`Frame::combine` at `0x00518FD0`.
|
||||
|
||||
**Remaining hypothesis space (untested):**
|
||||
**Investigation 2 (2026-05-04, 5 parallel agents + dat probes):**
|
||||
|
||||
1. **Texture decode produces skin pixels** for `0x05001AFE/0x05001AFC`
|
||||
where ACME / retail produces coat pixels. Compare our SurfaceDecoder
|
||||
against ACME's `TextureHelpers.cs` for INDEX16 / palette-indexed
|
||||
chains.
|
||||
2. **Polygon-to-surface mapping off-by-one.** Specific polygons of
|
||||
part 9 reference an unintended surface. Add a dump: for each polygon
|
||||
in gfx 0x0100120D, print `PosSurface` index + the resolved Surface id.
|
||||
3. **Multi-layer texture composition retail does and we skip.** AC's
|
||||
"ApplyCloth" or similar layered texture step. Grep
|
||||
`acclient_2013_pseudo_c.txt` for `BlendBaseLayer`, `LayerSurfaces`,
|
||||
any composition method that combines multiple textures into one.
|
||||
4. **UV mapping bug.** Part 9's polygon UVs map to a skin region of
|
||||
the coat texture. Dump per-vertex UV vs vertex Z; if a high-Z vertex
|
||||
has UV.v near a skin region, that's the source.
|
||||
ALL of the obvious hypotheses ruled out:
|
||||
|
||||
- **Byte-level decode primitive matches ACViewer.** INDEX16/P8/DXT/BGRA paths are byte-identical.
|
||||
- **Polygon emission matches retail.** All 43 polygons of gfx `0x0100120D` are `SidesType=0` (ST_SINGLE), all surfaces are `Base1Image` — NO ST_DOUBLE polygons we'd be missing, NO surfaces lacking the `Type & 6` bits that retail's `DrawPolyInternal` skips.
|
||||
- **Per-PART texture-override scoping is correct.** `resolvedOverridesByPart[partIdx]` gets per-MeshRef'd; not a global flat map (Agent 3's claim was wrong).
|
||||
- **SubPalettes are full-size (Colors.Count=2048) palettes.** Our `subPal.Colors[idx]` indexing matches ACViewer's `newPalette.Colors[j + offset]`.
|
||||
- **The `*8` wire un-pack is correctly single-applied** (parser stores raw bytes; ComposePalette multiplies once).
|
||||
|
||||
**The actual smoking gun (Investigation 2):**
|
||||
|
||||
For `+Acdream` the server sends 10 SubPaletteSwap ranges that overlay palette indices:
|
||||
`[0..320)`, `[576..1024)`, `[1392..1488)`, `[1728..1920)`. **The complement — indices `[320..576)`, `[1024..1392)`, `[1488..1728)`, `[1920..2048)` — is NOT overlaid.** Base palette `0x0400007E` at those indices contains the original red/skin tones (sampled values: `0x46 0x22 0x04`, `0x4A 0x28 0x09`, etc).
|
||||
|
||||
If the coat texture's UVs at the upper region map to texel-bytes whose palette index lands in one of those non-overlaid ranges, those pixels render with base-palette skin tones. That's the visible "skin stub at the top of the coat".
|
||||
|
||||
**Working hypothesis:** either
|
||||
1. ACE sends incomplete SubPalette ranges (retail-original would cover the full palette)
|
||||
2. Retail does *additional* client-side compute that ACE pre-resolves wrongly
|
||||
3. The base palette `0x0400007E` itself is supposed to have coat colors at those indices in retail's interpretation (different palette decode)
|
||||
|
||||
**Next investigation (deferred):**
|
||||
|
||||
- Diff ACE's `WorldObject_Networking.cs` CharGen ObjDesc construction against retail's
|
||||
`ClothingTable::BuildObjDesc` (`acclient_2013_pseudo_c.txt:436261`). Check if ACE
|
||||
actually walks every CloSubPaletteRange in the chosen PaletteTemplate, or skips some.
|
||||
- RenderDoc capture: confirm which texel/palette-index the upper-region polygons sample.
|
||||
- `tools/InspectCoatTex/Program.cs` is the diagnostic harness — extend it.
|
||||
|
||||
**Files (diagnostic env vars committed for next-session reuse):**
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue