-- Farm settings
local farmLength = 15 -- Farm length
local farmWidth = 15 -- Farm width
local homePosition = {x=0, y=0, z=0, facing=0} -- Home position and direction
local sleepDuration = 120 -- Sleep time in seconds
local seedItem = "minecraft:wheat_seeds" -- Seed ID
-- Turtle's current position
local currentPos = {x=0, y=0, z=0, facing=0} -- facing: 0=north, 1=east, 2=south, 3=west
-- Logging system
local logFile = "farm_log.txt"
local maxLogSize = 10000 -- Maximum lines in log file before rotation
-- Initialize logging
function initLog()
-- Rotate log if it gets too big
if fs.exists(logFile) then
local file = fs.open(logFile, "r")
local lineCount = 0
while file.readLine() do
lineCount = lineCount + 1
end
file.close()
if lineCount > maxLogSize then
local backupFile = "farm_log_old.txt"
if fs.exists(backupFile) then
fs.delete(backupFile)
end
fs.move(logFile, backupFile)
end
end
end
-- Log message to file and console
function log(message)
local timestamp = os.date("%Y-%m-%d %H:%M:%S")
local logMessage = "[" .. timestamp .. "] " .. message
-- Print to console
print(logMessage)
-- Write to log file
local file = fs.open(logFile, "a")
if file then
file.writeLine(logMessage)
file.close()
end
end
-- Main farm function
function main()
-- Initialize logging
initLog()
log("Farm turtle program starting...")
-- Initialize position
currentPos = {x=0, y=0, z=0, facing=0}
homePosition = {x=0, y=0, z=0, facing=0}
while true do
local collected = false
local outOfSeeds = false
log("Starting farm traversal. Farm size: " .. farmLength .. "x" .. farmWidth)
-- Farm traversal
for i = 1, farmLength do
log("Processing row " .. i .. " of " .. farmLength)
for j = 1, farmWidth do
local success, needsResupply = checkAndHarvest()
if needsResupply then
outOfSeeds = true
log("Out of seeds at position: " .. currentPos.x .. ", " .. currentPos.z)
break
end
-- Move forward
if j < farmWidth then
if not moveForward() then
-- If can't move forward, skip this block
log("Cannot move forward at row " .. i .. ", column " .. j .. ", skipping block")
else
log("Moved to position: " .. currentPos.x .. ", " .. currentPos.z)
end
end
end
if outOfSeeds then
log("Breaking due to out of seeds")
break
end
-- Turn and move to next row
if i < farmLength then
log("Moving to next row from row " .. i)
if i % 2 == 1 then
turnRight()
if not moveForward() then
log("Cannot move to next row from row " .. i)
break
end
turnRight()
else
turnLeft()
if not moveForward() then
log("Cannot move to next row from row " .. i)
break
end
turnLeft()
end
log("Successfully moved to next row. New position: " .. currentPos.x .. ", " .. currentPos.z)
else
log("Finished all rows")
end
end
-- Return home using coordinates
log("Farm traversal completed. Returning home.")
returnToHomeByCoords()
-- If out of seeds, resupply
if outOfSeeds then
if resupplySeeds() then
log("Seeds resupplied, continuing work")
else
log("Failed to resupply seeds! Waiting...")
os.sleep(60)
end
end
-- Unload harvest
if emptyInventory() then
collected = true
end
-- Wait
if collected then
log("Harvest collected. Resting for " .. sleepDuration .. " seconds...")
os.sleep(sleepDuration)
else
log("No harvest. Short rest for 60 seconds...")
os.sleep(60)
end
end
end
-- Move forward with position tracking
function moveForward()
local success = turtle.forward()
if success then
-- Update position based on direction
if currentPos.facing == 0 then -- North
currentPos.z = currentPos.z - 1
elseif currentPos.facing == 1 then -- East
currentPos.x = currentPos.x + 1
elseif currentPos.facing == 2 then -- South
currentPos.z = currentPos.z + 1
elseif currentPos.facing == 3 then -- West
currentPos.x = currentPos.x - 1
end
return true
else
return false
end
end
-- Turn right with direction tracking
function turnRight()
turtle.turnRight()
currentPos.facing = (currentPos.facing + 1) % 4
log("Turned right. Now facing: " .. currentPos.facing)
end
-- Turn left with direction tracking
function turnLeft()
turtle.turnLeft()
currentPos.facing = (currentPos.facing - 1) % 4
if currentPos.facing < 0 then
currentPos.facing = 3
end
log("Turned left. Now facing: " .. currentPos.facing)
end
-- Find seeds in inventory
function findSeeds()
for i = 1, 16 do
local item = turtle.getItemDetail(i)
if item and item.name == seedItem then
return i -- Return slot number with seeds
end
end
return nil -- Seeds not found
end
-- Resupply seeds from chest
function resupplySeeds()
log("Resupplying seeds...")
-- Assume chest is in front of turtle at home position
turtle.select(1) -- Select first slot for seed pickup
local success = turtle.suckDown(64) -- Take seeds from chest
if success then
log("Seeds successfully resupplied")
return true
else
log("Failed to get seeds from chest")
return false
end
end
-- Check and harvest crops
function checkAndHarvest()
local success, data = turtle.inspectDown()
local needsResupply = false
if success then
if data.name == "minecraft:wheat" then
if data.state.age == 7 then
log("Harvesting mature wheat at " .. currentPos.x .. ", " .. currentPos.z)
harvestAndReplant()
else
log("Wheat not ready (age: " .. data.state.age .. ") at " .. currentPos.x .. ", " .. currentPos.z)
end
elseif data.name == "minecraft:water" or data.name:find("slab") or data.name:find("stairs") then
-- Skip water blocks and half-blocks
log("Found unsuitable block: " .. data.name .. ", skipping at " .. currentPos.x .. ", " .. currentPos.z)
return true, false
else
log("Found block: " .. data.name .. " at " .. currentPos.x .. ", " .. currentPos.z)
end
else
-- If no block - plant seeds
log("No block found, planting seeds at " .. currentPos.x .. ", " .. currentPos.z)
local planted = plantSeed()
if not planted then
needsResupply = true
end
end
return true, needsResupply
end
-- Harvest and replant
function harvestAndReplant()
local slot = turtle.getSelectedSlot()
turtle.digDown()
plantSeed()
turtle.select(slot)
end
-- Plant seeds
function plantSeed()
local seedSlot = findSeeds()
if seedSlot then
local currentSlot = turtle.getSelectedSlot()
turtle.select(seedSlot)
local success = turtle.placeDown()
turtle.select(currentSlot)
if success then
log("Planted seeds successfully")
else
log("Failed to plant seeds")
end
return success
else
log("Out of seeds! Returning home...")
return false
end
end
-- Return home using coordinates
function returnToHomeByCoords()
log("Returning home from position: " .. currentPos.x .. ", " .. currentPos.z .. ", facing: " .. currentPos.facing)
-- First turn towards home
local dx = homePosition.x - currentPos.x
local dz = homePosition.z - currentPos.z
log("Distance to home: X=" .. dx .. ", Z=" .. dz)
-- Determine needed direction for X movement
if dx > 0 then
-- Need to move east
while currentPos.facing ~= 1 do
turnRight()
end
elseif dx < 0 then
-- Need to move west
while currentPos.facing ~= 3 do
turnRight()
end
end
-- Move along X axis
for i = 1, math.abs(dx) do
if not moveForward() then
-- If can't move straight, find alternative path
findAlternativePath()
end
end
-- Determine needed direction for Z movement
if dz > 0 then
-- Need to move south
while currentPos.facing ~= 2 do
turnRight()
end
elseif dz < 0 then
-- Need to move north
while currentPos.facing ~= 0 do
turnRight()
end
end
-- Move along Z axis
for i = 1, math.abs(dz) do
if not moveForward() then
-- If can't move straight, find alternative path
findAlternativePath()
end
end
-- Turn to home direction
while currentPos.facing ~= homePosition.facing do
turnRight()
end
log("Successfully returned home!")
end
-- Find alternative path when blocked
function findAlternativePath()
log("Looking for alternative path...")
-- Try to bypass obstacle
turnRight()
if moveForward() then
turnLeft()
if moveForward() then
turnLeft()
if moveForward() then
turnRight()
return true
end
end
end
-- If that didn't work, try other side
turnLeft()
turnLeft()
if moveForward() then
turnRight()
if moveForward() then
turnRight()
if moveForward() then
turnLeft()
return true
end
end
end
log("Cannot find alternative path!")
return false
end
-- Unload items to chest
function emptyInventory()
local collected = false
-- Preserve seed slot if exists
local seedSlot = findSeeds()
for i = 1, 16 do
-- Skip seed slot and fuel slot
if i ~= (seedSlot or 0) and i ~= 16 then
turtle.select(i)
local count = turtle.getItemCount()
if count > 0 then
local item = turtle.getItemDetail()
log("Dropping " .. count .. " of " .. (item and item.name or "unknown"))
turtle.dropDown()
collected = true
end
end
end
-- Move seeds to first slot for convenience
if seedSlot and seedSlot ~= 1 then
turtle.select(seedSlot)
turtle.transferTo(1, 64)
end
turtle.select(1) -- Return seeds to main slot
return collected
end
-- Check fuel level
function checkFuel()
local fuelLevel = turtle.getFuelLevel()
local neededFuel = farmLength * farmWidth * 2 + 10
log("Current fuel: " .. fuelLevel .. ", needed: " .. neededFuel)
if fuelLevel < neededFuel then
turtle.select(16)
if turtle.refuel(1) then
log("Fuel refilled. New level: " .. turtle.getFuelLevel())
else
log("No fuel in slot 16!")
end
end
end
-- Start program
checkFuel()
main()