validate_build_skill_icons rejected any required check with a blank hotkey before
the icon was ever looked at, so moving Blessed Hammer to its real home (left slot,
no key) traded one false failure for another. SkillCheck gains a `permanent` flag
for skills that sit on a slot with no hotkey selecting them; the guard skips those
and the icon check inspects the slot as-is.
Preflight now passes clean: blessed_hammer 100% (left), concentration 86.5%,
redemption 92.0%, holy_shield 93.0%, teleport 92.4%.
Co-Authored-By: Claude Opus 5 <[email protected]>
Probed the live client by pressing F1-F8 and reading the right skill slot; D2R
renders the key label into the icon, so the crops are self-proving. Actual binds:
f2=Holy Shield, f3=Redemption, f4=a charged item skill, f5=TELEPORT,
f6=Concentration, f8=an aura with no template (Conviction). f1 and f7 are UNBOUND.
Against that, [hammerdin] was wrong three ways:
- conviction=f5 pointed at TELEPORT, so every attack-aura cast would have
teleported the character — the exact hazard the [fohdin] profile section already
warns about. Conviction also does nothing for magic-damage hammers (Bug 17), so
it is now unbound rather than remapped.
- concentration=f8 pointed at Conviction; Concentration is on f6. The build was
running with no Concentration at all — less hammer damage and no party aura for
the merc, which plausibly fed the Travincal chickens.
- blessed_hammer=f1 pointed at nothing. The hammer lives permanently on LEFT-click
and no hotkey moves it to the right slot, so the preflight's right-slot check
could never pass; it scored 44.8% all session while the hammer sat correctly on
the left the whole time. The check now inspects the left slot and presses no key,
matching the comment that was already above it.
The stored blessed_hammer.png was a right-slot capture with "F1" baked into the
image, which is why it scored 34.4% against the unlabelled left slot. Recaptured
from the live left slot.
Co-Authored-By: Claude Opus 5 <[email protected]>
New modules:
- test/auto/log_analyzer.py: parses bot logs and event JSONL files,
categorizes failures (approach, maintenance, battle, chicken, timeout,
crash, OCR) into structured BotFailure objects
- test/auto/auto_fixer.py: maps failure patterns to targeted code fixes,
checks if fixes are already applied, reports what needs work
- test/auto/test_self_healing.py: orchestrator that launches the bot,
monitors for failures in real-time, analyzes logs, applies fixes,
and retries up to 3 rounds
Supporting changes:
- test/auto/test_log_analyzer.py: 8 tests against historical run data
- pytest.ini: added repo root to pythonpath for test package imports
- test/__init__.py: new, enables test/ as importable package
All 95 existing tests pass. 8 new auto-test tests pass.
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]>
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]>