-- Configuration Settings
local serverUrl = "wss://://yourdomain.com"
local token = "your_secure_secret_token"
local FUEL_LIMIT = 400
-- Operational & Spatial State Tracking
local turtleId = tostring(os.computerID())
local idNum = os.computerID()
local ws = nil
local stopRequested = false
local lastHeartbeat = os.epoch("utc")
-- Saved State for Resumption
local jobActive = false
local targetX, targetY, targetZ = 0, 0, 0
local savedX, savedY, savedZ = 1, 1, 1
-- Relative Position Tracking Matrix
local currentX, currentY, currentZ = 0, 0, 0
local currentDir = 0 -- 0=Forward (+X), 1=Right (+Y), 2=Back (-X), 3=Left (-Y)
local function trackTurnRight()
turtle.turnRight()
currentDir = (currentDir + 1) % 4
end
local function trackTurnLeft()
turtle.turnLeft()
currentDir = (currentDir - 1) % 4
end
local function trackForward()
while turtle.detect() do
turtle.dig()
os.sleep(0.4)
end
if turtle.forward() then
if currentDir == 0 then currentX = currentX + 1
elseif currentDir == 1 then currentY = currentY + 1
elseif currentDir == 2 then currentX = currentX - 1
elseif currentDir == 3 then currentY = currentY - 1
end
return true
end
return false
end
local function trackDown()
while turtle.detectDown() do turtle.digDown() end
if turtle.down() then
currentZ = currentZ - 1
return true
end
return false
end
local function trackUp()
while turtle.detectUp() do turtle.digUp() end
if turtle.up() then
currentZ = currentZ + 1
return true
end
return false
end
local function navigateHome()
sendUpdate("Returning Home", "Initiating return path tracking sequence to base dock.")
while currentZ < 0 do trackUp() end
while currentZ > 0 do trackDown() end
if currentY > 0 then
while currentDir ~= 3 do trackTurnRight() end
while currentY > 0 do trackForward() end
elseif currentY < 0 then
while currentDir ~= 1 do trackTurnRight() end
while currentY < 0 do trackForward() end
end
if currentX > 0 then
while currentDir ~= 2 do trackTurnRight() end
while currentX > 0 do trackForward() end
end
while currentDir ~= 0 do trackTurnRight() end
sendUpdate("Idle", "Successfully docked at home station.")
jobActive = false
end
local function getFullSlots()
local fullCount = 0
for i = 1, 16 do if turtle.getItemCount(i) > 0 then fullCount = fullCount + 1 end end
return fullCount
end
local function getTelemetry(currentStatus)
return {
fuel = turtle.getFuelLevel(),
maxFuel = turtle.getFuelLimit(),
inventorySlots = getFullSlots(),
status = currentStatus or "Idle",
pos = {x = currentX, y = currentY, z = currentZ}
}
end
local function sendUpdate(status, logMessage)
if ws then
pcall(function()
ws.send(textutils.serializeJSON({
type = "telemetry",
turtleId = turtleId,
data = getTelemetry(status),
logMessage = logMessage
}))
end)
end
end
local function checkFuelSafety()
if turtle.getFuelLevel() == "unlimited" then return true end
local distanceHome = math.abs(currentX) + math.abs(currentY) + math.abs(currentZ)
local absoluteMinimumNeeded = distanceHome + 5
if turtle.getFuelLevel() <= absoluteMinimumNeeded then
sendUpdate("Low Fuel Return", "Critical fuel fallback reached. Heading home.")
navigateHome()
return false
end
return true
end
-- Resumable Mining Engine Loop
local function executeMiningJob()
stopRequested = false
-- Handle Initial Shift Alignment only if we haven't started mining yet
if savedX == 1 and savedY == 1 and savedZ == 1 then
local myOffsetSequence = (idNum - 1) * targetY
if myOffsetSequence > 0 then
sendUpdate("Positioning", "Shifting right by " .. myOffsetSequence .. " blocks to align team row.")
trackTurnRight()
for i = 1, myOffsetSequence do trackForward() end
trackTurnLeft()
end
end
sendUpdate("Mining Grid Active", "Resuming/Starting sector clearing: " .. targetX .. "x" .. targetY .. "x" .. targetZ)
-- Resume directly from the saved structural pointers
for z = savedZ, targetZ do
savedZ = z
for y = savedY, targetY do
savedY = y
for x = savedX, targetX - 1 do
savedX = x
os.sleep(0.05)
-- If connection drops out, wait right here until ws is alive again!
if not ws then
sendUpdate("Reconnecting", "Connection lost! Pausing mining operation until server is online...")
print("Lost server handshake. Freezing task loop until reconnected...")
while not ws do os.sleep(1) end
lastHeartbeat = os.epoch("utc")
sendUpdate("Mining Grid Active", "Connection restored! Resuming task.")
end
if stopRequested then
sendUpdate("Aborted", "Halted by backend request.")
navigateHome()
return
end
if getFullSlots() >= 16 then
sendUpdate("Returning Base", "Inventory full.")
navigateHome()
return
end
if not checkFuelSafety() then return end
trackForward()
end
savedX = 1 -- Reset row index for next sequence loop line
if y < targetY then
if y % 2 == 1 then
trackTurnRight()
trackForward()
trackTurnRight()
else
trackTurnLeft()
trackForward()
trackTurnLeft()
end
end
end
savedY = 1 -- Reset grid column index for next depth drop
if z < targetZ then
trackDown()
trackTurnRight()
trackTurnRight()
end
end
navigateHome()
end
local function connect()
print("Connecting to Central Control...")
local success, socketOrErr = pcall(http.websocket, serverUrl)
if not success or not socketOrErr then return false end
ws = socketOrErr
ws.send(textutils.serializeJSON({
type = "handshake",
token = token,
turtleId = turtleId,
data = getTelemetry(jobActive and "Mining Grid Active" or "Online")
}))
lastHeartbeat = os.epoch("utc")
print("Connected safely.")
return true
end
-- Global parallel handler threads
local function listenToNetwork()
while true do
if not ws then
if not connect() then os.sleep(5) end
else
local event, url, msg = os.pullEvent()
if event == "websocket_message" then
lastHeartbeat = os.epoch("utc")
local success, payload = pcall(textutils.unserializeJSON, msg)
if success and payload then
if payload.command == "excavate" and not jobActive then
targetX = payload.args.x
targetY = payload.args.y
targetZ = payload.args.z
savedX, savedY, savedZ = 1, 1, 1 -- Reset step pointers
jobActive = true
elseif payload.command == "stop" then
stopRequested = true
end
end
elseif event == "websocket_closed" then
ws = nil
print("WebSocket closed by proxy.")
end
end
end
end
local function jobWorker()
while true do
if jobActive then
executeMiningJob()
end
os.sleep(1)
end
end
-- Fire up networking threads and engine workers side-by-side
parallel.waitForAll(listenToNetwork, jobWorker)