fix(fishing): the water's edge is not water, and only shape 0 is a tile #233

Merged
sickday merged 2 commits from fix/fishing-spots-on-land into main 2026-08-17 12:24:48 +00:00
Owner

A second screenshot from the same bank, one commit after the first: another
fishing splash on the mud at Barbarian Village. The overlay test had shipped,
the tile was overlay 6, and it was still wrong.

An overlay carries a SHAPE as well as an id -- shape = (op - 2) / 4,
rotation = (op - 2) % 4 -- and only shape 0 covers the whole tile. Shapes 1
to 11 split the square between the overlay and the underlay along one of the
client's tile-shape templates, which is exactly how a shoreline is drawn: a
water body's interior is overlay 6 shape 0, and its edge is a diagonal
carrying either the water id or the bank's.

So {3109, 3431} is overlay 6 shape 1 -- the plain diagonal, half river and
half west bank -- and a spot at the centre of it stands on the seam. Eleven of
the tiles re-derived in the previous commit were edges like that:

1506 Lumbridge     4 of 8 shaped     1508 Tree Gnome     3 of 5
1507 Barb Village  1 of 5 shaped     1509 Otto's Grotto  4 of 5
1512 Shilo         3 of 6 shaped

The dump settles this half the way it settled the id: 140 of its 147 water
rows are shape 0, and it never once uses shape 1. Cache.MapSquare sets the
water bit for shape 0 alone, so the bit means WHOLLY water rather than some
water, and Collision.water?/2 answers a shaped edge with false.

Nothing was lost to the tightening. The dump's failing rows went 7 to 14 and
the PINNED list did not grow -- every new failure is in a cluster that still
holds a tile the rule accepts. Measured on a live world: 86 of 91 spots on
water, the five that are not being the same underground clusters as before,
each named in the boot log.

Three things beyond the rule.

1509 moved and was renamed. Its tiles were the cliff at x 2498, and the
water below them is what the cache's own gazetteer calls Otto's Grotto rather
than the Barbarian Outpost -- World.Places.at/1 answers that, which is
cheaper and more honest than naming a place by eye. {2504, 3497} passes the
rule and is deliberately unused: the operator's own barbarian row stands on it.

The tile lists were derived by calling World.FishSpots.valid_tile?/2
directly. A scratch script that reimplemented the rule against the raw terrain
file proposed two tiles under the Tree Gnome BRIDGE, where the collision map
has already replaced the water with the bridge's floor -- it agreed with
itself and disagreed with the world, which is the same shape of mistake as the
bug it was written to fix.

And the lesson the three filters make: mobile?/2 is true of any shore,
blocked?/2 is true of the mud bank, and overlay == 6 is true of the water's
edge. The last one is not a lazy proxy -- it reads the right field off the
right file and is still wrong, because a tile is not a single material. A
property can be present on a tile without being the whole tile, and a creature
stands at a centre rather than on a set.

Areas now 27 rows and 12 live, counts unchanged at 3/2/2/2/3.
World.FishSpotsTest carries {3109, 3431} as a regression that fails
against both rules this replaces.

Still not verified in play. ::tele 3106 3432.

A second screenshot from the same bank, one commit after the first: another fishing splash on the mud at Barbarian Village. The overlay test had shipped, the tile was overlay 6, and it was still wrong. An overlay carries a SHAPE as well as an id -- `shape = (op - 2) / 4`, `rotation = (op - 2) % 4` -- and only shape 0 covers the whole tile. Shapes 1 to 11 split the square between the overlay and the underlay along one of the client's tile-shape templates, which is exactly how a shoreline is drawn: a water body's interior is overlay 6 shape 0, and its edge is a diagonal carrying either the water id or the bank's. So `{3109, 3431}` is overlay 6 shape 1 -- the plain diagonal, half river and half west bank -- and a spot at the centre of it stands on the seam. Eleven of the tiles re-derived in the previous commit were edges like that: 1506 Lumbridge 4 of 8 shaped 1508 Tree Gnome 3 of 5 1507 Barb Village 1 of 5 shaped 1509 Otto's Grotto 4 of 5 1512 Shilo 3 of 6 shaped The dump settles this half the way it settled the id: 140 of its 147 water rows are shape 0, and it never once uses shape 1. `Cache.MapSquare` sets the water bit for shape 0 alone, so the bit means WHOLLY water rather than some water, and `Collision.water?/2` answers a shaped edge with false. Nothing was lost to the tightening. The dump's failing rows went 7 to 14 and the PINNED list did not grow -- every new failure is in a cluster that still holds a tile the rule accepts. Measured on a live world: 86 of 91 spots on water, the five that are not being the same underground clusters as before, each named in the boot log. Three things beyond the rule. `1509` moved and was renamed. Its tiles were the cliff at x 2498, and the water below them is what the cache's own gazetteer calls Otto's Grotto rather than the Barbarian Outpost -- `World.Places.at/1` answers that, which is cheaper and more honest than naming a place by eye. `{2504, 3497}` passes the rule and is deliberately unused: the operator's own barbarian row stands on it. The tile lists were derived by calling `World.FishSpots.valid_tile?/2` directly. A scratch script that reimplemented the rule against the raw terrain file proposed two tiles under the Tree Gnome BRIDGE, where the collision map has already replaced the water with the bridge's floor -- it agreed with itself and disagreed with the world, which is the same shape of mistake as the bug it was written to fix. And the lesson the three filters make: `mobile?/2` is true of any shore, `blocked?/2` is true of the mud bank, and `overlay == 6` is true of the water's edge. The last one is not a lazy proxy -- it reads the right field off the right file and is still wrong, because a tile is not a single material. A property can be present on a tile without being the whole tile, and a creature stands at a centre rather than on a set. Areas now 27 rows and 12 live, counts unchanged at 3/2/2/2/3. `World.FishSpotsTest` carries `{3109, 3431}` as a regression that fails against both rules this replaces. Still not verified in play. `::tele 3106 3432`.
fix(fishing): the water's edge is not water, and only shape 0 is a tile
Some checks failed
ci / gates (pull_request) Has been cancelled
e2a690ac0c
A second screenshot from the same bank, one commit after the first: another
fishing splash on the mud at Barbarian Village. The overlay test had shipped,
the tile was overlay 6, and it was still wrong.

An overlay carries a SHAPE as well as an id -- `shape = (op - 2) / 4`,
`rotation = (op - 2) % 4` -- and only shape 0 covers the whole tile. Shapes 1
to 11 split the square between the overlay and the underlay along one of the
client's tile-shape templates, which is exactly how a shoreline is drawn: a
water body's interior is overlay 6 shape 0, and its edge is a diagonal
carrying either the water id or the bank's.

So `{3109, 3431}` is overlay 6 shape 1 -- the plain diagonal, half river and
half west bank -- and a spot at the centre of it stands on the seam. Eleven of
the tiles re-derived in the previous commit were edges like that:

    1506 Lumbridge     4 of 8 shaped     1508 Tree Gnome     3 of 5
    1507 Barb Village  1 of 5 shaped     1509 Otto's Grotto  4 of 5
    1512 Shilo         3 of 6 shaped

The dump settles this half the way it settled the id: 140 of its 147 water
rows are shape 0, and it never once uses shape 1. `Cache.MapSquare` sets the
water bit for shape 0 alone, so the bit means WHOLLY water rather than some
water, and `Collision.water?/2` answers a shaped edge with false.

Nothing was lost to the tightening. The dump's failing rows went 7 to 14 and
the PINNED list did not grow -- every new failure is in a cluster that still
holds a tile the rule accepts. Measured on a live world: 86 of 91 spots on
water, the five that are not being the same underground clusters as before,
each named in the boot log.

Three things beyond the rule.

`1509` moved and was renamed. Its tiles were the cliff at x 2498, and the
water below them is what the cache's own gazetteer calls Otto's Grotto rather
than the Barbarian Outpost -- `World.Places.at/1` answers that, which is
cheaper and more honest than naming a place by eye. `{2504, 3497}` passes the
rule and is deliberately unused: the operator's own barbarian row stands on it.

The tile lists were derived by calling `World.FishSpots.valid_tile?/2`
directly. A scratch script that reimplemented the rule against the raw terrain
file proposed two tiles under the Tree Gnome BRIDGE, where the collision map
has already replaced the water with the bridge's floor -- it agreed with
itself and disagreed with the world, which is the same shape of mistake as the
bug it was written to fix.

And the lesson the three filters make: `mobile?/2` is true of any shore,
`blocked?/2` is true of the mud bank, and `overlay == 6` is true of the water's
edge. The last one is not a lazy proxy -- it reads the right field off the
right file and is still wrong, because a tile is not a single material. A
property can be present on a tile without being the whole tile, and a creature
stands at a centre rather than on a set.

Areas now 27 rows and 12 live, counts unchanged at 3/2/2/2/3.
`World.FishSpotsTest` carries `{3109, 3431}` as a regression that fails
against both rules this replaces.

Still not verified in play. `::tele 3106 3432`.
Merge branch 'main' into fix/fishing-spots-on-land
All checks were successful
ci / gates (pull_request) Successful in 3m22s
build / image (push) Successful in 38s
ci / gates (push) Successful in 3m33s
e956c40da1
Sign in to join this conversation.
No reviewers
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!233
No description provided.