docs(issues): #37 humanoid coat doesn't extend up to neck (env-var diagnostics committed)

Filed as #37 after a ~3 hr investigation that ruled out animation source,
backface culling/winding, palette overlay, and head-GfxObj polygons.

Confirmed:
- Stub is from part 9 (upper torso/coat) post-AnimPartChange (gfx 0x0100120D)
- Part 9's both surfaces ARE matched by our 2 TextureChanges
- Server data complete; composition formula matches ACME + retail decomp

Untested hypothesis space (next session):
- Texture decode chain (compare our SurfaceDecoder vs ACME TextureHelpers)
- Polygon-to-surface index off-by-one on part 9
- Multi-layer texture composition AC may do
- UV mapping bug

Diagnostic env vars committed to source for next-session reuse:
- ACDREAM_HIDE_PART=N — hide specific humanoid part to localize bugs
- ACDREAM_NO_CULL=1 — disable backface culling
- ACDREAM_DUMP_CLOTHING=1 — dump APC + TC + per-part Surface chain coverage

Bug was originally reported as "head/neck protrudes forward"; the apparent
forward shift turned out to be an optical illusion from the missing
coat collar. Math + cdb-ground-truth + ACME comparison confirmed the
head placement is correct retail-faithful — see #37 for the long write-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-01 16:05:33 +02:00
parent 3361641655
commit 09e013b7bd
3 changed files with 166 additions and 3 deletions

View file

@ -46,6 +46,96 @@ Copy this block when adding a new issue:
# Active issues
## #37 — Humanoid coat doesn't extend up to neck (visible "skin stub" between hair and coat)
**Status:** OPEN
**Severity:** LOW (cosmetic; doesn't affect gameplay)
**Filed:** 2026-05-01
**Component:** rendering / clothing / textures
**Description:** Every humanoid character (player + NPCs) wearing a coat
shows a visible skin-colored region at the top of the coat where retail
shows continuous coat fabric. From the back view: hair → skin stub →
coat top. In retail: hair → coat collar (no exposed skin). This was
originally reported as "head/neck protruding forward" — the apparent
forward shift is an optical illusion caused by the missing coat collar.
**Investigation 2026-05-01 (~3 hr session, conclusively ruled out
many hypotheses):**
What we ruled out:
- **Animation source.** `ACDREAM_USE_PLACEMENT_BASE=1` (force chars to
`Setup.PlacementFrames[Resting]` instead of `Animation.PartFrames[0]`)
→ stub still visible.
- **Backface culling / mesh winding.** `ACDREAM_NO_CULL=1` (disable
`glCullFace` entirely) → stub still visible.
- **Palette overlay (SubPalettes).** `ACDREAM_NO_PALETTE_OVERLAY=1`
(skip `ComposePalette`) → stub still visible (other colors broke
as expected — confirms overlay was firing). Bug is NOT a body-skin
SubPalette being mis-applied to coat fabric.
- **Bug source = part 16 (head).** `ACDREAM_HIDE_PART=16` → head goes
away, stub remains UNCHANGED (clean coat top with same shape).
Stub is NOT from head GfxObj polygons.
- **Per-part placement frame Origin.** `ACDREAM_NUDGE_Y=-0.1` confirmed
`+Y = forward` in body-local; head Origin (0, 0.013, 1.587) places
head correctly relative to spine. Math checks out.
What we confirmed (data is correct):
- Player Setup `0x02000001` (Aluvian Male), 34 parts.
- Server (ACE) sends `animParts=34 texChanges=12 subPalettes=10`.
- Part 9 (upper torso/coat) has gfx `0x0100120D` after AnimPartChange.
- Part 9 has 2 surfaces, BOTH covered by 2 TextureChanges
(`oldTex=0x050003D5→0x05001AFE`, `oldTex=0x050003D4→0x05001AFC`).
- Stub IS from part 9: `ACDREAM_HIDE_PART=9` → entire torso (including
stub region) disappears.
- Per-part composition formula (`Scale × Rotation × Translation`)
matches ACME's `StaticObjectManager.cs:256-258` and retail decomp's
`Frame::combine` at `0x00518FD0`.
**Remaining hypothesis space (untested):**
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.
**Files (diagnostic env vars committed for next-session reuse):**
- `src/AcDream.App/Rendering/InstancedMeshRenderer.cs:210-275`
`ACDREAM_NO_CULL` env var
- `src/AcDream.App/Rendering/GameWindow.cs``ACDREAM_HIDE_PART=N`
hides specific humanoid part; `ACDREAM_DUMP_CLOTHING=1` dumps
AnimPartChanges + TextureChanges + per-part Surface chain coverage.
- `src/AcDream.App/Rendering/TextureCache.cs:159-204``DecodeFromDats`
is the texture decode entry. Compare against
`references/WorldBuilder-ACME-Edition/.../TextureHelpers.cs`.
**Reproduction:**
```powershell
$env:ACDREAM_LIVE = "1"; $env:ACDREAM_DEVTOOLS = "1"
# normal launch — visible from chase camera looking at +Acdream's back
```
Stub is visible on +Acdream and on every NPC humanoid (Pathwarden,
Town Crier, Shopkeeper Renald, etc.).
**Acceptance:** Side-by-side retail + acdream rendering of +Acdream
shows coat extending up to chin level on both. No exposed skin
between hair and coat.
## #L.1 — Hotbar UI panel
**Status:** OPEN