Hauling/JobRunner: fail unreachable walks; pre-check haul reachability
Two compounding bugs made hauling appear broken when targets were behind walls. User report: 'i set a stockpile and there is stuff to move' — items sat indefinitely. JobRunner._tick_walk treated 'path is empty' (unreachable) by marking the walk toil done and silently advancing to the next toil. Pickup/deposit then ran at the pawn's CURRENT tile instead of the intended target — 'Bram pickup: no item at (44, 25)' for an item that lived at (45, 21). The job 'completed' wrongly. Now an unreachable walk cancel_job()'s, letting Decision pick something else next tick. HaulingProvider didn't pre-check reachability before handing out a job. With the JobRunner fix alone, Decision would have re-picked the same unreachable haul every tick (busy-spin at 20 Hz). Now the item loop and corpse loop both skip targets where find_path is empty from pawn.tile. Cost: ~10 us pathfind per candidate; trivial at MVP scale. Verified MCP runtime: bread at (45, 21) (reachable) hauled end-to-end to the stockpile at (15, 62). Bread at (50, 21) (unreachable behind the cabin wall arrangement) correctly skipped — no job assigned, no busy spin in the log. Bram completed the haul and picked up his next job (Harvest wheat) naturally. Note: the JobRunner unreachable-cancel fix also helps any other provider whose walk_to leg fails — chop/mine/construction were silently 'finishing' the same way when targets walled off. They now cancel cleanly too. Their providers don't yet pre-check reachability, so they could cancel-loop on unreachable targets if nothing else is queued — left for a followup once a real case surfaces. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e7a2407af2
commit
f435c3c467
2 changed files with 16 additions and 2 deletions
|
|
@ -179,11 +179,16 @@ func _tick_walk(t) -> void:
|
|||
return
|
||||
var path: Array[Vector2i] = pathfinder.find_path(pawn.tile, dest)
|
||||
if path.is_empty():
|
||||
# Unreachable — abort the entire job so Decision can pick something
|
||||
# else next tick. Previously this marked the walk toil done and the
|
||||
# subsequent toils (pickup, deposit, etc.) ran at the wrong tile,
|
||||
# making haul/pickup silently fail with "no item at <pawn.tile>".
|
||||
Audit.log(
|
||||
"job_runner",
|
||||
"%s unreachable: %s → %s" % [pawn.pawn_name, pawn.tile, dest]
|
||||
"%s unreachable: %s → %s (canceling job '%s')" %
|
||||
[pawn.pawn_name, pawn.tile, dest, job.label]
|
||||
)
|
||||
t.done = true
|
||||
cancel_job()
|
||||
return
|
||||
pawn.walk_along_path(path)
|
||||
t.data["started"] = true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue