Port the 1531/0/0/0 comparator check into Rust - #348
Conversation
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
| } | ||
| } | ||
| s.missing = game.keys().filter(|k| !port.contains_key(k)).count(); | ||
| s | ||
| }; |
There was a problem hiding this comment.
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 (
FactorioMapWebUI/crates/fmw-noise/src/fixtures.rs
Line 4252 in 55e386a
port.contains_key(*k).
| } | |
| } | |
| s.missing = game.keys().filter(|k| !port.contains_key(k)).count(); | |
| s | |
| }; | |
| s.missing = game.keys().filter(|k| !port.contains_key(*k)).count(); |
There was a problem hiding this comment.
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
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
Hand the port the game's own destruction set in place of the lava and ore
predicates, over all three oracle regions, and the
applyCliffsmodelreproduces 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/0is not an artifact of a quiet halo, which is theobvious 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_nonecarry 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.
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.tomlpins:cargo fmt --checkis clean andclippy --all-targetsis silent.src/noise/wasm/engine.wasmis byte-unchanged atf4a011455351c07549895f39539ecb4240ac9b4e4845360771276d65e995a29a, as expectedfor a
cfg(test)change.Test-only. No
src/or crate source changes, so no wasm rebuild.Branched straight off
mainatdde8299, not stacked on #347.🤖 Generated with Claude Code
https://claude.ai/code/session_018PuJPe8q6EKwAxgVUXCGPh