Skip to content

Support Minecraft 1.21.10 to 26.2 - #2

Open
niklaswa wants to merge 2 commits into
mainfrom
feat/minecraft-26-support
Open

niklaswa wants to merge 2 commits into
mainfrom
feat/minecraft-26-support

Conversation

@niklaswa

@niklaswa niklaswa commented Sep 10, 2026

Copy link
Copy Markdown

The newest release covers 1.8.9<1.21.8, so the addon has been gone since 1.21.10, not only on 26.x. Six versions are missing: 1.21.10, 1.21.11, 26.1, 26.1.1, 26.1.2, 26.2.

What changed in the game

1.21.10 replaced immediate entity rendering with the submit pipeline, and everything the render path of this addon touches went with it:

up to 1.21.8 1.21.10 and later
entry point render(state, PoseStack, MultiBufferSource, int) submit(state, PoseStack, SubmitNodeCollector, CameraRenderState)
multiple items renderMultipleFromCount(..., MultiBufferSource, ...) submitMultipleFromCount(..., SubmitNodeCollector, ...)
drawing an item ItemRenderer#renderStatic(stack, ctx, light, overlay, pose, bufferSource, level, seed) ItemStackRenderState#submit(pose, collector, light, overlay, tint)
light method parameter renderState.lightCoords

ItemRenderer lost renderStatic in 1.21.11 and the class does not exist at all in 26.x, so VersionedVersionBridge#renderItem had nothing left to call.

How it is solved

The item is no longer drawn from the ItemStack, it is submitted from the ItemStackRenderState the game already extracted. The renderer has that (renderState.item), the bridge does not, so both travel together in a small SubmitContext record passed where the buffer source used to go.

That fits without touching shared code: ItemPhysicsRenderer takes the buffer as Object and only hands it to bridge.renderItem, so a SubmitContext rides through untouched. No change to core or to the VersionBridge interface.

Everything else still matches, checked against the remapped jars: ItemClusterRenderState#extractItemGroupRenderState, Entity#stuckSpeedMultiplier, ItemEntity#age, RandomSource#setSeed/nextFloat, Entity#getYRot/getXRot/setXRot/onGround/position, and extractRenderState.

The six modules differ only in the package of CameraRenderState: renderer.state up to 1.21.11, renderer.state.level from 26 on.

Build fixes

All three are pre-existing, main does not build without them.

  • org.cadixdev.licenser 0.6.1 cannot be applied under Gradle 9, its CaseInsensitiveMap.get recurses until StackOverflowError. 0.6.1 is the plugin's last release, so it is removed. Headers stay in the sources and gradle/LICENSE-HEADER.txt stays in the repo. Happy to swap in a maintained checker instead.
  • accessWidener is a function in LabyGradle 0.8.1, not a property with a setter.
  • The shared modules get the Java 21 pin the addon template has, otherwise api and core follow the build JDK and the version modules refuse to consume them.

Separate commit for the wrapper: gradlew is committed as 100644, so the workflow dies with ./gradlew: Permission denied and exit 126 before it reaches Gradle. That is why every run of this workflow has failed.

Testing

Dev client, :game-runner:client_v26.2, LabyMod 4.6.18+2840. Four items summoned onto a stone platform, addon toggled live.

  • All six mixins apply, no injection errors.
  • Enabled: sword, bow and golden apple lie flat on the ground. Disabled: they stand upright and hover, the vanilla look. Toggling back and forth switches cleanly.
  • No render thread exception in the log while the items were on screen, and the injected code runs per item per frame.

Not checked in game: 1.21.10, 1.21.11, 26.1, 26.1.1, 26.1.2. Same pipeline, same module.

Two things I noticed while reading, not touched here

ItemPhysicsRenderer has boolean gui3D = true; model.itemPhysics$isGui3D(); on one line. The call result is discarded, so gui3D is always true and the whole if (!gui3D) branch below is dead. It fits the picture that VersionedBakedModel has been a stub returning false since 1.21.4, so this looks like a leftover from the render state migration rather than intent. Left alone because fixing it changes rendering behaviour and belongs in its own change.

A rebuild raises requiredLabyModBuild from 2015 to 2840.

1.21.10 replaced immediate entity rendering with the submit pipeline, and
the addon still hooked the old one, so it has been gone since then, not
only on 26.x:

  render(state, PoseStack, MultiBufferSource, int)
    -> submit(state, PoseStack, SubmitNodeCollector, CameraRenderState)
  ItemRenderer#renderStatic(...)
    -> ItemStackRenderState#submit(pose, collector, light, overlay, tint)

ItemRenderer lost renderStatic in 1.21.11 and the class is gone entirely
in 26.x, so the item can no longer be drawn from the stack. It is drawn
from the ItemStackRenderState the game already extracted, which the
renderer holds and the bridge does not, so both travel to the bridge in a
SubmitContext where the buffer source used to go. The core passes that
argument through untouched, so nothing outside the version modules
changes. The light is read off the render state now that submit no longer
takes it.

Everything else the addon hooks is unchanged: extractItemGroupRenderState,
Entity#stuckSpeedMultiplier, ItemEntity#age, RandomSource#setSeed and the
rotation accessors all still match.

The six new modules differ only in the package of CameraRenderState,
renderer.state up to 1.21.11 and renderer.state.level from 26 on.

Build fixes, all pre-existing: org.cadixdev.licenser 0.6.1 cannot be
applied under Gradle 9 (its CaseInsensitiveMap recurses until the stack
overflows) and has no newer release, accessWidener is a function in
LabyGradle 0.8.1 rather than a property with a setter, and the shared
modules need the Java 21 pin so they stop following the build JDK.
gradlew is committed as 100644, so the workflow's `./gradlew build` dies
with "Permission denied" before it reaches the build. Every run of the
addon workflow has failed on this.
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.

1 participant