Skip to content

Adopt the applyCliffs connection stage for cliff rejection, on both ports #307

Description

@wormeyman

Two independent implementations now measure the same thing: rejecting a cliff at
the apply stage beats rejecting it at the crossing stage, and is worse on
nothing.

The measurement

Scored on ORIENTATION against the game's own LuaEntity.cliff_orientation,
across the three regions of
oracle-vulcanus-cliff-entities.seed123456.json:

model matched wrong surplus missing
rejectAtCrossingStage (ships) 1504 21 22 6
applyCliffs, lava + ore 1508 18 22 5
applyCliffs, no cascade 1500 25 22 6

Better on three counts and worse on none. The no-cascade row is what makes the
middle row mean something
: without it, "the apply stage is better" would not
separate the cascade from the re-staging.

test/cliffConnections.spec.ts has held these numbers on the TypeScript side.
crates/fmw-noise/src/fixtures.rs now reaches all twelve of them independently,
first run, from a separate implementation of Cliff::updateConnections and
onDestroy (#225, PR #306).

Why it is not already wired in

rejectAtCrossingStage zeroes a rejected cell's four edges. The real stage
destroys the entity and lets Cliff::onDestroy take the facing end of each
CONNECTED neighbour - one or two sides, not four, and by rewriting the
orientation rather than clearing a crossing.

The renderer paints POSITIONS and ignores orientation, and on positions alone
the two models are a wash: 1526 against 1525 of 1531, one cell. So the gain
is almost entirely in a quantity the preview does not draw.

What adopting it costs

The connection pass needs a HALO. A cell on the query's outer chunk ring reads
its neighbour across the boundary, and the onDestroy cascade can reach further
still, so the renderer would have to run the pass over a padded query and filter
afterwards.

That changes the geometry two gates currently pin byte-identical between a whole
render and its tiles:

It would also need doing on both ports in the same change, or tier 3's
byte-identity assertion goes red - which is the mechanism working, not a
problem.

Suggested shape

  1. Decide whether one position and three orientations justify a padded query.
    The honest answer may be no; recording that decision is worth as much as
    making the change.
  2. If yes: change both ports together, re-score the table above on both sides,
    and re-measure the tiled-vs-whole cost - the cliff pass quantises its
    enumeration to 32-tile chunks, so a wider query can pull in a whole extra
    chunk per axis. A symmetric-vs-exact halo was already measured at 1.40x for
    zero pixels of difference.
  3. Keep the no-cascade arm in whatever grades it. It is the control.

Related: #84 (the remaining 2.4% residual, open against both ports), #83.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions