From df436ff84d27ad5b92f54cb0275e124b380609ce Mon Sep 17 00:00:00 2001 From: MayaTheShy Date: Wed, 25 Mar 2026 21:45:33 -0400 Subject: [PATCH] feat: enhance crafting execution to support batch processing with clamping to max stack size --- lib/craft.lua | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/craft.lua b/lib/craft.lua index e883c34..c709297 100644 --- a/lib/craft.lua +++ b/lib/craft.lua @@ -168,7 +168,8 @@ end -- @param recipe crafting recipe table -- @param ctx context table with ops, cfg, state, log, craftTurtleName, networkModem -- @return success, error_message -function craft.executeSingleCraft(recipe, ctx) +function craft.executeSingleCraft(recipe, ctx, batches) + batches = batches or 1 local ops = ctx.ops local cfg = ctx.cfg local st = ctx.state @@ -177,11 +178,14 @@ function craft.executeSingleCraft(recipe, ctx) if not ctx.networkModem then return false, "No modem" end if not peripheral.isPresent(ctx.craftTurtleName) then return false, "Turtle offline" end + -- Clamp batches to 64 (max stack size per slot) + batches = math.min(batches, 64) + local chests = ops.getChests() local slotMap = {} local reserved = {} - -- Map each grid position to a chest slot + -- Map each grid position to a chest slot, pulling `batches` items per slot for gridPos = 1, 9 do local itemName = recipe.grid[gridPos] if itemName then @@ -195,11 +199,12 @@ function craft.executeSingleCraft(recipe, ctx) for slot, si in pairs(chest.list()) do local key = src.chest .. ":" .. slot if si.name == itemName and not reserved[key] then + local pullCount = math.min(batches, si.count) slotMap[tostring(tSlot)] = { chestName = src.chest, chestSlot = slot, itemName = itemName, - count = 1, + count = pullCount, } reserved[key] = true found = true @@ -298,16 +303,20 @@ function craft.executeChain(targetItem, count, ctx) ctx.state.needsRedraw = true ctx.state.smelterNeedsRedraw = true - for batch = 1, step.count do - local ok, batchErr = craft.executeSingleCraft(step.recipe, ctx) + -- Batch in chunks of 64 (max stack per turtle slot) + local remaining = step.count + while remaining > 0 do + local chunk = math.min(remaining, 64) + local ok, batchErr = craft.executeSingleCraft(step.recipe, ctx, chunk) if not ok then ctx.state.activity.crafting = false ctx.state.needsRedraw = true - ctx.log.error("CRAFT", "Chain failed at step %d batch %d: %s", i, batch, batchErr) + ctx.log.error("CRAFT", "Chain failed at step %d: %s", i, batchErr) return false, string.format("Step %d/%d failed: %s", i, #steps, batchErr) end - -- Brief pause between batches to let turtle finish - if batch < step.count then os.sleep(0.3) end + remaining = remaining - chunk + -- Brief pause between chunks to let turtle finish + if remaining > 0 then os.sleep(0.3) end end ctx.log.info("CRAFT", "Step %d/%d complete: %s x%d", i, #steps, step.output, step.outputCount)