Resolve block names to the default state, not the first one
blocks.json lists a block's states in getPossibleStates() order -- the property cartesian product -- and separately marks which one is the default. The parser declared only id and properties, so the default flag was dropped on the floor and nameToStateID returned states[0]. Those differ for 642 of the 1168 blocks. What that produced, measured rather than guessed: every redstone vein in the world was lit=true and glowing, every sunflower was placed as its own top half with nothing under it, and oak stairs came out upside down and waterlogged. It also quietly disagreed with the StateGrass, StateOakLog and StateOakLeaf constants next door in encode.go, which are the real defaults. Now it starts from the default state and applies the properties it recognises, keeping the default's value for an unknown key or an illegal value -- which is what vanilla does when it reads a palette entry. That matters on the disk path: a chunk written with a property we no longer know used to decode to a random corner state instead of something sane. The signature grows an ok result, because air was doing double duty as both a real block and "no such name". Separately, blockPaletteEntry filled the Properties compound by ranging a Go map. nbt.Compound preserves insertion order precisely so encoding is deterministic, so saving one chunk twice produced different region-file bytes for every multi-property block. Keys are sorted now.
This commit is contained in:
parent
9e91425c5d
commit
113a59e365
14 changed files with 215 additions and 62 deletions
|
|
@ -32,7 +32,7 @@ const dataVersion26 = 4790
|
|||
// first time it ran: chunkAt prefers the store over the generator, so the
|
||||
// already-explored area around spawn keeps its old terrain and every later fix
|
||||
// looks like it did nothing in exactly the place you are standing.
|
||||
const generatorVersion = 7
|
||||
const generatorVersion = 8
|
||||
|
||||
// generatorVersionTag is the NBT key holding generatorVersion. It is namespaced
|
||||
// because it is ours, not part of the vanilla chunk format.
|
||||
|
|
@ -565,7 +565,9 @@ func readBlockStates(c *Chunk, si int, sc *nbt.Compound) {
|
|||
}
|
||||
name := string(nbtAsString(ec, "Name"))
|
||||
props := readProps(ec)
|
||||
ids[i] = nameToStateID(name, props)
|
||||
// An unknown block name decodes to air rather than to a neighbour's
|
||||
// state; that loses the block but does not corrupt the column.
|
||||
ids[i], _ = nameToStateID(name, props)
|
||||
}
|
||||
c.section(si) // ensure allocated
|
||||
s := c.sections[si]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue