Write chunk NBT vanilla reads: flat root, byte section Y, four-bit block palettes
Our region files were not Anvil. Three things stood between them and vanilla's
deserializer, and each is enough on its own:
* everything was nested under a "Level" compound. Chunk data lived there until
1.18; SerializableChunkData builds a flat root and never looks for the key.
* a section's Y was an Int. Vanilla writes putByte and reads getByteOr, so
every section of ours decodes as index 0 and overwrites the one before it.
* block palettes were packed at ceil(log2(size)) bits. Strategy's tableswitch
routes bit counts 1 through 4 to the same four-bit configuration, so a
palette of 2..16 states is four bits wide on disk. Ours were one to three,
which makes the long array a quarter of the length vanilla computes, and
SimpleBitStorage rejects the section outright rather than misreading it.
Biome containers were already right: Strategy has no such floor for them, and a
Global configuration above three bits still stores palette indices, just at its
own width. The suspicion that biomes collapsed on save/load was unfounded --
what let it stand is that every round-trip test in this package set blocks and
asserted blocks, so nothing proved biomes survived. They do now, per cell, for
every palette width a section can hold.
Verified against vanilla rather than against our reading of it:
tools/VanillaChunkFormatCheck.java opens a region file we wrote using vanilla's
RegionFile, NbtIo, Strategy and SimpleBitStorage. Sixteen generated chunks pass.
Reverting either the Y type or the palette floor makes it fail with vanilla's
own message -- "Invalid length given for storage, got: 64 but expected: 256" --
so the check can fail, which is the only reason to trust it passing.
Reading a world the official server generated is what the surface-height parity
capture in CLAUDE.md has always needed, and this is half of it.
This commit is contained in:
parent
113a59e365
commit
e0fdddd887
4 changed files with 437 additions and 54 deletions
13
CLAUDE.md
13
CLAUDE.md
|
|
@ -73,9 +73,16 @@ java -cp "<out>;$CP" VanillaBlockStateDump > internal/world/block_properties.bin
|
|||
|
||||
The 39 jars under `libraries/` are required; the server jar alone will not boot the registry. Bump
|
||||
the format version in both the Java and `internal/world/block_properties.go` whenever the layout or
|
||||
a flag's meaning changes. Substring-matching block names is how the light table was wrong before
|
||||
(`grass_block` matched "grass", `bedrock` matched "bed"); don't reintroduce that shape of guess
|
||||
anywhere.
|
||||
a flag's meaning changes.
|
||||
|
||||
The same trick verifies output, not just constants. `tools/VanillaChunkFormatCheck.java` opens a
|
||||
region file we wrote with vanilla's own `RegionFile`, `NbtIo`, `Strategy` and `SimpleBitStorage` and
|
||||
fails if the root is not flat, a section `Y` is not a byte, or a palette array is not the width
|
||||
vanilla derives from its palette size. Note the server jar is *signed*, so a helper cannot be
|
||||
declared inside a `net.minecraft.*` package — reach protected members by reflection instead.
|
||||
|
||||
Substring-matching block names is how the light table was wrong before (`grass_block` matched
|
||||
"grass", `bedrock` matched "bed"); don't reintroduce that shape of guess anywhere.
|
||||
|
||||
## Layout
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue