The image used in the explanation:
Click here to view the secret text
×
Understanding this bug requires understanding some of the internals of how DROD handles briar, so sit tight and read if you're curious.
Each connected section of briar in DROD can be assigned to one of two types:
- Briar Component, which requires a section to have at least one briar root
- Freefloating briar which is almost completely ignored by any and all processing
By "
Connected section"
I mean like if there is a path between two tiles through briar then they form one section - there are some tiny exceptions but that's the gist of it. If a briar tile stands next to any other brair tile they are the same section.
Looking at A. you can see there is one Briar Component, encircled in yellow, and a freefloating section. It's not part of any component but it will be crucial to understanding the problem.
Okay, we wait one turn and see B. What has happened so far? Our Briar Component got larger, but the freefloating section IS NOT part of the Component. Nothing complicated is happening right now, until we wait another turn and...
On C. the bomb explodes splitting our Briar Component in two. Are the two bits still connected? They shouldn't be, because as I said a moment ago the freefloating briar is not part of this Component. But they are actually still connected. Why? Here is where the complexity starts.
When a briar that is part of a Briar Component is destroyed, game takes note and when it's time for briar processing the components are recalculated. The way it works on the high-level is that it removes all of the stored information about briar components. Then it checks every briar root, and using a "
flood fill"
method gets a list of all briar tiles connected to the root. Let's call it NEW_BRIARS.
Then it looks at the old data, at the component this briar root was part of, takes a list of all the tiles and calls it OLD_BRIARS.
Finally, it creates a new component that is made out of tiles from NEW_BRIARS that also exist in OLD_BRIARS, basically an intersections of two sets if you're into math.
It might not be obvious yet but that's the problem. You see, the "
flood fill"
method I talked about, it's a function called "
GetConnected8NeighborTiles"
and it does just that. If it neighbors a tile orthogonally or diagonally, it's part of the list and it then looks for that tile's neighbors. Which means, when regenerating the component at step C, the code manages to reach the separated part on the East through the freefloating briar, even though that briar is not part of its group.
But normally it would kind of make sense - if the top briar was left alone it'd almost look as if the briars are connected. The problem is, when the next turn the freefloating briar is removed by anothere explosion, the component remains untouched. Because, as established earlier, recalculation only happens when the removed briar is part of a component.
I hope it's more or less understandable.
The fix consisted of modifying the call to "
GetConnected8NeighborTiles"
so that it only looked at the tiles that were part of the component in the past.
Essentially it changed from "
Hey give me all neighbors and they neighbors"
to "
Hey give me all neighbors and they neighbors but skip the neighbors that are not on this fancy list"
.
I worry this might break some arcane behavior I was not aware of, let's hope not!
____________________________
My website