fix(collision): index a loc where it is clicked from, not where it is stored #133
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/bridge-loc-index"
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?
A bridge tile stores its locs one plane above the walkway they stand on, and
the plane in a click packet is the plane the player is standing on.
World.Collision.Flags.visual_plane/2has resolved that since the bridgemarker was corrected, and the flag build applies it. The loc index did
not — it keyed by
loc.plane, and argued for it in its own@doc:visual_plane/2's own doc, forty lines away in the same subsystem, says theopposite and gives the reason: the plane a player will be on when they click
it — and therefore the plane the server sees in the click packet — is this one
rather than
loc.plane. Anything that keys a loc by position needs the sameanswer.
So a bridge-tile loc had its collision on one plane and its identity on the
one above. The client draws it, draws its menu and sends a perfectly ordinary
click;
locs_at/1reads the tile the player is standing on, finds nothingthere, and the interaction is refused. Nothing is logged, because from the
dispatch's point of view the player clicked empty ground.
Measured over the whole world
The interactive ones are what a bug report would have been written about:
It is why the Grand Exchange had no on-foot entrance
That was recorded as a map-data gap — not one tile within five of any of the
four booths is floored — and filed as quite possibly the bridge-flag family.
It was the bridge-flag family, one layer up: the scan was correct and it was
scanning plane 1, where the booths were indexed and where nothing in that map
square exists at all.
With the index fixed the booths are at
{0, 3164, 3487},{0, 3165, 3487},{0, 3164, 3492}and{0, 3165, 3492}, each on open floor, withContract.Reachanswering true from the tile either side.World.Content.Exchange.booth?(10_061, 1)has always been true, so nothingabout the exchange needed building — the door was mis-filed.
Bot.Goals.Restocktargets the booth and can now derive a real one.
The clerk is still unreachable, and now for a knowable reason rather than a
mysterious one: it stands on the desk block, and the booth counter is a wall loc
on the tile between it and the only open ground, so
interactable_from?/4'sedge check refuses across the counter. That is the ordinary wall rule doing its
job, and the booth does not need it answered.
The change
Three lines of behaviour.
decode/2carries the square's terrain alongside itslocs, and
index_locs/4keys byFlags.visual_plane/2, dropping a loc thatresolves below plane 0 exactly as the flag build drops it — the clutter under an
arch, which the client also does not draw. The two halves of
publish/1nowanswer the same plane for the same loc, which is the invariant that was missing
rather than a special case for bridges.
Every consumer of the index wants the new answer:
World.DoorsandWorld.Depletionlook up what a click landed on,World.RoutePlanandWorld.Climbing.Geometryresolve a target, andBot.SitesandWorld.Teleportsbuild id-to-position tables for navigation.
Two tests pinned in
World.CollisionTest: the booth is indexed at plane 0 andabsent from plane 1, and there is somewhere to stand beside it that reach
accepts.
Gates
Suite green — 3167 tests, 1338 doctests, 55 properties, 0 failures (SQLite
leg); Credo clean.
mix format --check-formattedandmix dialyzerfail, andboth fail identically on a stashed clean
origin/mainon this machine: that isissue #131, not this branch.