Contract.Interaction.adjacent?/2 reads as a verdict but is only a gate #21

Closed
opened 2026-07-27 22:31:57 +00:00 by sickday · 0 comments
Owner

Contract.Interaction.adjacent?/2 is public, named as a verdict, and documented
as "stands on or beside action's footprint... Chebyshev distance, so a
diagonal counts as adjacent."

It is not a verdict. Reach is cardinal: a target is usable from a tile beside it
with the shared edge open, which is what World.Collision.Flags.interactable_from?/3
tests and what World.Movement.approach/3 routes to. adjacent?/2 is the
cheap filter that decides whether that stricter check is worth running.

Every caller that reads the name and uses it as the answer reintroduces the same
bug, which has now happened twice — World.reachable?/1 for NPCs, and
follow/2 when deciding a walk had finished. Both were live. The symptom is an
interaction firing one tile early, which is invisible in isolation because the
player usually keeps walking afterwards and ends up somewhere plausible.

Shape of a fix

Rename so the name cannot be mistaken for the answer — maybe_in_range?/2,
worth_checking?/2 — or make it private to the contract and expose only the
combined verdict. The doc should say outright that a true answer means "run the
real check", not "you can use this".

`Contract.Interaction.adjacent?/2` is public, named as a verdict, and documented as "stands on or beside `action`'s footprint... Chebyshev distance, so a diagonal counts as adjacent." It is not a verdict. Reach is cardinal: a target is usable from a tile beside it with the shared edge open, which is what `World.Collision.Flags.interactable_from?/3` tests and what `World.Movement.approach/3` routes *to*. `adjacent?/2` is the cheap filter that decides whether that stricter check is worth running. Every caller that reads the name and uses it as the answer reintroduces the same bug, which has now happened twice — `World.reachable?/1` for NPCs, and `follow/2` when deciding a walk had finished. Both were live. The symptom is an interaction firing one tile early, which is invisible in isolation because the player usually keeps walking afterwards and ends up somewhere plausible. ### Shape of a fix Rename so the name cannot be mistaken for the answer — `maybe_in_range?/2`, `worth_checking?/2` — or make it private to the contract and expose only the combined verdict. The doc should say outright that a true answer means "run the real check", not "you can use this".
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Revenant/Server#21
No description provided.