From 3fb904532f9bf4b148770b4501dd14eebef0a4f8 Mon Sep 17 00:00:00 2001 From: altrisi Date: Sun, 21 Jun 2026 13:01:13 +0200 Subject: [PATCH 01/13] Fix Curseforge versions --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index e61fd155..723e740e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ org.gradle.configuration-cache=false # The Curseforge versions "names" or ids for the main branch (comma separated: 1.16.4,1.16.5) # This is needed because CF uses too vague names for prereleases and release candidates # Can also be the version ID directly coming from https://minecraft.curseforge.com/api/game/versions?token=[API_TOKEN] - release-curse-versions = Minecraft 26:26.2 + release-curse-versions = Minecraft 26.2:26.2 # Whether or not to build another branch on release release-extra-branch = false # The name of the second branch to release From 8563bef68ac5d6ec8cea08fef825653f05d3786a Mon Sep 17 00:00:00 2001 From: altrisi Date: Sun, 21 Jun 2026 14:03:03 +0200 Subject: [PATCH 02/13] Remove Debug export in a mixin (oof), use remappable reference to field Carpet extra still uses yarn (for now), without the type loom cannot remap the dependency in the IDE --- .../carpet/mixins/ServerPlayer_fakeLastMovementMixin.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/carpet/mixins/ServerPlayer_fakeLastMovementMixin.java b/src/main/java/carpet/mixins/ServerPlayer_fakeLastMovementMixin.java index ab12fa88..4e4f7559 100644 --- a/src/main/java/carpet/mixins/ServerPlayer_fakeLastMovementMixin.java +++ b/src/main/java/carpet/mixins/ServerPlayer_fakeLastMovementMixin.java @@ -1,7 +1,6 @@ package carpet.mixins; import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Debug; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -15,7 +14,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; @Mixin(ServerPlayer.class) -@Debug(export = true) public abstract class ServerPlayer_fakeLastMovementMixin extends Player { public ServerPlayer_fakeLastMovementMixin(Level level, GameProfile gameProfile) { super(level, gameProfile); @@ -24,7 +22,7 @@ public abstract class ServerPlayer_fakeLastMovementMixin extends Player { @ModifyExpressionValue( method = {"getKnownMovement", "getKnownSpeed"}, // both because ServerPlayer overrides both to the same "movement" field - at = @At(value = "FIELD", target = "lastKnownClientMovement", opcode = Opcodes.GETFIELD), + at = @At(value = "FIELD", target = "Lnet/minecraft/server/level/ServerPlayer;lastKnownClientMovement:Lnet/minecraft/world/phys/Vec3;", opcode = Opcodes.GETFIELD), require = 2 ) private Vec3 bypassClientMovementInfo(Vec3 original) { From ddb0213de4276969cbe8c3ab7b21dcfcf960d0c8 Mon Sep 17 00:00:00 2001 From: altrisi Date: Sun, 21 Jun 2026 16:00:46 +0200 Subject: [PATCH 03/13] Update GHA versions --- .github/workflows/build-on-pr.yml | 6 +++--- .github/workflows/devbuild.yml | 7 +++---- .github/workflows/publish-release.yml | 20 ++++++++++---------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build-on-pr.yml b/.github/workflows/build-on-pr.yml index 3647d0d7..ad69a4b3 100644 --- a/.github/workflows/build-on-pr.yml +++ b/.github/workflows/build-on-pr.yml @@ -10,9 +10,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Set up JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: microsoft java-version: 25 @@ -21,7 +21,7 @@ jobs: run: chmod +x gradlew - name: Build with Gradle run: ./gradlew build - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: "Compiled artifacts for Pull Request #${{github.event.number}}" path: build/libs diff --git a/.github/workflows/devbuild.yml b/.github/workflows/devbuild.yml index e6cfebab..02ef2622 100644 --- a/.github/workflows/devbuild.yml +++ b/.github/workflows/devbuild.yml @@ -7,13 +7,12 @@ on: [push] jobs: Build: - runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Set up JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: microsoft java-version: 25 @@ -22,7 +21,7 @@ jobs: run: chmod +x gradlew - name: Build with Gradle run: ./gradlew build - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: Compiled artifacts for ${{ github.sha }} path: build/libs diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index bc01cc31..462d84ab 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -16,7 +16,7 @@ jobs: extra-branch-curse-version: ${{ steps.properties.outputs.release-extra-curse-version }} steps: - name: Checkout the sources - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Determine release type id: type run: | @@ -41,7 +41,7 @@ jobs: if ! ${{ steps.properties.outputs.release-extra-branch }}; then echo "matrix-to-exclude=Snapshots" >> $GITHUB_OUTPUT fi - - uses: actions/github-script@v7 + - uses: actions/github-script@v9 env: READ_VERSION: ${{ steps.properties.outputs.mod_version }} with: @@ -78,11 +78,11 @@ jobs: echo "curse-versions=${{ needs.Get-Properties.outputs.curse-versions }}" >> $GITHUB_OUTPUT fi - name: Checkout the sources - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: ref: ${{ steps.getbranchinfo.outputs.branchname }} - name: Set up JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: microsoft java-version: 25 @@ -97,7 +97,7 @@ jobs: output="$(find build/libs/ ! -name "*-dev.jar" ! -name "*-sources.jar" -type f -printf "%f\n")" echo "jarname=$output" >> $GITHUB_OUTPUT - name: Save build artifacts in the action - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: Artifacts for ${{ matrix.branch }} path: build/libs @@ -125,7 +125,7 @@ jobs: - name: Ask Gradle to publish run: ./gradlew publish - name: Save publish folder in action's artifacts # Remove when automated - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: Maven publishing artifacts for ${{ matrix.branch }} path: publish/carpet/fabric-carpet/ @@ -149,7 +149,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the sources - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: ref: master - name: Merge docs @@ -166,15 +166,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Carpet sources - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Set up JDK - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: microsoft java-version: 25 cache: 'gradle' - name: Checkout wiki - uses: actions/checkout@v4 + uses: actions/checkout@v7 with: repository: ${{github.repository}}.wiki path: wiki From 9241a6a127f2ea23d57eaef5e5c021f80acc9171 Mon Sep 17 00:00:00 2001 From: altrisi Date: Sun, 21 Jun 2026 18:49:49 +0200 Subject: [PATCH 04/13] Update loom to 1.17 and gradle to 9.5.1 Same versions as extra --- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 723e740e..7fe70482 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.configuration-cache=false # check https://fabricmc.net/develop/ minecraft_version=26.2 loader_version=0.19.3 - loom_version=1.15-SNAPSHOT + loom_version=1.17-SNAPSHOT # Mod Properties mod_version = 26.2 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 23449a2b..5dd3c012 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 73fc5f1d135735ce6e6f0dfd3296dec1b579b36c Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 2 Jul 2026 15:15:39 +0200 Subject: [PATCH 05/13] 26.3-snap-2 --- docs/scarpet/api/BlocksAndWorldAccess.md | 4 +- gradle.properties | 4 +- .../carpet/fakes/CoralFeatureInterface.java | 12 ---- .../carpet/helpers/FertilizableCoral.java | 10 ++- .../CoralFeature_renewableCoralMixin.java | 26 -------- ...lowingFluid_liquidDamageDisabledMixin.java | 4 +- .../carpet/mixins/HugeFungusFeatureMixin.java | 15 ++++- .../ItemStack_stackableShulkerBoxesMixin.java | 2 +- .../LevelRenderer_scarpetRenderMixin.java | 3 +- .../PieceGeneratorSupplier_plopMixin.java | 22 ------- ...istonMovingBlockEntity_movableBEMixin.java | 8 +-- .../mixins/Player_fakePlayersMixin.java | 4 +- .../java/carpet/mixins/Villager_aiMixin.java | 4 +- .../java/carpet/script/api/Auxiliary.java | 6 +- .../java/carpet/script/api/WorldAccess.java | 3 +- .../java/carpet/script/utils/BiomeInfo.java | 4 +- .../carpet/script/utils/FeatureGenerator.java | 66 +++++++++---------- .../java/carpet/script/value/EntityValue.java | 2 +- .../carpet/script/value/ValueConversions.java | 2 +- src/main/resources/carpet.mixins.json | 2 - 20 files changed, 73 insertions(+), 130 deletions(-) delete mode 100644 src/main/java/carpet/fakes/CoralFeatureInterface.java delete mode 100644 src/main/java/carpet/mixins/CoralFeature_renewableCoralMixin.java delete mode 100644 src/main/java/carpet/mixins/PieceGeneratorSupplier_plopMixin.java diff --git a/docs/scarpet/api/BlocksAndWorldAccess.md b/docs/scarpet/api/BlocksAndWorldAccess.md index a4555608..de44308b 100644 --- a/docs/scarpet/api/BlocksAndWorldAccess.md +++ b/docs/scarpet/api/BlocksAndWorldAccess.md @@ -637,7 +637,7 @@ with minecraft 1.16.1 and below or 1.16.2 and above since in 1.16.2 Mojang has a meaning that since 1.16.2 - they have official names that can be used by datapacks and scarpet. If you have most recent scarpet on 1.16.4, you can use `plop()` to get all available worldgen features including custom features and structures controlled by datapacks. It returns a map of lists in the following categories: -`'scarpet_custom'`, `'configured_features'`, `'structures'`, `'features'`, `'structure_types'` +`'scarpet_custom'`, `'features'`, `'structures'`, `'feature_types'`, `'structure_types'` ### Previous Structure Names, including variants (for MC1.16.1 and below only) * `'monument'`: Ocean Monument. Generates at fixed Y coordinate, surrounds itself with water. @@ -736,7 +736,7 @@ controlled by datapacks. It returns a map of lists in the following categories: ### World Generation Features and Structures (as of MC1.16.2+) -Use `plop():'structure_types'`, `plop():'structures'`, `plop():'features'`, and `plop():'configured_features'` for a list of available options. Your output may vary based on +Use `plop():'structure_types'`, `plop():'structures'`, `plop():'features'`, and `plop():'feature_types'` for a list of available options. Your output may vary based on datapacks installed in your world. ### Custom Scarpet Features diff --git a/gradle.properties b/gradle.properties index 7fe70482..b69c4319 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ org.gradle.configuration-cache=false # Fabric Properties # check https://fabricmc.net/develop/ - minecraft_version=26.2 + minecraft_version=26.3-snapshot-2 loader_version=0.19.3 loom_version=1.17-SNAPSHOT @@ -20,7 +20,7 @@ org.gradle.configuration-cache=false # The Curseforge versions "names" or ids for the main branch (comma separated: 1.16.4,1.16.5) # This is needed because CF uses too vague names for prereleases and release candidates # Can also be the version ID directly coming from https://minecraft.curseforge.com/api/game/versions?token=[API_TOKEN] - release-curse-versions = Minecraft 26.2:26.2 + release-curse-versions = Minecraft 26.3:26.3-Snapshot # Whether or not to build another branch on release release-extra-branch = false # The name of the second branch to release diff --git a/src/main/java/carpet/fakes/CoralFeatureInterface.java b/src/main/java/carpet/fakes/CoralFeatureInterface.java deleted file mode 100644 index 915d09b3..00000000 --- a/src/main/java/carpet/fakes/CoralFeatureInterface.java +++ /dev/null @@ -1,12 +0,0 @@ -package carpet.fakes; - -import java.util.Random; -import net.minecraft.core.BlockPos; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; - -public interface CoralFeatureInterface -{ - boolean growSpecific(Level worldIn, RandomSource random, BlockPos pos, BlockState blockUnder); -} diff --git a/src/main/java/carpet/helpers/FertilizableCoral.java b/src/main/java/carpet/helpers/FertilizableCoral.java index a588ec31..713faa9c 100644 --- a/src/main/java/carpet/helpers/FertilizableCoral.java +++ b/src/main/java/carpet/helpers/FertilizableCoral.java @@ -1,6 +1,5 @@ package carpet.helpers; -import carpet.fakes.CoralFeatureInterface; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; @@ -20,7 +19,6 @@ import net.minecraft.world.level.levelgen.feature.CoralClawFeature; import net.minecraft.world.level.levelgen.feature.CoralFeature; import net.minecraft.world.level.levelgen.feature.CoralMushroomFeature; import net.minecraft.world.level.levelgen.feature.CoralTreeFeature; -import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; import net.minecraft.world.level.material.MapColor; /** @@ -51,9 +49,9 @@ public interface FertilizableCoral extends BonemealableBlock { { int variant = random.nextInt(3); CoralFeature coral = switch (variant) { - case 0 -> new CoralClawFeature(NoneFeatureConfiguration.CODEC); - case 1 -> new CoralTreeFeature(NoneFeatureConfiguration.CODEC); - default -> new CoralMushroomFeature(NoneFeatureConfiguration.CODEC); + case 0 -> new CoralClawFeature(); + case 1 -> new CoralTreeFeature(); + default -> new CoralMushroomFeature(); }; MapColor color = blockUnder.getMapColor(worldIn, pos); @@ -69,7 +67,7 @@ public interface FertilizableCoral extends BonemealableBlock { } worldIn.setBlock(pos, Blocks.WATER.defaultBlockState(), Block.UPDATE_NONE); - if (!((CoralFeatureInterface)coral).growSpecific(worldIn, random, pos, properBlock)) + if (!coral.placeFeature(worldIn, random, pos, properBlock)) { worldIn.setBlock(pos, blockUnder, 3); } diff --git a/src/main/java/carpet/mixins/CoralFeature_renewableCoralMixin.java b/src/main/java/carpet/mixins/CoralFeature_renewableCoralMixin.java deleted file mode 100644 index f2d3800f..00000000 --- a/src/main/java/carpet/mixins/CoralFeature_renewableCoralMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package carpet.mixins; - -import carpet.fakes.CoralFeatureInterface; -import net.minecraft.util.RandomSource; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.Random; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.feature.CoralFeature; - -@Mixin(CoralFeature.class) -public abstract class CoralFeature_renewableCoralMixin implements CoralFeatureInterface -{ - - @Shadow protected abstract boolean placeFeature(LevelAccessor var1, RandomSource var2, BlockPos var3, BlockState var4); - - @Override - public boolean growSpecific(Level worldIn, RandomSource random, BlockPos pos, BlockState blockUnder) - { - return placeFeature(worldIn, random, pos, blockUnder); - } -} diff --git a/src/main/java/carpet/mixins/FlowingFluid_liquidDamageDisabledMixin.java b/src/main/java/carpet/mixins/FlowingFluid_liquidDamageDisabledMixin.java index 1990e719..fad9e343 100644 --- a/src/main/java/carpet/mixins/FlowingFluid_liquidDamageDisabledMixin.java +++ b/src/main/java/carpet/mixins/FlowingFluid_liquidDamageDisabledMixin.java @@ -19,7 +19,7 @@ public class FlowingFluid_liquidDamageDisabledMixin method = "canHoldAnyFluid", at = @At( value = "INVOKE", - target = "Lnet/minecraft/world/level/block/state/BlockState;blocksMotion()Z" + target = "Lnet/minecraft/world/level/block/state/BlockState;is(Lnet/minecraft/tags/TagKey;)Z" ), cancellable = true ) @@ -27,7 +27,7 @@ public class FlowingFluid_liquidDamageDisabledMixin { if (CarpetSettings.liquidDamageDisabled) { - cir.setReturnValue(state.isAir() || state.is(Blocks.WATER) || state.is(Blocks.LAVA)); + cir.setReturnValue((state.isAir() || state.is(Blocks.WATER) || state.is(Blocks.LAVA))); } } } diff --git a/src/main/java/carpet/mixins/HugeFungusFeatureMixin.java b/src/main/java/carpet/mixins/HugeFungusFeatureMixin.java index e07921bf..b780312a 100644 --- a/src/main/java/carpet/mixins/HugeFungusFeatureMixin.java +++ b/src/main/java/carpet/mixins/HugeFungusFeatureMixin.java @@ -2,23 +2,32 @@ package carpet.mixins; import carpet.CarpetSettings; import net.minecraft.util.RandomSource; -import net.minecraft.world.level.levelgen.feature.HugeFungusConfiguration; import net.minecraft.world.level.levelgen.feature.HugeFungusFeature; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArgs; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.invoke.arg.Args; import static carpet.CarpetSettings.FungusGrowthMode.*; @Mixin(HugeFungusFeature.class) public class HugeFungusFeatureMixin { - @ModifyArgs(method = "place", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/feature/HugeFungusFeature;placeStem(Lnet/minecraft/world/level/WorldGenLevel;Lnet/minecraft/util/RandomSource;Lnet/minecraft/world/level/levelgen/feature/HugeFungusConfiguration;Lnet/minecraft/core/BlockPos;IZ)V")) + @Inject( method = "planted", at = @At("HEAD"), cancellable = true) + private void planted(CallbackInfoReturnable cir) { + if (CarpetSettings.thickFungusGrowth == ALL) { + cir.setReturnValue(true); + } + } + + /*@ModifyArgs(method = "place", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/feature/HugeFungusFeature;placeStem(Lnet/minecraft/world/level/WorldGenLevel;Lnet/minecraft/util/RandomSource;Lnet/minecraft/world/level/levelgen/feature/HugeFungusConfiguration;Lnet/minecraft/core/BlockPos;IZ)V")) private void mixin(Args args) { boolean natural = !((HugeFungusConfiguration) args.get(2)).planted; args.set(5, natural && ((boolean) args.get(5)) || !natural && (CarpetSettings.thickFungusGrowth == ALL || CarpetSettings.thickFungusGrowth == RANDOM && ((RandomSource) args.get(1)).nextFloat() < 0.06F) ); - } + }*/ } diff --git a/src/main/java/carpet/mixins/ItemStack_stackableShulkerBoxesMixin.java b/src/main/java/carpet/mixins/ItemStack_stackableShulkerBoxesMixin.java index 79432d89..8746b71e 100644 --- a/src/main/java/carpet/mixins/ItemStack_stackableShulkerBoxesMixin.java +++ b/src/main/java/carpet/mixins/ItemStack_stackableShulkerBoxesMixin.java @@ -22,7 +22,7 @@ public interface ItemStack_stackableShulkerBoxesMixin && ((ItemInstance)((Object)this)) instanceof final ItemStack itemStack && itemStack.getItem() instanceof BlockItem blockItem && blockItem.getBlock() instanceof ShulkerBoxBlock - && ((ItemStack) ((Object) this)).getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).allItemsCopyStream().findAny().isEmpty() + && ((ItemStack) ((Object) this)).getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).itemCopies().findAny().isEmpty() ) { cir.setReturnValue(CarpetSettings.shulkerBoxStackSize); } diff --git a/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java b/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java index 9ce4505e..0cf13833 100644 --- a/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java +++ b/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java @@ -56,7 +56,8 @@ public class LevelRenderer_scarpetRenderMixin @Inject(method = "render", at = @At( value = "INVOKE", -target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V", +target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;F)V", +//target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V", //target = "Lnet/minecraft/client/renderer/LevelRenderer;addAlwaysOnTopPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;)V", //target = "Lnet/minecraft/client/renderer/LevelRenderer;submitFeatures(Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeCollector;Z)V", //target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V", diff --git a/src/main/java/carpet/mixins/PieceGeneratorSupplier_plopMixin.java b/src/main/java/carpet/mixins/PieceGeneratorSupplier_plopMixin.java deleted file mode 100644 index 0cd7363a..00000000 --- a/src/main/java/carpet/mixins/PieceGeneratorSupplier_plopMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package carpet.mixins; - -import carpet.CarpetSettings; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.function.Predicate; -import net.minecraft.world.level.levelgen.structure.pieces.PieceGeneratorSupplier; - -@Mixin(PieceGeneratorSupplier.class) -public interface PieceGeneratorSupplier_plopMixin -{ - @Redirect(method = "lambda$simple$0", at = @At( - value = "INVOKE", - target = "java/util/function/Predicate.test(Ljava/lang/Object;)Z" - ), remap = false) - private static boolean checkMate(Predicate predicate, Object o) - { - return CarpetSettings.skipGenerationChecks.get() || predicate.test(o); - } -} diff --git a/src/main/java/carpet/mixins/PistonMovingBlockEntity_movableBEMixin.java b/src/main/java/carpet/mixins/PistonMovingBlockEntity_movableBEMixin.java index 8e021890..b8998eac 100644 --- a/src/main/java/carpet/mixins/PistonMovingBlockEntity_movableBEMixin.java +++ b/src/main/java/carpet/mixins/PistonMovingBlockEntity_movableBEMixin.java @@ -106,14 +106,14 @@ public abstract class PistonMovingBlockEntity_movableBEMixin extends BlockEntity } @Redirect(method = "finalTick", at = @At(value = "INVOKE", - target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - private boolean movableTEsetBlockState1(Level world, BlockPos blockPos_1, BlockState blockState_2, int int_1) + target = "Lnet/minecraft/world/level/Level;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) + private boolean movableTESetBlockState1(Level world, BlockPos blockPos_1, BlockState blockState_2) { if (!CarpetSettings.movableBlockEntities) - return world.setBlock(blockPos_1, blockState_2, int_1); + return world.setBlockAndUpdate(blockPos_1, blockState_2); else { - boolean ret = ((LevelInterface) (world)).setBlockStateWithBlockEntity(blockPos_1, blockState_2, this.carriedBlockEntity, int_1); + boolean ret = ((LevelInterface) (world)).setBlockStateWithBlockEntity(blockPos_1, blockState_2, this.carriedBlockEntity, Block.UPDATE_ALL); this.carriedBlockEntity = null; //this will cancel the finishHandleBroken return ret; } diff --git a/src/main/java/carpet/mixins/Player_fakePlayersMixin.java b/src/main/java/carpet/mixins/Player_fakePlayersMixin.java index a585c0e2..debf0e0a 100644 --- a/src/main/java/carpet/mixins/Player_fakePlayersMixin.java +++ b/src/main/java/carpet/mixins/Player_fakePlayersMixin.java @@ -17,12 +17,12 @@ public abstract class Player_fakePlayersMixin method = "causeExtraKnockback", at = @At( value = "FIELD", - target = "Lnet/minecraft/world/entity/Entity;hurtMarked:Z", + target = "Lnet/minecraft/world/entity/Entity;syncVelocity:Z", ordinal = 0 ) ) private boolean velocityModifiedAndNotCarpetFakePlayer(Entity target) { - return target.hurtMarked && !(target instanceof EntityPlayerMPFake); + return target.syncVelocity && !(target instanceof EntityPlayerMPFake); } } diff --git a/src/main/java/carpet/mixins/Villager_aiMixin.java b/src/main/java/carpet/mixins/Villager_aiMixin.java index 054ad5d6..6d9d9635 100644 --- a/src/main/java/carpet/mixins/Villager_aiMixin.java +++ b/src/main/java/carpet/mixins/Villager_aiMixin.java @@ -4,6 +4,7 @@ import carpet.helpers.ParticleDisplay; import carpet.utils.Messenger; import carpet.utils.MobAI; import net.minecraft.core.particles.DustParticleOptions; +import net.minecraft.tags.ItemTags; import net.minecraft.world.entity.ai.village.poi.PoiTypes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -33,7 +34,6 @@ import net.minecraft.world.entity.npc.villager.AbstractVillager; import net.minecraft.world.entity.npc.villager.Villager; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.schedule.Activity; -import net.minecraft.world.item.BedItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.Level; @@ -140,7 +140,7 @@ public abstract class Villager_aiMixin extends AbstractVillager while(countFoodPointsInInventory() >= 12) eatAndDigestFood(); } - else if (itemStack_1.getItem() instanceof BedItem) + else if (itemStack_1.is(ItemTags.BEDS)) { List list_1 = ((ServerLevel) level()).getPoiManager().getInRange( type -> type.is(PoiTypes.HOME), diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java index daf55c50..69717e2e 100644 --- a/src/main/java/carpet/script/api/Auxiliary.java +++ b/src/main/java/carpet/script/api/Auxiliary.java @@ -857,12 +857,12 @@ public class Auxiliary plopData.put(StringValue.of("scarpet_custom"), ListValue.wrap(FeatureGenerator.featureMap.keySet().stream().sorted().map(StringValue::of)) ); + plopData.put(StringValue.of("feature_types"), + ListValue.wrap(cc.registry(Registries.FEATURE_TYPE).keySet().stream().sorted().map(ValueConversions::of)) + ); plopData.put(StringValue.of("features"), ListValue.wrap(cc.registry(Registries.FEATURE).keySet().stream().sorted().map(ValueConversions::of)) ); - plopData.put(StringValue.of("configured_features"), - ListValue.wrap(cc.registry(Registries.CONFIGURED_FEATURE).keySet().stream().sorted().map(ValueConversions::of)) - ); plopData.put(StringValue.of("structure_types"), ListValue.wrap(cc.registry(Registries.STRUCTURE_TYPE).keySet().stream().sorted().map(ValueConversions::of)) ); diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index 5499c5b4..af4e07eb 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -1799,8 +1799,7 @@ public class WorldAccess }; RandomState randomState = RandomState.create( - noiseBasedChunkGenerator.generatorSettings().value(), - level.registryAccess().lookupOrThrow(Registries.NOISE), level.getSeed() + level.registryAccess().lookupOrThrow(Registries.NOISE), level.getSeed(), noiseBasedChunkGenerator.generatorSettings().value() ); DensityFunction.Visitor visitor = Vanilla.RandomState_getVisitor(randomState); diff --git a/src/main/java/carpet/script/utils/BiomeInfo.java b/src/main/java/carpet/script/utils/BiomeInfo.java index 116c9447..b34806a8 100644 --- a/src/main/java/carpet/script/utils/BiomeInfo.java +++ b/src/main/java/carpet/script/utils/BiomeInfo.java @@ -19,7 +19,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.attribute.EnvironmentAttribute; import net.minecraft.world.attribute.EnvironmentAttributes; import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.Feature; public class BiomeInfo { @@ -36,7 +36,7 @@ public class BiomeInfo put("humidity", (w, b) -> NumericValue.of(Vanilla.Biome_getClimateSettings(b).downfall())); put("precipitation", (w, b) -> StringValue.of(b.getPrecipitationAt(new BlockPos(0, w.getSeaLevel(), 0), w.getSeaLevel()).name().toLowerCase(Locale.ROOT))); put("features", (w, b) -> { - Registry> registry = w.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE); + Registry registry = w.registryAccess().lookupOrThrow(Registries.FEATURE); return ListValue.wrap( b.getGenerationSettings().features().stream().map(step -> ListValue.wrap(step.stream().map(cfp -> diff --git a/src/main/java/carpet/script/utils/FeatureGenerator.java b/src/main/java/carpet/script/utils/FeatureGenerator.java index 844a843f..b9bcb7cf 100644 --- a/src/main/java/carpet/script/utils/FeatureGenerator.java +++ b/src/main/java/carpet/script/utils/FeatureGenerator.java @@ -38,11 +38,12 @@ import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.RandomState; import net.minecraft.world.level.levelgen.VerticalAnchor; -import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.CoralClawFeature; +import net.minecraft.world.level.levelgen.feature.CoralMushroomFeature; +import net.minecraft.world.level.levelgen.feature.CoralTreeFeature; import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.feature.configurations.CompositeFeatureConfiguration; -import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; -import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration; +import net.minecraft.world.level.levelgen.feature.SimpleRandomSelectorFeature; +import net.minecraft.world.level.levelgen.feature.TreeFeature; import net.minecraft.world.level.levelgen.feature.featuresize.TwoLayersFeatureSize; import net.minecraft.world.level.levelgen.feature.foliageplacers.BlobFoliagePlacer; import net.minecraft.world.level.levelgen.feature.foliageplacers.FancyFoliagePlacer; @@ -66,7 +67,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProc import org.jspecify.annotations.Nullable; -import static net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration.CAN_PLACE_BELOW_TREE_TRUNKS; +import static net.minecraft.world.level.levelgen.feature.TreeFeature.CAN_PLACE_BELOW_TREE_TRUNKS; public class FeatureGenerator { @@ -85,7 +86,7 @@ public class FeatureGenerator return plopAnywhere(structure, world, pos, world.getChunkSource().getGenerator(), false); } - ConfiguredFeature configuredFeature = world.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).getValue(id); + Feature configuredFeature = world.registryAccess().lookupOrThrow(Registries.FEATURE).getValue(id); if (configuredFeature != null) { ThreadLocal checks = Vanilla.skipGenerationChecks(world); @@ -108,10 +109,10 @@ public class FeatureGenerator return plopAnywhere(configuredStandard, world, pos, world.getChunkSource().getGenerator(), false); } } - Feature feature = world.registryAccess().lookupOrThrow(Registries.FEATURE).getValue(id); + Feature feature = world.registryAccess().lookupOrThrow(Registries.FEATURE).getValue(id); if (feature != null) { - ConfiguredFeature configuredStandard = getDefaultFeature(feature, world, pos, true); + Feature configuredStandard = getDefaultFeature(feature, world, pos, true); if (configuredStandard != null) { ThreadLocal checks = Vanilla.skipGenerationChecks(world); @@ -157,7 +158,7 @@ public class FeatureGenerator Boolean plop(ServerLevel world, BlockPos pos); } - private static Thing simplePlop(ConfiguredFeature feature) + private static Thing simplePlop(Feature feature) { return (w, p) -> { ThreadLocal checks = Vanilla.skipGenerationChecks(w); @@ -173,15 +174,10 @@ public class FeatureGenerator }; } - private static > Thing simplePlop(F feature, FC config) - { - return simplePlop(new ConfiguredFeature<>(feature, config)); - } - - private static Thing simpleTree(TreeConfiguration config) + private static Thing simpleTree(TreeFeature.Builder config) { //config.ignoreFluidCheck(); - return simplePlop(new ConfiguredFeature<>(Feature.TREE, config)); + return simplePlop(config.build()); } private static Thing spawnCustomStructure(Structure structure) @@ -212,14 +208,14 @@ public class FeatureGenerator return result; } - private static ConfiguredFeature getDefaultFeature(Feature feature, ServerLevel world, BlockPos pos, boolean tryHard) + private static @Nullable Feature getDefaultFeature(Feature feature, ServerLevel world, BlockPos pos, boolean tryHard) { List> configuredStepFeatures = world.getBiome(pos).value().getGenerationSettings().features(); for (HolderSet step : configuredStepFeatures) { for (Holder provider : step) { - if (provider.value().feature().value().feature() == feature) + if (provider.value().feature().value() == feature) { return provider.value().feature().value(); } @@ -229,13 +225,13 @@ public class FeatureGenerator { return null; } - return world.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).entrySet().stream(). - filter(cS -> cS.getValue().feature() == feature). + return world.registryAccess().lookupOrThrow(Registries.FEATURE).entrySet().stream(). + filter(cS -> cS.getValue() == feature). findFirst().map(Map.Entry::getValue).orElse(null); } - public static StructureStart shouldStructureStartAt(ServerLevel world, BlockPos pos, Structure structure, boolean computeBox) + public static StructureStart shouldStructureStartAt(ServerLevel world, BlockPos pos, Structure structure, boolean computeBox) { ServerChunkCache chunkSource = world.getChunkSource(); RandomState seed = chunkSource.randomState(); @@ -277,28 +273,30 @@ public class FeatureGenerator private static RuleBasedStateProvider belowTrees = RuleBasedStateProvider.ifTrueThenProvide(CAN_PLACE_BELOW_TREE_TRUNKS, Blocks.DIRT); - private static TreeConfiguration.TreeConfigurationBuilder createTree(Block block, Block block2, int i, int j, int k, int l) + private static TreeFeature.Builder createTree(Block block, Block block2, int i, int j, int k, int l) { - return new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(block), new StraightTrunkPlacer(i, j, k), BlockStateProvider.simple(block2), new BlobFoliagePlacer(ConstantInt.of(l), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), belowTrees); + return new TreeFeature.Builder(BlockStateProvider.simple(block), new StraightTrunkPlacer(i, j, k), BlockStateProvider.simple(block2), new BlobFoliagePlacer(ConstantInt.of(l), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), belowTrees); } public static final Map> featureMap = new HashMap<>() {{ // TODO remove this using what place feature is using - put("oak_bees", l -> simpleTree(createTree(Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build())); - put("fancy_oak_bees", l -> simpleTree((new TreeConfiguration.TreeConfigurationBuilder(BlockStateProvider.simple(Blocks.OAK_LOG), new FancyTrunkPlacer(3, 11, 0), BlockStateProvider.simple(Blocks.OAK_LEAVES), new FancyFoliagePlacer(ConstantInt.of(2), ConstantInt.of(4), 4), new TwoLayersFeatureSize(0, 0, 0, OptionalInt.of(4)), belowTrees)).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build())); - put("birch_bees", l -> simpleTree(createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))).build())); + put("oak_bees", l -> simpleTree(createTree(Blocks.OAK_LOG, Blocks.OAK_LEAVES, 4, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))))); + put("fancy_oak_bees", l -> simpleTree(new TreeFeature.Builder(BlockStateProvider.simple(Blocks.OAK_LOG), new FancyTrunkPlacer(3, 11, 0), BlockStateProvider.simple(Blocks.OAK_LEAVES), new FancyFoliagePlacer(ConstantInt.of(2), ConstantInt.of(4), 4), new TwoLayersFeatureSize(0, 0, 0, OptionalInt.of(4)), belowTrees).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))))); + put("birch_bees", l -> simpleTree(createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))))); - put("coral_tree", l -> simplePlop(Feature.CORAL_TREE, FeatureConfiguration.NONE)); + put("coral_tree", l -> simplePlop(new CoralTreeFeature())); - put("coral_claw", l -> simplePlop(Feature.CORAL_CLAW, FeatureConfiguration.NONE)); - put("coral_mushroom", l -> simplePlop(Feature.CORAL_MUSHROOM, FeatureConfiguration.NONE)); - put("coral", l -> simplePlop(Feature.SIMPLE_RANDOM_SELECTOR, new CompositeFeatureConfiguration(HolderSet.direct( - PlacementUtils.inlinePlaced(Feature.CORAL_TREE, FeatureConfiguration.NONE), - PlacementUtils.inlinePlaced(Feature.CORAL_CLAW, FeatureConfiguration.NONE), - PlacementUtils.inlinePlaced(Feature.CORAL_MUSHROOM, FeatureConfiguration.NONE) - )))); + put("coral_claw", l -> simplePlop(new CoralClawFeature())); + put("coral_mushroom", l -> simplePlop(new CoralMushroomFeature())); + put("coral", l -> simplePlop(new SimpleRandomSelectorFeature( + HolderSet.direct( + PlacementUtils.inlinePlaced(new CoralTreeFeature()), + PlacementUtils.inlinePlaced(new CoralClawFeature()), + PlacementUtils.inlinePlaced(new CoralMushroomFeature()) + ) + ))); put("bastion_remnant_units", l -> { RegistryAccess regs = l.registryAccess(); diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java index 38b4c91e..d46919cb 100644 --- a/src/main/java/carpet/script/value/EntityValue.java +++ b/src/main/java/carpet/script/value/EntityValue.java @@ -943,7 +943,7 @@ public class EntityValue extends Value private static void updateVelocity(Entity e, double scale) { - e.hurtMarked = true; + e.syncVelocity = true; if (Math.abs(scale) > 10000) { CarpetScriptServer.LOG.warn("Moved entity " + e.getScoreboardName() + " " + e.getName() + " at " + e.position() + " extremely fast: " + e.getDeltaMovement()); diff --git a/src/main/java/carpet/script/value/ValueConversions.java b/src/main/java/carpet/script/value/ValueConversions.java index 56d97e2e..dfda9269 100644 --- a/src/main/java/carpet/script/value/ValueConversions.java +++ b/src/main/java/carpet/script/value/ValueConversions.java @@ -532,7 +532,7 @@ public class ValueConversions } if (o instanceof final Vec3i vec3i) { - return of(new BlockPos(vec3i)); + return of(new BlockPos(vec3i.getX(), vec3i.getY(), vec3i.getZ())); } if (o instanceof final AABB aabb) { diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index d9b7cf43..4bb7dd93 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -67,7 +67,6 @@ "Level_getOtherEntitiesLimited", "CoralPlantBlock_renewableCoralMixin", "CoralFanBlock_renewableCoralMixin", - "CoralFeature_renewableCoralMixin", "BuddingAmethystBlock_movableAmethystMixin", "LiquidBlock_renewableBlackstoneMixin", "LiquidBlock_renewableDeepslateMixin", @@ -75,7 +74,6 @@ "Level_scarpetPlopMixin", "WorldGenRegion_scarpetPlopMixin", "StructurePiece_scarpetPlopMixin", - "PieceGeneratorSupplier_plopMixin", "ServerGamePacketListenerImpl_scarpetEventsMixin", "ServerPlayerGameMode_scarpetEventsMixin", "Player_parrotMixin", From c62bac8cab4230188087f01510fbed612a5af153 Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 2 Jul 2026 15:23:51 +0200 Subject: [PATCH 06/13] 26.3-beta-1 --- gradle.properties | 2 +- src/main/resources/fabric.mod.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index b69c4319..72cf25e0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ org.gradle.configuration-cache=false loom_version=1.17-SNAPSHOT # Mod Properties - mod_version = 26.2 + mod_version = 26.3-beta-1 maven_group = carpet archives_base_name = fabric-carpet diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index b1338171..eef7d9c2 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -33,7 +33,7 @@ "accessWidener" : "carpet.accesswidener", "depends": { - "minecraft": ">=26.2", + "minecraft": ">26.2", "fabricloader": ">=0.19.3", "java": ">=25" } From f146a9e30738753d2f00462210a504e2214e5ff3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 2 Jul 2026 13:44:10 +0000 Subject: [PATCH 07/13] Merge docs for 'Carpet Mod 26.3-beta-1 for Minecraft 26.3-snapshot-2' --- docs/scarpet/Full.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index 7f0cf592..279334d0 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -2966,7 +2966,7 @@ with minecraft 1.16.1 and below or 1.16.2 and above since in 1.16.2 Mojang has a meaning that since 1.16.2 - they have official names that can be used by datapacks and scarpet. If you have most recent scarpet on 1.16.4, you can use `plop()` to get all available worldgen features including custom features and structures controlled by datapacks. It returns a map of lists in the following categories: -`'scarpet_custom'`, `'configured_features'`, `'structures'`, `'features'`, `'structure_types'` +`'scarpet_custom'`, `'features'`, `'structures'`, `'feature_types'`, `'structure_types'` ### Previous Structure Names, including variants (for MC1.16.1 and below only) * `'monument'`: Ocean Monument. Generates at fixed Y coordinate, surrounds itself with water. @@ -3065,7 +3065,7 @@ controlled by datapacks. It returns a map of lists in the following categories: ### World Generation Features and Structures (as of MC1.16.2+) -Use `plop():'structure_types'`, `plop():'structures'`, `plop():'features'`, and `plop():'configured_features'` for a list of available options. Your output may vary based on +Use `plop():'structure_types'`, `plop():'structures'`, `plop():'features'`, and `plop():'feature_types'` for a list of available options. Your output may vary based on datapacks installed in your world. ### Custom Scarpet Features From 3a91edeecc3abc2e1d98397b1a805f9ed85b9b25 Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 9 Jul 2026 22:12:31 +0200 Subject: [PATCH 08/13] 26.3-snap-3 --- gradle.properties | 2 +- .../carpet/helpers/FertilizableCoral.java | 49 ++++++-- .../LevelRenderer_scarpetRenderMixin.java | 7 +- .../java/carpet/script/api/WorldAccess.java | 2 +- .../carpet/script/utils/FeatureGenerator.java | 108 ++++++++++++++++-- .../carpet/script/utils/ShapesRenderer.java | 2 - 6 files changed, 142 insertions(+), 28 deletions(-) diff --git a/gradle.properties b/gradle.properties index 72cf25e0..d64d14ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ org.gradle.configuration-cache=false # Fabric Properties # check https://fabricmc.net/develop/ - minecraft_version=26.3-snapshot-2 + minecraft_version=26.3-snapshot-3 loader_version=0.19.3 loom_version=1.17-SNAPSHOT diff --git a/src/main/java/carpet/helpers/FertilizableCoral.java b/src/main/java/carpet/helpers/FertilizableCoral.java index 713faa9c..1fc5c90d 100644 --- a/src/main/java/carpet/helpers/FertilizableCoral.java +++ b/src/main/java/carpet/helpers/FertilizableCoral.java @@ -1,13 +1,16 @@ package carpet.helpers; +import carpet.script.utils.FeatureGenerator; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; import net.minecraft.core.registries.Registries; +import net.minecraft.data.worldgen.placement.PlacementUtils; import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.BlockTags; import net.minecraft.tags.FluidTags; import net.minecraft.util.RandomSource; +import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.BaseCoralPlantTypeBlock; @@ -16,11 +19,16 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.BonemealableBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.feature.CoralClawFeature; -import net.minecraft.world.level.levelgen.feature.CoralFeature; -import net.minecraft.world.level.levelgen.feature.CoralMushroomFeature; import net.minecraft.world.level.levelgen.feature.CoralTreeFeature; +import net.minecraft.world.level.levelgen.feature.CuboidPlacement; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.SimpleRandomSelectorFeature; +import net.minecraft.world.level.levelgen.placement.OffsetPlacement; +import net.minecraft.world.level.levelgen.placement.RandomChancePlacement; import net.minecraft.world.level.material.MapColor; +import java.util.stream.Stream; + /** * Deduplicates logic for the different behaviors of the {@code renewableCoral} rule */ @@ -47,15 +55,9 @@ public interface FertilizableCoral extends BonemealableBlock { @Override public default void performBonemeal(ServerLevel worldIn, RandomSource random, BlockPos pos, BlockState blockUnder) { - int variant = random.nextInt(3); - CoralFeature coral = switch (variant) { - case 0 -> new CoralClawFeature(); - case 1 -> new CoralTreeFeature(); - default -> new CoralMushroomFeature(); - }; - MapColor color = blockUnder.getMapColor(worldIn, pos); BlockState properBlock = blockUnder; + var blocks = worldIn.registryAccess().lookupOrThrow(Registries.BLOCK); HolderSet.Named coralBlocks = worldIn.registryAccess().lookupOrThrow(Registries.BLOCK).get(BlockTags.CORAL_BLOCKS).orElseThrow(); for (Holder block: coralBlocks) { @@ -65,9 +67,36 @@ public interface FertilizableCoral extends BonemealableBlock { break; } } + Block actualProperBlock = properBlock.getBlock(); + worldIn.setBlock(pos, Blocks.WATER.defaultBlockState(), Block.UPDATE_NONE); - if (!coral.placeFeature(worldIn, random, pos, properBlock)) + var features = worldIn.registryAccess().lookupOrThrow(Registries.FEATURE); + Feature feature = new SimpleRandomSelectorFeature( HolderSet.direct(Stream.of(actualProperBlock) + .map(block -> FeatureGenerator.coral(features, blocks, actualProperBlock)) + .flatMap( + coralType -> Stream.of( + PlacementUtils.inlinePlaced(new CoralTreeFeature( + PlacementUtils.inlinePlaced(coralType, FeatureGenerator.coralPlacement)) + ), + PlacementUtils.inlinePlaced(new CoralClawFeature( + PlacementUtils.inlinePlaced(coralType, FeatureGenerator.coralPlacement))), + PlacementUtils.inlinePlaced( + coralType, + OffsetPlacement.vertical(UniformInt.of(-3, -1)), + new CuboidPlacement( + UniformInt.of(3, 5), + UniformInt.of(3, 5), + false, + false + ), + new RandomChancePlacement(0.9f), + FeatureGenerator.coralPlacement + ) + ) + ).toList()) + ); + if (!feature.place(worldIn, worldIn.getChunkSource().getGenerator(), random, pos)) { worldIn.setBlock(pos, blockUnder, 3); } diff --git a/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java b/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java index 0cf13833..4e5e4f84 100644 --- a/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java +++ b/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java @@ -3,10 +3,10 @@ package carpet.mixins; import carpet.network.CarpetClient; import carpet.script.utils.ShapesRenderer; import com.llamalad7.mixinextras.sugar.Local; -import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.mojang.blaze3d.framegraph.FrameGraphBuilder; import com.mojang.blaze3d.framegraph.FramePass; import com.mojang.blaze3d.resource.GraphicsResourceAllocator; +import com.mojang.renderpearl.api.buffers.GpuBufferSlice; import net.minecraft.client.DeltaTracker; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; @@ -56,8 +56,9 @@ public class LevelRenderer_scarpetRenderMixin @Inject(method = "render", at = @At( value = "INVOKE", -target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;F)V", -//target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V", +target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/renderpearl/api/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;F)V", + //target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;F)V", + //target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V", //target = "Lnet/minecraft/client/renderer/LevelRenderer;addAlwaysOnTopPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;)V", //target = "Lnet/minecraft/client/renderer/LevelRenderer;submitFeatures(Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeCollector;Z)V", //target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V", diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java index af4e07eb..18030891 100644 --- a/src/main/java/carpet/script/api/WorldAccess.java +++ b/src/main/java/carpet/script/api/WorldAccess.java @@ -1100,7 +1100,7 @@ public class WorldAccess for (ServerPlayer serverPlayer : cc.level().players()) { if (serverPlayer.distanceToSqr(pos) < 4096.0) { Optional optional = Optional.ofNullable((Vec3)serverExplosion.getHitPlayers().get(serverPlayer)); - serverPlayer.connection.send(new ClientboundExplodePacket(pos, powah, i, optional, particleOptions3, SoundEvents.GENERIC_EXPLODE, DEFAULT_EXPLOSION_BLOCK_PARTICLES)); + serverPlayer.connection.send(new ClientboundExplodePacket(pos, powah, i, optional, particleOptions3, SoundEvents.GENERIC_EXPLODE, DEFAULT_EXPLOSION_BLOCK_PARTICLES, true)); } } return Value.TRUE; diff --git a/src/main/java/carpet/script/utils/FeatureGenerator.java b/src/main/java/carpet/script/utils/FeatureGenerator.java index b9bcb7cf..203a6ab5 100644 --- a/src/main/java/carpet/script/utils/FeatureGenerator.java +++ b/src/main/java/carpet/script/utils/FeatureGenerator.java @@ -11,9 +11,11 @@ import java.util.Objects; import java.util.Optional; import java.util.OptionalInt; import java.util.function.Function; +import java.util.stream.Stream; import com.mojang.datafixers.util.Pair; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.Holder; import net.minecraft.core.HolderGetter; import net.minecraft.core.HolderSet; @@ -22,13 +24,19 @@ import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.Registries; import net.minecraft.data.worldgen.Pools; import net.minecraft.data.worldgen.ProcessorLists; +import net.minecraft.data.worldgen.features.AquaticFeatures; import net.minecraft.data.worldgen.placement.PlacementUtils; +import net.minecraft.references.BlockItemIds; import net.minecraft.resources.Identifier; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.BiomeTags; +import net.minecraft.tags.BlockTags; import net.minecraft.util.RandomSource; +import net.minecraft.util.random.Weighted; +import net.minecraft.util.random.WeightedList; import net.minecraft.util.valueproviders.ConstantInt; +import net.minecraft.util.valueproviders.UniformInt; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; @@ -38,18 +46,28 @@ import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.RandomState; import net.minecraft.world.level.levelgen.VerticalAnchor; +import net.minecraft.world.level.levelgen.blockpredicates.BlockPredicate; import net.minecraft.world.level.levelgen.feature.CoralClawFeature; -import net.minecraft.world.level.levelgen.feature.CoralMushroomFeature; import net.minecraft.world.level.levelgen.feature.CoralTreeFeature; +import net.minecraft.world.level.levelgen.feature.CuboidPlacement; import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.NoOpFeature; +import net.minecraft.world.level.levelgen.feature.OverlayFeature; +import net.minecraft.world.level.levelgen.feature.SimpleBlockFeature; import net.minecraft.world.level.levelgen.feature.SimpleRandomSelectorFeature; import net.minecraft.world.level.levelgen.feature.TreeFeature; +import net.minecraft.world.level.levelgen.feature.WeightedRandomSelectorFeature; import net.minecraft.world.level.levelgen.feature.featuresize.TwoLayersFeatureSize; import net.minecraft.world.level.levelgen.feature.foliageplacers.BlobFoliagePlacer; import net.minecraft.world.level.levelgen.feature.foliageplacers.FancyFoliagePlacer; import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.RandomBlockProvider; +import net.minecraft.world.level.levelgen.feature.stateproviders.RotatedBlockProvider; import net.minecraft.world.level.levelgen.feature.stateproviders.RuleBasedStateProvider; import net.minecraft.world.level.levelgen.heightproviders.ConstantHeight; +import net.minecraft.world.level.levelgen.placement.BlockPredicateFilter; +import net.minecraft.world.level.levelgen.placement.OffsetPlacement; +import net.minecraft.world.level.levelgen.placement.RandomChancePlacement; import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.level.levelgen.structure.Structure; import net.minecraft.world.level.levelgen.structure.StructureType; @@ -278,6 +296,78 @@ public class FeatureGenerator return new TreeFeature.Builder(BlockStateProvider.simple(block), new StraightTrunkPlacer(i, j, k), BlockStateProvider.simple(block2), new BlobFoliagePlacer(ConstantInt.of(l), ConstantInt.of(0), 3), new TwoLayersFeatureSize(1, 0, 1), belowTrees); } + // from AquaticFeatures + private static Holder wallCoral(final HolderGetter blocks, final Direction direction) { + return PlacementUtils.inlinePlaced( + new SimpleBlockFeature(new RotatedBlockProvider(new RandomBlockProvider(blocks.getOrThrow(BlockTags.WALL_CORALS)), Optional.of(direction))), + new RandomChancePlacement(0.2f), + OffsetPlacement.of(direction), + BlockPredicateFilter.forPredicate(BlockPredicate.matchesBlocks(Blocks.WATER)) + ); + } + + public static Feature coral(final HolderGetter features, final HolderGetter blocks, final Block block) { + return new OverlayFeature(HolderSet.direct( + PlacementUtils.inlinePlaced(new SimpleBlockFeature(BlockStateProvider.simple(block))), + PlacementUtils.inlinePlaced( + new WeightedRandomSelectorFeature(WeightedList.of( + new Weighted<>(PlacementUtils.inlinePlaced(new SimpleBlockFeature(new RandomBlockProvider(blocks.getOrThrow(BlockTags.CORALS)))), 20), + new Weighted<>(PlacementUtils.inlinePlaced(features.getOrThrow(AquaticFeatures.SEA_PICKLE)), 3), + new Weighted<>(PlacementUtils.inlinePlaced(new NoOpFeature()), 57) + )), + OffsetPlacement.above() + ), + wallCoral(blocks, Direction.NORTH), + wallCoral(blocks, Direction.EAST), + wallCoral(blocks, Direction.SOUTH), + wallCoral(blocks, Direction.WEST) + )); + } + + final static public BlockPredicateFilter coralPlacement = BlockPredicateFilter.forPredicate(BlockPredicate.allOf( + BlockPredicate.anyOf(BlockPredicate.matchesBlocks(Blocks.WATER), BlockPredicate.matchesTag(BlockTags.CORALS)), + BlockPredicate.matchesBlocks(Direction.UP, Blocks.WATER) + )); + + + private static Feature coral(ServerLevel level, final int type) { + var blocks = level.registryAccess().lookupOrThrow(Registries.BLOCK); + var features = level.registryAccess().lookupOrThrow(Registries.FEATURE); + + return new SimpleRandomSelectorFeature( + HolderSet.direct( + Stream.of(BlockItemIds.TUBE_CORAL_BLOCK, BlockItemIds.BRAIN_CORAL_BLOCK, BlockItemIds.BUBBLE_CORAL_BLOCK, BlockItemIds.FIRE_CORAL_BLOCK, BlockItemIds.HORN_CORAL_BLOCK) + .map(id -> blocks.getOrThrow(id.block()).value()) + .map(block -> coral(features, blocks, block)) + .map( + coralType -> switch (type) { + case 0 -> PlacementUtils.inlinePlaced(new CoralTreeFeature( + PlacementUtils.inlinePlaced(coralType, coralPlacement)) + ); + case 1 -> PlacementUtils.inlinePlaced(new CoralClawFeature( + PlacementUtils.inlinePlaced(coralType, coralPlacement)) + ); + default -> PlacementUtils.inlinePlaced( + coralType, + OffsetPlacement.vertical(UniformInt.of(-3, -1)), + new CuboidPlacement( + UniformInt.of(3, 5), + UniformInt.of(3, 5), + false, + false + ), + new RandomChancePlacement(0.9f), + coralPlacement + ); + } + ) + .toList() + ) + ); + } + + + public static final Map> featureMap = new HashMap<>() {{ @@ -286,17 +376,13 @@ public class FeatureGenerator put("fancy_oak_bees", l -> simpleTree(new TreeFeature.Builder(BlockStateProvider.simple(Blocks.OAK_LOG), new FancyTrunkPlacer(3, 11, 0), BlockStateProvider.simple(Blocks.OAK_LEAVES), new FancyFoliagePlacer(ConstantInt.of(2), ConstantInt.of(4), 4), new TwoLayersFeatureSize(0, 0, 0, OptionalInt.of(4)), belowTrees).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))))); put("birch_bees", l -> simpleTree(createTree(Blocks.BIRCH_LOG, Blocks.BIRCH_LEAVES, 5, 2, 0, 2).ignoreVines().decorators(List.of(new BeehiveDecorator(1.00F))))); - put("coral_tree", l -> simplePlop(new CoralTreeFeature())); + put("coral_tree", l -> simplePlop(coral(l, 0))); + + put("coral_claw", l -> simplePlop(coral(l, 1))); + put("coral_mushroom", l -> simplePlop(coral(l , 2))); + + put("coral", l -> simplePlop( l.registryAccess().lookupOrThrow(Registries.FEATURE).getOrThrow(AquaticFeatures.WARM_OCEAN_VEGETATION).value())); - put("coral_claw", l -> simplePlop(new CoralClawFeature())); - put("coral_mushroom", l -> simplePlop(new CoralMushroomFeature())); - put("coral", l -> simplePlop(new SimpleRandomSelectorFeature( - HolderSet.direct( - PlacementUtils.inlinePlaced(new CoralTreeFeature()), - PlacementUtils.inlinePlaced(new CoralClawFeature()), - PlacementUtils.inlinePlaced(new CoralMushroomFeature()) - ) - ))); put("bastion_remnant_units", l -> { RegistryAccess regs = l.registryAccess(); diff --git a/src/main/java/carpet/script/utils/ShapesRenderer.java b/src/main/java/carpet/script/utils/ShapesRenderer.java index 61dfc1af..426b2f30 100644 --- a/src/main/java/carpet/script/utils/ShapesRenderer.java +++ b/src/main/java/carpet/script/utils/ShapesRenderer.java @@ -8,8 +8,6 @@ import com.mojang.blaze3d.pipeline.RenderTarget; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.blaze3d.vertex.VertexFormat; -//import com.mojang.blaze3d.vertex.VertexFormat.Mode; import com.mojang.math.Axis; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; From 6f607be9f353f0244e1c0f2053f319b99affada6 Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 9 Jul 2026 22:15:02 +0200 Subject: [PATCH 09/13] 26.3-beta-2 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d64d14ac..6e84e0de 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ org.gradle.configuration-cache=false loom_version=1.17-SNAPSHOT # Mod Properties - mod_version = 26.3-beta-1 + mod_version = 26.3-beta-2 maven_group = carpet archives_base_name = fabric-carpet From 21993f2585d6714ced9fc86b1f6d3721cf4c60ab Mon Sep 17 00:00:00 2001 From: Seth de Silva <145926975+seth-desilva@users.noreply.github.com> Date: Fri, 14 Aug 2026 16:20:18 -0400 Subject: [PATCH 10/13] fixed horse-feeding offhand fallback, solving #2219 (#2220) --- .../java/carpet/helpers/EntityPlayerActionPack.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/carpet/helpers/EntityPlayerActionPack.java b/src/main/java/carpet/helpers/EntityPlayerActionPack.java index 599a9318..daea4e40 100644 --- a/src/main/java/carpet/helpers/EntityPlayerActionPack.java +++ b/src/main/java/carpet/helpers/EntityPlayerActionPack.java @@ -20,6 +20,7 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.animal.equine.AbstractHorse; +import net.minecraft.world.entity.animal.equine.SkeletonHorse; import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.vehicle.boat.Boat; @@ -331,8 +332,14 @@ public class EntityPlayerActionPack player.resetLastActionTime(); EntityHitResult entityHit = (EntityHitResult) hit; Entity entity = entityHit.getEntity(); - boolean handWasEmpty = player.getItemInHand(hand).isEmpty(); + ItemStack handItem = player.getItemInHand(hand); + boolean handWasEmpty = handItem.isEmpty(); boolean itemFrameEmpty = (entity instanceof ItemFrame) && ((ItemFrame) entity).getItem().isEmpty(); + // client always consumes action with food on a horse, unless it's a skeleton horse. + boolean isFeedingHorse = entity instanceof AbstractHorse horse + && horse.isAlive() + && horse.isFood(handItem) + && !(horse instanceof SkeletonHorse); Vec3 relativeHitPos = entityHit.getLocation().subtract(entity.getX(), entity.getY(), entity.getZ()); if (entity.interact(player, hand, relativeHitPos).consumesAction()) { @@ -340,7 +347,9 @@ public class EntityPlayerActionPack return true; } // fix for SS itemframe always returns CONSUME even if no action is performed - if (player.interactOn(entity, hand, relativeHitPos).consumesAction() && !(handWasEmpty && itemFrameEmpty)) + InteractionResult interactionResult = player.interactOn(entity, hand, relativeHitPos); + if ((interactionResult.consumesAction() && !(handWasEmpty && itemFrameEmpty)) + || isFeedingHorse) { ap.itemUseCooldown = 3; return true; From 15235864f27ac585d88fcd9e4665ca39a69efed7 Mon Sep 17 00:00:00 2001 From: gnembon Date: Thu, 20 Aug 2026 15:56:09 +0200 Subject: [PATCH 11/13] 26.3-snap-9 --- docs/scarpet/api/BlocksAndWorldAccess.md | 2 +- gradle.properties | 2 +- .../fakes/RandomStateVisitorAccessor.java | 2 +- .../helpers/EntityPlayerActionPack.java | 10 ++- .../carpet/helpers/FertilizableCoral.java | 7 +- .../carpet/helpers/RedstoneWireTurbo.java | 12 +-- .../BlockBehaviourBlockStateBase_mixin.java | 2 +- ...ingAmethystBlock_movableAmethystMixin.java | 6 +- .../ChunkGenerator_customMobSpawnsMixin.java | 3 +- .../mixins/Explosion_optimizedTntMixin.java | 2 +- .../LevelRenderer_scarpetRenderMixin.java | 12 ++- .../PistonBaseBlock_movableBEMixin.java | 2 +- .../mixins/RandomState_ScarpetMixin.java | 4 +- .../mixins/RedstoneWireBlock_fastMixin.java | 24 +++--- ...PacketListenerImpl_scarpetEventsMixin.java | 16 ++-- ...kerBoxBlockEntity_creativeNoClipMixin.java | 2 +- .../java/carpet/script/api/Auxiliary.java | 2 +- .../java/carpet/script/api/Inventories.java | 3 +- .../java/carpet/script/api/WorldAccess.java | 78 ++++++++++++------- .../java/carpet/script/external/Vanilla.java | 2 +- .../carpet/script/utils/FeatureGenerator.java | 6 +- .../java/carpet/script/value/EntityValue.java | 7 +- .../carpet/utils/PerimeterDiagnostics.java | 6 +- .../java/carpet/utils/SpawnOverrides.java | 13 ++-- src/main/java/carpet/utils/SpawnReporter.java | 6 +- 25 files changed, 134 insertions(+), 97 deletions(-) diff --git a/docs/scarpet/api/BlocksAndWorldAccess.md b/docs/scarpet/api/BlocksAndWorldAccess.md index de44308b..ff14f56d 100644 --- a/docs/scarpet/api/BlocksAndWorldAccess.md +++ b/docs/scarpet/api/BlocksAndWorldAccess.md @@ -540,7 +540,7 @@ On top of that, scarpet provides the following list of noises sampled directly f `'barrier_noise'`, `'fluid_level_floodedness_noise'`, `'fluid_level_spread_noise'`, `'lava_noise'`, `'temperature'`, `'vegetation'`, `'continents'`, `'erosion'`, `'depth'`, `'ridges'`, -`'preliminary_surface_level'`, `'final_density'`, `'vein_toggle'`, `'vein_ridged'` and `'vein_gap'` +`'preliminary_surface_level'`, `'final_density'`
 // requesting single value
diff --git a/gradle.properties b/gradle.properties
index 6e84e0de..2f89c048 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -7,7 +7,7 @@ org.gradle.configuration-cache=false
 
 # Fabric Properties
 	# check https://fabricmc.net/develop/
-	minecraft_version=26.3-snapshot-3
+	minecraft_version=26.3-snapshot-9
 	loader_version=0.19.3
     loom_version=1.17-SNAPSHOT
 
diff --git a/src/main/java/carpet/fakes/RandomStateVisitorAccessor.java b/src/main/java/carpet/fakes/RandomStateVisitorAccessor.java
index d423bb52..261f856f 100644
--- a/src/main/java/carpet/fakes/RandomStateVisitorAccessor.java
+++ b/src/main/java/carpet/fakes/RandomStateVisitorAccessor.java
@@ -1,6 +1,6 @@
 package carpet.fakes;
 
-import net.minecraft.world.level.levelgen.DensityFunction;
+import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
 
 public interface RandomStateVisitorAccessor {
     DensityFunction.Visitor getVisitor();
diff --git a/src/main/java/carpet/helpers/EntityPlayerActionPack.java b/src/main/java/carpet/helpers/EntityPlayerActionPack.java
index daea4e40..891dc7be 100644
--- a/src/main/java/carpet/helpers/EntityPlayerActionPack.java
+++ b/src/main/java/carpet/helpers/EntityPlayerActionPack.java
@@ -16,6 +16,7 @@ import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
 import net.minecraft.server.level.ServerLevel;
 import net.minecraft.server.level.ServerPlayer;
 import net.minecraft.util.Mth;
+import net.minecraft.util.Prediction;
 import net.minecraft.world.InteractionHand;
 import net.minecraft.world.InteractionResult;
 import net.minecraft.world.entity.Entity;
@@ -26,6 +27,7 @@ import net.minecraft.world.entity.player.Inventory;
 import net.minecraft.world.entity.vehicle.boat.Boat;
 import net.minecraft.world.entity.vehicle.minecart.Minecart;
 import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.component.SwingAnimation;
 import net.minecraft.world.level.block.state.BlockState;
 import net.minecraft.world.phys.BlockHitResult;
 import net.minecraft.world.phys.EntityHitResult;
@@ -261,7 +263,7 @@ public class EntityPlayerActionPack
         if (!inv.getItem(slot).isEmpty())
             player.drop(inv.removeItem(slot,
                     dropAll ? inv.getItem(slot).getCount() : 1
-            ), false, true); // scatter, keep owner
+            ), false, Prediction.SERVER_ONLY); // scatter, keep owner
     }
 
     public void drop(int selectedSlot, boolean dropAll)
@@ -320,7 +322,7 @@ public class EntityPlayerActionPack
                                 InteractionResult result = player.gameMode.useItemOn(player, world, player.getItemInHand(hand), hand, blockHit);
                                 if (result instanceof InteractionResult.Success success)
                                 {
-                                    if (success.swingSource() == InteractionResult.SwingSource.SERVER) player.swing(hand);
+                                    if (success.swingSource() == InteractionResult.SwingSource.SERVER_ONLY) player.swing(hand, SwingAnimation.DEFAULT, true);
                                     ap.itemUseCooldown = 3;
                                     return true;
                                 }
@@ -385,7 +387,7 @@ public class EntityPlayerActionPack
                         if (!action.isContinuous)
                         {
                             player.attack(entityHit.getEntity());
-                            player.swing(InteractionHand.MAIN_HAND);
+                            player.swing(InteractionHand.MAIN_HAND, SwingAnimation.DEFAULT, true);
                         }
                         player.resetAttackStrengthTicker();
                         player.resetLastActionTime();
@@ -453,7 +455,7 @@ public class EntityPlayerActionPack
 
                         }
                         player.resetLastActionTime();
-                        player.swing(InteractionHand.MAIN_HAND);
+                        player.swing(InteractionHand.MAIN_HAND, SwingAnimation.DEFAULT, true);
                         return blockBroken;
                     }
                 }
diff --git a/src/main/java/carpet/helpers/FertilizableCoral.java b/src/main/java/carpet/helpers/FertilizableCoral.java
index 1fc5c90d..7b7e2076 100644
--- a/src/main/java/carpet/helpers/FertilizableCoral.java
+++ b/src/main/java/carpet/helpers/FertilizableCoral.java
@@ -16,6 +16,7 @@ import net.minecraft.world.level.LevelReader;
 import net.minecraft.world.level.block.BaseCoralPlantTypeBlock;
 import net.minecraft.world.level.block.Block;
 import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.BonemealSource;
 import net.minecraft.world.level.block.BonemealableBlock;
 import net.minecraft.world.level.block.state.BlockState;
 import net.minecraft.world.level.levelgen.feature.CoralClawFeature;
@@ -39,7 +40,7 @@ public interface FertilizableCoral extends BonemealableBlock {
     boolean isEnabled();
 
     @Override
-    public default boolean isValidBonemealTarget(LevelReader world, BlockPos pos, BlockState state)
+    public default boolean isValidBonemealTarget(LevelReader world, BlockPos pos, BlockState state, BonemealSource bonemealSource)
     {
         return isEnabled()
                 && state.getValue(BaseCoralPlantTypeBlock.WATERLOGGED)
@@ -47,13 +48,13 @@ public interface FertilizableCoral extends BonemealableBlock {
     }
 
     @Override
-    public default boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state)
+    public default boolean isBonemealSuccess(Level world, RandomSource random, BlockPos pos, BlockState state, BonemealSource bonemealSource)
     {
         return random.nextFloat() < 0.15D;
     }
 
     @Override
-    public default void performBonemeal(ServerLevel worldIn, RandomSource random, BlockPos pos, BlockState blockUnder)
+    public default void performBonemeal(ServerLevel worldIn, RandomSource random, BlockPos pos, BlockState blockUnder, BonemealSource bonemealSource)
     {
         MapColor color = blockUnder.getMapColor(worldIn, pos);
         BlockState properBlock = blockUnder;
diff --git a/src/main/java/carpet/helpers/RedstoneWireTurbo.java b/src/main/java/carpet/helpers/RedstoneWireTurbo.java
index 57015ed0..ba095a7f 100644
--- a/src/main/java/carpet/helpers/RedstoneWireTurbo.java
+++ b/src/main/java/carpet/helpers/RedstoneWireTurbo.java
@@ -11,7 +11,7 @@ import net.minecraft.core.Direction;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.Block;
 import net.minecraft.world.level.block.Blocks;
-import net.minecraft.world.level.block.RedStoneWireBlock;
+import net.minecraft.world.level.block.RedstoneWireBlock;
 import net.minecraft.world.level.block.state.BlockState;
 import carpet.fakes.RedstoneWireBlockInterface;
 
@@ -79,7 +79,7 @@ public class RedstoneWireTurbo
      
      
     /* Reference to RedstoneWireBlock object, which uses this accelerator */
-    private final RedStoneWireBlock wire;
+    private final RedstoneWireBlock wire;
      
      
     /*
@@ -115,7 +115,7 @@ public class RedstoneWireTurbo
     private List updateQueue2 = new ArrayList<>();
      
      
-    public RedstoneWireTurbo(RedStoneWireBlock wire) {
+    public RedstoneWireTurbo(RedstoneWireBlock wire) {
         this.wire = wire;
     }
  
@@ -848,7 +848,7 @@ public class RedstoneWireTurbo
     private BlockState calculateCurrentChanges(final Level worldIn, final UpdateNode upd)
     {
         BlockState state = upd.currentState;
-        final int i = state.getValue(RedStoneWireBlock.POWER);
+        final int i = state.getValue(RedstoneWireBlock.POWER);
         int j = 0;
         j = getMaxCurrentStrength(upd, j);
         int l = 0;
@@ -918,7 +918,7 @@ public class RedstoneWireTurbo
             // and set it in the world.  
             // Possible optimization:  Don't commit state changes to the world until they
             // need to be known by some nearby non-redstone-wire block.
-            state = state.setValue(RedStoneWireBlock.POWER, j);
+            state = state.setValue(RedstoneWireBlock.POWER, j);
             // [gnembon] added state check cause other things in the tick may have popped it up already
             // https://github.com/gnembon/fabric-carpet/issues/117
             if (worldIn.getBlockState(upd.self).getBlock() == Blocks.REDSTONE_WIRE)
@@ -962,7 +962,7 @@ public class RedstoneWireTurbo
      */
     private static int getMaxCurrentStrength(final UpdateNode upd, final int strength) {   
         if (upd.type != UpdateNode.Type.REDSTONE) return strength;
-        final int i = upd.currentState.getValue(RedStoneWireBlock.POWER);
+        final int i = upd.currentState.getValue(RedstoneWireBlock.POWER);
         return i > strength ? i : strength;
     }
 }
\ No newline at end of file
diff --git a/src/main/java/carpet/mixins/BlockBehaviourBlockStateBase_mixin.java b/src/main/java/carpet/mixins/BlockBehaviourBlockStateBase_mixin.java
index 3e512d97..33b4cd79 100644
--- a/src/main/java/carpet/mixins/BlockBehaviourBlockStateBase_mixin.java
+++ b/src/main/java/carpet/mixins/BlockBehaviourBlockStateBase_mixin.java
@@ -21,7 +21,7 @@ public abstract class BlockBehaviourBlockStateBase_mixin
     {
         if (CarpetSettings.movableAmethyst && getBlock() instanceof BuddingAmethystBlock)
         {
-            cir.setReturnValue(PushReaction.NORMAL);
+            cir.setReturnValue(PushReaction.PUSH_PULL);
         }
     }
 }
diff --git a/src/main/java/carpet/mixins/BuddingAmethystBlock_movableAmethystMixin.java b/src/main/java/carpet/mixins/BuddingAmethystBlock_movableAmethystMixin.java
index f1adfc67..d063f4ff 100644
--- a/src/main/java/carpet/mixins/BuddingAmethystBlock_movableAmethystMixin.java
+++ b/src/main/java/carpet/mixins/BuddingAmethystBlock_movableAmethystMixin.java
@@ -3,13 +3,13 @@ package carpet.mixins;
 import carpet.CarpetSettings;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.registries.Registries;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
 import net.minecraft.tags.ItemTags;
-import net.minecraft.world.entity.player.Player;
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.item.Items;
 import net.minecraft.world.item.enchantment.EnchantmentHelper;
 import net.minecraft.world.item.enchantment.Enchantments;
-import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.Block;
 import net.minecraft.world.level.block.BuddingAmethystBlock;
 import net.minecraft.world.level.block.entity.BlockEntity;
@@ -24,7 +24,7 @@ public class BuddingAmethystBlock_movableAmethystMixin extends Block {
     }
 
     @Override
-    public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack) {
+    public void playerDestroy(ServerLevel world, ServerPlayer player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack) {
         super.playerDestroy(world, player, pos, state, blockEntity, stack);
         // doing it here rather than though loottables since loottables are loaded on reload
         // drawback - not controlled via loottables, but hey
diff --git a/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java b/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java
index 71f9b48d..0a87fa42 100644
--- a/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java
+++ b/src/main/java/carpet/mixins/ChunkGenerator_customMobSpawnsMixin.java
@@ -4,6 +4,7 @@ import carpet.utils.SpawnOverrides;
 import it.unimi.dsi.fastutil.longs.LongSet;
 import net.minecraft.core.Holder;
 import net.minecraft.util.random.WeightedList;
+import net.minecraft.world.level.Level;
 import net.minecraft.world.level.StructureManager;
 import net.minecraft.world.level.levelgen.structure.Structure;
 import org.spongepowered.asm.mixin.Mixin;
@@ -30,7 +31,7 @@ public abstract class ChunkGenerator_customMobSpawnsMixin
                     value = "INVOKE",
                    target = "Ljava/util/Map$Entry;getKey()Ljava/lang/Object;"
             ), cancellable = true)
-    private void checkCMSpawns(Holder holder, StructureManager structureFeatureManager, MobCategory mobCategory, BlockPos blockPos,
+    private void checkCMSpawns(Level holder, StructureManager structureFeatureManager, MobCategory mobCategory, BlockPos blockPos,
                                CallbackInfoReturnable> cir,
                                Map map, Iterator var6, Map.Entry entry)
     {
diff --git a/src/main/java/carpet/mixins/Explosion_optimizedTntMixin.java b/src/main/java/carpet/mixins/Explosion_optimizedTntMixin.java
index 76effd11..81913320 100644
--- a/src/main/java/carpet/mixins/Explosion_optimizedTntMixin.java
+++ b/src/main/java/carpet/mixins/Explosion_optimizedTntMixin.java
@@ -86,7 +86,7 @@ public abstract class Explosion_optimizedTntMixin
     }
 
     @Redirect(method = "hurtEntities",
-            at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;push(Lnet/minecraft/world/phys/Vec3;)V"))
+            at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;pushFromExplosion(Lnet/minecraft/world/phys/Vec3;)V"))
     private void setVelocityAndUpdateLogging(Entity entity, Vec3 velocity)
     {
         if (eLogger != null) {
diff --git a/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java b/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java
index 4e5e4f84..2d45981b 100644
--- a/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java
+++ b/src/main/java/carpet/mixins/LevelRenderer_scarpetRenderMixin.java
@@ -26,6 +26,7 @@ import net.minecraft.client.renderer.state.level.LevelRenderState;
 import net.minecraft.client.renderer.texture.TextureManager;
 import net.minecraft.client.resources.model.ModelManager;
 import net.minecraft.client.resources.model.sprite.AtlasManager;
+import org.joml.Matrix4f;
 import org.joml.Matrix4fc;
 import org.joml.Vector4f;
 import org.spongepowered.asm.mixin.Final;
@@ -56,7 +57,8 @@ public class LevelRenderer_scarpetRenderMixin
 
     @Inject(method = "render", at = @At(
             value = "INVOKE",
-target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/renderpearl/api/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;F)V",
+//target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/renderpearl/api/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;Z)V"
+target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/renderpearl/api/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;Z)V",
             //target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;F)V",
             //target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
             //target = "Lnet/minecraft/client/renderer/LevelRenderer;addAlwaysOnTopPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;)V",
@@ -65,7 +67,8 @@ target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/b
             //target = "Lnet/minecraft/client/renderer/LevelRenderer;addLateDebugPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/state/level/CameraRenderState;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lorg/joml/Matrix4fc;)V",
             shift = At.Shift.AFTER
     ))
-            private void renderScarpetThingsLate(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, CallbackInfo ci, @Local FrameGraphBuilder frameGraphBuilder)
+            private void renderStanperThingsLate  (GraphicsResourceAllocator resourceAllocator, boolean renderOutline, CameraRenderState cameraState, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, boolean consistentDepthRequired, CallbackInfo ci, @Local(name = "frame") FrameGraphBuilder frameGraphBuilder)
+            //private void renderScarpetThingsLate(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, boolean consistentDepthRequired, CallbackInfo ci, @Local FrameGraphBuilder frameGraphBuilder)
     //private void renderScarpetThinsLate(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, CallbackInfo ci, @Local FrameGraphBuilder frameGraphBuilder)
     {
         // in normal circumstances we want to render shapes at the very end so it appears correctly behind stuff.
@@ -73,10 +76,11 @@ target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/b
         //if (!FabricAPIHooks.WORLD_RENDER_EVENTS && CarpetClient.shapes != null )
         if (CarpetClient.shapes != null)
         {
-            final float deltaPartialTick = deltaTracker.getGameTimeDeltaPartialTick(false);
+            //final float deltaPartialTick = deltaTracker.getGameTimeDeltaPartialTick(false);
             FramePass pass = frameGraphBuilder.addPass("scarpet_shapes");
             targets.main = pass.readsAndWrites(targets.main);
-            pass.executes(() -> CarpetClient.shapes.render(submitNodeStorage, levelRenderState, modelViewMatrix, deltaPartialTick));
+            var modelViewMatrix =  new Matrix4f(levelRenderState.cameraRenderState.viewRotationMatrix);
+            pass.executes(() -> CarpetClient.shapes.render(submitNodeStorage, levelRenderState, modelViewMatrix, levelRenderState.worldPartialTicks));
             //featureRenderDispatcher.renderAllFeatures(submitNodeStorage);
             //renderBuffers.bufferSource().uploadAndDraw();
         }
diff --git a/src/main/java/carpet/mixins/PistonBaseBlock_movableBEMixin.java b/src/main/java/carpet/mixins/PistonBaseBlock_movableBEMixin.java
index 5cc5ba95..094274b0 100644
--- a/src/main/java/carpet/mixins/PistonBaseBlock_movableBEMixin.java
+++ b/src/main/java/carpet/mixins/PistonBaseBlock_movableBEMixin.java
@@ -79,7 +79,7 @@ public abstract class PistonBaseBlock_movableBEMixin extends DirectionalBlock
     ))
     private static PushReaction moveGrindstones(BlockState blockState)
     {
-        if (CarpetSettings.movableBlockEntities && blockState.getBlock() == Blocks.GRINDSTONE) return PushReaction.NORMAL;
+        if (CarpetSettings.movableBlockEntities && blockState.getBlock() == Blocks.GRINDSTONE) return PushReaction.PUSH_PULL;
         return blockState.getPistonPushReaction();
     }
 
diff --git a/src/main/java/carpet/mixins/RandomState_ScarpetMixin.java b/src/main/java/carpet/mixins/RandomState_ScarpetMixin.java
index 2e855238..e785540b 100644
--- a/src/main/java/carpet/mixins/RandomState_ScarpetMixin.java
+++ b/src/main/java/carpet/mixins/RandomState_ScarpetMixin.java
@@ -1,7 +1,7 @@
 package carpet.mixins;
 
 import carpet.fakes.RandomStateVisitorAccessor;
-import net.minecraft.world.level.levelgen.DensityFunction;
+import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
 import net.minecraft.world.level.levelgen.RandomState;
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.Unique;
@@ -17,7 +17,7 @@ public class RandomState_ScarpetMixin implements RandomStateVisitorAccessor {
             method = "",
             at = @At(
                     value = "INVOKE",
-                    target = "Lnet/minecraft/world/level/levelgen/NoiseRouter;mapAll(Lnet/minecraft/world/level/levelgen/DensityFunction$Visitor;)Lnet/minecraft/world/level/levelgen/NoiseRouter;"
+                    target = "Lnet/minecraft/world/level/levelgen/NoiseRouter;mapAll(Lnet/minecraft/world/level/levelgen/densityfunction/DensityFunction$Visitor;)Lnet/minecraft/world/level/levelgen/NoiseRouter;"
             ),
             index = 0
     )
diff --git a/src/main/java/carpet/mixins/RedstoneWireBlock_fastMixin.java b/src/main/java/carpet/mixins/RedstoneWireBlock_fastMixin.java
index 101ef513..0e810098 100644
--- a/src/main/java/carpet/mixins/RedstoneWireBlock_fastMixin.java
+++ b/src/main/java/carpet/mixins/RedstoneWireBlock_fastMixin.java
@@ -21,15 +21,15 @@ import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.block.RedStoneWireBlock;
+import net.minecraft.world.level.block.RedstoneWireBlock;
 import net.minecraft.world.level.block.state.BlockBehaviour;
 import net.minecraft.world.level.block.state.BlockState;
 
 import org.jspecify.annotations.Nullable;
 
-import static net.minecraft.world.level.block.RedStoneWireBlock.POWER;
+import static net.minecraft.world.level.block.RedstoneWireBlock.POWER;
 
-@Mixin(RedStoneWireBlock.class)
+@Mixin(RedstoneWireBlock.class)
 public abstract class RedstoneWireBlock_fastMixin implements RedstoneWireBlockInterface {
 
     @Shadow
@@ -43,7 +43,7 @@ public abstract class RedstoneWireBlock_fastMixin implements RedstoneWireBlockIn
     @Accessor("shouldSignal")
     public abstract boolean getWiresGivePower();
 
-    private RedstoneWireEvaluator legacy = new DefaultRedstoneWireEvaluator((RedStoneWireBlock)(Object) this);
+    private RedstoneWireEvaluator legacy = new DefaultRedstoneWireEvaluator((RedstoneWireBlock)(Object) this);
 
     // =
 
@@ -52,7 +52,7 @@ public abstract class RedstoneWireBlock_fastMixin implements RedstoneWireBlockIn
     @Inject(method = "", at = @At("RETURN"))
     private void onRedstoneWireBlockCTOR(BlockBehaviour.Properties settings, CallbackInfo ci) {
         //noinspection ConstantConditions
-        wireTurbo = new RedstoneWireTurbo((RedStoneWireBlock) (Object) this);
+        wireTurbo = new RedstoneWireTurbo((RedstoneWireBlock) (Object) this);
     }
 
     // =
@@ -114,24 +114,24 @@ public abstract class RedstoneWireBlock_fastMixin implements RedstoneWireBlockIn
     // =
 
 
-    @Redirect(method = "onPlace", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/RedStoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/redstone/Orientation;Z)V"))
-    private void redirectOnBlockAddedUpdate(RedStoneWireBlock self, Level world_1, BlockPos blockPos_1, BlockState blockState_1, Orientation o, boolean sup) {
+    @Redirect(method = "onPlace", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/RedstoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/redstone/Orientation;Z)V"))
+    private void redirectOnBlockAddedUpdate(RedstoneWireBlock self, Level world_1, BlockPos blockPos_1, BlockState blockState_1, Orientation o, boolean sup) {
         fastUpdate(world_1, blockPos_1, blockState_1, o, sup);
     }
 
-    @Redirect(method = "affectNeighborsAfterRemoval", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/RedStoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/redstone/Orientation;Z)V"))
-    private void redirectOnStateReplacedUpdate(RedStoneWireBlock self, Level world_1, BlockPos blockPos_1, BlockState blockState_1, Orientation o, boolean sup) {
+    @Redirect(method = "affectNeighborsAfterRemoval", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/RedstoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/redstone/Orientation;Z)V"))
+    private void redirectOnStateReplacedUpdate(RedstoneWireBlock self, Level world_1, BlockPos blockPos_1, BlockState blockState_1, Orientation o, boolean sup) {
         fastUpdate(world_1, blockPos_1, blockState_1, o, sup);
     }
 
     @Redirect(method = "neighborChanged", at = @At(value = "INVOKE", target =
-            "Lnet/minecraft/world/level/block/RedStoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/redstone/Orientation;Z)V"
-            //"Lnet/minecraft/world/level/block/RedStoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/redstone/Orientation;)V"
+            "Lnet/minecraft/world/level/block/RedstoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/redstone/Orientation;Z)V"
+            //"Lnet/minecraft/world/level/block/RedstoneWireBlock;updatePowerStrength(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/redstone/Orientation;)V"
     ))
     //private void red(final RedStoneWireBlock instance, final Level level,
     //                 final BlockPos blockPos, final BlockState blockState, final Orientation orientation)
     private void redirectNeighborUpdateUpdate(
-            RedStoneWireBlock self,
+            RedstoneWireBlock self,
             Level world_1,
             BlockPos blockPos_1,
             BlockState blockState_1,
diff --git a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java
index 42e0f3e0..620c86c9 100644
--- a/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java
+++ b/src/main/java/carpet/mixins/ServerGamePacketListenerImpl_scarpetEventsMixin.java
@@ -38,7 +38,7 @@ import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
 import net.minecraft.network.protocol.game.ServerboundPlayerCommandPacket;
 import net.minecraft.network.protocol.game.ServerboundPlayerInputPacket;
 import net.minecraft.network.protocol.game.ServerboundSetCarriedItemPacket;
-import net.minecraft.network.protocol.game.ServerboundSwingPacket;
+import net.minecraft.network.protocol.game.ServerboundPunchPacket;
 import net.minecraft.network.protocol.game.ServerboundUseItemOnPacket;
 import net.minecraft.network.protocol.game.ServerboundUseItemPacket;
 import net.minecraft.server.level.ServerPlayer;
@@ -171,8 +171,8 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
     {
         if (PLAYER_RIGHT_CLICKS_BLOCK.isNeeded())
         {
-            InteractionHand hand = playerInteractBlockC2SPacket_1.getHand();
-            BlockHitResult hitRes = playerInteractBlockC2SPacket_1.getHitResult();
+            InteractionHand hand = playerInteractBlockC2SPacket_1.hand();
+            BlockHitResult hitRes = playerInteractBlockC2SPacket_1.hitResult();
             if(PLAYER_RIGHT_CLICKS_BLOCK.onBlockHit(player, hand, hitRes)) {
                 ci.cancel();
             }
@@ -187,7 +187,7 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
     {
         if (PLAYER_USES_ITEM.isNeeded())
         {
-            InteractionHand hand = playerInteractItemC2SPacket_1.getHand();
+            InteractionHand hand = playerInteractItemC2SPacket_1.hand();
             if(PLAYER_USES_ITEM.onItemAction(player, hand, player.getItemInHand(hand).copy())) {
                 ci.cancel();
             }
@@ -267,16 +267,16 @@ public class ServerGamePacketListenerImpl_scarpetEventsMixin
         }
     }
 
-    @Inject(method = "handleAnimate", at = @At(
+    @Inject(method = "handlePunch", at = @At(
             value = "INVOKE", target =
             "Lnet/minecraft/server/level/ServerPlayer;resetLastActionTime()V",
             shift = At.Shift.BEFORE)
     )
-    private void onSwing(ServerboundSwingPacket packet, CallbackInfo ci)
+    private void onSwing(ServerboundPunchPacket packet, CallbackInfo ci)
     {
-        if (PLAYER_SWINGS_HAND.isNeeded() && !player.swinging)
+        if (PLAYER_SWINGS_HAND.isNeeded() && !player.isSwinging())
         {
-            PLAYER_SWINGS_HAND.onHandAction(player, packet.getHand());
+            PLAYER_SWINGS_HAND.onHandAction(player, InteractionHand.MAIN_HAND);
         }
     }
 
diff --git a/src/main/java/carpet/mixins/ShulkerBoxBlockEntity_creativeNoClipMixin.java b/src/main/java/carpet/mixins/ShulkerBoxBlockEntity_creativeNoClipMixin.java
index ec344482..12856aba 100644
--- a/src/main/java/carpet/mixins/ShulkerBoxBlockEntity_creativeNoClipMixin.java
+++ b/src/main/java/carpet/mixins/ShulkerBoxBlockEntity_creativeNoClipMixin.java
@@ -19,7 +19,7 @@ public class ShulkerBoxBlockEntity_creativeNoClipMixin
     private PushReaction getPistonBehaviourOfNoClipPlayers(Entity entity)
     {
         if (CarpetSettings.creativeNoClip && entity instanceof Player && (((Player) entity).isCreative()) && ((Player) entity).getAbilities().flying)
-            return PushReaction.IGNORE;
+            return PushReaction.IGNORE_ENTITY;
         return entity.getPistonPushReaction();
     }
 }
diff --git a/src/main/java/carpet/script/api/Auxiliary.java b/src/main/java/carpet/script/api/Auxiliary.java
index 69717e2e..20d627a2 100644
--- a/src/main/java/carpet/script/api/Auxiliary.java
+++ b/src/main/java/carpet/script/api/Auxiliary.java
@@ -424,7 +424,7 @@ public class Auxiliary
             armorstand.setHeadPose(new Rotations((int) pointLocator.pitch, 0, 0));
             armorstand.setNoGravity(true);
             armorstand.setInvisible(true);
-            armorstand.setInvulnerable(true);
+            armorstand.setPermanentlyInvulnerable(true);
             armorstand.getEntityData().set(ArmorStand.DATA_CLIENT_FLAGS, (byte) (interactable ? 8 : 16 | 8));
             level.addFreshEntity(armorstand);
             return new EntityValue(armorstand);
diff --git a/src/main/java/carpet/script/api/Inventories.java b/src/main/java/carpet/script/api/Inventories.java
index 28b9de22..1b2602a2 100644
--- a/src/main/java/carpet/script/api/Inventories.java
+++ b/src/main/java/carpet/script/api/Inventories.java
@@ -36,6 +36,7 @@ import net.minecraft.network.chat.Component;
 import net.minecraft.resources.Identifier;
 import net.minecraft.server.level.ServerPlayer;
 import net.minecraft.tags.TagKey;
+import net.minecraft.util.Prediction;
 import net.minecraft.util.context.ContextMap;
 import net.minecraft.world.entity.LivingEntity;
 import net.minecraft.world.entity.item.ItemEntity;
@@ -441,7 +442,7 @@ public class Inventories
             ItemEntity item;
             if (owner instanceof Player player)
             {
-                item = player.drop(droppedStack, false, true);
+                item = player.drop(droppedStack, false, Prediction.SERVER_ONLY);
                 if (item == null)
                 {
                     return Value.ZERO;
diff --git a/src/main/java/carpet/script/api/WorldAccess.java b/src/main/java/carpet/script/api/WorldAccess.java
index 18030891..96dfdc88 100644
--- a/src/main/java/carpet/script/api/WorldAccess.java
+++ b/src/main/java/carpet/script/api/WorldAccess.java
@@ -61,8 +61,9 @@ import net.minecraft.world.level.ServerExplosion;
 import net.minecraft.world.level.chunk.ChunkGenerator;
 import net.minecraft.world.level.chunk.PalettedContainer;
 import net.minecraft.world.level.chunk.status.ChunkStatus;
-import net.minecraft.world.level.levelgen.DensityFunction;
-import net.minecraft.world.level.levelgen.DensityFunctions;
+import net.minecraft.world.level.levelgen.Aquifer;
+import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
+import net.minecraft.world.level.levelgen.densityfunction.DensityFunctions;
 import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
 import net.minecraft.world.level.levelgen.NoiseRouter;
 import net.minecraft.world.level.levelgen.RandomState;
@@ -1730,33 +1731,41 @@ public class WorldAccess
             {
                 return ListValue.wrap(cc.registry(Registries.DENSITY_FUNCTION).keySet().stream().map(ValueConversions::of));
             }
-            NoiseRouter router = level.getChunkSource().randomState().router();
+            RandomState router = level.getChunkSource().randomState();
             return densityFunctionQueries.length == 1
                     ? NumericValue.of(sampleNoise(router, level, densityFunctionQueries[0], pos))
                     : ListValue.wrap(Arrays.stream(densityFunctionQueries).map(s -> NumericValue.of(sampleNoise(router, level, s, pos))));
         });
     }
 
-    public static double sampleNoise(NoiseRouter router, ServerLevel level, String what, BlockPos pos)
+    public static double sampleNoise(RandomState router, ServerLevel level, String what, BlockPos pos)
     {
         DensityFunction densityFunction = switch (what)
         {
-            case "barrier_noise" -> router.barrierNoise();
-            case "fluid_level_floodedness_noise" -> router.fluidLevelFloodednessNoise();
-            case "fluid_level_spread_noise" -> router.fluidLevelSpreadNoise();
-            case "lava_noise" -> router.lavaNoise();
-            case "temperature" -> router.temperature();
-            case "vegetation" -> router.vegetation();
-            case "continents" -> router.continents();
-            case "erosion" -> router.erosion();
-            case "depth" -> router.depth();
-            case "ridges" -> router.ridges();
-            case "preliminary_surface_level" -> router.preliminarySurfaceLevel();
-            case "final_density" -> router.finalDensity();
-            case "vein_toggle" -> router.veinToggle();
-            case "vein_ridged" -> router.veinRidged();
-            case "vein_gap" -> router.veinGap();
-            default -> stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, what));
+            case "temperature" -> router.router().temperature();
+            case "vegetation" -> router.router().vegetation();
+            case "continents" -> router.router().continents();
+            case "erosion" -> router.router().erosion();
+            case "depth" -> router.router().depth();
+            case "ridges" -> router.router().ridges();
+            case "preliminary_surface_level" -> router.router().preliminarySurfaceLevel();
+            case "final_density" -> router.router().finalDensity();
+            //case "vein_toggle" -> router. router(). veinToggle();
+            //case "vein_ridged" -> router.router().veinRidged();
+            //case "vein_gap" -> router.router().veinGap();
+            default -> {
+                Aquifer.Config aquifer = router.aquifers().orElse(null);
+                if (aquifer != null) {
+                    yield switch (what) {
+                        case "barrier_noise" -> aquifer.barrierNoise();
+                        case "fluid_level_floodedness_noise" -> aquifer.fluidLevelFloodednessNoise();
+                        case "fluid_level_spread_noise" -> aquifer.fluidLevelSpreadNoise();
+                        case "lava_noise" -> aquifer.lavaNoise();
+                        default -> stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, what));
+                    };
+                }
+                yield stupidWorldgenNoiseCacheGetter.apply(Pair.of(level, what));
+            }
         };
         return densityFunction.compute(new DensityFunction.SinglePointContext(pos.getX(), pos.getY(), pos.getZ()));
     }
@@ -1773,10 +1782,6 @@ public class WorldAccess
             NoiseRouter router = noiseBasedChunkGenerator.generatorSettings().value().noiseRouter();
             DensityFunction densityFunction = switch (densityFunctionQuery)
                     {
-                        case "barrier_noise" -> router.barrierNoise();
-                        case "fluid_level_floodedness_noise" -> router.fluidLevelFloodednessNoise();
-                        case "fluid_level_spread_noise" -> router.fluidLevelSpreadNoise();
-                        case "lava_noise" -> router.lavaNoise();
                         case "temperature" -> router.temperature();
                         case "vegetation" -> router.vegetation();
                         case "continents" -> router.continents();
@@ -1785,10 +1790,29 @@ public class WorldAccess
                         case "ridges" -> router.ridges();
                         case "preliminary_surface_level" -> router.preliminarySurfaceLevel();
                         case "final_density" -> router.finalDensity();
-                        case "vein_toggle" -> router.veinToggle();
-                        case "vein_ridged" -> router.veinRidged();
-                        case "vein_gap" -> router.veinGap();
+                        //case "vein_toggle" -> router.veinToggle();
+                        //case "vein_ridged" -> router.veinRidged();
+                        //case "vein_gap" -> router.veinGap();
                         default -> {
+                            Aquifer.Config aquifers = noiseBasedChunkGenerator.generatorSettings().value().aquifers().orElse(null);
+                            if (aquifers != null) {
+                                yield switch (densityFunctionQuery) {
+                                    case "barrier_noise" -> aquifers.barrierNoise();
+                                    case "fluid_level_floodedness_noise" -> aquifers.fluidLevelFloodednessNoise();
+                                    case "fluid_level_spread_noise" -> aquifers.fluidLevelSpreadNoise();
+                                    case "lava_noise" -> aquifers.lavaNoise();
+                                    default -> {
+                                        DensityFunction result = densityFunctionRegistry.getValue(InputValidator.identifierOf(densityFunctionQuery));
+                                        if (result == null)
+                                        {
+                                            throw new InternalExpressionException("Density function '" + densityFunctionQuery + "' is not defined in the registies.");
+                                        }
+                                        yield result;
+                                    }
+                                };
+                            }
+
+
                             DensityFunction result = densityFunctionRegistry.getValue(InputValidator.identifierOf(densityFunctionQuery));
                             if (result == null)
                             {
diff --git a/src/main/java/carpet/script/external/Vanilla.java b/src/main/java/carpet/script/external/Vanilla.java
index a7bce205..5ddfecff 100644
--- a/src/main/java/carpet/script/external/Vanilla.java
+++ b/src/main/java/carpet/script/external/Vanilla.java
@@ -53,7 +53,7 @@ import net.minecraft.world.level.biome.Biome;
 import net.minecraft.world.level.block.Block;
 import net.minecraft.world.level.block.state.BlockState;
 import net.minecraft.world.level.block.state.pattern.BlockInWorld;
-import net.minecraft.world.level.levelgen.DensityFunction;
+import net.minecraft.world.level.levelgen.densityfunction.DensityFunction;
 import net.minecraft.world.level.levelgen.RandomState;
 import net.minecraft.world.level.storage.LevelStorageSource;
 import net.minecraft.world.level.storage.ServerLevelData;
diff --git a/src/main/java/carpet/script/utils/FeatureGenerator.java b/src/main/java/carpet/script/utils/FeatureGenerator.java
index 203a6ab5..d422b370 100644
--- a/src/main/java/carpet/script/utils/FeatureGenerator.java
+++ b/src/main/java/carpet/script/utils/FeatureGenerator.java
@@ -269,7 +269,7 @@ public class FeatureGenerator
         {
             //Holder genBiome = generator.getBiomeSource().getNoiseBiome(QuartPos.fromBlock(pos.getX()), QuartPos.fromBlock(pos.getY()), QuartPos.fromBlock(pos.getZ()), seed.sampler());
             if (structure.findValidGenerationPoint(new Structure.GenerationContext(
-                    world.registryAccess(), generator, generator.getBiomeSource(),
+                    world.registryAccess(), generator, world.uncachedBiomeResolver(),
                     seed, world.getStructureManager(), world.getSeed(), chunkPos, world, structureBiomes::contains
             )).isPresent())
             {
@@ -279,7 +279,7 @@ public class FeatureGenerator
         else
         {
             StructureStart filledStructure = structure.generate(Holder.direct(structure), world.dimension(),
-                    world.registryAccess(), generator, generator.getBiomeSource(), seed, world.getStructureManager(),
+                    world.registryAccess(), generator, world.uncachedBiomeResolver(), seed, world.getStructureManager(),
                     world.getSeed(), chunkPos, 0, world, structureBiomes::contains);
             if (filledStructure != null && filledStructure.isValid())
             {
@@ -508,7 +508,7 @@ public class FeatureGenerator
         checks.set(true);
         try
         {
-            StructureStart start = structure.generate(Holder.direct(structure), world.dimension(), world.registryAccess(), generator, generator.getBiomeSource(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), ChunkPos.containing(pos), 0, world, b -> true);
+            StructureStart start = structure.generate(Holder.direct(structure), world.dimension(), world.registryAccess(), generator, world.uncachedBiomeResolver(), world.getChunkSource().randomState(), world.getStructureManager(), world.getSeed(), ChunkPos.containing(pos), 0, world, b -> true);
             if (start == StructureStart.INVALID_START)
             {
                 return false;
diff --git a/src/main/java/carpet/script/value/EntityValue.java b/src/main/java/carpet/script/value/EntityValue.java
index d46919cb..8fae3636 100644
--- a/src/main/java/carpet/script/value/EntityValue.java
+++ b/src/main/java/carpet/script/value/EntityValue.java
@@ -70,6 +70,7 @@ import net.minecraft.world.entity.projectile.Projectile;
 import net.minecraft.world.entity.projectile.hurtingprojectile.WitherSkull;
 import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart;
 import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.component.SwingAnimation;
 import net.minecraft.world.level.GameType;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.entity.EntityTypeTest;
@@ -554,7 +555,7 @@ public class EntityValue extends Value
         put("sneaking", (e, a) -> e.isShiftKeyDown() ? Value.TRUE : Value.FALSE);
         put("sprinting", (e, a) -> e.isSprinting() ? Value.TRUE : Value.FALSE);
         put("swimming", (e, a) -> e.isSwimming() ? Value.TRUE : Value.FALSE);
-        put("swinging", (e, a) -> e instanceof LivingEntity le ? BooleanValue.of(le.swinging) : Value.NULL);
+        put("swinging", (e, a) -> e instanceof LivingEntity le ? BooleanValue.of(le.isSwinging()) : Value.NULL);
         put("air", (e, a) -> new NumericValue(e.getAirSupply()));
         put("language", (e, a) -> !(e instanceof ServerPlayer p) ? NULL : StringValue.of(p.clientInformation().language()));
         put("persistence", (e, a) -> e instanceof Mob mob ? BooleanValue.of(mob.isPersistenceRequired()) : Value.NULL);
@@ -1586,7 +1587,7 @@ public class EntityValue extends Value
                         hand = InteractionHand.OFF_HAND;
                     }
                 }
-                le.swing(hand, true);
+                le.swing(hand, SwingAnimation.DEFAULT, true);
             }
         });
 
@@ -1603,7 +1604,7 @@ public class EntityValue extends Value
             }
             else
             {
-                e.setInvulnerable(invulnerable);
+                e.setPermanentlyInvulnerable(invulnerable);
             }
         });
 
diff --git a/src/main/java/carpet/utils/PerimeterDiagnostics.java b/src/main/java/carpet/utils/PerimeterDiagnostics.java
index b52a88d9..e8974b73 100644
--- a/src/main/java/carpet/utils/PerimeterDiagnostics.java
+++ b/src/main/java/carpet/utils/PerimeterDiagnostics.java
@@ -161,10 +161,10 @@ public class PerimeterDiagnostics
 
     private boolean check_entity_spawn(BlockPos pos)
     {
-        if (sle == null || !worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureManager(), ctype, pos).unwrap().contains(sle))
+        if (sle == null || !worldServer.getChunkSource().getGenerator().getMobsAt(worldServer, worldServer.structureManager(), ctype, pos).unwrap().contains(sle))
         {
             sle = null;
-            for (Weighted wsle: worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureManager(), ctype, pos).unwrap())
+            for (Weighted wsle: worldServer.getChunkSource().getGenerator().getMobsAt(worldServer, worldServer.structureManager(), ctype, pos).unwrap())
             {
                 MobSpawnSettings.SpawnerData sle = wsle.value();
                 if (el.getType() == sle.type())
@@ -173,7 +173,7 @@ public class PerimeterDiagnostics
                     break;
                 }
             }
-            if (sle == null || !worldServer.getChunkSource().getGenerator().getMobsAt(worldServer.getBiome(pos), worldServer.structureManager(), ctype, pos).unwrap().contains(sle))
+            if (sle == null || !worldServer.getChunkSource().getGenerator().getMobsAt(worldServer, worldServer.structureManager(), ctype, pos).unwrap().contains(sle))
             {
                 return false;
             }
diff --git a/src/main/java/carpet/utils/SpawnOverrides.java b/src/main/java/carpet/utils/SpawnOverrides.java
index 58113d77..f0fbc717 100644
--- a/src/main/java/carpet/utils/SpawnOverrides.java
+++ b/src/main/java/carpet/utils/SpawnOverrides.java
@@ -9,6 +9,9 @@ import net.minecraft.resources.ResourceKey;
 import net.minecraft.resources.Identifier;
 import net.minecraft.server.level.ServerLevel;
 import net.minecraft.util.random.WeightedList;
+import net.minecraft.util.valueproviders.ConstantInt;
+import net.minecraft.util.valueproviders.IntProvider;
+import net.minecraft.util.valueproviders.UniformInt;
 import net.minecraft.world.entity.EntityTypes;
 import net.minecraft.world.entity.MobCategory;
 import net.minecraft.world.level.StructureManager;
@@ -32,16 +35,16 @@ public class SpawnOverrides {
 
     static {
         addOverride(() -> CarpetSettings.huskSpawningInTemples, MobCategory.MONSTER, BuiltinStructures.DESERT_PYRAMID, StructureSpawnOverride.BoundingBoxType.STRUCTURE,
-                WeightedList.of(new MobSpawnSettings.SpawnerData(EntityTypes.HUSK, 1, 1))
+                WeightedList.of(new MobSpawnSettings.SpawnerData(EntityTypes.HUSK, ConstantInt.of(1)))
         );
         addOverride(() -> CarpetSettings.shulkerSpawningInEndCities, MobCategory.MONSTER, BuiltinStructures.END_CITY, StructureSpawnOverride.BoundingBoxType.PIECE,
-                WeightedList.of(new MobSpawnSettings.SpawnerData(EntityTypes.SHULKER, 4, 4))
+                WeightedList.of(new MobSpawnSettings.SpawnerData(EntityTypes.SHULKER,  ConstantInt.of(4)))
         );
         addOverride(() -> CarpetSettings.piglinsSpawningInBastions, MobCategory.MONSTER, BuiltinStructures.BASTION_REMNANT, StructureSpawnOverride.BoundingBoxType.PIECE,
                 WeightedList.builder()
-                        .add(new MobSpawnSettings.SpawnerData(EntityTypes.PIGLIN_BRUTE,1, 2), 5)
-                        .add(new MobSpawnSettings.SpawnerData(EntityTypes.PIGLIN, 2, 4), 10)
-                        .add(new MobSpawnSettings.SpawnerData(EntityTypes.HOGLIN, 1, 2), 2)
+                        .add(new MobSpawnSettings.SpawnerData(EntityTypes.PIGLIN_BRUTE, UniformInt.of(1, 2)), 5)
+                        .add(new MobSpawnSettings.SpawnerData(EntityTypes.PIGLIN, UniformInt.of(2, 4)), 10)
+                        .add(new MobSpawnSettings.SpawnerData(EntityTypes.HOGLIN, UniformInt.of(1, 2)), 2)
                         .build()
         );
 
diff --git a/src/main/java/carpet/utils/SpawnReporter.java b/src/main/java/carpet/utils/SpawnReporter.java
index 35dfc479..642caa6d 100644
--- a/src/main/java/carpet/utils/SpawnReporter.java
+++ b/src/main/java/carpet/utils/SpawnReporter.java
@@ -397,7 +397,7 @@ public class SpawnReporter
 
     // yeeted from NaturalSpawner - temporary access fix
     private static WeightedList getSpawnEntries(ServerLevel serverLevel, StructureManager structureManager, ChunkGenerator chunkGenerator, MobCategory mobCategory, BlockPos blockPos, @Nullable Holder holder) {
-        return NaturalSpawner.isInNetherFortressBounds(blockPos, serverLevel, mobCategory, structureManager) ? NetherFortressStructure.FORTRESS_ENEMIES : chunkGenerator.getMobsAt(holder != null ? holder : serverLevel.getBiome(blockPos), structureManager, mobCategory, blockPos);
+        return NaturalSpawner.isInNetherFortressBounds(blockPos, serverLevel, mobCategory, structureManager) ? NetherFortressStructure.FORTRESS_ENEMIES : chunkGenerator.getMobsAt(serverLevel, structureManager, mobCategory, blockPos);
     }
 
     public static List report(BlockPos pos, ServerLevel worldIn)
@@ -492,7 +492,7 @@ public class SpawnReporter
                     {
                         String color = (fits && willSpawn > 0) ? "e" : "gi";
                         rep.add(Messenger.c(
-                                String.format("%s %s: %s (%d:%d-%d/%d), can: ", color, categoryCode, mobTypeName, weight, spawnEntry.minCount(), spawnEntry.maxCount(),  mob.getMaxSpawnClusterSize()),
+                                String.format("%s %s: %s (%d:%d-%d/%d), can: ", color, categoryCode, mobTypeName, weight, spawnEntry.count().minInclusive(), spawnEntry.count().maxInclusive(),  mob.getMaxSpawnClusterSize()),
                                 "l YES",
                                 color + " , fit: ",
                                 (fits ? "l YES" : "r NO"),
@@ -502,7 +502,7 @@ public class SpawnReporter
                     }
                     else
                     {
-                        rep.add(Messenger.c(String.format("gi %s: %s (%d:%d-%d/%d), can: ", categoryCode, mobTypeName, weight, spawnEntry.minCount(), spawnEntry.maxCount(), mob.getMaxSpawnClusterSize()), "n NO"));
+                        rep.add(Messenger.c(String.format("gi %s: %s (%d:%d-%d/%d), can: ", categoryCode, mobTypeName, weight, spawnEntry.count().minInclusive(), spawnEntry.count().maxInclusive(), mob.getMaxSpawnClusterSize()), "n NO"));
                     }
                     killEntity(mob);
                 }

From ec91dd1c85a8c0697c2b933323252d871dd65fa5 Mon Sep 17 00:00:00 2001
From: gnembon 
Date: Thu, 20 Aug 2026 15:56:56 +0200
Subject: [PATCH 12/13] 26.3-beta-3

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 2f89c048..42795fed 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -12,7 +12,7 @@ org.gradle.configuration-cache=false
     loom_version=1.17-SNAPSHOT
 
 # Mod Properties
-	mod_version = 26.3-beta-2
+	mod_version = 26.3-beta-3
 	maven_group = carpet
 	archives_base_name = fabric-carpet
 

From 4a97c841b8befba711a671937687767f81ca7c0e Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" 
Date: Thu, 20 Aug 2026 14:15:48 +0000
Subject: [PATCH 13/13] Merge docs for 'Carpet Mod 26.3-beta-3 for Minecraft
 26.3-snapshot-9'

---
 docs/scarpet/Full.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md
index 279334d0..b8f807a7 100644
--- a/docs/scarpet/Full.md
+++ b/docs/scarpet/Full.md
@@ -2869,7 +2869,7 @@ On top of that, scarpet provides the following list of noises sampled directly f
 
 `'barrier_noise'`, `'fluid_level_floodedness_noise'`, `'fluid_level_spread_noise'`, `'lava_noise'`,
 `'temperature'`, `'vegetation'`, `'continents'`, `'erosion'`, `'depth'`, `'ridges'`, 
-`'preliminary_surface_level'`, `'final_density'`, `'vein_toggle'`, `'vein_ridged'` and `'vein_gap'`
+`'preliminary_surface_level'`, `'final_density'`
 
 
 // requesting single value