Skip to main content

AutoMine

Auto-farm gemstones in MINEWORLD. Two scripts ship in scripts/lua/, two different control shapes — pick whichever you find easier to read and modify.

ScriptControl shapeLinesBest for
auto_mine.luaFinite-state machine (Surveying → Approaching → Acting → Exiting)~1500Production runs. Most edge-case recovery, hot-reloadable config, humanizer breaks, repair-kit handling.
auto_mine_v2.luaFlat single-tick loop~420Reading + tweaking. Fewer state transitions, easier to follow if you're forking the algorithm.

Both achieve the same goal — they walk to gem blocks / drops, mine, collect, and chain biome levels — but the FSM variant is the one used by the desktop app's "Start AutoMine" button.


What both scripts do

  1. Loop with ping-aware delay (~280–450 ms + jitter) — keeps send cadence below the server's speed-hack threshold.
  2. Auto-enter MINEWORLD at the configured biome level if the bot isn't there already.
  3. Equip the best pickaxe in inventory (Dark > Epic > Master > Heavy > Sturdy > Basic > Flimsy > Crappy).
  4. Pick the closest reachable target within a 60-tile radius. Collectables (drops on the floor) win over gem blocks.
  5. Skip targets near AI enemies (3-tile buffer). Hit melee-range enemies before mining if any are inside reach.
  6. Auto-collect any drop within a 2-tile magnet radius every tick.
  7. Track per-tile hit attempts. After ~12 misses on the same tile, mark it as a dead-end and stop pathing through it.
  8. Walk one step at a time, checking the path on every tick — handles drops appearing mid-route, enemies spawning, paths being mined open by other players.

The FSM variant adds: humanizer (chat lines + idle breaks), pickaxe repair-kit handling, ER=8 (broken pickaxe) escalation, periodic profile-level checks, and mine-tier auto-progression.


FSM variant

scripts/lua/auto_mine.lua

Default. Production-grade. The desktop app's AutoMine toggle runs this script.

Run from Lua

dofile("scripts/lua/auto_mine.lua")

The script reads its config from storage:get("automine.cfg") at start. Touch storage:get("automine.cfg_version") to force a hot-reload — the running script picks up the new config without a restart.

Config shape (storage key automine.cfg)

KeyTypeDefaultDescription
enabledbooleantrueMaster switch. Set to false to keep the script alive but idle.
mine_tierstring"Bronze"Current biome tier. One of Newbie, Bronze, Silver, Golden, Platinum. Auto-bumps when the bot's level crosses each tier's gate.
speedstring"normal""think", "normal", or "fast". Tunes punch / walk delays. "fast" is closer to the server's speed-hack ceiling.
humanizebooleantrueSend occasional chat + take idle breaks. Disable for short runs.
respect_adminbooleantrueExit the world if an admin joins.

Config is a Lua table — write it through storage:set("automine.cfg", { … }) from another script, or via the desktop UI's AutoMine settings.

Stop

getClient():scripting():stop()

Or hit Stop on the Scripts page.


Flat-loop variant

scripts/lua/auto_mine_v2.lua

Same goal, simpler shape. ~420 lines, no state machine, no storage config — tunables live as locals at the top of the file. Recommended if you want to read or fork the mining loop without unwrapping the FSM.

Raw download: auto_mine_v2.lua · auto_mine.lua — paste either URL into your script editor's "Open from URL" or fetch it via http:get(url).

Run from Lua

-- Default: enter MINEWORLD level 0 (Newbie), run until stopped
dofile("scripts/lua/auto_mine_v2.lua")

The script auto-runs runAutomine(getClient()) once loaded.

Run from URL

local source, err = http:get("https://docs-seraph.growpai.site/scripts/auto_mine_v2.lua")
if source then
load(source)()
end

Run with options

runAutomine(getClient(), {
level = 4, -- 0=Newbie, 1=Bronze, 2=Silver, 3=Golden, 4=Platinum
world = "MINEWORLD", -- usually leave default
})

Tunables

Edit the constants at the top of auto_mine_v2.lua:

ConstantDefaultDescription
MAX_TILE_ATTEMPTS12Per-tile hit retries before marking dead-end.
SEARCH_RADIUS60Max distance (tiles) for gem-block hunt.
COLLECT_RADIUS2Magnet pickup radius.
ENEMY_BUFFER3Skip targets this close to AI enemies.
MELEE_RANGE2Combat reach for hitting enemies.
BASE_DELAY_MS280Tick baseline (real client ~250 ms).
JITTER_MAX_MS80Random jitter ceiling.
WORLD_TRANSITION_WAIT4.0Seconds to wait after sending mines() before re-evaluating.

Caveats vs FSM variant

  • No humanizer (no chat, no idle breaks).
  • No hot-reload via storage config — restart the script to apply tunable changes.
  • No pickaxe repair-kit handling — assumes you have a non-broken pickaxe in inventory.
  • No ER=8 broken-pickaxe escalation — the script just keeps swinging.
  • No mine-tier auto-progression — call runAutomine again with a new level when ready to bump.

The trade-off is intentional: simpler script, fewer surprises while reading, slower to recover from edge cases.


How target selection works

Both scripts share the same priority logic:

  1. Pass 1: collectables. For every drop on the floor (not on cooldown), distance-rank against the player. Skip drops within 3 tiles of an AI enemy. Closest wins.
  2. Pass 2: gemstones. Only run if no collectable was found. Scan a 60-tile box around the player. A tile is a candidate if its block id sits in one of these ranges:
    • 3995..4003 (basic gem blocks)
    • 4101..4102 (rare gem blocks)
    • 4154..4162 (advanced gem blocks)
  3. Sticky target. Once a target is picked, both scripts stick with it across ticks — even if a slightly closer one appears — until either: the target is destroyed/collected, the tile is flagged as a dead-end, or the path becomes unreachable.

How combat works

Single-target priority. On every tick:

  1. Find the closest alive AI enemy within Manhattan distance 2.
  2. Send one HAI (Hit AI Enemy) packet at it.
  3. Continue with the mining loop — combat is a side action, not a state.

This matches the upstream MineBot.cs reference: spamming HAI at multiple enemies in one tick triggers a "machine-gun" anti-cheat kick.


How dead-ends work

Tiles that absorb 12 hits without dropping a DB (destroy block) packet are treated as bedrock for path planning. The script:

  1. Bumps a per-tile counter on every hit.
  2. When the counter hits 12, marks the tile as a permanent dead-end for this world.
  3. Drops the entry from the counter table only if the server later confirms the tile destroyed (foreground tile id goes to 0).

The FSM variant masks dead-end tiles in a copy of the foreground layer and feeds the masked tiles to A*. The flat-loop variant catches dead-ends at the next-step gate (so A* might still propose a path through one, but the script skips re-hitting it).


Tuning checklist

If the script feels off:

  • "Speed-hack" kicks (KErr ER=7) → bump BASE_DELAY_MS or switch to speed = "think" in the FSM config.
  • Bot stuck swinging at one tile → check inventory for a working pickaxe. The FSM variant will fire ER=8 broken-pickaxe handling automatically; the flat-loop variant just waits.
  • Bot wanders past valid gem blocks → check is_minegem ranges match the current world's biome IDs. Newer biomes occasionally add IDs.
  • Auto-collect misses drops → drops further than 2 tiles are out of magnet range; the script doesn't chase them. Lower BASE_DELAY_MS to scan more often, or widen COLLECT_RADIUS if your map allows.

See also

  • Client → Pathfindingclient:planPath / hasPathBetween for custom target-pick logic.
  • Protocol — KErr codes — what each kick code means and how the runtime reacts.
  • Events — subscribe to p:DB / p:HAI / p:KErr if you want to instrument your own miner.