AIO Smelter
by SolemnVanguard ·Smithing
All in one smelter
1
Installed
1.0
Version
23 Aug 2026
Updated
About this script
All in one smelter, smelts all bars from Bronze to Rune.
Builds
| Version | Kind | Published | Size | What changed |
|---|---|---|---|---|
| 1.0 current | text script | 23 Aug 2026 | 10 KB | First upload. |
Source of 1.0
Published by the author. This is the current build, exactly as it will be delivered.
script "AIO Bar Smelter" author "SolemnVanguard" version "1.0" every 600 setting BarType selectedBar = BarType.BRONZE "Which bar to smelt (only one at a time)" enum BarType { BRONZE, IRON, STEEL, SILVER, GOLD, MITHRIL, ADAMANTITE, RUNE } # Withdraws the correct ore(s) - and coal, if the selected bar needs it - # from the Bank Chest (id 942) near tile(333, 553), walks to the Furnace # (id 118) via tile(324, 553), tile(315, 550), and tile(311, 545), # smelts them, then walks back and deposits the bars, repeating forever. # Uses Sleeping Bag (id 1263) at 100% fatigue. # # Recipes (ore ids, coal-per-bar, bar id): # BRONZE - copper ore (150) + tin ore (202), no coal -> 169 # IRON - iron ore (151), no coal -> 170 # STEEL - iron ore (151) + 2 coal (155) -> 171 # SILVER - silver ore (383), no coal -> 384 # GOLD - gold ore (152), no coal -> 172 # MITHRIL - mithril ore (153) + 4 coal (155) -> 173 # ADAMANTITE - adamantite ore (154) + 6 coal (155) (estimated) -> 174 # RUNE - runite ore (409) + 8 coal (155) (estimated) -> 408 # The adamantite/rune coal amounts follow the classic 2/4/6/8 coal # progression by tier but were not separately confirmed - verify in # game and adjust coalPerBar below if smelting fails partway. # # The withdraw amount is computed from how many total inventory slots # one "unit" of the recipe needs (1 ore, or 1 ore + N coal, or 2 ores # for bronze), so it always fits in the 30-slot inventory regardless of # which bar is selected. # # 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 prevFatigueVal = -1 var haltedFatigueJump = false var FatigueJumpLimit = 25 var oreIdA = 150 var oreIdB = -1 var coalPerBar = 0 var barId = 169 var withdrawAmount = 15 var useCoalAsSelector = false fun halted() -> bool { return haltedFatigueJump } 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 } # Sets oreIdA/oreIdB/coalPerBar/barId/withdrawAmount from the chosen # BarType. withdrawAmount = how many units of the recipe fit in 30 # inventory slots (1 slot spare), where a "unit" is 1 ore (+ coal, or # + a second ore for bronze). fun setupRecipe() { useCoalAsSelector = false if selectedBar.name == "BRONZE" { oreIdA = 150 oreIdB = 202 coalPerBar = 0 barId = 169 withdrawAmount = 15 } else if selectedBar.name == "IRON" { oreIdA = 151 oreIdB = -1 coalPerBar = 0 barId = 170 withdrawAmount = 30 } else if selectedBar.name == "STEEL" { oreIdA = 151 oreIdB = -1 coalPerBar = 2 barId = 171 withdrawAmount = 10 useCoalAsSelector = true } else if selectedBar.name == "SILVER" { oreIdA = 383 oreIdB = -1 coalPerBar = 0 barId = 384 withdrawAmount = 30 } else if selectedBar.name == "GOLD" { oreIdA = 152 oreIdB = -1 coalPerBar = 0 barId = 172 withdrawAmount = 30 } else if selectedBar.name == "MITHRIL" { oreIdA = 153 oreIdB = -1 coalPerBar = 4 barId = 173 withdrawAmount = 6 } else if selectedBar.name == "ADAMANTITE" { oreIdA = 154 oreIdB = -1 coalPerBar = 6 barId = 174 withdrawAmount = 4 } else if selectedBar.name == "RUNE" { oreIdA = 409 oreIdB = -1 coalPerBar = 8 barId = 408 withdrawAmount = 3 } } on start { if not bankAvailable() { print("Bank not available") } if not minimapAvailable() { print("Warning: minimap hooks not ready yet - walkPath may misbehave") } setupRecipe() print("Selected bar:", selectedBar.name, "ore A:", oreIdA, "ore B:", oreIdB) print("coal/bar:", coalPerBar, "withdraw:", withdrawAmount) pathStart("route", "bank", tile(333, 553)) pathTile("route", tile(324, 553)) pathTile("route", tile(315, 550)) pathFinish("route", "furnace", tile(311, 545)) } state banking { 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) } setupRecipe() let chest = nearestObject(id: 942, within: 5) if chest == none { print("No Bank Chest (942) found - waiting") return 1000 } if not bankIsOpen() { if reach(chest) == "DRAWN" { interact(chest, "open") wait until bankIsOpen() timeout 2000 else { return 300 } } return 1000 } if invContains(barId) { bankDepositAll(barId) wait random(200, 500) return 600 } if not bankWithdraw(oreIdA, withdrawAmount) { print("Failed to withdraw ore A (", oreIdA, ") - bank may be out of stock") bankClose() return 1000 } wait random(200, 400) if oreIdB != -1 { if not bankWithdraw(oreIdB, withdrawAmount) { print("Failed to withdraw ore B (", oreIdB, ") - bank may be out of stock") bankClose() return 1000 } wait random(200, 400) } if coalPerBar > 0 { if not bankWithdraw(155, withdrawAmount * coalPerBar) { print("Failed to withdraw coal - bank may be out of stock") bankClose() return 1000 } wait random(200, 400) } bankClose() become goingToFurnace } state goingToFurnace { 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", "furnace") print("walkPath to furnace =", how) if how == "ARRIVED" { stuckCount = 0 become smelting } else if how == "WALKING" { stuckCount = 0 return 900 } else if how == "CROSSING" { stuckCount = 0 return 1500 } else if how == "RECOVERING" or how == "BLOCKED" { return 900 } else if how == "STUCK" or how == "LOST" { stuckCount = stuckCount + 1 print("Stuck/lost (", stuckCount, ") going to furnace") if stuckCount >= 10 { print("Been stuck too long - resetting path") pathReset("route") stuckCount = 0 } return 1200 } else { print("goingToFurnace status:", how) return 1000 } } state smelting { 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 not invContains(oreIdA) { become goingToBank } if oreIdB != -1 and not invContains(oreIdB) { become goingToBank } if batchActive() { return 600 } let furnace = nearestObject(id: 118, within: 10) if furnace == none { print("No Furnace (118) found nearby") return 1000 } # Only STEEL selects coal and uses it on the furnace (with iron ore # just sitting in inventory). MITHRIL/ADAMANTITE/RUNE work the other # way around: you select the ORE itself and use it on the furnace, # with coal just sitting in inventory. let selectItemId = oreIdA if useCoalAsSelector { selectItemId = 155 } let ore = invItem(selectItemId) if ore == none { become goingToBank } if reach(furnace) == "DRAWN" { let selected = interact(ore, "Use") if not selected { return 600 } let used = interact(furnace, "Use") if not used { walkTo(myTile()) } else { wait until not batchActive() timeout 90000 else { return 600 } } } return random(1500, 2000) } state goingToBank { 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") print("walkPath to bank =", how) if how == "ARRIVED" { stuckCount = 0 become banking } else if how == "WALKING" { stuckCount = 0 return 900 } else if how == "CROSSING" { stuckCount = 0 return 1500 } else if how == "RECOVERING" or how == "BLOCKED" { return 900 } else if how == "STUCK" or how == "LOST" { stuckCount = stuckCount + 1 print("Stuck/lost (", stuckCount, ") going to bank") if stuckCount >= 10 { print("Been stuck too long - resetting path") pathReset("route") stuckCount = 0 } return 1200 } else { print("goingToBank status:", how) return 1000 } } on render { if halted() { 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) } }