The real cause of "the crafter buttons do nothing", reported three
times. IconButton._blocked_by_modal tested `menu.visible`, but hiding a
parent leaves a child's own `visible` flag true - and the build menu's
info popup is itself one of the modal panels. So opening any building's
info popup and then closing the build menu with the X left an invisible
popup still claiming to be open, and from that moment EVERY button in
the game was blocked, with no way for a player to get out of it.
It tests is_visible_in_tree() now, and closing the build menu also
closes its popup rather than leaving it half-open.
My earlier attempts kept missing it because the probes called the
handlers directly - they exercised the crafter logic, which was fine all
along, and never the input path in that state. The regression test
reproduces the exact sequence: open the build menu, show a building's
info, hide the menu, then check an unrelated button still fires.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three play-testing reports.
1. Buttons behind an open panel were still clickable. There are two
input paths and both leaked. GUI clicks: the research and formation
panels cannot block with mouse_filter = STOP, because their contents
are driven from raw _unhandled_input and a Control consuming touches
through the GUI system swallows them first - so the panels stay
transparent and IconButton now checks whether it is behind one, via a
"modal_menus" group. Raw input: a touch landing on the research panel
but missing a node was left unhandled, so it fell through to
GameController - which sits on the ROOT node and sees whatever its
children ignore - and moved the fleet or pinch-zoomed the world.
2. "Store ore here" looked dead. It was working: the confirmation was
overwritten one frame later by the per-frame status refresh added in
#16, so it flashed for a single frame. Craft-panel messages now
outlive a refresh (3s), and the button stays ENABLED with an empty
hold so pressing it can say why - a greyed button that cannot explain
itself is the same dead-button problem.
3. The mothership's description could overlap the button below it. The
description block was positioned from the TOP while the buttons were
anchored to the BOTTOM, so the gap between them was whatever the
screen height left over - overlapping at 1280 and separating at 960.
It is one bottom-anchored stack now, checked at both.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>