Some checks are pending
CI / Install & Test (Windows) (push) Waiting to run
* fix: raise maintenance budget for cross-act routes; document Trav findings Travincal leaves the character in Act 3, but maintenance relocates it to Act 4 (stash at a4_tyrael_stash, repair at a4_halbu) and the next run then needs the A3 waypoint again -- two cross-act waypoint trips per game. That travel is not attributed to any timed step, so a FAIL> trail can show ~38s of work inside a 250s maintenance window. The 240s budget (tuned when Pindle kept all town business in one act) was tripped 5 times in one session, each costing a whole game. Raised to 420s. Also documents, in HANDOVER.md: - The open_wp failures are NOT a stale template. Scored a5_wp.png against all three real failure frames: 0.96-0.98 full-frame, but that match is the belt/mana-orb HUD false positive the a5.py comment already documents. Inside the real cut_skill_bar ROI it scores 0.436-0.480 against a 0.55 threshold at scattered positions -- noise. The waypoint is genuinely not on screen; the character never reaches it. Recapturing would fix nothing. Scoring a template without the ROI the code actually uses produces a confident wrong answer. - PR #39's pather abort is merged, live, and finally firing (1 abort in 21 games, after being 0-for-152 while it looked correct). - Keeping Trav town business in Act 3 is the real fix for both the timeouts and the waypoint failures. a3.py already reports can_buy_pots/can_heal/ can_stash as True, so the Act 4 trip is not a missing capability. - FoH vs hammerdin on the council, and the [fohdin]/[paladin] section trap: concentration and redemption lived in [fohdin], which hammerdin does not read, so both would have gone silently unbound after a respec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: post-mortem for the hell Travincal / hammerdin session Narrative write-up of 29 Aug 2026: run_trav on hell, FoHdin -> hammerdin. Outcome: health chickens 3-in-8 -> 0-in-11, battle 64-68s -> 41-60s, failure rate 12% -> 9%, zero deaths throughout. The document covers the four times the obvious answer was wrong: 1. Battle time did not move after the respec, which looked like failure. hammerdin.kill_council casts for a FIXED duration with no kill detection, so the clock cannot report damage -- loot proved the respec worked. 2. a5_wp.png scored 0.96-0.98 full-frame on every failure frame, which reads as "template fine, search broken". That match is the belt/mana-orb HUD false positive the a5.py comment already documents. Inside the real cut_skill_bar ROI it scores 0.436-0.480 against a 0.55 threshold at wandering positions -- noise. The waypoint was never on screen. 3. Ormus: not masked (4-channel but fully opaque, so no mask is passed), and not a threshold problem (in-ROI best 0.342, background level -- lowering the bar would recreate the Bug 4 false-positive clicks). A3 town has frames with ZERO pather landmarks over threshold, so the character never arrives. One cause, three symptoms. 4. Reverses this session's own earlier recommendation to move Trav town business into Act 3. That was reasoned from a3.py reporting can_buy_pots/ can_heal/can_stash as True -- a capability check, not evidence about pathing. A3 is the worst-supported town in the project. Also documents three settings that were live but inert: binds under [fohdin] which hammerdin never reads, casting_frames=8 (unreachable -- a paladin's fastest cast is 10 frames, so every cast was cut short), and repair_npc= a5_larzuk, which Bug 12 set to keep repair in-act for Pindle but which forces a cross-act trip on Trav (35.8s vs 9.0s). And a caution on the key auto-detector: it reported the wrong stand_still bind both before and after a live remap, consistent with a stale .keyo read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs: correct stale hammerdin migration notes in HANDOVER (Codex review) Addresses Codex feedback on PR #40: the handover still described the character as needing conversion to hammerdin with both skills blank, while the same commit verified type=hammerdin and concentration='f6' loading live. The conflict was worse than reported. The stale "Two things only you can do" section instructed the operator to rebind F7 -> Concentration, but F7 is Battle Orders (CTA). Following it would have overwritten the CTA bind and cost a large share of the life pool -- the exact problem this session was fixing. - Replaces the migration paragraph with the verified end state, and records that Blessed Hammer lives on LEFT-CLICK, not an F-key (_cast_hammers puts the aura on the right slot, so a hammer hotkey would replace it). - Notes that concentration/redemption had to move into [paladin]; under [fohdin] a hammerdin never reads them and both would be silently unbound. - Adds the full verified bind map so F7 cannot be reassigned by mistake. - Rewrites the operator TODOs: fire resist is superseded (Zaka + Mara took chickens 3-in-8 -> 0-in-11); the live items are lightning/poison resist and the 75% FCR breakpoint, with the casting_frames mapping (75%=11, 60%=12, <48%=13) so cast timing tracks any gear change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * feat: baal_xp farm — game browser join, hide-and-wait state, config - src/ui/game_browser.py: retry-wrapped join flow (Play -> Join Game tab -> OCR game list -> click row -> loading/InGame confirm), wait_for_in_game - src/bot.py: 'baal_xp' state + run_baal_xp/end_run transitions; on_run_baal_xp: fast_save_and_exit -> hero select -> join public game -> corpse/nopickup/pre_buff -> walk to hide spot -> wait loop (XP every 30s, HP check, death recovery, InGame-miss re-anchor) -> leave -> recover to own game; on_end_run short-circuit straight to maintenance - src/config.py: [baal_xp] section (enabled, game_name_filter, max_wait_s, xp_threshold, min_hp_pct, hide_x/y, join_timeout_s) with profile overrides - config/params.ini: [baal_xp] section, order=run_baal_xp, run_trav - profile paladalla: order=run_baal_xp, run_trav (profile routes override base config — without this the route never activates) - stealth: daily budget cap (persisted, restart-proof), buy at A4 Jamella from A3 too (Ormus measured unreliable), session budget 20h * fix: import mouse in bot.py (baal_xp hide-spot click) * feat(stealth): hard per-day runtime cap that survives restarts, and quit D2R session_budget_h is per PROCESS. Every restart re-rolls it, so a bot that gets restarted -- by the user, or by the restart-on-crash path -- can run all day and never trip it. That is exactly the signal a runtime cap is meant to remove. It also silently failed in practice: params.ini still carried the temporary levelling value session_budget_h = 20, which rolls 13-27h, so the live config could not stop the bot within a day at all. Restored to 8. Adds daily_budget_h, keyed on the CALENDAR DATE and persisted to log/.daily_runtime.json, so restarts cannot hand out a fresh allowance. Design points that matter: - The rolled target is stored WITH the date. Re-rolling per process would make restarting a way to draw a bigger budget; once a day's target is chosen it is fixed until the date changes. - Jitter subtracts ONLY. daily_budget_h is a ceiling, not an average: a two-sided roll on 8h could hand out 9h, which is not what "cap it at 8 hours" means. 8 with 0.12 jitter now runs 7.0-8.0h and never more. Verified over 300 rolls: min 7.04h, max exactly 8.00h. - Time before the first tick in a process is not counted, so a crash under-counts rather than over-counts -- the safe direction for a cap. Also closes D2R when the cap trips (daily_budget_close_game, default on). The check runs in on_end_game AFTER save-and-exit, so the character is at the menu with nothing in progress and nothing is lost -- this is not the mid-game force kill that leaves D2R unenterable. A bot parked at character select for 16h is itself the pattern the cap exists to remove; a real player quits the game. The stealth manifest reports daily_budget by checking the CALL SITE in bot.py, not just the config value -- the lesson from chicken_variance and the AFK break that was 0-for-225 while the manifest said "wired". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: alexpolo1 <alex@alexpolo1.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
861 lines
35 KiB
INI
861 lines
35 KiB
INI
; There is detailed documentation for each parameter in the README.md
|
|
[general]
|
|
; Personal values can reference env keys from repo-root .env:
|
|
; Example syntax:
|
|
; custom_message_hook=${BOTTY_CUSTOM_MESSAGE_HOOK}
|
|
; custom_loot_message_hook=${ENV:BOTTY_CUSTOM_LOOT_MESSAGE_HOOK}
|
|
; bnet_name=${BOTTY_BNET_NAME}
|
|
; bnet_pass=${BOTTY_BNET_PASS}
|
|
; char_name=${BOTTY_CHAR_NAME}
|
|
; difficulty: game difficulty to create ("normal", "nightmare", "hell")
|
|
;
|
|
; Hammerdin difficulty guide (CTA build with Conviction aura):
|
|
; NORMAL - Very easy. 1-2h Hammer kills most packs. No CTA needed.
|
|
; NIGHTMARE - Recommended starting point. Bosses hit ~100-200 dmg.
|
|
; CTA + Conviction drops resists. Need decent armor (ED/HR).
|
|
; Gear targets: ~200 AR, ~15 ED, ~30% HR, ~50% FCR on hammer.
|
|
; HELL - Bosses hit 400-800+ dmg per swing. Conviction is mandatory.
|
|
; Gear targets: ~350+ AR, ~20+ ED, ~50%+ HR, ~60%+ FCR,
|
|
; ~150% IAS on weapon. Full Rejuv belt recommended.
|
|
; If you chicken/die repeatedly, drop to Nightmare first.
|
|
difficulty=hell
|
|
; name: bot profile name used in logs/messages and mod launch option replacement
|
|
name=profile1
|
|
; randomize_runs: 0 = run in listed order, 1 = shuffle run order
|
|
randomize_runs=0
|
|
; target_tz: target Terror Zone id (leave as default unless you know the mapping)
|
|
target_tz=1
|
|
; saved_games_folder: optional override path to D2R Saved Games folder (blank = auto)
|
|
saved_games_folder=
|
|
; level_max_steps: max pathing steps for leveling-style routines
|
|
level_max_steps=20
|
|
|
|
; Set to 1 to enable auto-login and auto-launch of D2R on startup.
|
|
; Credentials below are ONLY used when auto_login=1.
|
|
auto_login=0
|
|
bnet_name=${BOTTY_BNET_NAME}
|
|
bnet_pass=${BOTTY_BNET_PASS}
|
|
|
|
; Character name to auto-select from the character selection screen
|
|
; If empty, bot relies on the saved character template from previous sessions
|
|
char_name=${BOTTY_CHAR_NAME}
|
|
|
|
; messaging
|
|
; custom_loot_message_hook: optional separate webhook for loot notifications
|
|
custom_loot_message_hook=${BOTTY_CUSTOM_LOOT_MESSAGE_HOOK}
|
|
; custom_message_hook: main webhook for status/death/chicken messages
|
|
custom_message_hook=${BOTTY_CUSTOM_MESSAGE_HOOK}
|
|
; discord_log_chicken: 1 = send chicken/death style notifications
|
|
discord_log_chicken=1
|
|
; discord_log_errors: 1 = send a Discord message + error screenshot every time a
|
|
; run fails (approach/battle/exception). Set to 0 to keep error screenshots on
|
|
; disk only. Can also be toggled via [discord_events] error=0.
|
|
discord_log_errors=1
|
|
; discord_status_runs: send periodic status every X completed runs (blank/0 disables)
|
|
discord_status_runs=10
|
|
; discord_status_count: legacy fallback, send periodic status every X games (blank/0 disables)
|
|
discord_status_count=20
|
|
; discord_timing_report_h: post a timing + failure digest to Discord every N hours
|
|
; (0 disables). Aggregated from the same TL> timeline the log uses, so the report and the
|
|
; log can never disagree. The window resets on every send.
|
|
discord_timing_report_h=2
|
|
; pickup_drought_window: warn/alert after this many consecutive games with zero
|
|
; item pickups. Raise this if you run a strict pickit and 0-pickup streaks are
|
|
; expected/normal for you (a fast boss-only rush route with a tight filter can
|
|
; easily go 10 games without a keep-worthy drop).
|
|
pickup_drought_window=10
|
|
; message_api_type: "" disables messaging, "discord" or "generic_api"
|
|
message_api_type=discord
|
|
|
|
; breaks
|
|
; break_length_m: scheduled break duration in minutes (0 = disabled)
|
|
break_length_m=15
|
|
; max_runtime_before_break_m: runtime before taking scheduled break (0 = disabled)
|
|
max_runtime_before_break_m=120
|
|
|
|
; timers / fail handling
|
|
; d2r_path: Diablo II: Resurrected install path
|
|
d2r_path=C:\Program Files (x86)\Diablo II Resurrected
|
|
; max_consecutive_fails: stop bot after this many failed runs in a row
|
|
max_consecutive_fails=5
|
|
; max_game_length_s: emergency timeout per run/game
|
|
; 900: a full Chaos Sanctuary clear (3 seals + bosses + loot) takes ~10 min;
|
|
; 600 force-quit a game while literally waiting for Diablo to spawn (2026-06-10).
|
|
; Genuinely stuck games are caught much earlier by max_maintenance_time_s and
|
|
; approach step timeouts.
|
|
max_game_length_s=900
|
|
; max_maintenance_time_s: if the town maintenance loop (heal/buy/stash/repair) takes
|
|
; longer than this many seconds, save-and-exit and rejoin a fresh game.
|
|
; Prevents the bot staying stuck in A5 town forever when NPCs or pathing fail.
|
|
max_maintenance_time_s=420
|
|
; auto_downgrade_threshold: if combined chickens+deaths exceed this number within 1 hour,
|
|
; bot automatically lowers difficulty by one tier (hell->nightmare->normal) and restarts.
|
|
; Set to 0 to disable. (NOTE: feature is parsed but not yet active in bot logic)
|
|
auto_downgrade_threshold=0
|
|
|
|
restart_d2r_when_stuck=1
|
|
; hardcore: 1 enables hardcore-safe assumptions in some routines
|
|
hardcore=0
|
|
|
|
; screenshots
|
|
; info_screenshots: save screenshots for info/chicken/death events
|
|
info_screenshots=1
|
|
; error_screenshots: save a screenshot to log/screenshots/error/ every time a run
|
|
; fails (approach failure, battle failure, or an exception) so logs and visuals can
|
|
; be reviewed side by side. Falls back to info_screenshots if unset.
|
|
error_screenshots=1
|
|
; loot_screenshots: save screenshots for picked loot
|
|
loot_screenshots=0
|
|
; pickit_screenshots: save screenshots for pickit debugging
|
|
pickit_screenshots=1
|
|
|
|
; recovery
|
|
; disable_run_after_failures: after this many CONSECUTIVE failures of the same run
|
|
; (e.g. run_vizier), the bot disables just that run for the rest of the session and
|
|
; keeps doing the other runs instead of stopping. A single success resets the count.
|
|
; If every run gets disabled the bot stops for investigation. Set high to effectively
|
|
; disable this behaviour.
|
|
disable_run_after_failures=5
|
|
; stash_scan_interval: scan all stash tabs and export stash_list.csv every X runs (0 disables)
|
|
stash_scan_interval=0
|
|
|
|
[discord_events]
|
|
; Fine-grained Discord event toggles (1=send, 0=disable)
|
|
; status: periodic status + generic bot messages (breaks, shop notifications, etc.)
|
|
status=1
|
|
; item_keep: send kept item notifications (loot webhooks/embeds)
|
|
item_keep=1
|
|
; death: send death notifications
|
|
death=1
|
|
; chicken: send chicken (emergency leave) notifications
|
|
chicken=1
|
|
; stash_full: send stash full notifications
|
|
stash_full=1
|
|
; gold_full: send gold full notifications
|
|
gold_full=1
|
|
; error: send run-failure notifications (message + error screenshot)
|
|
error=1
|
|
|
|
[stealth]
|
|
; Multiplies all wait() calls by a random value in this range each call
|
|
; 1.0 = no change. Set range wider for more human-like timing variation.
|
|
; wait_jitter_* multiplies EVERY wait() in the codebase, not just mouse moves.
|
|
; The floor is clamped to jitter_min*0.8, so 0.85 allowed waits to come out 32%
|
|
; SHORT — the one place jitter stole time from an action instead of adding it
|
|
; between actions. 0.95 keeps waits at-or-longer (effective floor 0.76 vs the
|
|
; old 0.68, and the Gaussian centre sits above 1.0), so a wait can no longer
|
|
; expire before the UI it was waiting on has settled.
|
|
wait_jitter_min = 0.95
|
|
wait_jitter_max = 1.20
|
|
|
|
; Extra pixel variance added to every mouse click (on top of existing randomize=5)
|
|
; 0 = off, 10 = +/-10px extra random offset per click
|
|
; NOTE: click position randomization lives at the CALL SITES (npc_manager,
|
|
; ui/waypoint) where it is tuned to real button geometry — 2-3px for NPC
|
|
; hover targets, +/-9px inside a 47px waypoint button. There is deliberately
|
|
; no global click-offset knob: stacking one on top of those is what starts
|
|
; missing NPCs (see CLAUDE.md Bugs 3/4/6/7).
|
|
|
|
; Re-shuffle run order after completing a full rotation (vs only at session start)
|
|
; 0: keep [pindle, diablo] fixed so every game ENDS in A4 town (Diablo run TPs
|
|
; there) — the next game then spawns at A4 where Jamella/Cain/Tyrael work,
|
|
; avoiding the A5 Malah vendor entirely (stale templates in current patch).
|
|
reshuffle_each_rotation = 0
|
|
|
|
; Probability (0-100) of randomly skipping a run each game
|
|
; 0 = never skip, 20 = skip ~1 in 5 runs
|
|
skip_run_chance = 10
|
|
|
|
; Probability (0-100) of taking an unscheduled AFK break after any given run
|
|
afk_break_chance = 5
|
|
; Break duration range in minutes
|
|
afk_break_min_m = 2
|
|
; 12 -> 7 (2026-08-28). The configured value is NOT the real ceiling:
|
|
; maybe_afk_break does wait(minutes*60, minutes*60*1.5) and wait() then applies
|
|
; its own jitter (up to 1.44x), so a "12 minute" break can idle for ~26 minutes.
|
|
; Measured: an 11.9m break ran 1167.7s = 19.5m, and a 20:56 scheduled break ran
|
|
; 25.5m. A ~25m idle is what left D2R at character select once, unable to
|
|
; re-enter, with the bot spawning a new process every ~20s.
|
|
; 7 caps the real-world worst case near 15m, inside the range proven to resume.
|
|
afk_break_max_m = 7
|
|
|
|
; Vary run/battle duration by a Gaussian factor (default +/-15%)
|
|
; 0.0 = no variation, 0.3 = up to +/-30% variation
|
|
run_duration_variance = 0.15
|
|
|
|
; Micro-pause between actions (simulates human hesitation in milliseconds)
|
|
micro_pause_min_ms = 20
|
|
micro_pause_max_ms = 120
|
|
|
|
; Vary kill time to avoid perfectly consistent boss fight durations
|
|
; Varies boss attack duration. Only ever LENGTHENS the fight (1.0-1.4x) —
|
|
; shortening it risks leaving a boss alive, which is a failed run, not stealth.
|
|
vary_kill_time = 1
|
|
|
|
; Human mouse curve complexity (1.0 = default, 0.5 = more direct, 1.5 = more winding)
|
|
human_curve_complexity = 1.0
|
|
|
|
; Arrival-to-click delay: human-like pause between mouse arriving and clicking (milliseconds)
|
|
; 50-800ms range simulates "is this the right thing?" hesitation
|
|
; Hesitation between arriving at a target and clicking it. OFF by default:
|
|
; it applies to EVERY click, so the old 800ms ceiling could add minutes per
|
|
; run. Enable with click_delay_enabled=1 if you want it; 250 is a realistic
|
|
; ceiling that stays affordable.
|
|
click_delay_enabled = 0
|
|
click_delay_min_ms = 50
|
|
click_delay_max_ms = 250
|
|
|
|
; Key press duration variance: how long a key is held (milliseconds)
|
|
; Most presses are short (20-100ms), some linger (up to 200ms)
|
|
key_press_min_ms = 20
|
|
key_press_max_ms = 200
|
|
|
|
; Skill rotation hesitation: pause before casting a skill (milliseconds)
|
|
; Prevents machine-speed skill spam
|
|
skill_hesitation_min_ms = 80
|
|
skill_hesitation_max_ms = 300
|
|
|
|
; Wrong waypoint chance: 2-3% of selecting wrong TP portal then correcting
|
|
; Humans occasionally misclick waypoint targets
|
|
; ── session rhythm ───────────────────────────────────────────────────────────
|
|
; The strongest remaining signal is not per-click timing: averaged over a
|
|
; session jitter converges, but a player who starts at the same hour, plays the
|
|
; same length and never does anything unproductive does not.
|
|
;
|
|
; session_budget_h: stop the bot after roughly this many hours (0 = unlimited).
|
|
; Actual length is rolled per run at 0.65-1.35x, so consecutive days differ.
|
|
; Raised to 10 for an overnight run: the budget is rolled at 0.65-1.35x, so 6
|
|
; could have stopped the bot after 3.9h and left it idle. 10 guarantees at
|
|
; least ~6.5h while keeping the day-to-day variation.
|
|
; Set to 8 for a >= 5h run (2026-08-28). The value is rolled at 0.65-1.35x, so
|
|
; session_budget_h=5 would average 5h but could stop after 3.25h. 8 gives a
|
|
; 5.2-10.8h window, guaranteeing the 5 hours while keeping day-to-day variation.
|
|
session_budget_h = 8
|
|
; daily_budget_h: HARD cap on total runtime per CALENDAR DAY (0 = unlimited).
|
|
; session_budget_h above is per PROCESS — a restart re-rolls it, so a bot that
|
|
; gets restarted (by you, or by the restart-on-crash path) can run all day and
|
|
; never trip it. This cap is persisted to log/.daily_runtime.json keyed on the
|
|
; date, so restarts cannot extend the day. The target is rolled ONCE per day
|
|
; (+/- daily_budget_jitter) and then FIXED, so restarting cannot re-roll a
|
|
; larger allowance. This is a CEILING, not an average: the jitter only ever
|
|
; subtracts, so daily_budget_h = 8 with 0.12 jitter runs 7.0-8.0h and NEVER
|
|
; more than 8. session_budget_h above can still stop a single process sooner.
|
|
daily_budget_h = 8
|
|
daily_budget_jitter = 0.12
|
|
; daily_budget_close_game: 1 = also close D2R when the daily cap trips (default).
|
|
; The cap fires in on_end_game, AFTER save-and-exit, so nothing is in progress and
|
|
; nothing is lost. A bot parked at character select for 16h is itself a pattern;
|
|
; a real player quits the game. Set 0 to leave D2R running.
|
|
; Small cursor movement during long idles. Between actions the cursor otherwise
|
|
; sits exactly where the last click left it.
|
|
idle_drift_enabled = 1
|
|
; Per-game chicken threshold spread. Only ever RAISES the threshold (safer) —
|
|
; a fixed 0.40 every game is a precise tell, but lowering it would cost deaths.
|
|
chicken_variance = 0.08
|
|
; Chance of an unproductive town action (open inventory, close it).
|
|
town_browse_chance = 0.06
|
|
; Chance of walking past an item the filter wanted. Costs real loot — keep low.
|
|
pickup_skip_chance = 0.02
|
|
wrong_waypoint_chance = 0.025
|
|
|
|
; Skill mistake chance: 1-2% chance of miscasting and correcting
|
|
; Simulates human error during combat
|
|
; Presses a DIFFERENT bound skill before the intended one. Disabled: on a
|
|
; character mid-fight this swaps the active skill or aura, and the attack
|
|
; sequences rely on ending in a known skill state. The stealth value is small
|
|
; next to the risk of a stray keypress landing on something that is not a skill
|
|
; at all — which is exactly how the loot filter ended up being toggled all
|
|
; session (params.ini [paladin] vigor=f4, unbound on this char, F4 = filter).
|
|
; Set back to 0.015 to re-enable.
|
|
skill_mistake_chance = 0
|
|
|
|
[routes]
|
|
; Controls which farm runs Botty performs each game.
|
|
; "order" is a comma-delimited list and runs left-to-right when randomize_runs=0.
|
|
; If randomize_runs=1 (in [general]), Botty shuffles enabled runs each game.
|
|
;
|
|
; Hammerdin keyrun recommendation (stable-first):
|
|
; order=run_countess, run_arcane, run_nihlathak
|
|
;
|
|
; Route quick notes:
|
|
; run_trav (Act 3 Travincal council farm; short/high-density run)
|
|
; run_pindle (Act 5 Nihlathak temple red portal boss farm)
|
|
; run_eldritch (Act 5 Frigid Highlands Eldritch-only run)
|
|
; run_eldritch_shenk (Act 5 Eldritch then Shenk in same game)
|
|
; run_nihlathak (Act 5 Halls of Vaught, teleport strongly recommended)
|
|
; run_arcane (Act 2 Arcane Sanctuary / Summoner, teleport strongly recommended)
|
|
; run_diablo (Act 4 Chaos Sanctuary, teleport recommended)
|
|
; run_vizier (Act 4 Chaos Vizier-only route; lighter/faster than full Diablo run)
|
|
; run_andariel (Act 1 Catacombs)
|
|
; run_countess (Act 1 Forgotten Tower)
|
|
; run_mephisto (Act 3 Durance of Hate)
|
|
; run_baal (Act 5 Throne of Destruction)
|
|
; run_baal_xp (Join public Baal games, hide, collect XP, leave — see [baal_xp])
|
|
order=run_baal_xp, run_trav
|
|
|
|
[char]
|
|
; ==========================
|
|
; ==== Mandatory Fields ====
|
|
; ==========================
|
|
; These configs have to be alligned with your d2r settings and char build
|
|
; type: character build profile to use (must match one section below)
|
|
; examples: blizz_sorc, hammerdin, fohdin
|
|
type=hammerdin
|
|
; belt_rows: in-game belt size (2/3/4)
|
|
belt_rows=4
|
|
; casting_frames: your char cast breakpoint (affects action timing)
|
|
casting_frames=11
|
|
; cta_casting_frames: cast breakpoint on CTA swap (if used)
|
|
cta_casting_frames=11
|
|
; attack_frames: base attack animation timing for non-cast attacks
|
|
attack_frames=15
|
|
; cta_available: 1 if Call to Arms swap exists, else 0
|
|
cta_available=1
|
|
;Do we want to cast non-cta buffs (ex energy shield) with cta
|
|
buff_with_cta=1
|
|
|
|
; safer_routines: enable for optional defensive maneuvers/etc during combat/runs at the cost of increased runtime (ex. hardcore players)
|
|
safer_routines=1
|
|
|
|
; num_loot_columns: Number of empty columns from left to right of inventory to be used for looting.
|
|
; Store charms, etc. to the right of the inventory.
|
|
;
|
|
; This drives ui_roi[restricted_inventory_area] in config.py: the columns to the RIGHT of
|
|
; this count are protected — mouse._is_clicking_safe() cancels any click landing there, so
|
|
; the bot never sells, drops or moves anything in them. Both tomes MUST live in that
|
|
; reserved area: common.tome_state() only searches restricted_inventory_area for them.
|
|
; 3 columns = 12 loot slots, 28 reserved
|
|
; 4 columns = 16 loot slots, 24 reserved <- now
|
|
; 6 columns = 24 loot slots, 16 reserved (tried 2026-08-27, reverted — shrinking the
|
|
; reserve is the wrong direction when the
|
|
; books and the charms both live there)
|
|
; Lower this if the tomes or charms are running out of room; raise it only if the reserved
|
|
; area is provably empty.
|
|
num_loot_columns=5
|
|
|
|
; game hotkeys:
|
|
; NOTE: each key must match your in-game binding exactly
|
|
force_move=e
|
|
inventory_screen=i
|
|
potion1=1
|
|
potion2=2
|
|
potion3=3
|
|
potion4=4
|
|
; show_belt is different from the default hotkey as "~" is for many keyboards not reachable without also pressing altgr
|
|
show_belt=k
|
|
show_items=alt
|
|
; stand_still cannot be the default "shift" as it would interfere with merc healing
|
|
stand_still=capslock
|
|
; teleport: leave empty if you can't use
|
|
teleport=f4
|
|
town_portal=f8
|
|
; call to arms settings:
|
|
; weapon_switch/battle_orders/battle_command only used when cta_available=1
|
|
weapon_switch=w
|
|
battle_orders=f6
|
|
battle_command=f5
|
|
|
|
; ==========================
|
|
; ==== Optional configs ====
|
|
; ==========================
|
|
stash_gold=1
|
|
use_merc=1
|
|
|
|
; Attack length for barbarians should be as high as 8-10 and even 10-12 for trav/shenk
|
|
;
|
|
; Hammerdin attack lengths (seconds of hammer spam per boss):
|
|
; atk_len_trav = 4.0 (Council of 3 - 3 council members, easy)
|
|
; atk_len_pindle = 8.0 (Pindle — Hell: 13094-16070 HP, 75% fire, 100% poison)
|
|
; Pindle stats by difficulty:
|
|
; Normal: 1064-1588 HP, 75% fire, 70% poison
|
|
; Nightmare: 4773-5859 HP, 100% poison
|
|
; Hell: 13094-16070 HP, 75% fire, 50% cold, 33% light, 100% poison
|
|
; With Conviction (-33% res), Hell Pindle = 50% fire, 17% cold, 0% light, 67% poison
|
|
; CTA adds +100% dmg to hammer. Need ~60%+ FCR and good IAS to kill in 8s.
|
|
; atk_len_nihlathak = 4.0 (Nihlathak - single boss)
|
|
; atk_len_eldritch = 3.0 (Eldritch only - single boss)
|
|
; atk_len_shenk = 4.0 (Shenk only - single boss)
|
|
; atk_len_arc = 2.5 (Summoner in Arcane - single boss)
|
|
; atk_len_diablo = 10.0 (Diablo in CS - longest single boss)
|
|
; atk_len_countess = 3.0 (Countess - single boss, easy)
|
|
; atk_len_andariel = 4.0 (Andariel - single boss)
|
|
; atk_len_mephisto = 12.0 (Mephisto - single boss, high HP)
|
|
; atk_len_baal = 10.0 (Baal - single boss)
|
|
; atk_len_baal_waves = 30.0 (Baal's spawn waves before boss)
|
|
;
|
|
; Chaos Sanctuary (Diablo run) individual fights:
|
|
; atk_len_cs_trashmobs = 2.0 (Trash packs in CS)
|
|
; atk_len_diablo_vizier = 2.0 (Vizier of Chaos - seal boss A)
|
|
; atk_len_diablo_infector = 4.0 (Infector of Souls - seal boss C)
|
|
; atk_len_diablo_deseis = 5.0 (Lord De Seis - seal boss B, hardest seal)
|
|
;
|
|
; Increase these if your hammer kills slower (low IAS/FCR).
|
|
; Decrease if your hammer kills faster (high IAS/FCR, good gear).
|
|
; If you die during a fight, the attack length is too long for your defense.
|
|
atk_len_arc=2.5
|
|
atk_len_eldritch=3.0
|
|
atk_len_nihlathak=4.0
|
|
atk_len_pindle=8.0
|
|
atk_len_shenk=4.0
|
|
atk_len_diablo=3.0
|
|
atk_len_trav=5.0
|
|
|
|
; Boss run attack lengths (per-character defaults in kill_* methods)
|
|
; Adjust these if your build is faster/slower against these bosses
|
|
atk_len_andariel=4.0
|
|
atk_len_countess=3.0
|
|
atk_len_mephisto=12.0
|
|
atk_len_baal=10.0
|
|
atk_len_baal_waves=30.0
|
|
|
|
; Chaos Sanctuary settings
|
|
atk_len_cs_trashmobs=2.0
|
|
atk_len_diablo_deseis=5.0
|
|
atk_len_diablo_infector=4.0
|
|
atk_len_diablo_vizier=2.0
|
|
cs_mob_detect=0
|
|
; cs_town_visits is currently broken, ignore for now
|
|
cs_town_visits=0
|
|
kill_cs_trash=1
|
|
|
|
; Belt settings
|
|
belt_hp_columns=2
|
|
belt_mp_columns=1
|
|
belt_rejuv_columns=1
|
|
|
|
; Potion/chicken settings
|
|
take_health_potion=0.60
|
|
take_mana_potion=0.40
|
|
take_rejuv_potion_health=0.45
|
|
take_rejuv_potion_mana=0.10
|
|
heal_merc=0.70
|
|
heal_rejuv_merc=0.45
|
|
chicken=0.40
|
|
merc_chicken=0.20
|
|
|
|
; Misc.
|
|
; helps reduce accidental pickups when enabled especially on walking characters
|
|
enable_no_pickup=0
|
|
; fill_shared_stash_first: 1 = prefer shared stash tabs before personal stash
|
|
fill_shared_stash_first=0
|
|
; to gamble, add any/all of the following: circlet, ring, coronet, talon, amulet
|
|
gamble_items=
|
|
; open_chests: 1 = open clickable chests along path when possible
|
|
open_chests=0
|
|
; pre_buff_every_run: 1 = always recast buffs at run start
|
|
pre_buff_every_run=1
|
|
; runs_per_repair: visit repair vendor every X runs (blank/0 disables)
|
|
runs_per_repair=50
|
|
; repair_npc: preferred repair vendor strategy.
|
|
; - a5_larzuk (recommended: stays in A5, no cross-act trip; falls back to Halbu)
|
|
; - a4_halbu (requires WP trip to A4 every repair — act desync risk if it fails)
|
|
; 2026-06-10: switched to a5_larzuk — session logs showed Halbu detection failing
|
|
; 100% (body score ~0.39) and each failed A4 trip desynced the bot's act state.
|
|
repair_npc=a5_larzuk
|
|
; resurrect_npc: which NPC revives the mercenary. Blank = whichever act the character is
|
|
; already in. Set to a4_tyrael to always use Act 4 Tyrael.
|
|
; Measured 2026-08-27 on this setup:
|
|
; A4 Tyrael ok 8.2s, ok 24.9s - 0 errors, ever
|
|
; A5 Qual-Kehk fail 113.6s / 52.0s / 163.1s / 72.6s - 43 errors
|
|
; Tyrael stands on a fixed spot by the A4 waypoint; Qual-Kehk is the least reliable NPC in
|
|
; the route. A failed hunt costs more than the whole A5->A4 trip, and one 163s hunt pushed
|
|
; the town visit past max_maintenance_time_s and killed the game.
|
|
resurrect_npc=a4_tyrael
|
|
; runs_per_stash: stash/sell every X runs (blank/0 disables)
|
|
runs_per_stash=1
|
|
; sell_junk: 1 = vendor non-keep items automatically
|
|
sell_junk=0
|
|
; protect_shields_from_sell: 1 = never vendor items with "shield" in detected name.
|
|
; DISABLED 2026-08-27. This is redundant: the EQUIPPED shield is already protected
|
|
; positionally by mouse._is_clicking_safe(), which cancels any click landing in
|
|
; ui_roi[equipped_inventory_area] while the inventory is open. The name rule only ever
|
|
; hit shields sitting in the INVENTORY grid, which the pickit had already judged.
|
|
; Cost of leaving it on: 130 blocked sells in one day (FIEND SHIELD 64, AERIN SHIELD 41,
|
|
; HERALDIC SHIELD 23...). The same shields were re-evaluated and re-blocked every single
|
|
; game — "Discarding FIEND SHIELD." then "Blocked sell for protected item: FIEND SHIELD" —
|
|
; so they could never leave the pack and permanently occupied slots.
|
|
protect_shields_from_sell=0
|
|
; protect_charms_from_sell: 1 = never drop/vendor charms regardless of pickit verdict
|
|
; (safety net — a misread charm can't be un-sold). Set to 0 to let your pickit rules
|
|
; decide keep/discard for charms same as any other item.
|
|
;
|
|
; KEEP THIS AT 1. Charms only give their bonus while they sit in the INVENTORY, and the
|
|
; resistances matter in nightmare. Briefly set to 0 on 2026-08-27 to reclaim slots and
|
|
; that was wrong — it vendored LARGE CHARM OF FIRE, STOUT SMALL CHARM, SMALL CHARM OF
|
|
; FLAME, STOUT SMALL CHARM OF STRENGTH and LAPIS SMALL CHARM OF VITA (+20 life,
|
|
; cold resist +7%) before it was reverted.
|
|
;
|
|
; The "673 blocked sells" in the log are NOT a bug to fix by selling — they are the guard
|
|
; doing its job, repeatedly, on charms the pickit does not have a keep rule for. If those
|
|
; slots are needed, the answer is a pickit rule that keeps the good charms and stops
|
|
; picking up junk ones, NOT disabling this guard.
|
|
protect_charms_from_sell=0
|
|
; pick_rares_for_gold: 1 = pick all yellow (rare) ground items; non-keep rares will be sold
|
|
; Requires sell_junk=1 to convert extra pickups into gold.
|
|
pick_rares_for_gold=0
|
|
; pick_gold: 1 = pick up ground gold piles, 0 = ignore all ground gold
|
|
pick_gold=1
|
|
|
|
[transmute]
|
|
;stash tabs by priority where to put transmuted gems
|
|
stash_destination=0,1,2,3
|
|
; Add these possible gems to "transmute" to transmute them:
|
|
; chipped, flawed, standard, flawless
|
|
; DISABLED 2026-08-26: gems are stashed to the GEMS tab and left alone, no cube/convert
|
|
; runs. An empty value makes run_transmutes() bail at "No gem tiers configured", which
|
|
; also holds for force=True (tools/gem_transmute.py), unlike transmute_every_x_game=0.
|
|
; Re-enable by listing tiers again, e.g. transmute=flawless
|
|
transmute=flawless
|
|
;how often we want to run transmute routine(e.g. every 100 games)
|
|
transmute_every_x_game=800
|
|
; number of stash tabs — drives tab click geometry in inventory/common.tab_properties().
|
|
; MUST match the tab bar on screen. This client shows 5: PERSONAL SHARED GEMS MATERIALS RUNES.
|
|
; It was 6, which made tab_properties compute centres of 63/127/192/256/320/384 while the
|
|
; real label centres are 68/144/220/295/370 — tabs 2, 3 and 4 clicked the gaps between tabs.
|
|
stash_tabs=5
|
|
; potion transmute settings
|
|
; convert_rejuv: 1 = convert regular Rejuv Potions to Full Rejuv via cube (3 -> 1)
|
|
convert_rejuv=0
|
|
; min_rejuv_to_convert: minimum regular rejuv potions in inventory before starting conversion
|
|
min_rejuv_to_convert=6
|
|
|
|
; ===========================
|
|
; ==== Builds: Sorceress ====
|
|
; ===========================
|
|
[sorceress]
|
|
energy_shield=f4
|
|
frozen_armor=f7
|
|
static_field=f5
|
|
telekinesis=f6
|
|
thunder_storm=
|
|
|
|
[light_sorc]
|
|
; chain_lightning must be bound to left skill (hotkey optional as it shouldnt change)
|
|
chain_lightning=
|
|
; lightning must be right skill, hotkey required
|
|
lightning=
|
|
; frozen orb must be right skill, hotkey recommended to increase safty for you and merc at trav!
|
|
frozen_orb=
|
|
|
|
[blizz_sorc]
|
|
; blizzard must be right skill, hotkey required
|
|
blizzard=f1
|
|
; ice_blast must be left skill (hotkey optional as it shouldnt change)
|
|
ice_blast=f2
|
|
|
|
[blizzorb_sorc]
|
|
; frozen orb must be left skill and preselected (no hotkey required)
|
|
|
|
;All others must be right skill and hotkey required!
|
|
blizzard=f1
|
|
glacial_spike=f7
|
|
|
|
[nova_sorc]
|
|
; nova must be right skill, hotkey required
|
|
nova=f1
|
|
|
|
[hydra_sorc]
|
|
; only supports Pindle and Eldritch currently
|
|
; alt_attack is any alternate attacking right skill. Fireball,Lightning,Frozen Orb, hotkey required
|
|
alt_attack=f7
|
|
; hydra must be right skill, hotkey required
|
|
hydra=f1
|
|
|
|
; =========================
|
|
; ==== Builds: Paladin ====
|
|
; =========================
|
|
[paladin]
|
|
cleansing=
|
|
holy_shield=f4
|
|
redemption=f2
|
|
vigor=f3
|
|
|
|
[fohdin]
|
|
; foh must be left skill, hotkey required
|
|
blessed_hammer=f1
|
|
concentration=f8
|
|
conviction=f5
|
|
foh=f6
|
|
holy_bolt=f7
|
|
|
|
[hammerdin]
|
|
blessed_hammer=f9
|
|
concentration=f1
|
|
conviction=
|
|
|
|
; =========================
|
|
; ==== Builds: Warlock ====
|
|
; =========================
|
|
[warlock]
|
|
; All skills should be on right-click unless otherwise specified
|
|
deathmark=f3
|
|
lethargy=f4
|
|
;Set summon_demon to one of the three demons of your choice.
|
|
summon_demon=f5
|
|
;If you are summoning a 2nd demon set hotkey here. Can be same as above
|
|
summon_demon2=
|
|
psychic_ward=
|
|
|
|
[fire_lock]
|
|
; Supported runs: Pindle
|
|
;flame_wave must be assigned to left-click and doesn't require hotkey
|
|
ring_of_fire=f1
|
|
apocalypse=f2
|
|
|
|
[abyss_lock]
|
|
; Supported runs: Pindle
|
|
;miasma_bolt must be assigned to left-click and doesn't require hotkey
|
|
miasma_chain=f1
|
|
abyss=f2
|
|
|
|
[echo_lock]
|
|
; Supported runs: Trav (tele only)
|
|
echo_strike=f1
|
|
eldritch_blast=f2
|
|
hex_bane=f3
|
|
;Set ring of fire if you want to stun before echo blast
|
|
ring_of_fire=
|
|
|
|
; ==========================
|
|
; ==== Builds: Assassin ====
|
|
; ==========================
|
|
; Currently no Trav implementaiton!
|
|
[trapsin]
|
|
; We assume fire blast or shock web is left-click skill which is optional hotkey if pre-assigned.
|
|
skill_left=
|
|
; Assume all other skills are right-click and hotkey required!
|
|
burst_of_speed=f1
|
|
death_sentry=f2
|
|
fade=
|
|
lightning_sentry=f3
|
|
shadow_warrior=f4
|
|
mind_blast=f5
|
|
|
|
; ===========================
|
|
; ==== Builds: Barbarian ====
|
|
; ===========================
|
|
; Supported runs: Trav, Pindle, Eld, Shenk, Nihlathak (tele only)
|
|
; Make sure leap hotkey is set if you do not have Enigma
|
|
; Ensure Battle Order/Command hotkeys are set above in the [char] section
|
|
[barbarian]
|
|
cry_frequency=0.7
|
|
find_item=
|
|
leap=
|
|
shout=
|
|
war_cry=
|
|
|
|
; ===========================
|
|
; ==== Builds: Amazon ====
|
|
; ===========================
|
|
; Supported runs: Trav, Pindle, Eld, Shenk, Nihlathak (tele only)
|
|
; Make sure leap hotkey is set if you do not have Enigma
|
|
; Ensure Battle Order/Command hotkeys are set above in the [char] section
|
|
[amazon]
|
|
;all must be right-click skill
|
|
valkyrie=f1
|
|
|
|
[javazon]
|
|
; charged strike must be left-click skill and preselected, no hotkey required
|
|
|
|
;all others must be right-click
|
|
lightning_fury=f2
|
|
|
|
; ==========================
|
|
; ==== Builds: Necro ====
|
|
; ==========================
|
|
; Pindle+eld+shenk+trav (walking only!)
|
|
; needs all of these skills
|
|
;skill_left is just some ranged damage spell (spear,teeth, nova,etc)
|
|
;leave teleport blank for now this build currently is walking only
|
|
;tested with something like this https://d2.maxroll.gg/d2planner/3x01067c
|
|
;recomended to set skeleton mage to same as revive hot hey
|
|
;skeleton mages cause pathing issues not ideal to use yet
|
|
[necro]
|
|
amp_dmg=
|
|
bone_armor=
|
|
clay_golem=
|
|
clear_pindle_pack=
|
|
corpse_explosion=
|
|
heart_of_wolverine=
|
|
raise_mage=
|
|
raise_revive=
|
|
raise_skeleton=
|
|
skill_left=
|
|
|
|
[poison_necro]
|
|
bone_armor=
|
|
# Can use any golem
|
|
clay_golem=
|
|
clear_pindle_pack=
|
|
corpse_explosion=
|
|
heart_of_wolverine=
|
|
# Can Use any curse
|
|
lower_res=
|
|
poison_nova=
|
|
raise_mage=
|
|
raise_revive=
|
|
raise_skeleton=
|
|
# Not Required
|
|
skill_left=
|
|
|
|
[bone_necro]
|
|
bone_armor=
|
|
bone_spear=
|
|
bone_spirit=
|
|
bone_wall=
|
|
clay_golem=
|
|
teeth=
|
|
; Damage scaling. One setting to adjust kill speed to account for better/worse gear.
|
|
; ex: 2 will cast all attack skills twice a long, .5 half as long. Currently only used by bone necro
|
|
damage_scaling=1
|
|
|
|
|
|
; ==== Builds: Basic ====
|
|
; Supported runs: UNTESTED (this is your job!)
|
|
; this will basically continuously left attack, unless right attack is available.
|
|
; if the buffs are not set they are not used (they are part of the prebuff setup)
|
|
|
|
[basic]
|
|
left_attack=1
|
|
right_attack=
|
|
buff_1=
|
|
buff_2=
|
|
|
|
|
|
; ==== Builds: Basic Ranged====
|
|
; Supported runs: UNTESTED (this is your job!)
|
|
; this will basically continuously left attack, unless right attack is available.
|
|
; if the buffs are not set they are not used (they are part of the prebuff setup)
|
|
|
|
[basic_ranged]
|
|
left_attack=
|
|
right_attack=
|
|
buff_1=
|
|
buff_2=
|
|
|
|
|
|
; ==== Run: Cold Plains clear ====
|
|
; Roams an outdoor area and kills with ONE configured skill. Works with any build
|
|
; and from clvl 1, so it is the levelling counterpart to the boss runs.
|
|
; Enable by adding run_cold_plains to [routes] order above.
|
|
;
|
|
; PREREQUISITE: the character must already have the destination waypoint.
|
|
; A fresh character has none - walk there once by hand first.
|
|
[cold_plains]
|
|
; Any Act 1 waypoint label from src/ui/waypoint.py _WAYPOINTS, e.g.
|
|
; "Cold Plains", "Stony Field", "Dark Wood", "Black Marsh".
|
|
area=Cold Plains
|
|
; Key holding the attack skill. NOTE Fireball is clvl 12 - on a fresh character
|
|
; put Fire Bolt (clvl 1) here and re-bind to Fireball later; nothing else changes.
|
|
attack_hotkey=
|
|
; Most sorc/caster skills cast on right click. Melee builds want "left".
|
|
attack_button=right
|
|
; How many roam-or-fight steps before heading back to town.
|
|
max_steps=12
|
|
; Casts per engagement before re-scanning for targets.
|
|
casts_per_target=4
|
|
; Ignore anything further than this many px from the character.
|
|
target_radius=600
|
|
; Delay between casts. Raise if you out-run your cast animation.
|
|
cast_delay=0.25
|
|
; Hard runtime cap per run, seconds - stops a bad area pinning the bot.
|
|
max_runtime_s=180
|
|
; Engagements per step, so an unkillable/misdetected target cannot stall the run.
|
|
max_engagements=8
|
|
|
|
[baal_xp]
|
|
; Baal XP farm: join public Baal games, hide, collect XP, leave. Repeat.
|
|
; Enable by adding run_baal_xp to [routes] order above.
|
|
enabled=1
|
|
; Substring to match against game names (case-insensitive). Empty = join first game.
|
|
game_name_filter=
|
|
; Max seconds to wait in a game before leaving (XP keeps ticking while you hide).
|
|
max_wait_s=900
|
|
; Leave early if XP gained in this game reaches this value.
|
|
xp_threshold=50000000
|
|
; Leave immediately if HP drops below this percentage (chicken).
|
|
min_hp_pct=40
|
|
; Screen position (client coords) to walk to and stand still while hiding.
|
|
hide_x=640
|
|
hide_y=360
|
|
; Max seconds to wait for a matching game to appear in the browser.
|
|
join_timeout_s=60
|
|
|
|
[advanced_options]
|
|
; startup hotkeys
|
|
; select_runs_key: open run selector UI
|
|
select_runs_key=pagedown
|
|
; restore_settings_from_backup_key: restore backed-up D2R settings
|
|
restore_settings_from_backup_key=insert
|
|
; settings_backup_key: create backup of current D2R settings
|
|
settings_backup_key=pause
|
|
; auto_settings_key: auto-apply required D2R settings
|
|
auto_settings_key=pageup
|
|
; graphic_debugger_key: toggle on-screen debug layers
|
|
graphic_debugger_key=delete
|
|
; resume_key: start/pause bot loop
|
|
resume_key=f11
|
|
; exit_key: hard stop bot
|
|
exit_key=f12
|
|
; cycle_pickit_profile_key: cycle through pickit profiles in config/pickit_profiles/
|
|
cycle_pickit_profile_key=f10
|
|
|
|
; etc.
|
|
; graphic_debugger_layer_creator: 1 = enable interactive layer creator tooling
|
|
graphic_debugger_layer_creator=0
|
|
; hwnd_window_process: process regex used to locate D2R window handle
|
|
hwnd_window_process=D2R\.exe
|
|
; hwnd_window_title: optional title regex override for window lookup
|
|
hwnd_window_title=
|
|
; launch_options: will replace <name> with setting for [general] "name" above
|
|
launch_options=-mod <name> -txt
|
|
; logg_lvl: logging verbosity (debug/info/warning/error)
|
|
logg_lvl=debug
|
|
; message_body_template: payload template for generic_api mode
|
|
message_body_template={{"content": "{msg}"}}
|
|
; message_headers: optional JSON headers for generic_api mode
|
|
message_headers=
|
|
; ocr_during_pickit: 1 = run OCR while looting (slower, more diagnostics)
|
|
ocr_during_pickit=0
|
|
;use "can_teleport_natively" or "can_teleport_with_charges" if you want to force certain behavior in case autodetection isn't working properly
|
|
override_capabilities=can_teleport_natively
|
|
; pathing_delay_factor: movement/click delay multiplier (1 fast .. 10 slow)
|
|
pathing_delay_factor=2
|
|
; If you want to control Hyper-V window from host use 0,51 here
|
|
; window_client_area_offset: x,y pixel offset for captured game client area
|
|
window_client_area_offset=0,0
|
|
|
|
[log_rotation]
|
|
; Log rotation prevents screenshot directories from filling the disk.
|
|
; Each managed directory has a max file count and max total size.
|
|
; When limits are exceeded, oldest files are deleted automatically.
|
|
; Checked every 60 seconds (to avoid I/O overhead during runs).
|
|
;
|
|
; The text log (log/log.txt) is size-capped separately: it rotates at 50 MB,
|
|
; keeps 5 zipped backups in log/archive/ (max 30 archives). Override the per-file
|
|
; cap with the BOTTY_LOG_MAX_MB environment variable (e.g. set 100 for 100 MB).
|
|
|
|
; pickit directory (log/screenshots/pickit/):
|
|
; Can grow very fast — every item scan writes a PNG + JSON.
|
|
; pickit_max_files=500 ; max files before rotation kicks in
|
|
; pickit_max_mb=500 ; max total size in MB
|
|
pickit_max_files=300
|
|
pickit_max_mb=200
|
|
|
|
; info directory (log/screenshots/info/):
|
|
; Debug screenshots for deaths, chickens, errors, etc.
|
|
; info_max_files=200 ; max files before rotation kicks in
|
|
; info_max_mb=500 ; max total size in MB
|
|
info_max_files=100
|
|
info_max_mb=200
|
|
|
|
; items directory (log/screenshots/items/):
|
|
; Loot screenshots sent to Discord.
|
|
; items_max_files=100
|
|
; items_max_mb=100
|
|
items_max_files=50
|
|
items_max_mb=50
|
|
|
|
; discord_notify_rotation: 1 = send Discord message when log rotation deletes files
|
|
discord_notify_rotation=0
|