fix(bots): ask whether the spot is still there before believing the timer #241
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/bank-stands-and-site-pairing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Watched five fishers for twenty minutes once the bank leg worked. They banked
345 fish between them, and two of them also stood still for eight minutes
mid-pack: phase
working,fails=0, nothing animating, skilling clock pinnedat zero. The instrumented sitting names it --
target={17914, 1}against aTickSnapshot.npc/1answering nil. The spot had retired under them, which iswhat a relocating spot does: the replacement stands at another tile under a
new index.
workingaskedskilling?beforepresent?/1.skilling?is aWorld.Content.Fishtimer on the body and the timer was still registered --which is the whole of a timer is not the interaction that armed it -- so it
answered "yes, working" about a spot that was not there, and the branch that
would have noticed sat underneath it and was never reached. The goal's own
moduledoc says relocation costs it nothing because presence is re-asked. It
could not be, and never had been.
So presence goes first, here and in
GatherAndBank'salive?/1mirror, whichhas the same two lines in the same order and had not been seen doing it.
Re-watched: the retire now lasts one poll -- index 17905 gone, 18026 acquired,
fishing again.
Both unit tests for the hold were passing against the bug.
Bot.FishTestheldagainst index
50andBot.GatherAndBankTestagainst loc999_999, andneither is placed anywhere, so in both files the hold was only ever reachable
while the stale-target branch came second. They now hold against a spot and a
tree that are really there -- one seeded into the snapshot tables, one drawn
from the derived table -- because a test that asserts a branch is also an
assertion about every branch above it.
What is left is engine rather than bot: the orphaned timer itself.
pass/3halts on
not standing?andhalt/1clears the timer, so a loop that firedwould have cleaned up within a tick. It did not fire -- clock at zero,
permanently due, nothing animating -- which points at the timer being driven
from an interaction the engine dropped when the NPC was retired. No goal
depends on the answer now; anything else reading
skilling?still does.Watched five fishers for twenty minutes once the bank leg worked. They banked 345 fish between them, and two of them also stood still for **eight minutes** mid-pack: phase `working`, `fails=0`, nothing animating, skilling clock pinned at zero. The instrumented sitting names it -- `target={17914, 1}` against a `TickSnapshot.npc/1` answering nil. The spot had retired under them, which is what a relocating spot does: the replacement stands at another tile under a new index. `working` asked `skilling?` before `present?/1`. `skilling?` is a `World.Content.Fish` timer on the body and the timer was still registered -- which is the whole of *a timer is not the interaction that armed it* -- so it answered "yes, working" about a spot that was not there, and the branch that would have noticed sat underneath it and was never reached. The goal's own moduledoc says relocation costs it nothing *because* presence is re-asked. It could not be, and never had been. So presence goes first, here and in `GatherAndBank`'s `alive?/1` mirror, which has the same two lines in the same order and had not been seen doing it. Re-watched: the retire now lasts one poll -- index 17905 gone, 18026 acquired, fishing again. Both unit tests for the hold were passing against the bug. `Bot.FishTest` held against index `50` and `Bot.GatherAndBankTest` against loc `999_999`, and neither is placed anywhere, so in both files the hold was only ever reachable while the stale-target branch came second. They now hold against a spot and a tree that are really there -- one seeded into the snapshot tables, one drawn from the derived table -- because a test that asserts a branch is also an assertion about every branch above it. What is left is engine rather than bot: the orphaned timer itself. `pass/3` halts on `not standing?` and `halt/1` clears the timer, so a loop that fired would have cleaned up within a tick. It did not fire -- clock at zero, permanently due, nothing animating -- which points at the timer being driven from an interaction the engine dropped when the NPC was retired. No goal depends on the answer now; anything else reading `skilling?` still does.