You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Three separate gates on Vulcanus refuse the same two tiles, lava and lava-hot. They are equal today. They are not the same rule, and the
repo now says so in one place but has nothing that would notice if they came
apart.
the cliff's collision mask holds water_tile, and tile_collision_masks.lava() sets it
rocks
rocks/vulcanus_placement.rs, tile_allowed
the four rock prototypes' vulcanus_tiles_cold / vulcanus_tiles_hot autoplace lists, whose union is every Vulcanus tile except these two
geysers
resources/vulcanus_geyser.rs, tile_allowed
type = "resource" defaults to the collision mask {resource = true}, which tile_collision_masks.lava() also lists
Three unrelated axes in the game's data. Change any one of them and the three
sets come apart.
Why this is a ticket and not a refactor
#364 removed real duplication: the cliff set had four copies and nothing
compared them. The obvious next step is to notice these two gates and fold them
into is_cliff_blocking as well. That would be wrong, and it is worth
having written down somewhere a future audit will look, because the code reads
as three identical matches! arms and the argument against merging them is not
visible from the shape.
A shared predicate would be wrong in two places at once, and silently: the
rock and geyser gates would keep answering the cliff question after the cliff
question stopped being their question.
resources/vulcanus_geyser.rs already carried the finding in its own doc
comment - "the forbidden set coincides with the rock overlay's while being
reached by a completely different route" - which is what caught it. #364 added
the same warning to is_cliff_blocking, with the table above.
What would actually make them diverge
Any of these, all of which are data changes rather than code changes:
a new Vulcanus tile whose mask sets water_tile but which the rock
prototypes' tile lists still allow
a rock prototype's vulcanus_tiles_cold / vulcanus_tiles_hot list gaining
or losing a tile
tile_collision_masks.lava() dropping resource = true while keeping water_tile, which would split the geyser gate off from the cliff gate while
leaving the rocks alone
None is hypothetical in kind: the cliff set itself was established by
measurement, not by reading the masks, and the notes on it say a future
blocking tile would be found the same way.
Possible shapes for a fix
Not obviously worth doing yet, which is why this is filed rather than done:
Give the rock and geyser gates their own named predicates, each with its own
comment naming its mechanism, so all three read as three rules instead of
three copies. Cheap, and it makes the independence visible at the call site.
Grade each of the three against the game's own data separately, so a data
change moves exactly the gates it should. The rock gate already has the_tile_gate_refuses_exactly_the_two_lava_tiles; the geyser gate does not
have an equivalent, and the cliff gate's is now the The Vulcanus cliff-blocking tile set has four definitions and nothing checks they agree #364 parity test.
Add the recheck to whatever runs when the pinned Factorio version moves,
since that is when the data can change under all three at once.
Found while doing #364, by sweeping the repo for Lava | LavaHot rather than
trusting that issue's table, which listed four sites and missed these two.
Three separate gates on Vulcanus refuse the same two tiles,
lavaandlava-hot. They are equal today. They are not the same rule, and therepo now says so in one place but has nothing that would notice if they came
apart.
tiles/vulcanus_catalog.rs,VulcanusTile::is_cliff_blockingwater_tile, andtile_collision_masks.lava()sets itrocks/vulcanus_placement.rs,tile_allowedvulcanus_tiles_cold/vulcanus_tiles_hotautoplace lists, whose union is every Vulcanus tile except these tworesources/vulcanus_geyser.rs,tile_allowedtype = "resource"defaults to the collision mask{resource = true}, whichtile_collision_masks.lava()also listsThree unrelated axes in the game's data. Change any one of them and the three
sets come apart.
Why this is a ticket and not a refactor
#364 removed real duplication: the cliff set had four copies and nothing
compared them. The obvious next step is to notice these two gates and fold them
into
is_cliff_blockingas well. That would be wrong, and it is worthhaving written down somewhere a future audit will look, because the code reads
as three identical
matches!arms and the argument against merging them is notvisible from the shape.
A shared predicate would be wrong in two places at once, and silently: the
rock and geyser gates would keep answering the cliff question after the cliff
question stopped being their question.
resources/vulcanus_geyser.rsalready carried the finding in its own doccomment - "the forbidden set coincides with the rock overlay's while being
reached by a completely different route" - which is what caught it. #364 added
the same warning to
is_cliff_blocking, with the table above.What would actually make them diverge
Any of these, all of which are data changes rather than code changes:
water_tilebut which the rockprototypes' tile lists still allow
vulcanus_tiles_cold/vulcanus_tiles_hotlist gainingor losing a tile
tile_collision_masks.lava()droppingresource = truewhile keepingwater_tile, which would split the geyser gate off from the cliff gate whileleaving the rocks alone
None is hypothetical in kind: the cliff set itself was established by
measurement, not by reading the masks, and the notes on it say a future
blocking tile would be found the same way.
Possible shapes for a fix
Not obviously worth doing yet, which is why this is filed rather than done:
comment naming its mechanism, so all three read as three rules instead of
three copies. Cheap, and it makes the independence visible at the call site.
change moves exactly the gates it should. The rock gate already has
the_tile_gate_refuses_exactly_the_two_lava_tiles; the geyser gate does nothave an equivalent, and the cliff gate's is now the The Vulcanus cliff-blocking tile set has four definitions and nothing checks they agree #364 parity test.
since that is when the data can change under all three at once.
Found while doing #364, by sweeping the repo for
Lava | LavaHotrather thantrusting that issue's table, which listed four sites and missed these two.