s&box/field-guide
the symptom, in your words

"The bone-name `.` → `_` compiler trap"

✓ verified on engine 26.07lane: Rigging & animationposted
▸ SYMPTOM
  • Ragdoll / ModelPhysics: torso works, limbs float disconnected or ignore joints.
  • Compile log warnings like: Physics shape node references unknown bone / Unknown parent|child physics body.
  • Static FBX inspection looks fine — bone names still show upper_arm.L.
  • A physics-bearing vmdl can still report compile Succeeded with a pile of warnings.
▸ CAUSE

The model compiler sanitizes ._ in bone names.

Physics KV3 that names a mirrored limb by its Blender name (upper_arm.L) references a bone that no longer exists in the compiled skeleton (upper_arm_L). Every limb body fails to bind.

The FBX skeleton and skin deformers keep the dot name, so inspecting the FBX misleads. Truth is in the compiled *.vmdl_c bone strings: upper_arm_L, thigh_L, foot_L, …

Torso bones (pelvis / spine / chest / neck / head) have no ., so they always resolve — which is exactly why only the limbs break.

Citizen physics reference names mirrored bones arm_upper_L / leg_upper_R with underscores, never dots. Same family as material .001 dedup illegality for bone names.

▸ FIX

Sanitize only at the strings written into physics KV3:

snippet
parent_bone / parent_body / child_body
snippet
def phys_bone_name(blender_name: str) -> str:
    # upper_arm.L → upper_arm_L  (and .R → _R)
    return blender_name.replace(".L", "_L").replace(".R", "_R")

Keep Blender/FBX/armature/skin-weight authoring on the dot names — those must match the FBX.

Apply inside every capsule/joint emitter. This is a whole-lane defect: any physics-bearing rig that copies Blender names into KV3 will hit it.

Verify: recompile and read console warnings with timestamps. An old .L warning can linger in the buffer — only a fresh timestamp proves the fix. Confirm compiled bone strings in *_c use underscores.

▸ WHY IT WORKS

Skinning binds through the FBX bone names; ModelDoc physics binds through the compiled skeleton name table after sanitization. Writing Blender-faithful dotted names into physics nodes creates a lookup miss that doesn't fail the whole compile — torso capsules still bind, limbs don't — producing the partial-ragdoll detective story.

Verified on engine 26.07 — seen in a real project.
s&box moves fast; an undated fix is a liability. Spot a stale detail?