Skip to content

Port the 1531/0/0/0 comparator check into Rust - #348

Merged
wormeyman merged 2 commits into
mainfrom
test/84-oracle-kill-comparator
Aug 29, 2026
Merged

Port the 1531/0/0/0 comparator check into Rust#348
wormeyman merged 2 commits into
mainfrom
test/84-oracle-kill-comparator

Conversation

@wormeyman

Copy link
Copy Markdown
Collaborator

Hand the port the game's own destruction set in place of the lava and ore
predicates, over all three oracle regions, and the applyCliffs model
reproduces every one of the 1531 game cliffs - positions and orientations.

This is the Rust side of test/cliffDestructionResidual.spec.ts.

The part you cannot reconstruct from the diff

The anti-vacuity control gives the identical answer. The first arm destroys
nothing outside the region, because no fixture says what the game did out there.
Run our own lava + ore predicate in the 64-tile halo instead and the score does
not move. So 1531/0/0/0 is not an artifact of a quiet halo, which is the
obvious way a result this clean could be hollow.

Why this is stronger than the arms we already freeze

All three arms of
the_apply_stage_beats_the_crossing_stage_on_three_counts_and_loses_on_none
carry our own collision model, so each one measures the port and the model
together. Removing the model from the comparison is what isolates the residual
to Surface::wouldCollide.

What is fitted and what is predicted

That distinction is the whole weight of the result.

FITTED the 225-cell destruction set, chosen as the raw cells the game lacks. 225 booleans.
PREDICTED all 1531 orientations, including the 14 the cascade actively rewrites; that the cascade destroys nothing beyond the 225, which would have shown as missing; and that the answer does not depend on what the halo does.

Measured

On Menehune, x86-64 WSL2, Rust 1.98.0 as rust-toolchain.toml pins:

cargo test -p fmw-noise --release
test fixtures::the_games_own_destruction_set_reproduces_the_game_exactly ... ok
test result: ok. 423 passed; 0 failed; 0 ignored

cargo fmt --check is clean and clippy --all-targets is silent.
src/noise/wasm/engine.wasm is byte-unchanged at
f4a011455351c07549895f39539ecb4240ac9b4e4845360771276d65e995a29a, as expected
for a cfg(test) change.

Test-only. No src/ or crate source changes, so no wasm rebuild.

Branched straight off main at dde8299, not stacked on #347.

🤖 Generated with Claude Code

https://claude.ai/code/session_018PuJPe8q6EKwAxgVUXCGPh

Hand the port the game's OWN destruction set in place of the lava and ore
predicates, over all three oracle regions, and the applyCliffs model reproduces
every one of the 1531 game cliffs - positions AND orientations.

This is the Rust side of test/cliffDestructionResidual.spec.ts, and it is
stronger than any arm of
the_apply_stage_beats_the_crossing_stage_on_three_counts_and_loses_on_none:
all three of those carry our own collision model, so each one measures the port
and the model together. Removing the model from the comparison is what isolates
the residual to Surface::wouldCollide.

What is fitted and what is predicted, because that is the whole weight of the
result. FITTED: the 225-cell destruction set, chosen as the raw cells the game
lacks - 225 booleans. PREDICTED: all 1531 orientations, including the 14 the
cascade actively rewrites; that the cascade destroys nothing beyond the 225,
which would have shown as missing; and that the answer does not depend on what
the halo does.

The second arm is the anti-vacuity control. The first destroys nothing outside
the region, because no fixture says what the game did out there. Running our own
lava + ore predicate in the halo instead gives the identical answer, so "exact"
is not an artifact of a quiet halo.

Measured on Menehune, x86-64 WSL2, Rust 1.98.0 as rust-toolchain.toml pins:
cargo test -p fmw-noise --release gives 423 passed, 0 failed. cargo fmt --check
is clean and clippy --all-targets is silent. engine.wasm is byte-unchanged, as
expected for a cfg(test) change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018PuJPe8q6EKwAxgVUXCGPh
Comment on lines +4421 to +4425
}
}
s.missing = game.keys().filter(|k| !port.contains_key(k)).count();
s
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't compile. game.keys() yields Item = &(u64, u64), so inside filter the closure parameter k is &&(u64, u64). BTreeMap::contains_key<Q> requires (u64, u64): Borrow<Q>, and unifying &Q with &&(u64,u64) picks Q = &(u64,u64) — but there's no Borrow<&(u64,u64)> impl for (u64,u64) (std only has the reflexive impl and Borrow<T> for &T/&mut T), so this hits E0277.

The existing sibling line just above this test (

totals[i].missing += game.keys().filter(|k| !port.contains_key(*k)).count();
) does the identical comparison correctly with the deref: port.contains_key(*k).

Suggested change
}
}
s.missing = game.keys().filter(|k| !port.contains_key(k)).count();
s
};
s.missing = game.keys().filter(|k| !port.contains_key(*k)).count();

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken, but the reason given is not right, so recording the measurement in case it saves someone a re-derivation.

The original line compiled. Verified on 55e386a, the exact commit reviewed:

cargo test -p fmw-noise --release --no-run
    Finished `release` profile [optimized] target(s) in 21.57s

and the full run was 423 passed / 0 failed, with cargo fmt --check clean and clippy --all-targets silent. The rust CI job also passed on that commit.

Why it compiled: inference is not forced to pick Q = &(u64, u64). &&(u64, u64) deref-coerces to &(u64, u64) at the argument position, so Q resolves to (u64, u64) and the reflexive Borrow impl applies. Deref coercion at coercion sites is what the analysis above leaves out.

I have applied the change anyway, because the sibling line at L4252 already writes it as *k and matching the file's own idiom is worth more than the one saved character.

🤖 Generated with Claude Code

https://claude.ai/code/session_018PuJPe8q6EKwAxgVUXCGPh

No behaviour change - the original compiled, verified on 55e386a. But L4252
already writes the same comparison as *k, so match the file rather than lean on
the deref coercion.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018PuJPe8q6EKwAxgVUXCGPh
@wormeyman
wormeyman merged commit 33fae8e into main Aug 29, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant