Build 1.21.10 with Stonecutter from the shared src/
Check / compile (pull_request) Successful in 7m13s

Step 2 of #8. versions/1.21.10/src is gone; 1.21.10 builds from src/ as
:1.21.10, with versions/1.21.10 keeping only gradle.properties and run/.

API differences go behind version comments: render layers (ShaderUtils),
Camera.update's World vs BlockView (CameraMixin), the text and textured-quad
render states (RenderScopeImpl), Screen.init (SplashOverlayMixin) and
jspecify's @NonNull (SaturnRenderState).

Features 1.21.11 leaves out stay on 1.21.10, with a TODO for 1.21.11:
WorldFeatureImpl.getWorldAge, SaturnScreenFabric.resize and
EntityDrawerImpl clearing the hitbox.

Hats now render on 1.21.10: its HatFeatureRenderer overrode the
render-queue method with an empty body, and the working code sat in an old
VertexConsumerProvider method nothing called. 1.21.10 now uses 1.21.11's
render-queue implementation (HatFeatureRenderer, ObjModel, ObjRenderer),
and also gets 1.21.11's null check on the player's display name.

The 1.21.10 jar has the same entries, fabric.mod.json and mixin configs as
before; only those four classes and ShaderUtils (a helper method for
entityAlpha) have different bytecode. The 1.21.11 jar only differs in
ShaderUtils.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-09-27 05:05:03 +02:00
co-authored by claude
parent a30cf4d3ab
commit 95e4dff448
66 changed files with 80 additions and 3598 deletions
@@ -7,9 +7,14 @@ import com.mojang.blaze3d.pipeline.RenderPipeline;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.render.RenderLayer;
//? if >=1.21.11 {
import net.minecraft.client.render.RenderLayers;
import net.minecraft.client.render.RenderSetup;
import net.minecraft.client.render.block.entity.AbstractEndPortalBlockEntityRenderer;
//?} else {
/*import net.minecraft.client.render.RenderPhase.Textures;
import net.minecraft.client.render.block.entity.EndPortalBlockEntityRenderer;
*///?}
import net.minecraft.util.Identifier;
public class ShaderUtils {
@@ -21,19 +26,35 @@ public class ShaderUtils {
.withCull(false)
.build());
//? if >=1.21.11 {
public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway",
RenderSetup.builder(END_GATEWAY_PIPELINE)
.texture("Sampler0", AbstractEndPortalBlockEntityRenderer.SKY_TEXTURE)
.texture("Sampler1", AbstractEndPortalBlockEntityRenderer.PORTAL_TEXTURE).build());
//?} else {
/*public static final RenderLayer END_GATEWAY = RenderLayer.of("end_gateway", 1536, false, false,
END_GATEWAY_PIPELINE,
RenderLayer.MultiPhaseParameters.builder()
.texture(Textures.create().add(EndPortalBlockEntityRenderer.SKY_TEXTURE, false)
.add(EndPortalBlockEntityRenderer.PORTAL_TEXTURE, false).build())
.build(false));
*///?}
public static RenderLayer getRenderLayer(IdentifierRef texture) {
String path = texture.toString();
if (path.endsWith(".gif")) {
return RenderLayers.entityAlpha((Identifier) (Object) GifUtils.get(texture));
return entityAlpha((Identifier) (Object) GifUtils.get(texture));
} else if (path.endsWith("end.png")) {
return END_GATEWAY;
} else {
return RenderLayers.entityAlpha((Identifier) (Object) texture);
return entityAlpha((Identifier) (Object) texture);
}
}
}
private static RenderLayer entityAlpha(Identifier texture) {
//? if >=1.21.11 {
return RenderLayers.entityAlpha(texture);
//?} else
//return RenderLayer.getEntityAlpha(texture);
}
}
@@ -13,7 +13,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.render.Camera;
import net.minecraft.entity.Entity;
//? if >=1.21.11 {
import net.minecraft.world.World;
//?} else
//import net.minecraft.world.BlockView;
@Mixin(Camera.class)
public abstract class CameraMixin {
@@ -25,7 +28,10 @@ public abstract class CameraMixin {
@Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setRotation(FF)V", ordinal = 1, shift = At.Shift.AFTER))
public void lockRotation(
//? if >=1.21.11 {
World focusedBlock,
//?} else
//BlockView focusedBlock,
Entity cameraEntity,
boolean isThirdPerson,
boolean isFrontFacing,
@@ -31,7 +31,10 @@ public class WorldFeatureImpl implements WorldFeature {
*/
@Override
public long getWorldAge() {
// return hasWorld() ? mc.world.getTime() : 0L;
//? if >=1.21.11 {
// TODO: not implemented on 1.21.11 yet.
return 0L;
//?} else
//return hasWorld() ? mc.world.getTime() : 0L;
}
}
@@ -62,7 +62,8 @@ public class EntityDrawerImpl implements EntityDrawer {
EntityRenderManager entityRenderDispatcher = SaturnClient.client.getEntityRenderDispatcher();
EntityRenderer<? super LivingEntity, ?> entityRenderer = entityRenderDispatcher.getRenderer(entity);
EntityRenderState entityRenderState = entityRenderer.getAndUpdateRenderState(entity, 1.0F);
// entityRenderState.hitbox = null;
//? if <1.21.11
//entityRenderState.hitbox = null;
if (renderScope instanceof RenderScopeImpl i)
i.addEntity(entityRenderState, scale, translation, rotation, overrideCameraAngle, x1, y1, x2, y2);
@@ -34,6 +34,7 @@ import net.minecraft.client.gui.render.state.TexturedQuadGuiElementRenderState;
import net.minecraft.client.gui.render.state.special.EntityGuiElementRenderState;
import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.client.render.item.KeyedItemRenderState;
//? if >=1.21.11
import net.minecraft.client.texture.AbstractTexture;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.texture.TextureSetup;
@@ -145,7 +146,10 @@ public class RenderScopeImpl implements RenderScope {
((Text) Fonts.setFont(line, font)).asOrderedText(),
new Matrix3x2f(this.matrices.stack),
0, font == 0 ? 1 : 8,
//? if >=1.21.11 {
finalColor, 0, false, false, this.scissorStack.peekLast()));
//?} else
//finalColor, 0, false, this.scissorStack.peekLast()));
matrices.pop();
@@ -206,11 +210,15 @@ public class RenderScopeImpl implements RenderScope {
GpuTextureView gpuTextureView = SaturnClient.client.getTextureManager()
.getTexture(sprite).getGlTextureView();
//? if >=1.21.11
AbstractTexture abstractTexture = SaturnClient.client.getTextureManager().getTexture(sprite);
this.state.addSimpleElement(new TexturedQuadGuiElementRenderState(
RenderPipelines.GUI_TEXTURED,
//? if >=1.21.11 {
TextureSetup.of(gpuTextureView, abstractTexture.getSampler()),
//?} else
//TextureSetup.withoutGlTexture(gpuTextureView),
new Matrix3x2f(this.matrices.stack),
x1, y1, x2, y2, u1, u2, v1, v2, color,
this.scissorStack.peekLast()));
@@ -116,11 +116,14 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider {
return super.keyPressed(input);
}
// @Override
// public void resize(MinecraftClient client, int width, int height) {
// screen.resize(width, height);
// super.resize(client, width, height);
// }
// TODO: resize isn't hooked on 1.21.11 yet.
//? if <1.21.11 {
/*@Override
public void resize(MinecraftClient client, int width, int height) {
screen.resize(width, height);
super.resize(client, width, height);
}
*///?}
@Override
public void close() {
@@ -1,11 +1,13 @@
package org.saturnclient.saturnclient;
//? if >=1.21.11
import org.jspecify.annotations.NonNull;
import org.saturnclient.client.player.SaturnPlayer;
import net.fabricmc.fabric.api.client.rendering.v1.RenderStateDataKey;
public class SaturnRenderState {
//? if >=1.21.11
@NonNull
public static RenderStateDataKey<SaturnPlayer> saturnDataKey = RenderStateDataKey
.create(() -> "saturn-client-player");
@@ -15,6 +15,7 @@ import org.spongepowered.asm.mixin.Final;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.SplashOverlay;
//? if >=1.21.11
import net.minecraft.client.util.Window;
import net.minecraft.resource.ResourceReload;
import net.minecraft.util.Util;
@@ -155,9 +156,13 @@ public abstract class SplashOverlayMixin {
reloadCompleteTime = Util.getMeasuringTimeMs();
//? if >=1.21.11
Window window = client.getWindow();
if (client.currentScreen != null) {
//? if >=1.21.11 {
client.currentScreen.init(window.getScaledWidth(), window.getScaledHeight());
//?} else
//client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight());
}
}
}