Skip to content

Add Minecraft 26.1 support - #484

Open
u9g wants to merge 9 commits into
PrismarineJS:masterfrom
u9g:26-1-support
Open

Add Minecraft 26.1 support#484
u9g wants to merge 9 commits into
PrismarineJS:masterfrom
u9g:26-1-support

Conversation

@u9g

@u9g u9g commented Aug 16, 2026

Copy link
Copy Markdown
Member

Three changes needed to render 26.x worlds:

modelsBuilder: unwrap object texture refs
26.x wraps some model texture references in objects instead of plain strings:

"textures": {
  "all": { "force_translucent": true, "sprite": "minecraft:block/black_stained_glass" }
}

The #-reference resolution loop in prepareModel calls .charAt(0) on these, throwing root.charAt is not a function. Unwrap to the sprite string. (force_translucent is a vanilla render-type hint — the viewer's single transparent material has no use for it.)

atlas: pack tiles at native resolution
26.1 ships 32x32 block textures (per-wood shelves). makeTextureAtlas hard-coded 16x16 tiles and cropped every source to its top-left 16x16, which mangles these. Tiles now keep their native size; each atlas entry already carries its own u/v/su/sv extents, so consumers (modelsBuilder UV math, bu/bv sampling) are resolution-agnostic. Animated textures (taller-than-wide strips) still contribute only their first frame. Versions with only 16x16 textures produce an equivalent atlas.

version: add 26.1 to supportedVersions

Verified end-to-end: generated 26.1 assets locally (via the minecraft-assets data from this pipeline) and rendered a live 26.1 world with the standalone viewer — all 1168 blocks resolve, zero missing-texture fallbacks, shelf blocks render at native resolution. Re-verified against the published minecraft-assets 1.18.0 data (with the version-index fix below): atlas + blocksStates generation completes for all 1168 blocks.

Depends on:

public/ assets are generated at install time by viewer/prerender.js; the devDependency is now pinned to minecraft-assets@^1.18.0 (first release shipping the 26.1 data), so once a release containing the version-index fix is out, this PR needs no further changes.

@rom1504

rom1504 commented Aug 16, 2026

Copy link
Copy Markdown
Member

CI fails. Please release the deps then reun CI here

u9g added a commit to u9g/bot-harness that referenced this pull request Sep 6, 2026
…ds (#4)

Pins prismarine-viewer to the v1.33.0-host26.1 release of u9g/prismarine-viewer:
the host-object series (PrismarineJS/prismarine-viewer#498-#503) merged with
PrismarineJS/prismarine-viewer#484 (26.1 support), with the world bounds file
fetched through the host. Recording no longer needs -v 1.21.4.
u9g added 9 commits September 12, 2026 11:05
Three changes needed for 26.x:

- modelsBuilder: unwrap object texture refs. 26.x wraps some model
  texture references in objects ({ sprite, force_translucent, ... })
  instead of plain strings, which broke the #ref resolution loop.
- atlas: pack tiles at native resolution. 26.1 ships 32x32 block
  textures (per-wood shelves); each atlas entry already carries its
  own u/v/su/sv extents so consumers are resolution-agnostic.
  Animated textures still contribute only their first frame. For
  16x16-only versions the generated atlas is equivalent.
- version: add 26.1 to supportedVersions.

Regenerating public/ assets for 26.1 also needs a minecraft-assets
release containing data/26.1 (PrismarineJS/minecraft-assets#50) and
the extractor fix (PrismarineJS/minecraft-jar-extractor#68).
Sections below y=0 were never meshed: worldrenderer's dirty-section loops
hardcoded the pre-1.18 0..256 range, and the worker's section-presence
guard indexed chunk.sections by y/16 even though ChunkColumn indexes
sections from minY (-64 since 1.18), so negative sections resolved to
undefined and were skipped. Any camera below y=0 saw only the clear color.

Derive minY/worldHeight from the version's chunk implementation, index
worker sections by (y - minY) / 16, and gate models.js face culling on
world.minY instead of 0.
1.18.0 is the first npm release shipping data/26.1. Exposing it through
mcAssets('26.1') additionally needs PrismarineJS/node-minecraft-assets#54,
so the effective minimum is the release that includes that fix.
1.18.0 ships data/26.1 but has no 26.1 entry in index.js, so
mcAssets('26.1') returns null and viewer/prerender.js throws
during npm install. The entry landed in 1.19.0.
worldrenderer.js reached for prismarine-chunk to read minY/worldHeight,
which pulled prismarine-registry and all of minecraft-data into the browser
entry bundle. indexConfig only externalizes five minecraft-data files, so
webpack tried to inline ~252 MiB of JSON and died at the V8 heap limit
before emitting index.js, taking `npm install` down with it via prepare.

prerender.js already has prismarine-chunk as a build-time dependency, so it
now emits public/worldBounds.json (653 bytes) and the renderer fetches it
through the loadJSON it already uses for blocksStates.

addColumn/removeColumn still post to the worker immediately and defer only
the section-marking loop until the bounds land. The worker's mesh loop is
gated on blockStates arriving from the same kind of fetch, so this costs no
rendering latency. world.js keeps prismarine-chunk: it runs in the worker
and needs Chunk.fromJson, so prismarine-chunk stays the single source of
truth for world bounds on both sides.
supportedVersions already lists 26.1, so the suite generates a client 26.1
describe block that nothing was running: the matrix stopped at 1.21.4, which
covered the other versions against regressions but left the version this
branch adds untested.
The 26.1 server jar is compiled for class file version 69 (Java 25); the
pinned JRE 21 only reads up to 65, so it cannot start the server at all.
mineflayer runs its whole matrix, 1.8.8 upward, on Java 25.
worldBounds.json is keyed by supportedVersions, but since "Keep the
server's version for block data, snap only the assets" (PrismarineJS#492) the
version passed to WorldRenderer.setVersion is the server's exact
version rather than the snapped one. A 26.1.2 server therefore missed
the lookup and silently defaulted to minY 0 / worldHeight 256, undoing
the negative-Y rendering this branch adds.

Prefer an exact match and fall back to the snapped assets version,
which shares the major and so has the same bounds.
.gitignore had no trailing newline, so appending the worldBounds.json
entry concatenated it onto the last line as the single dead pattern
"test/server_*public/worldBounds.json", ignoring neither path.
@u9g
u9g force-pushed the 26-1-support branch 2 times, most recently from e6a1941 to dc777aa Compare September 12, 2026 15:21
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