Select a pawn or building on the map (#78) #144

Merged
liamjd merged 2 commits from 78-select-pawn-or-building into main 2026-10-09 06:01:54 +01:00
Owner

Left-click a pawn or a building on the map to select it. This is the foundation for milestone #6: the pawn list (#140), building list (#141) and inspector (#142) all build on it. The spec is the comment on #78.

What changed

  • GameState.selected: Entity with selection_changed(new, previous).
    • Only a Pawn, a Building or null is accepted; anything else hits push_error and leaves the selection unchanged.
    • Any change of interaction mode clears the selection, before interaction_mode_changed fires.
    • Removing the selected pawn or building clears it.
  • InteractionMode.SELECT is removed. Selection is what a click means in NONE mode.
  • Pawns.pick() mirrors Buildings.pick():
    • Pawns are on their own physics layer 3, named "pawns", set up in _spawn_view() with the layer, collision_mask = 0 and an id meta.
    • The ray needs collide_with_areas = true, because the pawn's collider is an Area3D.
  • SelectionController is a new node in game.tscn, after DemolishController.
    • It handles the new select action (left mouse) only in NONE mode.
    • A pawn wins over a building under the same click, and empty ground deselects.
  • SelectionHighlight is a translucent tint in material_overlay, so it never conflicts with the status tints or with PawnView.flash(), which both use material_override.
    • Applied through Pawns.set_highlighted() and Buildings.set_highlighted(). Both do nothing quietly when there's no view.

Testing

  • The full GUT suite passes: 39 scripts, 872 tests, 871 passing, plus the existing pending #85 test.
  • Three new spec files with 56 tests:
    • test_selection.gd: the GameState rules.
    • test_selection_highlight.gd: the overlay material.
    • test_selection_picking.gd: the real game.tscn, covering picking, mode gating, click handling, and highlights surviving status changes and flashes.
  • The tests were written before the implementation and confirmed red for the right reason. They were then checked against a throwaway implementation, and three deliberate breaks (no collide_with_areas, clearing the selection after the mode signal, highlight in material_override) were each caught.
  • Headed checks: a selected pawn, and a selected building under construction, both screenshotted.

Caveats and follow-ups

  • The highlight changed from the spec's outline shell to a tint. The outline was a one-pixel rim on built buildings, and showed through translucent sites as a fill. Recorded on #78 (2026-10-09). No tests changed.
  • The selected pawn is hard to see, because the tint is close to the pawn's own teal. Accepted for now; tracked in #143.
  • Not yet screenshotted: a selected built building. The "built" screenshot turned out to be a copy of the under-construction one.
  • Pawns are picked through buildings: a pawn hidden behind a building still wins the click. It's rare at this pawn size, and known.
  • The tests and implementation went in as one commit (fa11363) rather than a separate spec commit first.

Closes #78

🤖 Generated with Claude Code

Left-click a pawn or a building on the map to select it. This is the foundation for milestone #6: the pawn list (#140), building list (#141) and inspector (#142) all build on it. The spec is the comment on #78. ## What changed - **`GameState.selected: Entity`** with `selection_changed(new, previous)`. - Only a Pawn, a Building or null is accepted; anything else hits `push_error` and leaves the selection unchanged. - Any change of interaction mode clears the selection, *before* `interaction_mode_changed` fires. - Removing the selected pawn or building clears it. - **`InteractionMode.SELECT` is removed.** Selection is what a click means in NONE mode. - **`Pawns.pick()`** mirrors `Buildings.pick()`: - Pawns are on their own physics layer 3, named `"pawns"`, set up in `_spawn_view()` with the layer, `collision_mask = 0` and an id meta. - The ray needs `collide_with_areas = true`, because the pawn's collider is an `Area3D`. - **`SelectionController`** is a new node in `game.tscn`, after `DemolishController`. - It handles the new `select` action (left mouse) only in NONE mode. - A pawn wins over a building under the same click, and empty ground deselects. - **`SelectionHighlight`** is a translucent tint in `material_overlay`, so it never conflicts with the status tints or with `PawnView.flash()`, which both use `material_override`. - Applied through `Pawns.set_highlighted()` and `Buildings.set_highlighted()`. Both do nothing quietly when there's no view. ## Testing - The full GUT suite passes: 39 scripts, 872 tests, 871 passing, plus the existing pending #85 test. - Three new spec files with 56 tests: - `test_selection.gd`: the GameState rules. - `test_selection_highlight.gd`: the overlay material. - `test_selection_picking.gd`: the real `game.tscn`, covering picking, mode gating, click handling, and highlights surviving status changes and flashes. - The tests were written before the implementation and confirmed red for the right reason. They were then checked against a throwaway implementation, and three deliberate breaks (no `collide_with_areas`, clearing the selection after the mode signal, highlight in `material_override`) were each caught. - **Headed checks:** a selected pawn, and a selected building under construction, both screenshotted. ## Caveats and follow-ups - **The highlight changed from the spec's outline shell to a tint.** The outline was a one-pixel rim on built buildings, and showed through translucent sites as a fill. Recorded on #78 (2026-10-09). No tests changed. - **The selected pawn is hard to see**, because the tint is close to the pawn's own teal. Accepted for now; tracked in #143. - **Not yet screenshotted: a selected *built* building.** The "built" screenshot turned out to be a copy of the under-construction one. - Pawns are picked through buildings: a pawn hidden behind a building still wins the click. It's rare at this pawn size, and known. - The tests and implementation went in as one commit (`fa11363`) rather than a separate spec commit first. Closes #78 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The selection highlight is very unclear and may be worse with real 3D models.
The outline shell failed the headed check: a one-pixel rim on a built
building, and its back wall showing through a translucent site as a fill.
SelectionHighlight is now a translucent, unshaded tint in the same
material_overlay slot, so no test changed. The selected pawn is still hard
to see against its own teal; that is #143.

- Drop the unused GROW and the stale "cool blue" comment on COLOUR.
- Revert pawn.tscn's Area3D collision_layer = 5 (layers 1 and 3).
  _spawn_view() sets the layer, mask and meta in code, so the scene value
  was overwritten anyway and only disagreed with it.
- pick_at() returns the Entity directly; the as-casts did nothing.
- Trailing whitespace and blank-line spacing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
liamjd merged commit 0e56b5027f into main 2026-10-09 06:01:54 +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!144
No description provided.