Write the section fluid count instead of a hardcoded zero

LevelChunkSection puts two shorts in front of every section: nonEmptyBlockCount
and fluidCount. We wrote the first and then a literal 0 for the second, under a
comment claiming it was a reserved field that vanilla always leaves at zero.
It is not reserved and vanilla does not.

So every client was told every section is fluid-free, in a world where the
aquifer now fills oceans, lakes and flooded caves. The golden test did not catch
it because its fixture is a superflat chunk whose real fluid count is zero.

The count is per block state, not per block: a waterlogged stair holds a fluid
while a dry one does not, and the flag for that comes from the block-state dump
added with the heightmaps.
This commit is contained in:
Master290 2026-07-27 03:28:49 +03:00
parent 7880531bdb
commit 9e91425c5d
3 changed files with 69 additions and 14 deletions

View file

@ -106,8 +106,8 @@ func TestFlatChunkEncodesCleanly(t *testing.T) {
if err != nil {
t.Fatalf("section %d count: %v", s, err)
}
if _, err := r.Uint16(); err != nil { // reserved 2-byte field
t.Fatalf("section %d reserved: %v", s, err)
if _, err := r.Uint16(); err != nil { // fluidCount
t.Fatalf("section %d fluid count: %v", s, err)
}
if count > 0 {
nonAirSections++
@ -125,10 +125,10 @@ func TestFlatChunkEncodesCleanly(t *testing.T) {
}
// Light: four bitsets, then sky arrays, then block arrays.
expectedSkyArrays := parseBitSet(t, r) // sky mask
expectedSkyArrays := parseBitSet(t, r) // sky mask
expectedBlockArrays := parseBitSet(t, r) // block mask
parseBitSet(t, r) // empty sky mask
parseBitSet(t, r) // empty block mask
parseBitSet(t, r) // empty sky mask
parseBitSet(t, r) // empty block mask
skyArrays, err := r.VarInt()
if err != nil || skyArrays != int32(expectedSkyArrays) {
t.Fatalf("sky arrays = %d (err %v), want %d", skyArrays, err, expectedSkyArrays)