From f5ea29489e8c71a3b6bf860c69cd14ac4a6ba264 Mon Sep 17 00:00:00 2001 From: FiskenPoul <123322006+FiskenPoul@users.noreply.github.com> Date: Mon, 13 Jul 2026 18:44:11 +0200 Subject: [PATCH] Fix runaway gem transmute loop: verify stack presence before every click MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A "999" gem count (OCR couldn't read the digit, code assumes "convert until depleted") relied on the loop noticing an empty stack and breaking — but that check only ran when _gems_stack_monitor_for returned None. For any registered gem type it always returns a static screen coordinate, so the depletion check was dead code: the loop just kept blindly clicking the same fixed position forever. Observed in the wild: stuck on Topaz Flawless for 30+ minutes and 177 iterations (of a fake "999" target, ~2.7h worst case) before being manually force-exited, repeatedly clicking fixed convert-panel/GEMS coordinates with nothing real there — the likely cause of it also grabbing and re-placing unrelated stash items during that time. Now always does a live template search before clicking, breaking immediately once the stack is genuinely gone, on every gem type. Verified end-to-end with a mocked run: a fake depleted "999" stack now stops instantly instead of looping, and a real gem right after it still converts correctly. --- src/transmute/transmute.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/transmute/transmute.py b/src/transmute/transmute.py index 3be7fdc..b800e1a 100644 --- a/src/transmute/transmute.py +++ b/src/transmute/transmute.py @@ -879,14 +879,18 @@ class Transmute: self._switch_to_gems_tab() wait(0.3, 0.4) - pos = self._gems_stack_monitor_for(gem_template) - if pos is None: - img = grab() - matches = template_finder.search_all(gem_template, img, threshold=0.85, roi=left_roi) - if not matches: - Logger.info(f" no {gem_template} left in GEMS tab -- stopping {tier_name}") - break - pos = matches[0].center_monitor + # Always verify the stack is actually still there before clicking it. + # A static coordinate from _gems_stack_monitor_for tells us WHERE to + # click but says nothing about whether anything is still there — for + # a "999 = depleted-unknown" plan (OCR couldn't read the count), that + # made the depletion check dead code: it kept blindly clicking the + # same empty slot every iteration instead of ever stopping. + img = grab() + matches = template_finder.search_all(gem_template, img, threshold=0.85, roi=left_roi) + if not matches: + Logger.info(f" no {gem_template} left in GEMS tab -- stopping {tier_name}") + break + pos = self._gems_stack_monitor_for(gem_template) or matches[0].center_monitor # Step 1: ctrl+shift+left-click x3 -- 3 gems move from GEMS tab into the convert panel. Logger.info(f" [{i+1}/{n_transmutes}] loading 3x {gem_template} into GEMS convert panel @ {pos}")