Skip to content

The world renderer drew nothing; make it draw the world - #128

Merged
CaYatur merged 1 commit into
mainfrom
fix/world-render-actually-works
Jul 29, 2026
Merged

The world renderer drew nothing; make it draw the world#128
CaYatur merged 1 commit into
mainfrom
fix/world-render-actually-works

Conversation

@CaYatur

@CaYatur CaYatur commented Jul 29, 2026

Copy link
Copy Markdown
Owner

The world renderer drew nothing; make it draw the world

#119 shipped a world renderer that produced no output at all on a real world,
and every test was green because none of them read a real chunk.

The palette was unwrapped once and needed twice. prismarine-nbt represents
an NBT list as {type:'list', value:{type:'compound', value:[...]}} — the outer
wrapper says "list", the inner says what the elements are. sections happened
to work because that code unwrapped twice; palette did not, so
Array.isArray(palette) was false for every section of every chunk, every
section was skipped, and every tile came back null. Silently: no error, no
exception, just a map with nothing on it.

Verified against a real Paper 1.21.6 world rather than argued about — 339 chunks
of one region decoded, rendered to an image and looked at. The bit-level work
from #119 turned out to be right: DataVersion 4435, padded packing, and the
long counts match bitsPerIndex exactly (a 26-entry palette is 5 bits and 342
longs, which is what the file holds).

And then it looked wrong, so this fixes that too. The topmost block of a
column is usually the plant standing on the ground rather than the ground: on
that world the commonest surface blocks after grass were short_grass, vine,
fern and bamboo, none of them in the colour table, all falling through to
the stable-hash fallback. A bamboo jungle rendered as a maroon smear and every
meadow as blue-grey.

A map looks through foliage. seeThrough skips grass, ferns, vines, flowers,
bamboo, crops, carpets, signs and the rest — by name and by suffix family, so a
flower added in a future version needs no release — while leaves stay, because a
forest canopy is exactly what you see from above. After it, every drawn surface
block is one the table names.

The common colours are Minecraft's own map-item palette now instead of eyeballed
values, since that is the palette a player recognises. Mine were darker and
redder, which is the other half of why podzol read as maroon.

Asserted with a real NBT chunk built in the test and read by the real function:
air above and stone below renders as stone at the right height, grass with
short_grass on it renders as grass, and an all-air chunk produces no tile.
Proved failable — restoring the single unwrap gives
FAIL - a valid chunk produced no tile — the reader found no sections, which is
precisely what was shipping.

#119 shipped a world renderer that produced no output at all on a real world,
and every test was green because none of them read a real chunk.

**The palette was unwrapped once and needed twice.** prismarine-nbt represents
an NBT list as `{type:'list', value:{type:'compound', value:[...]}}` — the outer
wrapper says "list", the inner says what the elements are. `sections` happened
to work because that code unwrapped twice; `palette` did not, so
`Array.isArray(palette)` was false for every section of every chunk, every
section was skipped, and every tile came back null. Silently: no error, no
exception, just a map with nothing on it.

Verified against a real Paper 1.21.6 world rather than argued about — 339 chunks
of one region decoded, rendered to an image and looked at. The bit-level work
from #119 turned out to be right: DataVersion 4435, padded packing, and the
long counts match `bitsPerIndex` exactly (a 26-entry palette is 5 bits and 342
longs, which is what the file holds).

**And then it looked wrong, so this fixes that too.** The topmost block of a
column is usually the plant standing on the ground rather than the ground: on
that world the commonest surface blocks after grass were `short_grass`, `vine`,
`fern` and `bamboo`, none of them in the colour table, all falling through to
the stable-hash fallback. A bamboo jungle rendered as a maroon smear and every
meadow as blue-grey.

A map looks *through* foliage. `seeThrough` skips grass, ferns, vines, flowers,
bamboo, crops, carpets, signs and the rest — by name and by suffix family, so a
flower added in a future version needs no release — while leaves stay, because a
forest canopy is exactly what you see from above. After it, every drawn surface
block is one the table names.

The common colours are Minecraft's own map-item palette now instead of eyeballed
values, since that is the palette a player recognises. Mine were darker and
redder, which is the other half of why podzol read as maroon.

Asserted with a real NBT chunk built in the test and read by the real function:
air above and stone below renders as stone at the right height, grass with
`short_grass` on it renders as *grass*, and an all-air chunk produces no tile.
Proved failable — restoring the single unwrap gives
`FAIL - a valid chunk produced no tile — the reader found no sections`, which is
precisely what was shipping.
Copilot AI review requested due to automatic review settings July 29, 2026 01:17
@CaYatur
CaYatur merged commit e683c82 into main Jul 29, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@CaYatur
CaYatur deleted the fix/world-render-actually-works branch July 29, 2026 01:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants