Track actual scheduler output arrivals

This commit is contained in:
2026-07-18 03:42:14 +02:00
parent 10d96bba81
commit 2476e7b78f
+34 -8
View File
@@ -1,7 +1,7 @@
-- ATM10 Create factory scheduler V1
-- Persistent jobs, dependency planning, progress-aware retries and diagnostics.
local VERSION = "1.0.0"
local VERSION = "1.0.1"
local REFRESH_SECONDS = 1
local CONFIRM_SECONDS = 6
local DRAIN_SECONDS = 60
@@ -128,8 +128,18 @@ local function loadState()
state.version, state.nextJobId = state.version or 1, state.nextJobId or 1
state.mode, state.jobs, state.errors = state.mode or "MANUAL", state.jobs or {}, state.errors or {}
for _, job in ipairs(state.jobs) do
job.lastObserved, job.baseline = job.lastObserved or {}, job.baseline or {}
local hadArrivalCounter = type(job.arrived) == "table"
job.lastObserved, job.baseline, job.arrived = job.lastObserved or {}, job.baseline or {}, job.arrived or {}
job.retries, job.status = job.retries or 0, job.status or "WAITING"
-- One-time migration of jobs created by V1.0.0.
if not hadArrivalCounter and (job.progress or 0) > 0 then
local recipe = RECIPES[job.recipeId]
if recipe and recipe.output then
job.arrived[recipe.output] = job.progress
elseif recipe and recipe.outputs and recipe.outputs[1] then
job.arrived[recipe.outputs[1]] = job.progress
end
end
job.lastProgressAt, job.phaseStartedAt = epoch(), epoch()
end
-- Timers were deliberately rebased above; begin a fresh pause window too.
@@ -177,12 +187,16 @@ local function stationBusy(station, exceptJob)
end
local function produced(job, item)
return math.max(0, (stock[item] or 0) - (job.baseline[item] or 0))
-- Count real positive arrivals. Unlike a stock difference this never drops
-- when another factory step consumes the output while the job is running.
return math.max(0, (job.arrived and job.arrived[item]) or 0)
end
local function setBaseline(job, item)
if job.baseline[item] == nil then
job.baseline[item], job.lastObserved[item] = stock[item] or 0, stock[item] or 0
job.arrived = job.arrived or {}
job.arrived[item] = job.arrived[item] or 0
end
end
@@ -216,13 +230,20 @@ end
local function observeItems(job, items)
local changed = false
job.arrived = job.arrived or {}
for _, item in ipairs(items) do
local current = stock[item] or 0
if current > (job.lastObserved[item] or current) then changed = true end
local previous = job.lastObserved[item]
if previous == nil then previous = current end
if current > previous then
job.arrived[item] = (job.arrived[item] or 0) + (current - previous)
changed = true
end
job.lastObserved[item] = current
end
if changed then
job.lastProgressAt, job.drainStartedAt, job.warned = epoch(), epoch(), false
saveState()
end
return changed
end
@@ -303,7 +324,8 @@ local function dispatchZincWashing(job, remaining)
if sent <= 0 then failJob(job, "Zinc-Clump-Versand fehlgeschlagen: " .. tostring(err or "unbekannt")) return end
job.activeStation, job.phase, job.status = "fan:washing", "WASHING", "RUNNING"
job.lastBatchInput, job.phaseStartedAt, job.lastProgressAt, job.warned = sent, epoch(), epoch(), false
job.phaseOutputBaseline, job.phaseExpected = stock["alltheores:zinc_nugget"] or 0, sent * 9
job.phaseOutputBaseline = produced(job, "alltheores:zinc_nugget")
job.phaseExpected = sent * 9
logEvent("#" .. job.id .. " Teilauftrag: " .. sent .. " Clumps waschen", colors.orange) saveState()
end
@@ -327,7 +349,7 @@ local function updateZinc(job)
if job.phase == "CRUSHING" then
job.status, job.phase, job.lastProgressAt = "WAITING", "PLAN", epoch() saveState()
elseif job.phase == "WASHING" then
local phaseGain = math.max(0, (stock["alltheores:zinc_nugget"] or 0) - (job.phaseOutputBaseline or 0))
local phaseGain = math.max(0, produced(job, "alltheores:zinc_nugget") - (job.phaseOutputBaseline or 0))
if phaseGain >= (job.phaseExpected or 0) then
-- Batch arrived completely, but the parent still needs more: replan.
job.status, job.phase, job.lastProgressAt = "WAITING", "PLAN", epoch()
@@ -356,7 +378,7 @@ local function newJob(recipeId)
id = state.nextJobId, recipeId = recipeId, status = "WAITING",
phase = recipe.planner and "PLAN" or "NORMAL",
targetCount = recipe.targetCount or recipe.outputCount or 1,
baseline = {}, lastObserved = {}, progress = 0, retries = 0,
baseline = {}, lastObserved = {}, arrived = {}, progress = 0, retries = 0,
createdAt = epoch(), lastProgressAt = epoch(), phaseStartedAt = epoch(),
}
state.nextJobId = state.nextJobId + 1
@@ -416,9 +438,13 @@ local function drawStock(width)
end
local function progressText(job)
local recipe = RECIPES[job.recipeId]
local idle = math.max(0, epoch() - (job.lastProgressAt or epoch()))
if recipe and recipe.completion == "activity" then
return formatNumber(job.progress or 0) .. " ANGEKOMMEN " .. tostring(job.phase) .. " " .. idle .. "s"
end
local target, progress = math.max(1, job.targetCount or 1), math.min(job.targetCount or 1, job.progress or 0)
local percent = math.floor(progress * 1000 / target) / 10
local idle = math.max(0, epoch() - (job.lastProgressAt or epoch()))
return formatNumber(progress) .. "/" .. formatNumber(target) .. " " .. percent .. "% " .. tostring(job.phase) .. " " .. idle .. "s"
end