Skip to content

Task: Fix runtime SMR reconstruction to a connected in-game boss body (#72 Phases 1-2) #74

Description

@jarlbrak

Summary

Fix the runtime skinned-mesh reconstruction so the Mudwretch Foreman renders as a single connected body in-game instead of an exploded triangle cloud. Apply the minimal fix first (FR-2): after assigning the runtime-built sharedMesh, reassign the live SkinnedMeshRenderer.bones array so Unity rebinds the skin to the new mesh's bindpose set. Only if that does not reach connected:PASS, escalate (FR-3) to a FTK.Stitcher-exact fresh SkinnedMeshRenderer. The two share one acceptance (an in-game connected body on the rigid asset), so they are one deliverable with an internal escalation decided by the gate.

Parent Spec

Implements #72

Responsible Agent

csharp-harmony-engineer

Files to Touch

  • FTKModFramework/Core/EnemyVisualPatch.cs (the glb path in ApplyMeshSwap: FR-2 smr.bones rebind; FR-3 fresh-SMR fallback)

Dependencies

Acceptance Criteria

  • FR-2 (attempted first): after the runtime sharedMesh swap, the patch reassigns smr.bones (and refreshes rootBone only if proven necessary) to force the rebind.
  • FR-3 (only if FR-2 does not reach connected:PASS): a fresh SkinnedMeshRenderer is created that shares the live bones/rootBone, the custom mesh and material are assigned to it, and the original renderer is disabled (not destroyed). It is idempotent per combat clone via a name/flag guard, exactly like the existing lantern and golem paths.
  • The custom mesh keeps its OWN bindposes (name-remapped to the live rig order, as the loader already does); the live troll bindposes are never reused against the custom vertices.
  • The change is confined to Core/EnemyVisualPatch.cs: no public Content.* surface is added and the glTF decoder is not modified.
  • It is recorded which fix sufficed (FR-2 minimal rebind, or FR-3 fresh SMR).
  • Build green; existing SELF-TEST PASS lines still present.

In-Game Verification

Run tools/ai-model-pipeline/run_visual_gate.py against a bridge-enabled launch (diagnostic flag OFF). The in-game verdict for the Mudwretch Foreman must report connected:PASS: a single connected component, not a shard cloud, on the rigid asset.

A green build alone does NOT satisfy this work item. The in-game connected:PASS is required.

Technical Notes

  • In-engine precedent (verified via game-decompile-analyst): FTK.Stitcher is the only runtime skinned-mesh build path in the game (player wearables). It keeps each mesh's own sharedMesh, copies materials, and NAME-remaps bones[] onto the live skeleton via TranslateTransforms; it never sets bindposes/boneWeights/rootBone. Mirror this exactly for FR-3.
  • The enemy SMR is otherwise fully prefab-baked (zero runtime enemy bindposes/boneWeights/rootBone assignments assembly-wide), which is why swapping only sharedMesh on the live renderer leaves the skin bound to the previous mesh and scatters the new verts.
  • BuildFreshSkin does NOT exist on this branch; FR-3 builds it fresh.
  • Do NOT use Mesh.indexFormat / IndexFormat.UInt32 (absent in Unity 2017.2.2p2); 16-bit indices only (21662 verts).
  • EnemyVisualPatch re-applies per spawn by design (no _done on the apply); idempotency is PER CLONE.
  • If, after BOTH FR-2 and FR-3, the gate still reports connected:FAIL on the rigid asset, do NOT keep grinding: surface it; the spec's objective pivot rule (FR-6) then applies and is recorded in the acceptance work item.

Definition of Done

  • Code complete and compiles without errors
  • No new SELF-TEST line is expected; existing SELF-TEST PASS lines still appear on startup (no regression)
  • In-game run_visual_gate.py reports connected:PASS for the Mudwretch Foreman on the rigid asset
  • Recorded which fix sufficed (FR-2 or FR-3); confined to Core/, no Content.* surface, no decoder change

Metadata

Metadata

Assignees

No one assigned

    Labels

    coreCode area: Core/ framework internalsenemyContent: enemywork-itemImplementation task from a spec

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions