Selection ring under the selected pawn (#143) #155

Merged
liamjd merged 2 commits from 143-pawn-selection-ring into main 2026-10-11 19:40:52 +01:00
Owner

Closes #143. Last open issue in milestone #6 (Selection and inspection).

What changed

  • Pawns get a ring on the ground instead of the overlay. PawnView builds a SelectionRing child in _ready(), lowered to the pawn's feet, and set_highlighted() shows or hides it. Because it's a child, it walks with the pawn and rides terraces the way the capsule does.
  • SelectionHighlight gains ring_material() and make_ring(). The ring is a flattened TorusMesh (inner 0.45, outer 0.7, Y squashed to 0.25) in COLOUR at full opacity, unshaded, with no shadow. The mesh and material are shared, but each pawn gets its own MeshInstance3D, so showing one ring shows no other.
  • Buildings are unchanged. They still use the overlay, which reads well on them.
  • is_highlighted() reads a _highlighted flag rather than the ring's visibility, so a set_highlighted() that arrives before _ready() still takes effect.

Verification

  • Spec first: test/unit/test_pawn_selection_ring.gd (14 tests, committed red ahead of the implementation). Full suite: 991 tests, 990 passing, 1 pending (the existing #85 one).
  • The 7–8 orphans reported by test_selection_picking.gd were already there on main and are not from this change.
  • Headed check: tools/screenshot_pawn_selection.gd frames a pawn at the default zoom (60), selects it, and samples 24 points around its feet. 0% match ring green before selection, 75% after, 0% after deselection, and no other pawn is highlighted. In that run the pawn was standing on grass, which is the worst case for a green ring. It still reads clearly in the close-up PNG and is visible at the default zoom.

Caveats

  • At zoom 60 the ring is visible but small, because the pawns themselves are only a few pixels wide there. The ring's size is set by RING_INNER_RADIUS and RING_OUTER_RADIUS if it needs to be bigger.
  • I did not re-screenshot the second acceptance criterion ("a selected building still reads as selected in every status"). The building highlight code path is untouched by this PR, so it stands as it was verified in #78.
  • On a terrace edge, part of the ring can clip into the riser next to the pawn. This is cosmetic.

🤖 Generated with Claude Code

Closes #143. Last open issue in milestone #6 (Selection and inspection). ## What changed - **Pawns get a ring on the ground instead of the overlay.** `PawnView` builds a `SelectionRing` child in `_ready()`, lowered to the pawn's feet, and `set_highlighted()` shows or hides it. Because it's a child, it walks with the pawn and rides terraces the way the capsule does. - **`SelectionHighlight` gains `ring_material()` and `make_ring()`.** The ring is a flattened `TorusMesh` (inner 0.45, outer 0.7, Y squashed to 0.25) in `COLOUR` at full opacity, unshaded, with no shadow. The mesh and material are shared, but each pawn gets its own `MeshInstance3D`, so showing one ring shows no other. - **Buildings are unchanged.** They still use the overlay, which reads well on them. - `is_highlighted()` reads a `_highlighted` flag rather than the ring's visibility, so a `set_highlighted()` that arrives before `_ready()` still takes effect. ## Verification - Spec first: `test/unit/test_pawn_selection_ring.gd` (14 tests, committed red ahead of the implementation). Full suite: 991 tests, 990 passing, 1 pending (the existing #85 one). - The 7–8 orphans reported by `test_selection_picking.gd` were already there on `main` and are not from this change. - Headed check: `tools/screenshot_pawn_selection.gd` frames a pawn at the **default zoom (60)**, selects it, and samples 24 points around its feet. 0% match ring green before selection, 75% after, 0% after deselection, and no other pawn is highlighted. In that run the pawn was standing on grass, which is the worst case for a green ring. It still reads clearly in the close-up PNG and is visible at the default zoom. ## Caveats - At zoom 60 the ring is visible but small, because the pawns themselves are only a few pixels wide there. The ring's size is set by `RING_INNER_RADIUS` and `RING_OUTER_RADIUS` if it needs to be bigger. - I did not re-screenshot the second acceptance criterion ("a selected building still reads as selected in every status"). The building highlight code path is untouched by this PR, so it stands as it was verified in #78. - On a terrace edge, part of the ring can clip into the riser next to the pawn. This is cosmetic. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The overlay's green sits too close in hue to the pawn's teal to show. A
flattened torus at the pawn's feet, in the selection colour at full
opacity, reads at the default zoom and does not depend on the pawn model.
Buildings keep the overlay.

tools/screenshot_pawn_selection.gd is the headed check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
liamjd merged commit 8a5ae26392 into main 2026-10-11 19:40:52 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
liamjd/UntitledColonyBuilder!155
No description provided.