# Phase 9 Round 4 — Bugfix: Head Position vs. the Editor's Silhouette Guide ## Overview User report: the head is **too high** in the harness. Reference: the editor's silhouette guide head is a circle; the bottom of the mounted head shape must line up with the bottom of that circle relative to the torso bone, so the head **overlaps the torso** some. ### Guide geometry (source of truth, `scripts/whole_stickman_preview.gd`) | Constant | Value | |---|---| | `GUIDE_JOINTS["Neck"]` (`:61`) | `(0, −391.5)` — the Head bone origin | | `GUIDE_JOINTS["Head"]` (`:62`) | `(0, −463.5)` — the head circle **center** | | `GUIDE_HEAD_RADIUS` (`:49`) | `100.0` | → The guide's head circle bottom = `−463.5 + 100 = −363.5` — **28 px below the neck**, overlapping the torso's top region (torso spans `0 → −391.5`) by 28 px. ### Current behavior (wrong) Round 3 zeroes the Head driver's local position, so `Body/Head` sits on the Head bone origin (the neck, `y = −391.5`); the mounted chin is the local origin → the chin lands at the neck and the head floats above the torso with no overlap. ### Required behavior The mounted head's bottom (chin) must land at `y = −363.5` — i.e. the mounted head geometry gets a `+28 px` local Y offset so the chin sits 28 px below the neck joint, matching the guide circle's bottom and overlapping the torso. ## Fix specification — `scripts/stk_rig_adapter.gd` 1. Add `const HEAD_CHIN_DROP := 28.0` with a doc comment deriving the value (guide head circle bottom `−363.5` − neck `−391.5` = 28; the guide circle has radius 100 centered at the Head joint `(0, −463.5)`). 2. In the head branch of the mount (where `θ = 0`, `s = 1`), after transforming the points, translate them by `Vector2(0.0, HEAD_CHIN_DROP)` — the chin (local origin) ends up 28 px below the node origin (the neck). 3. The flip anchor rule from Round 3 is unchanged (a flipped head still attaches at its cap top; the drop applies identically). 4. Nothing else changes (no driver/overlay/serialization changes). Note: the offset is applied **after** the part scale/rotation composition (it is a rig-space fixture position, not part geometry), so a 180°-rotated head drops by the same 28 px. ## Files modified | File | Changes | |---|---| | `scripts/stk_rig_adapter.gd` | `HEAD_CHIN_DROP` const + head-points translation. | | `docs/phase9_round4_bugfix_spec.md` | This file. | ## Test plan 1. Parse check: `..\Godot_v4.7.1-stable_win64_console.exe . --headless --check-only --quit`. 2. Headless smoke test (spawn `break.stk`, stack enabled, 2 frames): - `Body/Head` world position ≈ `(0, −391.5)` (node still at the neck). - Mounted head chin point ≈ local `(0, +28)`; world chin ≈ `(0, −363.5)`. - Head top ≈ world `(0, −363.5 − 219)` ≈ `(0, −582)`; the head now overlaps the torso's top region (torso top at −391.5) by ≈ 28 px. - Regression: the head's other Round 3 properties (scale ≈160 face, one node per shape, IK following, flip behavior) unchanged. 3. Manual harness check (F6): head bottom aligned with the guide circle's bottom; head overlaps the torso. ## Design decisions | # | Decision | Justification | |---|---|---| | D1 | Fixed `+28 px` rig-space offset (not relative to the head's drawn size) | The guide circle is a fixed rig fixture; the requirement is to align to its bottom. | | D2 | Offset applied to the mounted points (not the driver) | The Head driver's zeroing stays (rotation about the neck with the LookAt); a driver offset would swing with the bone rotation. |