From 88e1fa6cb4f636dec01cad09653780770215d4d8 Mon Sep 17 00:00:00 2001 From: kohenevans Date: Sat, 26 Sep 2026 13:50:17 -0700 Subject: [PATCH 1/8] Add Minecraft 26.3 target --- settings.gradle.kts | 2 +- versions/26.3/gradle.properties | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 versions/26.3/gradle.properties diff --git a/settings.gradle.kts b/settings.gradle.kts index ec06d301..82182107 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,7 +29,7 @@ stonecutter { centralScript = "build.gradle.kts" create(rootProject) { - versions("1.21.4", "1.21.5", "1.21.8", "1.21.10", "1.21.11", "26.1.2") + versions("1.21.4", "1.21.5", "1.21.8", "1.21.10", "1.21.11", "26.1.2", "26.3") vcsVersion = "1.21.11" } } diff --git a/versions/26.3/gradle.properties b/versions/26.3/gradle.properties new file mode 100644 index 00000000..0d77a4d7 --- /dev/null +++ b/versions/26.3/gradle.properties @@ -0,0 +1,7 @@ +minecraft_version=26.3 +minecraft_version_out=26.3 + +fabric_version=0.161.0+26.3 +malilib_version=26.3:0.30.1 +malilib_api_version=0.8.3-26.2 +worldedit_version=26.3:7.4.6-SNAPSHOT From a19607aa280e40b6f9d06c115c8db4c23aa041fd Mon Sep 17 00:00:00 2001 From: kohenevans Date: Sat, 26 Sep 2026 13:50:18 -0700 Subject: [PATCH 2/8] Exclude malilib-api's stale transitive malilib-fabric dependency --- build.gradle.kts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index bf7a2ee7..d9b8d292 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -87,7 +87,9 @@ dependencies { implementation("net.fabricmc.fabric-api:fabric-api:${project.property("fabric_version")}") implementation("com.sk89q.worldedit:worldedit-fabric-mc${project.property("worldedit_version")}") implementation("fi.dy.masa.malilib:malilib-fabric-${project.property("malilib_version")}") - implementation("net.kr1v:malilib-api:${project.property("malilib_api_version")}") + implementation("net.kr1v:malilib-api:${project.property("malilib_api_version")}") { + exclude(group = "fi.dy.masa.malilib") // avoid pulling in malilib-api's pinned (possibly stale) transitive malilib-fabric version + } } annotationProcessor("net.kr1v:malilib-api-processor:1.0.0") } From 6d1eb9084c0437e6a0a0033eff200f109a2f2c05 Mon Sep 17 00:00:00 2001 From: kohenevans Date: Sat, 26 Sep 2026 13:50:18 -0700 Subject: [PATCH 3/8] Fix shulker box lookup for 26.3's dyed item consolidation --- .../redstone/redstonetools/utils/SignalBlockSupplier.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java b/src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java index a8b2bcba..6ce5aa35 100644 --- a/src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java +++ b/src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java @@ -91,7 +91,10 @@ private static int calculateComparatorOutput(int items, int slots, int item$getM private static Item getBestItem(int signalStrength, int slots) { if (signalStrength > 15) - return Items.WHITE_SHULKER_BOX; + //? if >=26.3 { + return Items.DYED_SHULKER_BOX.white(); + //? } else + //return Items.WHITE_SHULKER_BOX; else if (slots >= 15) return Items.WOODEN_SHOVEL; else From 85a4e69456e9eefff6cd32671c98597d9e686431 Mon Sep 17 00:00:00 2001 From: kohenevans Date: Sat, 26 Sep 2026 13:50:18 -0700 Subject: [PATCH 4/8] Fix RedStoneWireBlock rename to RedstoneWireBlock on 26.3 --- .../mixin/blocks/RedstoneHitboxMixin.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/client/java/tools/redstone/redstonetools/mixin/blocks/RedstoneHitboxMixin.java b/src/client/java/tools/redstone/redstonetools/mixin/blocks/RedstoneHitboxMixin.java index 25d53f10..58c46a27 100644 --- a/src/client/java/tools/redstone/redstonetools/mixin/blocks/RedstoneHitboxMixin.java +++ b/src/client/java/tools/redstone/redstonetools/mixin/blocks/RedstoneHitboxMixin.java @@ -3,7 +3,10 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.RedStoneWireBlock; +//? if >=26.3 { +import net.minecraft.world.level.block.RedstoneWireBlock; +//? } else +//import net.minecraft.world.level.block.RedStoneWireBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -15,7 +18,10 @@ import tools.redstone.redstonetools.config.General; import tools.redstone.redstonetools.features.toggleable.BigDustFeature; -@Mixin(RedStoneWireBlock.class) +//? if >=26.3 { +@Mixin(RedstoneWireBlock.class) +//? } else +//@Mixin(RedStoneWireBlock.class) public class RedstoneHitboxMixin { // use array for better performance @Unique From 385daf0f2cd75170d284e8ec607ed8e299e99f3c Mon Sep 17 00:00:00 2001 From: kohenevans Date: Sat, 26 Sep 2026 13:50:18 -0700 Subject: [PATCH 5/8] Fix Minecraft.screen access moving to Minecraft.gui.screen() on 26.3 --- .../redstone/redstonetools/config/option/ConfigMacro.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/client/java/tools/redstone/redstonetools/config/option/ConfigMacro.java b/src/client/java/tools/redstone/redstonetools/config/option/ConfigMacro.java index 2ffa8a11..1b902c55 100644 --- a/src/client/java/tools/redstone/redstonetools/config/option/ConfigMacro.java +++ b/src/client/java/tools/redstone/redstonetools/config/option/ConfigMacro.java @@ -116,7 +116,10 @@ public void resetToDefault() { @Override protected boolean onMouseClickedImpl(/*? if >=1.21.10 {*/net.minecraft.client.input.MouseButtonEvent click, boolean doubleClick/*? } else {*//*int mouseX, int mouseY, int mouseButton*//*? }*/) { super.onMouseClickedImpl(/*? if >=1.21.10 {*/click, doubleClick/*? } else {*//*mouseX, mouseY, mouseButton*//*? }*/); - GuiBase.openGui(new GuiMacroEditor(Component.nullToEmpty(configMacro.macroName), configMacro, Minecraft.getInstance().screen)); + //? if >=26.3 { + GuiBase.openGui(new GuiMacroEditor(Component.nullToEmpty(configMacro.macroName), configMacro, Minecraft.getInstance().gui.screen())); + //? } else + //GuiBase.openGui(new GuiMacroEditor(Component.nullToEmpty(configMacro.macroName), configMacro, Minecraft.getInstance().screen)); return true; } }); From 3248f33a896120e3845b507d5a8ee4d076ad882a Mon Sep 17 00:00:00 2001 From: kohenevans Date: Sat, 26 Sep 2026 13:50:18 -0700 Subject: [PATCH 6/8] Port AirPlace outline rendering to 26.3's submit-node render pipeline --- .../features/toggleable/AirPlaceFeature.java | 28 +++++++++++++++---- .../mixin/features/WorldRendererInvoker.java | 4 ++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/client/java/tools/redstone/redstonetools/features/toggleable/AirPlaceFeature.java b/src/client/java/tools/redstone/redstonetools/features/toggleable/AirPlaceFeature.java index f75dde5f..58ad031e 100644 --- a/src/client/java/tools/redstone/redstonetools/features/toggleable/AirPlaceFeature.java +++ b/src/client/java/tools/redstone/redstonetools/features/toggleable/AirPlaceFeature.java @@ -1,5 +1,6 @@ package tools.redstone.redstonetools.features.toggleable; +import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; @@ -134,7 +135,10 @@ public static BlockHitResult findAirPlaceBlockHit(Player playerEntity) { return; /* render block outline */ - Camera camera = client.gameRenderer.getMainCamera(); + //? if >=26.3 { + Camera camera = client.gameRenderer.mainCamera(); + //? } else + //Camera camera = client.gameRenderer.getMainCamera(); Vec3 camPos = camera //? if <=1.21.5 { /*.getPosition(); @@ -146,14 +150,15 @@ public static BlockHitResult findAirPlaceBlockHit(Player playerEntity) { //? if <26.1 { VertexConsumer consumer = context.consumers().getBuffer( - //? } else - //VertexConsumer consumer = context.bufferSource().getBuffer( //? if <=1.21.10 { /*RenderType.lines() *///?} else { RenderTypes.lines() //?} ); + //? } else if <26.3 { + /*VertexConsumer consumer = context.bufferSource().getBuffer(RenderTypes.lines()); + *///?} //? if <1.21.10 { /*((WorldRendererInvoker) context.worldRenderer()).invokeRenderHitOutline( @@ -165,7 +170,7 @@ public static BlockHitResult findAirPlaceBlockHit(Player playerEntity) { blockState, CommonColors.BLACK ); - *///?} else { + *///?} else if <26.3 { //? if <26.1 { ((WorldRendererInvoker) context.worldRenderer()).invokeRenderHitOutline( //? } else @@ -193,7 +198,20 @@ public static BlockHitResult findAirPlaceBlockHit(Player playerEntity) { *///? } CommonColors.BLACK/*? if >=1.21.11 {*/, client.getWindow().getAppropriateLineWidth()/*?}*/ ); - //?} + //?} else { + /*PoseStack matrices = context.poseStack(); + matrices.pushPose(); + matrices.translate(blockPos.getX() - camPos.x, blockPos.getY() - camPos.y, blockPos.getZ() - camPos.z); + context.submitNodeCollector().submitShapeOutline( + matrices, + blockState.getShape(client.level, blockPos, net.minecraft.world.phys.shapes.CollisionContext.of(camera.entity())), + RenderTypes.lines(), + CommonColors.BLACK, + client.getWindow().getAppropriateLineWidth(), + false + ); + matrices.popPose(); + *///?} }; //? if <1.21.10 { diff --git a/src/client/java/tools/redstone/redstonetools/mixin/features/WorldRendererInvoker.java b/src/client/java/tools/redstone/redstonetools/mixin/features/WorldRendererInvoker.java index 5efd3ac7..72560b13 100644 --- a/src/client/java/tools/redstone/redstonetools/mixin/features/WorldRendererInvoker.java +++ b/src/client/java/tools/redstone/redstonetools/mixin/features/WorldRendererInvoker.java @@ -15,6 +15,7 @@ @Mixin(LevelRenderer.class) public interface WorldRendererInvoker { + //? if <26.3 { @Invoker //? if <=1.21.8 { /*void invokeRenderHitOutline(PoseStack matrices, VertexConsumer vertexConsumer, Entity entity, double cameraX, double cameraY, double cameraZ, BlockPos pos, BlockState state, int color); @@ -23,4 +24,5 @@ public interface WorldRendererInvoker { *///?} else { void invokeRenderHitOutline(PoseStack matrices, VertexConsumer vertexConsumer, double x, double y, double z, BlockOutlineRenderState state, int color, float lineWidth); //?} -} \ No newline at end of file + //? } +} From 61f7d64ebe0fc5b1b33d3bff11940897101046bd Mon Sep 17 00:00:00 2001 From: kohenevans Date: Sat, 26 Sep 2026 13:50:18 -0700 Subject: [PATCH 7/8] Bump Minecraft upper bound to 26.3 --- src/main/resources/fabric.mod.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 569983a9..449dabbf 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -37,7 +37,7 @@ "depends": { "fabricloader": ">=0.18.1", "fabric-api": "*", - "minecraft": ">=1.21.4 <=26.1.2" + "minecraft": ">=1.21.4 <=26.3" }, "recommends": { "worldedit": "*", From 9e0687bba139d7a12af6d51886f4a72e3b62bc4c Mon Sep 17 00:00:00 2001 From: kohenevans Date: Sat, 26 Sep 2026 14:30:05 -0700 Subject: [PATCH 8/8] Add explanatory comments to the 26.3 rendering/API-change branches for reviewability --- .../redstonetools/config/option/ConfigMacro.java | 1 + .../features/toggleable/AirPlaceFeature.java | 15 ++++++++++++++- .../mixin/blocks/RedstoneHitboxMixin.java | 1 + .../mixin/features/WorldRendererInvoker.java | 3 +++ .../redstonetools/utils/SignalBlockSupplier.java | 2 ++ 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/client/java/tools/redstone/redstonetools/config/option/ConfigMacro.java b/src/client/java/tools/redstone/redstonetools/config/option/ConfigMacro.java index 1b902c55..86a85d1a 100644 --- a/src/client/java/tools/redstone/redstonetools/config/option/ConfigMacro.java +++ b/src/client/java/tools/redstone/redstonetools/config/option/ConfigMacro.java @@ -116,6 +116,7 @@ public void resetToDefault() { @Override protected boolean onMouseClickedImpl(/*? if >=1.21.10 {*/net.minecraft.client.input.MouseButtonEvent click, boolean doubleClick/*? } else {*//*int mouseX, int mouseY, int mouseButton*//*? }*/) { super.onMouseClickedImpl(/*? if >=1.21.10 {*/click, doubleClick/*? } else {*//*mouseX, mouseY, mouseButton*//*? }*/); + // The current screen moved off Minecraft directly and onto its Gui/HUD holder in 26.3. //? if >=26.3 { GuiBase.openGui(new GuiMacroEditor(Component.nullToEmpty(configMacro.macroName), configMacro, Minecraft.getInstance().gui.screen())); //? } else diff --git a/src/client/java/tools/redstone/redstonetools/features/toggleable/AirPlaceFeature.java b/src/client/java/tools/redstone/redstonetools/features/toggleable/AirPlaceFeature.java index 58ad031e..a0b10fba 100644 --- a/src/client/java/tools/redstone/redstonetools/features/toggleable/AirPlaceFeature.java +++ b/src/client/java/tools/redstone/redstonetools/features/toggleable/AirPlaceFeature.java @@ -134,7 +134,20 @@ public static BlockHitResult findAirPlaceBlockHit(Player playerEntity) { if (blockState == null) return; - /* render block outline */ + /* + * Render the block outline. + * + * Three rendering eras are threaded through this block: + * - <1.21.10: WorldRenderContext + a VertexConsumer, entity/camera position passed + * as raw doubles into the renderHitOutline mixin invoker. + * - 1.21.10-26.2: same VertexConsumer + mixin invoker approach, but the outline is + * described by a BlockOutlineRenderState instead of raw block/state args. + * - >=26.3: Mojang replaced the VertexConsumer/mixin approach with a submit-node + * pipeline. The context now hands out a PoseStack directly plus a + * SubmitNodeCollector that draws shapes itself, so there is no VertexConsumer, no + * mixin invoker (WorldRendererInvoker.invokeRenderHitOutline no longer exists), and + * no BlockOutlineRenderState needed - see the final `//? } else {` branch below. + */ //? if >=26.3 { Camera camera = client.gameRenderer.mainCamera(); //? } else diff --git a/src/client/java/tools/redstone/redstonetools/mixin/blocks/RedstoneHitboxMixin.java b/src/client/java/tools/redstone/redstonetools/mixin/blocks/RedstoneHitboxMixin.java index 58c46a27..24ef61e7 100644 --- a/src/client/java/tools/redstone/redstonetools/mixin/blocks/RedstoneHitboxMixin.java +++ b/src/client/java/tools/redstone/redstonetools/mixin/blocks/RedstoneHitboxMixin.java @@ -3,6 +3,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; +// Mojang mappings renamed RedStoneWireBlock -> RedstoneWireBlock in 26.3 (casing fix only). //? if >=26.3 { import net.minecraft.world.level.block.RedstoneWireBlock; //? } else diff --git a/src/client/java/tools/redstone/redstonetools/mixin/features/WorldRendererInvoker.java b/src/client/java/tools/redstone/redstonetools/mixin/features/WorldRendererInvoker.java index 72560b13..834738cb 100644 --- a/src/client/java/tools/redstone/redstonetools/mixin/features/WorldRendererInvoker.java +++ b/src/client/java/tools/redstone/redstonetools/mixin/features/WorldRendererInvoker.java @@ -13,6 +13,9 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; +// LevelRenderer.renderHitOutline was removed in 26.3, replaced by the submit-node pipeline's +// SubmitNodeCollector.submitShapeOutline(...), which is a public API and needs no invoker mixin. +// This interface is intentionally empty on >=26.3; see AirPlaceFeature for the call site. @Mixin(LevelRenderer.class) public interface WorldRendererInvoker { //? if <26.3 { diff --git a/src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java b/src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java index 6ce5aa35..efb30cf0 100644 --- a/src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java +++ b/src/main/java/tools/redstone/redstonetools/utils/SignalBlockSupplier.java @@ -91,6 +91,8 @@ private static int calculateComparatorOutput(int items, int slots, int item$getM private static Item getBestItem(int signalStrength, int slots) { if (signalStrength > 15) + // 26.3 consolidated the per-color shulker box items into a single DYED_SHULKER_BOX + // color collection; WHITE_SHULKER_BOX etc. no longer exist as separate items. //? if >=26.3 { return Items.DYED_SHULKER_BOX.white(); //? } else