Repository navigation
fix(walker): report ARRIVED when a pass starts on the final path endpoint - #1959
Conversation
…oint processWalk cleared the target on reaching the path endpoint and let the same pass fall through to the after-stuck-check, which read the null currentTarget as an external cancel and returned EXIT even when the player stood on the goal. The endpoint branch now checks for a genuine cancel first, then returns ARRIVED when the player is within the tight finish threshold of the target (EXIT otherwise, with an honest trace). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
WalkthroughRs2Walker now settles a reached path endpoint by checking cancellation and comparing the player’s distance to the goal with Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to
|
Problem
The 2.6.32 release E2E (#1957, known issue) saw
Rs2Walker.walkWithStatereturnEXITinstead ofARRIVEDfor a walk through a closed door that ended exactly on the target. The log sequence was:Root cause: when a
processWalkpass begins with the player standing on the final (non-partial) path endpoint and no interim target set, it callssetTarget(null, "reached-path-endpoint")and keeps going. A few lines later,walkCancelledDiag(..., "processWalk:after-stuck-check")seescurrentTarget == null, takes it for an external cancel, and returnsEXIT. Thearrived-immediatecheck further down would have returnedARRIVED, but it never runs.This happens every time a pass starts on the endpoint. It only looks timing-dependent because most walks arrive during a movement wait inside a pass, where
arrived-within-distanceorarrived-after-door-canvas-nudgehandle it. After the door interaction in the failing run, the next pass started on the endpoint.Change
The endpoint branch now goes through a small helper,
settleReachedPathEndpoint:walkCancelledDiag(target, "processWalk:at-path-endpoint"). If another thread calledsetTarget(null), or the target changed, the thread was interrupted, the human took over input or a completion condition was met, the result is stillEXITwith an accurate trace. Arrival never hides a real cancel.ARRIVEDwhen the player is withintightFinishThreshold(target, endpoint, distance)of the target. That is the same thresholdarrived-within-distanceuses later in the same pass.EXITas before. If the player is on the endpoint but outside that tight threshold, the result is stillEXIT. The log now sayspath-endpoint-short-of-targetinstead of the misleadingcancel:processWalk:after-stuck-check.In all three cases the target is cleared with the same
reached-path-endpointreason as before.I also checked the other places that clear the target. The
tryDirectShortWalkarrivals andarrived-immediate,arrived-within-distanceandarrived-after-door-canvas-nudgealready returnARRIVEDdirectly.off-path-cancel-instead, the rockfall and obstacle aborts,completion-condition-metand the error exits mean to stop the walk. The endpoint branch was the only one that cleared the target on success and then reached a cancel check.To keep
legacyProcessWalkCannotGrowpassing, the logic lives in the helper and the call site inprocessWalkstays at its old length. A package-privateprocessWalkForTestingseam drives one realprocessWalkcall from the new test.Testing
Rs2WalkerPathEndpointArrivalTestruns the realprocessWalkloop withMicrobot,Rs2Player,Rs2TileandRs2PathApimocked:standingOnTheEndpointThatIsTheTargetArrives: player on the endpoint, which is the target, distance 0. ExpectsARRIVED. Fails without the fix (expected:<ARRIVED> but was:<EXIT>), with the sameclear | reached-path-endpoint, thenexit | r=cancel:processWalk:after-stuck-check nullCur=truesequence as the E2E log.externalCancelBeforeTheEndpointCheckStillExits:currentTargetis set to null mid-pass, before the endpoint check. ExpectsEXIT, with the target not cleared asreached-path-endpoint. Also fails without the fix, because the old code cleared with that reason regardless.endpointShortOfTheTightFinishThresholdDoesNotArrive: endpoint 3 tiles from the target with distance 5 (tight threshold 1). ExpectsEXIT. Passes before and after, which pins the unchanged behaviour../gradlew :client:runUnitTests --offline: BUILD SUCCESSFUL. 2384 tests ran, 2382 passed, 2 skipped and none failed,WalkerArchitectureGuardTestandClientThreadGuardrailTestincluded.MICROBOT_E2E_WORLD=301 scripts/run-release-e2e.sh quick walker-transportwith a shaded jar built from this branch, run 4 times, PASSED 4/4 (59.7s to 1m05s each).Not verified live: none of the 4 runs started a pass on the endpoint. In every run, arrival went through
arrived-within-distanceortryDirectShortWalk, so the changed branch never ran live. The unit test is the evidence for the fix. The E2E runs only show that the door, short-walk and stairs flows still work.🤖 Generated with Claude Code
https://claude.ai/code/session_01LjtEMzQHGuq4M1Mpqk9pPV