Tin/Copper Miner Varrock East
by SolemnVanguard ·Mining
Mines in Varock East with banking, build in sleep, bank from chest and mod protection
0
Installed
1.0
Version
22 Aug 2026
Updated
Builds
| Version | Kind | Published | Size | What changed |
|---|---|---|---|---|
| 1.0 current | text script | 22 Aug 2026 | 9 KB | First upload. |
Source of 1.0
Published by the author. This is the current build, exactly as it will be delivered.
script "Tin & Copper Miner Varrock" author "SolemnVanguard" version "1.0" every 600 setting string depositIds = "202,150,160,159,154,153,157" "Comma-separated item ids to deposit at the bank" # Mines ONLY the Tin rock (id 104) at exact tile(78, 547) and the Copper # rock (id 100) at exact tile(76, 547), standing at tile(77, 547) - # ignores any other rock with the same ids elsewhere. Alternates between # the two on every attempt (tin is closer to the standing tile and would # otherwise always be picked first), so both get mined even without # knowing when either one is actually depleted. When the inventory is # full, walks the same path as Iron Miner Varrock East to Bank Chest # (id 942) near tile(99, 512), deposits each item id from the depositIds # setting (Tin ore 202, Copper ore 150, plus gems - 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. # # Teleport protection: if the character's tile jumps more than 20 tiles # between passes, the script halts (shows a red warning) rather than # continuing from an unknown location. # # 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. var stuckCount = 0 var lastMinedWasTin = false var lastTile = tile(0, 0) var haveLastTile = false var pendingJump = false var haltedTeleport = false var prevFatigueVal = -1 var haltedFatigueJump = false var FatigueJumpLimit = 25 var depositIdList = range(0, 0) # filled in on start from the setting var depositIndex = 0 fun halted() -> bool { return haltedTeleport or haltedFatigueJump } fun teleportCheck() { let now = myTile() if haveLastTile { let jumped = distance(lastTile, now) if jumped > 20 { if pendingJump { print("Jumped", jumped, "tiles, confirmed on second check - halting") haltedTeleport = true lastTile = now } else { print("Jumped", jumped, "tiles - unconfirmed, checking again next pass") pendingJump = true } } else { pendingJump = false lastTile = now } } else { lastTile = now haveLastTile = true } } 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 start { if not bankAvailable() { print("Bank not available") } if not minimapAvailable() { print("Warning: minimap hooks not ready yet - walkPath may misbehave") } for piece in split(depositIds, ",") { let parsed = parseInt(piece) if parsed != none { depositIdList = append(depositIdList, parsed) } } print("Deposit ids loaded:", count(depositIdList)) pathStart("route", "mine", tile(75, 543)) pathTile("route", tile(74, 543)) pathTile("route", tile(75, 536)) pathTile("route", tile(75, 530)) pathTile("route", tile(79, 522)) pathTile("route", tile(83, 514)) pathTile("route", tile(90, 511)) pathFinish("route", "bank", tile(99, 512)) } state mining { teleportCheck() fatigueSuspiciousCheck() if halted() { 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 batchActive() { return 100 } if lastMinedWasTin { for rock in objectsByDistance(within: 5) { if rock.id == 100 and rock.tile == tile(76, 547) { if reach(rock) == "DRAWN" { interact(rock, "Mine") } lastMinedWasTin = false return random(900, 1400) } } for rock in objectsByDistance(within: 5) { if rock.id == 104 and rock.tile == tile(78, 547) { if reach(rock) == "DRAWN" { interact(rock, "Mine") } lastMinedWasTin = true return random(900, 1400) } } } else { for rock in objectsByDistance(within: 5) { if rock.id == 104 and rock.tile == tile(78, 547) { if reach(rock) == "DRAWN" { interact(rock, "Mine") } lastMinedWasTin = true return random(900, 1400) } } for rock in objectsByDistance(within: 5) { if rock.id == 100 and rock.tile == tile(76, 547) { if reach(rock) == "DRAWN" { interact(rock, "Mine") } lastMinedWasTin = false return random(900, 1400) } } } print("No tin/copper rock found - waiting") return 1000 } state goingToBank { teleportCheck() fatigueSuspiciousCheck() if halted() { 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) } let how = walkPath("route", "bank") if how == "ARRIVED" { stuckCount = 0 depositIndex = 0 become banking } else if how == "WALKING" { stuckCount = 0 return 900 } else if how == "CROSSING" { stuckCount = 0 return 1500 } else if how == "BLOCKED" or how == "STUCK" { stuckCount = stuckCount + 1 print("Blocked/stuck (", stuckCount, ") - waiting for it to clear") if stuckCount >= 10 { print("Been stuck too long - resetting path") pathReset("route") stuckCount = 0 } return 1200 } else { print("goingToBank status:", how) return 1000 } } state banking { teleportCheck() fatigueSuspiciousCheck() if halted() { 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: 5) if chest == none { print("No Bank Chest (942) found - waiting") return 1000 } if not bankIsOpen() { let howReach = reach(chest) print("reach(chest) =", howReach) if howReach == "DRAWN" { let opened = interact(chest, "open") print("interact(chest, 'open') =", opened) 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 { teleportCheck() fatigueSuspiciousCheck() if halted() { 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) } let how = walkPath("route", "mine") if how == "ARRIVED" { stuckCount = 0 become mining } else if how == "WALKING" { stuckCount = 0 return 900 } else if how == "CROSSING" { stuckCount = 0 return 1500 } else if how == "BLOCKED" or how == "STUCK" { stuckCount = stuckCount + 1 print("Blocked/stuck (", stuckCount, ") - waiting for it to clear") if stuckCount >= 10 { print("Been stuck too long - resetting path") pathReset("route") stuckCount = 0 } return 1200 } else { print("goingToMine status:", how) return 1000 } } on render { if halted() { let flashOn = wrap(nowMillis(), 0, 999) < 500 let bg = "#cc0000ee" if haltedTeleport { if not flashOn { bg = "#660000ee" } paintRoundFill(4, 300, 220, 60, 12, bg) paintTextCenteredSized(114, 322, "TELEPORTED", "white", 16) } else { 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) } }