Commit Graph
1176 Commits
Author SHA1 Message Date
alexpolo1andClaude Fable 5 b06c77d2e4 Profile system: per-user char profiles + shared pickit profiles
Per-user character profiles (gitignored, survive git pulls):
- config/profiles/<name>/profile.ini overrides any params.ini key
  (runs, difficulty, char type, keybinds...). Priority:
  custom.ini > profile.ini > params.ini. Injected into _select_val and
  all 22 build-section merges.
- Active profile selected via config/active_profile.txt (gitignored);
  Config.get/set_active_profile + list_profiles/list_pickit_profiles.

Shared pickit profiles (git-tracked team content):
- config/pickit_profiles/<set>/*.bnip - one folder per season phase,
  built once, shared via git. Selected per user with
  [general] pickit_profile=<set> in their profile.
- Pickit dir priority: config/profiles/<me>/pickit/ (personal)
  > config/pickit_profiles/<set>/ > config/bnip/ > default.bnip.

Menu integration (main.py):
- startup banner shows active profile + pickit set + available lists
- "end" hotkey cycles character profiles (applies on restart)

Verified: fistman profile active end-to-end (general/char/build-section
overrides + shared pickit set resolution + 474 expressions loaded).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 10:16:12 +02:00
alexpolo1andClaude Fable 5 0834831220 Run skill bind preflight once per session at first town maintenance
Mirrors the D2R settings check: on the first on_maintenance of a bot
session, validate_build_skill_icons presses each configured skill hotkey
and verifies the icon on the right slot, warning loudly (with a pointer to
tools/set_binds_from_params.py) when a bind does not match params.ini.
Non-blocking; ~5s once per session.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 09:14:52 +02:00
alexpolo1andClaude Fable 5 40e4dd8a4f Skill hotkeys select the RIGHT slot - fix cast flow, prove auto-binding live
Live finding (fresh game, 2026-06-12): D2R skill hotkeys select onto the
RIGHT skill slot, not the left as the old comments assumed. The left slot
permanently holds Blessed Hammer. Consequence: _cast_hammers pressing the
hammer hotkey after activating an aura was REPLACING the aura on the right
slot every cast cycle - the true root cause of fights running without
Concentration. _cast_hammers no longer touches the hammer hotkey: select
aura (lands on right, stays active), hold stand-still, spam left-click.
Verified live: full Diablo kill at 09:04, ~55s from last seal to kill.

Auto skill binding proven end-to-end (tools/set_binds_from_params.py):
blessed_hammer/concentration/redemption/vigor/holy_shield/teleport all
bound via the in-game picker and visually verified (6/7 OK; conviction
correctly reported missing - not skilled on this char).

- capture tool + preflight verify now watch the RIGHT slot
- fresh skill slot templates + clean PICKER_* cell templates captured at
  current settings (blessed_hammer, concentration, redemption, vigor,
  holy_shield, teleport)
- removed bogus conviction.png (had captured vigor's icon)

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 09:13:52 +02:00
alexpolo1andClaude Fable 5 1b4773b42e Never sell or drop charms (and other protected items)
transfer_items now filters protected items out of BOTH the sell and drop
paths (previously only shields, only on sell): anything whose name contains
"charm" is blocked by default (charms live in the inventory permanently -
a pickit misread must not vendor them), shields stay protected, and
never_sell_keywords in [char] params can extend the list. Blocked items
stay untouched in the inventory.

Motivated by a real grand-charm-sold-by-mistake incident.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 08:55:16 +02:00
alexpolo1andClaude Fable 5 77b35df26b Two-layer keybind verification/setting driven by params.ini
Layer 1 (Controls page / .keyo): tools/set_controls_keyo.py parses the
character keyo (same binary format as utils/key_detector) and verifies every
skill hotkey in params.ini is bound to a skill slot; --fix writes missing keys
into free skill slots with a backup (D2R must be closed). Picks the configured
character file. Verified: fistman controls match params.

Layer 2 (skill assignment / picker): enabled the existing skill_hotkey_setter
machinery for the hammerdin build:
- skill_preflight: hammerdin build rules (blessed_hammer left/required,
  concentration right/required, redemption/vigor/conviction/holy_shield/
  teleport right/optional) + PALADIN_TEMPLATE_ALIASES, merged TEMPLATE_ALIASES.
- skill_hotkey_setter: paladin picker template aliases with slot-icon fallback.
- tools/set_binds_from_params.py: end-to-end runner - opens the in-game picker,
  binds each skill to its params hotkey, verifies via slot icon, reports
  match/mismatch per skill.
- tools/capture_skill_hotkeys.py now saves crops straight into
  assets/templates/ui/skills/ so captures immediately become live templates
  for both the preflight and the picker search.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 08:30:43 +02:00
alexpolo1andClaude Fable 5 63248a9437 Hammerdin: hold Concentration through trash clears; add deps doc + keybind tool
- hammerdin.py _cast_hammers: skip aura/hammer re-selection when the slot
  already holds the wanted skill (tracked via _active_skill, invalidated by
  pre_move/_weapon_switch/cast_buffs and all raw redemption/vigor hotkey
  sends). Visible effect: aura stays on right-click and hammers fly from
  plain left-click spam instead of constant F1/F3/F8 churn.
- 35 mid-clear attack casts switched from Redemption to Concentration
  (damage aura while fighting); Redemption still pulses between packs and
  after kills for corpse cleanup.
- DEPENDENCIES.md: full verified working-state snapshot (env paths, package
  versions, tesseract wiring, D2R settings, DPI specifics, safety nets).
- tools/capture_skill_hotkeys.py: presses each params.ini skill hotkey
  in-game and saves labeled left-slot icon crops - verifies binds match the
  character and builds skill-icon templates for future aura checks.
- CLAUDE.md: remove stale main.exe mention (no exe build exists; bat runs
  current source directly).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-12 00:18:23 +02:00
alexpolo1andClaude Fable 5 2862591492 Fix launcher exit, OCR backend, A5 WP loops, Diablo aura, stash paging
Session fixes (2026-06-11), all live-tested over multiple farm games:

- input_layer/hotkey.py: no-arg keyboard.wait() returned on ANY keypress,
  silently killing the process right after F11 (all bot threads are
  daemons). Now blocks forever like the original keyboard lib. Poll loop
  is edge-triggered (no ~20ms refire while a hotkey is held) and callback
  exceptions print instead of being swallowed. (Bug 13)
- d2r_image/ocr.py: pytesseract never read PYTESSERACT_TESSERACT_CMD;
  tesseract_cmd is now wired from env var / PATH / winget default, fixing
  exit 0xC0000135 on every OCR call. (Bug 14)
- bnip/utils.py + config/default.bnip: undefined NipSyntaxError ->
  BNipSyntaxError, and Shaefershammer -> Schaefershammer typo; 474 pickit
  expressions load (was 473 + parser error). (Bug 15)
- town_manager/a5/bot: A5 WP death-loop containment - per-game WP failure
  budget (2 strikes), quick=True direct-path-only retries, sweep trimmed
  10->6 steps with 4s select timeouts, A5 select thresholds lowered
  (WP 0.62, stash 0.60/0.45; safe - every select is success_func-gated).
  Worst case dropped from 10+ min wandering to ~4.5 min contained fail
  with fresh-game recovery. (Bug 16)
- bot.py: vendor trip gating - the failure-prone A5->A4 Jamella round
  trip now only runs when consumables are needed or 3+ sell items pend.
- town_manager.py: Cain identify skips acts whose Cain timed out this
  session (straight to working A5 fallback).
- char/i_char.py: Battle Command buff check waits 0.6-0.8s after the
  hotkey (icon fade-in) to reduce double weapon-swaps.
- char/paladin/hammerdin.py: kill_diablo fights with Concentration
  instead of Conviction (useless for magic-damage hammers) and drops
  mid-fight Redemption downtime - faster kills, merc survives. (Bug 17)
- inventory: stash supports all 6 pages (personal + 5 shared, D2R 2.7+);
  gold deposits navigate via OCR-verified select_stash_page instead of
  raw 4-tab clicks; rotation %6, shared-first starts at page 5. (Bug 18)

Docs: CLAUDE.md Bugs 13-18; .hermes/plans/dia_run_test_state.md has the
full test log (two complete Diablo kills verified end-to-end today).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-11 22:05:53 +02:00
alexpolo1 ddb7008419 fix: reinstall OpenSSL, rename broken conda tesseract, use winget tesseract 5.5.0\n- Reinstalled OpenSSL (was corrupted in conda cache)\n- Renamed conda tesseract.exe to tesseract_broken.exe (access violation)\n- install.bat: winget tesseract-ocr.tesseract + rename conda binary\n- run_botty.bat: PYTESSERACT_TESSERACT_CMD points to winget version 2026-06-11 15:33:04 +02:00
alexpolo1 43c77deede fix: use winget tesseract 5.5.0, rename broken conda tesseract\n- winget install tesseract-ocr.tesseract\n- PYTESSERACT_TESSERACT_CMD points to winget version\n- conda tesseract renamed to tesseract_broken.exe 2026-06-11 15:17:27 +02:00
alexpolo1 b77347542d fix: patch pytesseract to handle tesseract --version crashes 2026-06-11 15:04:13 +02:00
alexpolo1 1b7721779c fix: remove tesserocr/tesseract from env yml; install.bat handles it\n- conda-forge tesserocr requires Python 3.11+, we use 3.10\n- conda tesseract crashes with access violation on this system\n- install.bat: tesseract=4.* + DLL renames + bundled wheel\n- run_botty.bat: SSL_CERT_DIR= + full PATH 2026-06-11 14:53:33 +02:00
alexpolo1 6822a7e495 fix: install.bat copies liblept.dll from conda leptonica 2026-06-11 14:51:23 +02:00
alexpolo1 66a71b4ad3 fix: add Scripts + DLLs to PATH in run_botty.bat for pytesseract/tesserocr 2026-06-11 14:34:50 +02:00
alexpolo1 b8479c2300 fix: broaden pytesseract import exception catch 2026-06-11 14:34:29 +02:00
alexpolo1 2bfcf0ff02 fix: patch ssl.load_default_certs to handle corrupted Windows cert store
OpenSSL 3.x + corrupted Windows cert store causes aiohttp to crash
at import time. Monkey-patch ssl.SSLContext.load_default_certs to
fall back to certifi when Windows store fails.
2026-06-11 13:53:54 +02:00
alexpolo1 c80e002ab9 fix: SSL cert store corruption + install.bat fixes\n- run_botty.bat: set SSL_CERT_DIR= to bypass corrupted Windows cert store\n- install.bat: use tesseract 4.x, bundled wheel, DLL copy, PATH fix 2026-06-11 13:45:32 +02:00
alexpolo1 1fe95aae08 fix: install.bat - use tesseract 4.x + bundled wheel, add DLL copy + PATH fix 2026-06-11 13:43:11 +02:00
alexandClaude Fable 5 f1c5b6cdf4 feat: pather auto-recovery sweep when a node is lost
traverse_nodes previously gave up after one random-guess move when a node
template wasn't on screen, failing every travel path where the char was
mis-positioned (the A5-after-Pindle stranding was the worst case). Now,
on timeout during travel pathing (timeout > 3.1s, so boss approaches keep
their fast fail), it walks an expanding 12-step sweep, re-scanning for the
node each step, and only fails once the sweep is exhausted. Makes ALL
node pathing self-healing, not just A5.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 20:51:20 +02:00
alexandClaude Fable 5 19011c1a12 fix: robust A5 open_wp — re-anchor via NPC landmarks + directed sweep
The A5 waypoint was unopenable after a Pindle return: the char lands in
the NE near Anya, where the town_start->WP node templates are off-screen,
so the pather random-guessed and timed out. Pathing to NPC spots
(Qual-Kehk/Malah) DOES work from there, and each has a defined path to
the WP. New open_wp: direct -> re-anchor via Qual-Kehk/town_start/Malah
-> directed sweep that re-attempts node pathing + full-screen WP scan
each step. This is the linchpin: it unblocks the A5->A4 vendor redirect,
maintenance, stash, and the Diablo run's travel out of A5.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 20:49:59 +02:00
alexandClaude Fable 5 78bc195bd9 fix: vendor failure non-fatal so maintenance always reaches stash
CRITICAL loot-loss bug: buy_consumables failure called end_game and
returned BEFORE the stash step, so Pindle runes/items piled in inventory
and were never banked (zero stash events across a whole session). Buying
pots is optional (belt refills from drops); stashing loot is the point.
Now warn + re-anchor + fall through to stash. Also raise
max_maintenance_time_s 120->240 so the A5 vendor thrash completes and
reaches stash instead of timing out first (transitional — disappears once
a Diablo run shifts spawns to A4).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 20:28:23 +02:00
alexandClaude Fable 5 2784b50675 config: fixed route order [pindle, diablo] so games end in A4 town
A5-spawn games burn on the Malah vendor step (stale patch templates);
A4-spawn games sail through Jamella. The Diablo run ends with a TP to
A4 town, so running it LAST makes every next game spawn in A4.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 20:09:48 +02:00
alexandClaude Fable 5 4e7c517764 fix: grid sweep ESC could open the game menu and blind the rest of the hunt
The blind ESC after a failed sweep click opens the ESC game menu when no
dialogue was actually open (seen covering the screen during the Tyrael
hunt). Detect SaveAndExit after the ESC and close the menu again.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 19:55:18 +02:00
alexandClaude Fable 5 3093e04517 fix: force boss loot past the mobs-alive pickit guard
Diablo died in 22s but picked_up_items was false: his death animation /
lingering effects register as visible targets, so the mobs-alive guard
skipped his drops. pick_up_items(force=True) at the Diablo loot site.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 19:48:44 +02:00
alexandClaude Fable 5 b1bec0cecc fix: grid sweep waits 5s for walk-to-NPC before declaring click failed
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 19:36:18 +02:00
alexandClaude Fable 5 54e63197c2 fix: spawn fallback uses act detection then A5, not blind A1 default
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 19:26:47 +02:00
alexandClaude Fable 5 3372b91ed7 fix: CS entrance loop budget 10s -> 20s (most common Diablo-run abort)
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 19:21:07 +02:00
alexandClaude Fable 5 9d0ae9322a fix: grid sweep ESC after wrong-NPC click, wide second pass, 25s budget
The sweep for Tyrael clicked Deckard Cain (stands in the same zone) and
left his TALK dialogue open, blinding the rest of the sweep. Also sweep
the full search area as a second pass since NPCs can stand outside the
stored ROI, with a total time budget.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 18:49:13 +02:00
alexandClaude Fable 5 06c73e7cbf fix: fuzzy char-name OCR match; single-instance guard in detached launcher
- OCR reads FISTMAN as "fabiman" — SequenceMatcher >= 0.6 on the first
  word of the row handles the mangling
- start_bot_detached.bat kills existing main.py instances first: F11/F12
  are global hotkeys, so duplicate bots receive every press and fight
  each other (one starts while the other pauses/exits)

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 18:28:12 +02:00
alexandClaude Fable 5 f410ea21f1 feat: grid hover sweep fallback when NPC body templates fail
Body templates went stale with the June 2026 patch (Malah, Cain,
Tyrael, Larzuk, Qual-Kehk all undetectable), but name tags on hover
score 0.9+ reliably. When the body-template hunt times out, sweep a
coarse hover grid over the NPC ROI and click wherever the name tag
appears.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 18:00:44 +02:00
alexandClaude Fable 5 d9a6e7ce40 feat: per-NPC body/pose thresholds (Malah 0.35/200); skip pickit while mobs alive
User-tuned detection thresholds and a safety guard against teleporting
into live packs during loot phases.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 17:58:31 +02:00
alexandClaude Fable 5 c92b7730ee fix: close open stash/inventory panels before NPC hunts and WP searches
A misclick on the stash chest (Cain stands beside it) opens the stash
UI which covers most of the screen and blinds every template search:
NPC hunts, A5_WP selection, act detection. The old guard pressed the
inventory key, which leaves a stash panel open — ESC closes both.
Panels are now closed at hunt start, per hover-loop iteration, and
before WP traversal.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 14:37:34 +02:00
alexandClaude Fable 5 a7b12bc8a3 fix: buy consumables at A4 Jamella when in A5 (Malah unreliable in current patch)
Malah wanders and her body templates predate the patch; the hunt fails
most games and the failed-hunt position strands the char. Jamella is
static and detects at 0.99+. Travel cost ~30s vs a lost game.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 14:24:49 +02:00
alexandClaude Fable 5 0b8d67b4e4 config: max_game_length_s 600 -> 900
A full CS clear takes ~10 min; the 600s watchdog force-quit a game that
had all three seals open and was waiting for Diablo to spawn.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 14:15:46 +02:00
alexandClaude Fable 5 3479a74503 fix: A5 open_wp walk-and-scan last resort for stranded positions
After a failed NPC hunt the char can be in a corner where no path nodes
anchor; both node traverses fail and the game dies. Walk a search
pattern across the small town scanning the whole screen for the WP
template directly each step.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 14:00:48 +02:00
alexandClaude Fable 5 5727a81cb8 fix: A2-Y boss seal 36B variant template; sanitize seal screenshot filename
- Seal 36 has two visual variants; dia_a2y4_36b_closed.png existed in
  assets but was never searched, so the B variant could never be clicked
  (8 sealdance tries then aborted the run)
- info_failed_seal_ screenshot name contained ": " (illegal on Windows)
  producing 0-byte files

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 13:53:17 +02:00
alexandClaude Fable 5 95bd5a76ec fix: post-loot seal calibration hops are non-fatal
After Vizier/De Seis are dead, a failed recalibration traverse aborted
the whole Diablo run (threw away two boss kills at 13:43). The seal
stage re-anchors at the pentagram via template loop immediately after,
so just skip the extra loot pass and continue.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 13:45:51 +02:00
alexandClaude Fable 5 a05a13be67 fix: on_init save+exit recovery when stranded mid-town with no visible marker
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 13:34:43 +02:00
alexandClaude Fable 5 a06e46df09 fix: track physical act across failed cross-act NPC trips; prefer A4 Jamella retry
- town_manager.identify: return the reached A5 location when Cain fails
  after successful travel (returning False made bot.py fall back to the
  pre-travel act and run wrong-act pathing all maintenance long)
- town_manager.resurrect: leave last_known_loc breadcrumb when the A4
  revive fails after travel; bot.py consumes it to re-anchor
- bot.py: alternate vendor retry prefers A4 Jamella (static, reliable)
  over A1; Malah wanders and is the main A5 vendor failure

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 13:31:32 +02:00
alexandClaude Fable 5 8a58b44866 fix: substring match in OCR char-name row scan (rows include level/class text)
Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 13:26:22 +02:00
alexandClaude Fable 5 d99e3461fe fix: seal layout-check retry via pentagram; never skip hammers on unbound aura
- diablo.py _layoutcheck: ambiguous/lost layout check now loops back to
  the pentagram and retries the approach once before aborting the run;
  template checks bumped from single-frame 0.1s to 0.5s
- hammerdin.py _cast_hammers: an unbound aura (e.g. conviction in
  kill_diablo on a non-Infinity build) silently cast NOTHING, so Diablo
  was never attacked with the damage aura. Fall back to concentration
  and always cast hammers.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 13:24:50 +02:00
alexandClaude Fable 5 a695252614 fix: select configured char_name before saving char template
First encounter at char select blindly saved whichever character was
highlighted, locking in a wrong character for the whole session. Now,
when char_name is configured, select it via OCR first and warn if the
saved template name does not match.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 13:09:26 +02:00
alexandClaude Fable 5 7ef62161ca fix: spawn-act tracking, alternate-act vendor retry, broader CS entrance templates
- bot.py: track _spawn_act at game start as act-of-record when mid-town
  marker detection fails; _verify_town_location(assumed) fallback chain
  assumed_act -> spawn_act -> A5; pass previous location at every
  retry/fallback site instead of blind defaults
- bot.py: buy_consumables alternate-act retry ladder (A5 Malah unless
  already in A5, then A1 Akara) gated on confirmed go_to_act travel
- diablo.py/vizier.py: widen CS entrance template set (DIA_CS_ENTRANCE_*
  node-603 variants) and lower threshold 0.8 -> 0.75
- start_bot_detached.bat: detached launcher with per-launch console log

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 13:06:15 +02:00
alexandClaude Fable 5 6301490cc4 fix: act-state verification, NPC dialogue confirm wait, stats integrity
Root causes from the 2026-06-09 session (51 games, 45 failed):

- Act desync: add TownManager.detect_current_act() and
  Bot._verify_town_location(); every maintenance/end-run retry and
  fallback now verifies the physical act instead of hardcoding town
  starts. open_wp/go_to_act self-heal act mismatches. Never run A1
  pathing when travel to A1 failed.
- NPC dialogue: poll action buttons up to 2.5s after click instead of
  a single-frame check (premature retry click was closing the dialog).
- Stats integrity: log_end_game skips duplicate calls (phantom 0s
  "successful" games were resetting the consecutive-fail breaker);
  clear stale failure reason at game start; set chicken flag before
  bot.stop() so chickens are no longer labeled "Bot stopped".
- Repair: prefer in-act Larzuk over cross-act Halbu trip (Halbu
  detection failed 100% last session and desynced the act state).

Documented as Bugs 9-12 in CLAUDE.md.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-06-10 08:23:10 +02:00
alexandClaude Sonnet 4.6 83951db876 fix: resolve NPC name tag template mismatch causing open_npc_menu timeouts
NPC body templates find Akara/Malah correctly but the name tag templates
score ~0.28, below the 0.35 threshold, causing 20s spinning when the NPC
is detected but the hover confirmation never passes.

Three targeted changes in open_npc_menu():
- Use a 240x140px ROI directly above the hover cursor for name tag search
  instead of the full screen, containing false-positive risk
- Lower name tag threshold from 0.35 to 0.26 so Akara at ~0.28 now passes
- Check ScreenObjects.NPCDialogue after click as primary confirmation;
  this is UI-state based and immune to stale template images
- Reduce per-NPC search timeout from 20s to 8s for faster failure recovery

Also lower max_maintenance_time_s from 120 to 60 to cap total stuck time.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-08 19:09:11 +02:00
alexandClaude Sonnet 4.6 793d7ed967 feat: resilient town loop, step tracking, per-run disable, maintenance timeout
Reliability
- All run approach() methods now set approach_fail_step before every return False;
  bot.py _run_wrapper reads it and includes [step: X] in Discord/log failure reasons
- on_maintenance() sets _maintenance_step before each town step (heal, identify,
  buy_consumables, stash_items, repair, resurrect_merc, gamble) for the same coverage
- on_init() logs startup line: char=X | difficulty=Y | routes=[...] each game

Per-run disable (bot runs as long as possible)
- GameStats tracks per-run failure counts across Bot instances (previously reset each game)
- After disable_run_after_failures consecutive failures a run is disabled for the session;
  game-level consecutive-fail counter resets so the bot continues on remaining routes
- game_controller no longer quits on max_consecutive_fails if active routes remain;
  only exits when all routes are disabled

Maintenance timeout (params.ini: max_maintenance_time_s=120)
- Hard 120 s wall on the entire town maintenance loop; checked between each major step
  and before every retry (buy_consumables, stash, repair, resurrect_merc, gamble)
- On timeout: error screenshot + Discord, then trigger end_game → save-and-exit → rejoin

Bug fixes
- Win11 mouse overshoot: mouse_move() uses SetCursorPos + zero-delta MOUSEEVENTF_MOVE
- _curr_loc = True propagation: TownManager.identify() now returns the act Location enum
- DAMAGED KeyError in pickit: added ItemQualityKeyword.Damaged.value to NTIP_ALIAS_QUALITY_MAP
- A4 WP interaction range: force-move character to WP stone before select_by_template
- NPC click blocked by equipped-area guard: open_npc_menu() closes inventory if open

Docs
- Added CLAUDE.md: AI working guide with step tables, bug history, debugging tips

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-06-08 18:44:45 +02:00
alex 5fbac05e4e Stabilize Diablo verification and potion handling 2026-06-07 20:17:04 +02:00
alex 594d633787 Fix D2R window sizing and input targeting 2026-06-07 19:00:15 +02:00
alex 9f45539210 feat: capture missing screen verification evidence 2026-06-07 18:42:43 +02:00
alex 83539ed9c3 fix: require stable screen verification 2026-06-07 18:37:58 +02:00
alex f1d6c6bd1c ci: align validation environment with Windows 11 2026-06-07 18:31:10 +02:00