fix(merc): always dismiss the panel the merc check opens (CHRONICLE stayed up all game)
resurrect_merc confirms a live merc by pressing 'o' and looking for MercPanelText, then
closed the panel ONLY when that check passed:
keyboard.send("o")
merc_panel_open = is_visible(ScreenObjects.MercPanelText)
if merc_panel_open:
keyboard.send("o") # the only path that closed anything
On this client 'o' (skill slot 54) opens the CHRONICLE collection panel, not the merc panel.
MercPanelText never matched, the closing keypress was never sent, and Chronicle stayed open
for the rest of the game — a large centred panel that blanks every later template match. The
run then died on click_red_portal after ~66s of clicking at a covered screen.
The health manager's guard did not catch it either: it looks for LeftPanel/RightPanel, and
Chronicle is centred and matches neither.
Fix: always dismiss whatever appeared. When MercPanelText is absent, send esc, then re-check
LeftPanel/RightPanel and esc again if something is still up.
Diagnosed straight from the new FAIL> record, which named the culprit without any log
archaeology:
FAIL> g90 r83 | at=False | step=resurrect_merc | shot=...
FAIL> g90 r83 | trail: town.repair(12s) > town.maintenance(18s) > run.approach!(66s)
The step named in the failure reason was click_red_portal; the step that actually caused it
was resurrect_merc, three entries earlier in the trail. That is exactly the case the trail
was added for.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
32
CLAUDE.md
32
CLAUDE.md
@@ -662,6 +662,38 @@ Note `NAME_TAG_THRESHOLD = 0.26` (the hover path, line ~289) is deliberately muc
|
||||
was NOT changed — Akara genuinely hovers at ~0.28 (Bug 3). The two thresholds serve different
|
||||
paths; don't unify them.
|
||||
|
||||
### Bug 31: merc panel check left the CHRONICLE panel open for the whole game (2026-08-27)
|
||||
**File:** `src/bot.py` — `on_maintenance()`, merc-alive confirmation
|
||||
|
||||
`resurrect_merc` confirms a live merc by pressing `o` and looking for `MercPanelText`. It
|
||||
then closed the panel **only when that check passed**:
|
||||
|
||||
```python
|
||||
keyboard.send("o")
|
||||
merc_panel_open = is_visible(ScreenObjects.MercPanelText)
|
||||
if merc_panel_open:
|
||||
keyboard.send("o") # the ONLY path that closed anything
|
||||
```
|
||||
|
||||
On this client `o` (skill slot 54) opens the **CHRONICLE** collection panel, not the merc
|
||||
panel. So `MercPanelText` never matched, the closing keypress was never sent, and Chronicle
|
||||
stayed open for the rest of the game — a large centred panel that blanks every subsequent
|
||||
template match. The run then died on `click_red_portal` after ~66s of clicking at a covered
|
||||
screen.
|
||||
|
||||
**Why nothing caught it:** the health manager's panel guard looks for `LeftPanel` /
|
||||
`RightPanel`. Chronicle is centred and matches neither, so it was never auto-escaped.
|
||||
|
||||
**Fix:** always dismiss whatever appeared. If `MercPanelText` is not found, send `esc`, then
|
||||
re-check `LeftPanel`/`RightPanel` and send `esc` again if something is still up.
|
||||
|
||||
**The general rule:** *any* keypress that may open a panel must be paired with an
|
||||
unconditional dismiss. Closing only on the happy path leaves the UI wedged on every other
|
||||
path — and here that cost a whole run each time.
|
||||
|
||||
**Symptom to grep for:** `FAIL>` records showing `step=resurrect_merc` followed by
|
||||
`run.approach!` with a long duration, or an error screenshot with a UI panel covering the map.
|
||||
|
||||
---
|
||||
|
||||
## The run timeline — `grep "TL>"`
|
||||
|
||||
12
src/bot.py
12
src/bot.py
@@ -974,6 +974,18 @@ class Bot:
|
||||
keyboard.send("o")
|
||||
wait(0.2, 0.3)
|
||||
merc_visible = True
|
||||
else:
|
||||
# 'o' opened SOMETHING that is not the merc panel and nothing closed it.
|
||||
# On this client it opens the CHRONICLE collection panel, which covers
|
||||
# the screen and blanks every later template match — the run then dies
|
||||
# on click_red_portal after ~66s of flailing at a covered screen
|
||||
# (g90 2026-08-27). Always dismiss whatever appeared, then confirm.
|
||||
keyboard.send("esc")
|
||||
wait(0.25, 0.35)
|
||||
if is_visible(ScreenObjects.LeftPanel) or is_visible(ScreenObjects.RightPanel):
|
||||
Logger.warning("Merc check: a panel is still open after esc — sending esc again")
|
||||
keyboard.send("esc")
|
||||
wait(0.25, 0.35)
|
||||
gs = self._game_stats
|
||||
skip_until = getattr(gs, "_merc_resurrect_skip_until", 0)
|
||||
if not merc_visible and gs._game_counter < skip_until:
|
||||
|
||||
Reference in New Issue
Block a user