Ask the game which snapping mode carries the grid position, and pin it - #226
Merged
Merged
Conversation
PR #222 rewrites `Blueprint.serialize` to write `position-relative-to-grid` only under Relative snapping, which drops it from every real blueprint - 325 of the corpus's 367 carry snapping and all 325 are absolute. The corpus can say the two co-occur; it cannot say one requires the other, because no corpus blueprint uses relative snapping at all. Arguing from 325 rows that agree is the shape of argument #133 item 5 and #142 both got wrong. Measured on 2.0.77, the version the editor targets: the game writes `position-relative-to-grid` under ABSOLUTE and omits it under RELATIVE. `relative-offset` sets a position of {3,5} and the game writes no position key at all; `absolute-offset` sets the same and writes {3,5}. Both candidate rules were transcribed into the probe and scored against every measured row before any editor code was touched - the inversion agrees on all seven rows with a grid, PR #222's rule disagrees on three. The trap, which cost a run and is why the probe carries a per-setter trace: setting `blueprint_position_relative_to_grid` turns `blueprint_absolute_snapping` ON. The first version set snap, then absolute, then position, so the position write flipped absolute back on and every row exported as absolute - relative mode was never reached and the relative rows were measuring nothing. The readback control caught that the instrument was broken; only the per-setter trace said which setter did it. Set position before absolute, or not at all. Three no-grid rows are recorded and deliberately not scored. A grid position or absolute snapping with no `snap-to-grid` is a state the GUI cannot produce, and the game answers it inconsistently - writing keys with no grid beside them and failing to reconstruct them on import. #133 item 4's lesson: record a section its control voids rather than reading it as an answer. Conclusion for the editor: no change. The existing pass-through is correct, and the fix #222 needs is the inversion of what it currently does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Dbza77QEZnkqt1mGssY71
2 tasks
Every other probe here carries a paragraph in the "Asking the real game" section; this one landed without. The paragraph states the rule, and the three things worth carrying: that 325 agreeing corpus rows could not have answered the question, that setting the position property turns absolute snapping on (which cost the probe a run), and that the no-grid rows are recorded but not scored. Also notes the template-literal trap in the probe file itself - a backtick in a Lua comment closes the surrounding JS template, and a matched pair on one line closes and reopens it, which a scan for odd backtick counts cannot see. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Dbza77QEZnkqt1mGssY71
Nothing pinned this. `blueprint-round-trip.spec.ts` caught #222 dropping `position-relative-to-grid`, but only by accident of the corpus: exactly one of its 367 blueprints carries a grid position, so re-capturing that fixture or swapping the corpus the way #186 did would take the coverage with it. And what it reports is a moved hash rather than a named field. The rule asserted here is the measured one from tools/oracle/fixtures/blueprint-snapping.json: the game writes `position-relative-to-grid` under absolute snapping and omits it under relative. Synthetic because it has to be. All 325 corpus blueprints that carry snapping are absolute, so a test built from real exports cannot tell the two modes apart - the same reason the corpus could not answer the question and the binary had to. Mutation-checked with PR #222's own condition pasted into `Blueprint.serialize`: two of the five fail and three pass, so the headline test is not decoration and the origin test is doing work of its own. The no-snapping test is a control that survives that mutation and would catch the opposite mistake, a default grid written onto every blueprint. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Dbza77QEZnkqt1mGssY71
This was referenced Aug 17, 2026
wormeyman
added a commit
that referenced
this pull request
Aug 17, 2026
…d pin it (#230) PR #222 adds a second X/Y pair to the alignment dialog, "Grid position", on the premise that the game's own control writes no blueprint field and instead moves every entity by the negation of what is typed. That premise was inferred from a screenshot of the game's dialog, not measured, and it is why Blueprint.translateEntities and Entity.forceMoveBy exist. Measured on 2.0.77, the binary #226 used. Setting a grid position moves no entity: not in get_blueprint_entities(), not in the exported string, not after importing that string back. The game writes position-relative-to-grid and leaves every coordinate where it was, over positions of {3, 5} and {10, -7}. So there is no second thing to model, and #226 already measured all of it. The positive control is what makes a null result mean anything. Four of the seven cases report "nothing changed" whether the probe is right or comparing a value with itself, so shifted-entities places the same two chests three tiles left and four up through set_blueprint_entities, touching no snapping property. Its exported coordinates differ from the baseline, which is the only reason the zeros count as evidence. The #133 item 4 lesson in null-result form. One new API fact, which confirms #226 from the other end. That probe found that setting blueprint_position_relative_to_grid turns blueprint_absolute_snapping on. This one found the reverse: setting blueprint_absolute_snapping to false clears the position. The readback control caught it on the one relative row, which holds no position by the time anything is read, so that row is recorded and left unscored rather than counted as "did not move". Relative snapping cannot carry a position because the game takes it away, not only because the exporter drops it. Two consecutive captures are byte-identical, so a third that disagrees is a finding rather than noise. Also adds the probe-blueprint-snapping.mjs row that #226 left out of the script table. Claude-Session: https://claude.ai/code/session_01DxZFeyzpXmxjwVHXxDo8zb Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Evidence for #222, captured on 2.0.77 — the version the editor targets, not the 2.1.12 most fixtures here come from.
The question
#222 rewrites
Blueprint.serializeto writeposition-relative-to-gridonly under Relative snapping. That drops it from every real blueprint: 325 of the corpus's 367 carry snapping and all 325 areabsolute-snapping: true.The corpus can say the two co-occur. It cannot say one requires the other, because no corpus blueprint uses relative snapping at all. Arguing from 325 rows that all agree is the shape of argument #133 item 5 and #142 both got wrong, so this asks the binary instead.
The answer
The game writes
position-relative-to-gridunder Absolute and omits it under Relative:Both candidate rules were transcribed into the probe and scored against every measured row before any editor code was touched:
The trap, which cost a run
Setting
blueprint_position_relative_to_gridturnsblueprint_absolute_snappingON.The first version set snap, then absolute, then position — so the position write flipped absolute back on afterwards, every row exported as absolute, and relative mode was never reached. The three relative rows were measuring nothing while looking perfectly plausible.
The readback control caught that the instrument was broken. It could not say which setter was responsible; a per-setter trace of
absolute_snappingis what identified it, and that trace is now part of the probe:Set position before absolute, or not at all.
Three rows recorded and deliberately not scored
A grid position or absolute snapping with no
snap-to-gridis a state the GUI cannot produce, and the game answers it inconsistently — writing keys with no grid beside them, then failing to reconstruct them on import. Per #133 item 4, that's a section its own control voids, recorded rather than read as an answer.Conclusion for the editor
No change. The existing pass-through is correct. The fix #222 needs is the inversion of what it currently does, and this fixture is the table to code against.
🤖 Generated with Claude Code
https://claude.ai/code/session_017Dbza77QEZnkqt1mGssY71