Coal/Mith/Addy Miner Mining guild
by SolemnVanguard ·Mining
Coal/Mith/Addy Miner Mining guild
0
Installed
1.1
Version
21 Aug 2026
Updated
About this script
Coal/Mith/Addy Miner Mining guild with toggle for which ores you want. It will always priorit addy > Mith > Coal
Got sleeping and banking + mod protection
Got sleeping and banking + mod protection
Builds
| Version | Kind | Published | Size | What changed |
|---|---|---|---|---|
| 1.1 current | text script | 21 Aug 2026 | 13 KB | First upload. |
Source of 1.1
Published by the author. This is the current build, exactly as it will be delivered.
script "Coal Miner Guild" author "SolemnVanguard" version "1.1" every 600 setting string depositIds = "155,160,159,154,153,157" "Comma-separated item ids to deposit at the bank" # Mines Adamantite rock (id 108, highest priority), then Mithril rock # (id 107), then Coal rock (id 110 or 111) in the guild mine - each type # has its own on/off toggle in the UI ("Mine adamantite", "Mine # mithril", "Mine coal") so any combination can be enabled at once. # Priority rocks are searched within 30 tiles regardless of how far that # is compared to nearby coal. Rocks with tile.y <= 3387 are ignored # entirely for all three types. When the inventory is full, walks the # path across Ladder (id 198 up / id 223 down) between tile(275, 3397) # (mine side) and tile(281, 570) (bank side), finds a Bank Chest within # 20 tiles, deposits each item id from the depositIds setting (one per # pass, 650ms apart, skipping any id the inventory doesn't actually # contain), then walks back and resumes mining. Uses Sleeping Bag # (id 1263) at 100% fatigue. # # Fatigue failsafe: if fatigue jumps more than 25 points in a single # pass, that is treated as suspicious (e.g. a mod forcing it up to test # you) and the script halts (shows an orange warning) instead of using # the Sleeping Bag as if it were normal. No teleport protection. # # Mining does not use the batch system, so batchActive() never fires for # it. Instead, a swing is tracked as "in progress" until the server's own # chat message reports its outcome (success, a scratch/miss, an empty # rock, a bonus gem find, or "Nothing interesting happens" when a click # lands but produces no real mining action), and only then does the # script click again - this stops it from spamming clicks on the same # rock mid-swing, and reacts to a rock depleting almost instantly since # the very next pass re-evaluates which rock to click. # # Unreachable priority rocks: if reach() fails to reach DRAWN status on # the same adamantite/mithril tile 5 times in a row (e.g. it is boxed in # by other rocks), that tile is skipped for ~15 seconds and the script # falls through to the next priority instead of retrying forever - each # failed reach() can cost up to 7 seconds per the engine's own docs. # # Ladder crossings: on the way back down to the mine, walkPath is only # called once to start the walk. After that the script just waits 22 # seconds (the known time for the whole walk + climb) before checking # status again, instead of polling and risking a re-click mid-climb. # # TEMPORARY DIAGNOSTICS: every chat line is printed, and if miningActive # is stuck true it prints that too - this is to catch any unhandled # server message that silently blocks mining, like the coal/gem/empty- # rock/nothing-interesting ones already found. Remove once confirmed no # more are missing. var miningActive = false var lastAttemptedTile = tile(0, 0) var emptyRockTile = tile(0, 0) var emptyRockUntil = 0 var prevFatigueVal = -1 var haltedFatigueJump = false var FatigueJumpLimit = 25 var ladderCooldownUntil = 0 var reachFailTile = tile(0, 0) var reachFailCount = 0 var depositIdList = range(0, 0) # filled in on start from the setting var depositIndex = 0 fun fatigueSuspiciousCheck() { let curFatigue = fatigue() if prevFatigueVal >= 0 { let jump = curFatigue - prevFatigueVal if jump > FatigueJumpLimit { print("Fatigue spike detected:", prevFatigueVal, "->", curFatigue, "- halting") haltedFatigueJump = true } } prevFatigueVal = curFatigue } on message(line, from) { print("MSG:", line) if contains(line, "You only succeed in scratching the rock") { miningActive = false } if contains(line, "You manage to obtain some coal") { miningActive = false } if contains(line, "You manage to obtain some adamantite ore") { miningActive = false } if contains(line, "You manage to obtain some mithril ore") { miningActive = false } if contains(line, "You just found a ruby") { miningActive = false } if contains(line, "You just found a emerald") { miningActive = false } if contains(line, "You just found a sapphire") { miningActive = false } if contains(line, "You just found a diamond") { miningActive = false } if contains(line, "There is currently no ore available in this rock") { miningActive = false emptyRockTile = lastAttemptedTile emptyRockUntil = nowMillis() + 15000 # avoid it for ~15s, then retry } if contains(line, "Nothing interesting happens") { # The click landed but produced no real mining action - treat it # as a failed attempt so the script tries again next pass instead # of hanging forever waiting for a swing outcome that never comes. miningActive = false } } on start { if not bankAvailable() { print("Bank not available") } if not minimapAvailable() { print("Warning: minimap hooks not ready yet - walkPath may misbehave") } uiToggle("mineAddy", "Mine adamantite", true) uiToggle("mineMith", "Mine mithril", true) uiToggle("mineCoal", "Mine coal", true) for piece in split(depositIds, ",") { let parsed = parseInt(piece) if parsed != none { depositIdList = append(depositIdList, parsed) } } print("Deposit ids loaded:", count(depositIdList)) pathStart("guild", "mine", tile(275, 3397)) pathObject("guild", "Ladder", "Climb-up", "Climb-down", within: 10) pathTile("guild", tile(274, 565)) pathTile("guild", tile(274, 562)) pathTile("guild", tile(280, 563)) pathTile("guild", tile(287, 563)) pathTile("guild", tile(287, 571)) pathFinish("guild", "bank", tile(281, 570)) } state mining { fatigueSuspiciousCheck() if haltedFatigueJump { return 999999 } if isSleeping() { print("Sleeping, fatigue left to sleep off:", sleepFatigue()) return 2000 } if fatigue() >= 100 { print("Fatigue is 100 - using Sleeping Bag") let bag = invItem(1263) if bag != none { interact(bag, "Sleep") } return random(600, 900) } if invIsFull() { become goingToBank } if miningActive { print("miningActive is stuck true - waiting for it to clear") return 300 } let skipEmpty = nowMillis() < emptyRockUntil if uiToggled("mineAddy") { for candidate in objectsByDistance(within: 30) { if candidate.id == 108 and candidate.tile.y > 3387 { if skipEmpty and candidate.tile == emptyRockTile { continue } let howReach = reach(candidate) if howReach == "DRAWN" { lastAttemptedTile = candidate.tile reachFailCount = 0 if interact(candidate, "Mine") { miningActive = true } } else { print("Walking to adamantite rock at", str(candidate.tile), "- reach() =", howReach) if candidate.tile == reachFailTile { reachFailCount = reachFailCount + 1 } else { reachFailTile = candidate.tile reachFailCount = 1 } if reachFailCount >= 5 { print("Adamantite rock unreachable - skipping it for a while") emptyRockTile = candidate.tile emptyRockUntil = nowMillis() + 15000 reachFailCount = 0 } } return random(300, 600) } } } if uiToggled("mineMith") { for candidate in objectsByDistance(within: 30) { if candidate.id == 107 and candidate.tile.y > 3387 { if skipEmpty and candidate.tile == emptyRockTile { continue } let howReach = reach(candidate) if howReach == "DRAWN" { lastAttemptedTile = candidate.tile reachFailCount = 0 if interact(candidate, "Mine") { miningActive = true } } else { print("Walking to mithril rock at", str(candidate.tile), "- reach() =", howReach) if candidate.tile == reachFailTile { reachFailCount = reachFailCount + 1 } else { reachFailTile = candidate.tile reachFailCount = 1 } if reachFailCount >= 5 { print("Mithril rock unreachable - skipping it for a while") emptyRockTile = candidate.tile emptyRockUntil = nowMillis() + 15000 reachFailCount = 0 } } return random(300, 600) } } } if uiToggled("mineCoal") { for rock in objectsByDistance(within: 15) { if (rock.id == 110 or rock.id == 111) and rock.tile.y > 3387 { if skipEmpty and rock.tile == emptyRockTile { continue } if reach(rock) == "DRAWN" { lastAttemptedTile = rock.tile if interact(rock, "Mine") { miningActive = true } } return random(300, 600) } } } print("No coal rock found nearby - waiting") return 1000 } state goingToBank { fatigueSuspiciousCheck() if haltedFatigueJump { return 999999 } if isSleeping() { print("Sleeping, fatigue left to sleep off:", sleepFatigue()) return 2000 } if fatigue() >= 100 { print("Fatigue is 100 - using Sleeping Bag") let bag = invItem(1263) if bag != none { interact(bag, "Sleep") } return random(600, 900) } if nowMillis() < ladderCooldownUntil { return 500 # ladder just clicked once - wait for the climb to finish } let how = walkPath("guild", "bank") print("walkPath to bank =", how) if how == "ARRIVED" { depositIndex = 0 become banking } else if how == "WALKING" { return 900 } else if how == "CROSSING" { ladderCooldownUntil = nowMillis() + 4000 return 500 } else if how == "STUCK" or how == "BLOCKED" { print("Stuck going to bank - resetting path") pathReset("guild") return 1200 } else { print("goingToBank status:", how) return 1000 } } state banking { fatigueSuspiciousCheck() if haltedFatigueJump { return 999999 } if isSleeping() { print("Sleeping, fatigue left to sleep off:", sleepFatigue()) return 2000 } if fatigue() >= 100 { if bankIsOpen() { bankClose() return 600 } print("Fatigue is 100 - using Sleeping Bag") let bag = invItem(1263) if bag != none { interact(bag, "Sleep") } return random(600, 900) } let chest = nearestObject(id: 942, within: 20) if chest == none { print("No Bank Chest (942) found within 20 tiles") return 1000 } if not bankIsOpen() { if reach(chest) == "DRAWN" { interact(chest, "open") wait until bankIsOpen() timeout 2000 else { return 300 } } return 1000 } let id = depositIdList[depositIndex] if id == none { depositIndex = 0 bankClose() become goingToMine } else { if invContains(id) { bankDepositAll(id) } depositIndex = depositIndex + 1 return 650 } } state goingToMine { fatigueSuspiciousCheck() if haltedFatigueJump { return 999999 } if isSleeping() { print("Sleeping, fatigue left to sleep off:", sleepFatigue()) return 2000 } if fatigue() >= 100 { print("Fatigue is 100 - using Sleeping Bag") let bag = invItem(1263) if bag != none { interact(bag, "Sleep") } return random(600, 900) } if nowMillis() < ladderCooldownUntil { return 500 # already clicked once - just waiting to arrive } let how = walkPath("guild", "mine") print("walkPath to mine =", how) if how == "ARRIVED" { miningActive = false become mining } else if how == "WALKING" or how == "CROSSING" { ladderCooldownUntil = nowMillis() + 22000 return 500 } else if how == "STUCK" or how == "BLOCKED" { print("Stuck going to mine - resetting path") pathReset("guild") return 1200 } else { print("goingToMine status:", how) return 1000 } } on render { if haltedFatigueJump { let flashOn = wrap(nowMillis(), 0, 999) < 500 let bg = "#cc6600ee" if not flashOn { bg = "#663300ee" } paintRoundFill(4, 300, 220, 60, 12, bg) paintTextCenteredSized(114, 322, "FATIGUE SPIKE", "white", 16) paintTextCenteredSized(114, 344, "SCRIPT STOPPED", "white", 12) } }