Derive the context action row from the build button, not a fixed y

Seating the HUD columns below the resource readout moved the build button
from the scene-authored 160 to 288. _layout_context_buttons() then wrote the
action row straight back to a hardcoded 324 on the next context change - and
it runs on the first frame, so the action button overlapped the build button
immediately.

Same shape of bug as the overlap that seating fixed: a literal coordinate
that meant "directly below the thing above me" and silently stopped being
true when that thing moved. It now measures instead:

    row_top = build_button.position.y + build_button.size.y + HUD_ROW_GAP

Both the action button and the expanded context row derive from that, so
wherever the build button ends up, the row below follows.

tests/test_hud_layout.gd asserts the RELATIONSHIP rather than any
coordinate, so a freshly hardcoded y fails whatever value someone picks:
every HUD button clears the readout's real bottom, and no two
simultaneously-usable buttons overlap - checked at load, collapsed and
expanded, which is the path that broke. BuildingActionButton and
HangarButton are excluded as a deliberately exclusive pair.

Verified to fail against the previous code with the reported symptom:
build_button y288..436 overlapping action_button y324.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Loïc Wisniewski 2026-08-18 12:09:44 +02:00
commit 6a62b6f5f8
3 changed files with 146 additions and 4 deletions

View file

@ -197,6 +197,8 @@ var context_actions_expanded: bool = false
# Gap between the last resource row and the first row of HUD buttons.
const HUD_COLUMN_MARGIN: float = 18.0
# Vertical gap between one row of HUD buttons and the next.
const HUD_ROW_GAP: float = 16.0
# Seats the top-anchored HUD button columns below the resource readout instead
@ -438,8 +440,17 @@ func _process(delta: float) -> void:
func _layout_context_buttons() -> void:
# Build is permanently under the resource counter. The contextual berth
# directly below it is compact until it has more than one real choice.
action_button.offset_top = 324
action_button.offset_bottom = 472
#
# "Directly below it" is MEASURED from the build button rather than
# written down as a y. This used to hardcode 324, which was the right
# answer only while the build button sat at the 160 the scene authored -
# once _seat_hud_columns() started moving the whole block down to clear
# the resource readout, this ran on the next context change and dropped
# the action row straight back on top of the build button.
var row_top: float = build_button.position.y + build_button.size.y + HUD_ROW_GAP
var row_height: float = build_button.size.y
action_button.offset_top = row_top
action_button.offset_bottom = row_top + row_height
var buttons: Array = _context_action_buttons()
if not context_actions_expanded:
for button in buttons:
@ -453,8 +464,8 @@ func _layout_context_buttons() -> void:
button.visible = true
button.offset_left = 188 + i * 164
button.offset_right = button.offset_left + 148
button.offset_top = 324
button.offset_bottom = 472
button.offset_top = row_top
button.offset_bottom = row_top + row_height
func _context_action_buttons() -> Array: