mojira.dev

phizlip

Assigned

No issues.

Reported

View all
MC-306335 Chat restriction warnings do not get narrated by chat narration Unconfirmed MC-306237 The "Rotate with Minecarts" toggle does not rotate the player's view when spectating another entity until the view direction is changed Community Consensus MC-306193 Bee nests cannot generate on trees from saplings planted near potted flowers Works As Intended MC-306151 Cannot use x+NUM to load saved hotbar while creative menu is open Duplicate MC-306150 Paintings found within Operator Utilities creative tab are missing Epic rarity Duplicate MC-306149 The "Close Menu" action on the Spectator mode hotbar buffers if the 9 key is held Confirmed MC-306148 Spectator GUI automatically hides even if the game is paused Works As Intended MC-306147 On servers, you can continue using items after pausing the game Confirmed MC-306143 Many splash texts do not have correct capitalization Invalid MC-306141 Tall flowers render incorrectly when viewed from above Won't Fix

Comments

Can confirm

[media: image-20260211-185551.png]

Issue occurring in 26.1 Snapshot 7.

Can confirm in 1.21.11

Can confirm for 1.21.11

@kyleisNOTmyname the issue here is that the rotation starts working once the entity in the minecart looks around, notice how the villager was properly following the rotation until I stopped spectating it, then it returned to its old behavior.

Were you using an Intel Arc GPU?

Can confirm, tested with IntelliJ Profiler (CPU and Total time), 26.1 Snapshot 6


Setup:

  • FOV 90, unlimited max framerate, biome blend 15x15, render distance 16

  • Superflat world, water world preset, no strutures, peaceful

  • Load world, do not move mouse or player, wait 10 seconds for initial chunk load, press F3 + A, wait additional 15 seconds (10+15 for 25 in total), then quit


Details:
I’ve tested this with a mixin addressing the issue. There are multiple ways to go about this issue, all I did was confirm that that moving the water color sampling behind the face render check removes most of the time spent in BiomeColors.getAverageWaterColor.


Profiling results:

Note: I can also attach every run's .jfr profiler results to view in IntelliJ if needed

Run

Mode

Method

CPU % (parent %)

Total % (parent %)

CPU ms

Total ms

1

Vanilla

BiomeColors.getAverageWaterColor

81.74% (98.88%)

9.99% (98.88%)

211,028

211,212

1

Vanilla

LiquidBlockRenderer.tesselate

82.66% (99.88%)

10.11% (99.88%)

213,402

213,600

2

Vanilla

BiomeColors.getAverageWaterColor

81.76% (98.84%)

13.03% (98.83%)

204,557

240,717

2

Vanilla

LiquidBlockRenderer.tesselate

82.71% (99.88%)

13.18% (99.88%)

243,357

243,565

3

Vanilla

BiomeColors.getAverageWaterColor

82.36% (98.99%)

14.66% (98.98%)

233,273

233,494

3

Vanilla

LiquidBlockRenderer.tesselate

83.19% (99.89%)

14.81% (99.89%)

235,635

235,886

1

Mixin

BiomeColors.getAverageWaterColor

15.34% (96.24%)

0.48% (96.10%)

8,297

8,297

1

Mixin

LiquidBlockRenderer.tesselate

15.94% (99.86%)

0.50% (99.86%)

8,621

8,633

2

Mixin

BiomeColors.getAverageWaterColor

15.55% (95.10%)

0.44% (95.10%)

8,833

8,833

2

Mixin

LiquidBlockRenderer.tesselate

16.36% (100.00%)

0.46% (100.00%)

9,288

9,288

3

Mixin

BiomeColors.getAverageWaterColor

13.68% (84.07%)

0.43% (83.63%)

7,229

7,241

3

Mixin

LiquidBlockRenderer.tesselate

16.27% (99.58%)

0.51% (99.58%)

8,598

8,658


Summary:

This confirms that with a high biome blend, BiomeColors.getAverageWaterColor takes up most of a chunks render compile time because its called for every water block including fully occluded ones. Moving the sampling behind the face render check, or early returning when no faces render removes most of that time.


Mixin used:

package com.example.mixin.client;

import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.block.LiquidBlockRenderer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(LiquidBlockRenderer.class)
public abstract class LiquidBlockRendererMixin {
	@Shadow
	private static boolean isNeighborSameFluid(FluidState fluidState, FluidState neighborFluidState) {
		return false;
	}

	@Shadow
	private static boolean isFaceOccludedByNeighbor(Direction direction, float height, BlockState neighborState) {
		return false;
	}

	@Shadow
	public static boolean shouldRenderFace(
		FluidState fluidState, BlockState blockState, Direction direction, FluidState neighborFluidState
	) {
		return false;
	}

	@Inject(method = "tesselate", at = @At("HEAD"), cancellable = true)
	private void templateMod$skipFullyOccludedFluids(
		BlockAndTintGetter level,
		BlockPos pos,
		VertexConsumer builder,
		BlockState blockState,
		FluidState fluidState,
		CallbackInfo info
	) {
		BlockState blockStateDown = level.getBlockState(pos.relative(Direction.DOWN));
		FluidState fluidStateDown = blockStateDown.getFluidState();
		BlockState blockStateUp = level.getBlockState(pos.relative(Direction.UP));
		FluidState fluidStateUp = blockStateUp.getFluidState();
		BlockState blockStateNorth = level.getBlockState(pos.relative(Direction.NORTH));
		FluidState fluidStateNorth = blockStateNorth.getFluidState();
		BlockState blockStateSouth = level.getBlockState(pos.relative(Direction.SOUTH));
		FluidState fluidStateSouth = blockStateSouth.getFluidState();
		BlockState blockStateWest = level.getBlockState(pos.relative(Direction.WEST));
		FluidState fluidStateWest = blockStateWest.getFluidState();
		BlockState blockStateEast = level.getBlockState(pos.relative(Direction.EAST));
		FluidState fluidStateEast = blockStateEast.getFluidState();

		boolean renderUp = !isNeighborSameFluid(fluidState, fluidStateUp);
		boolean renderDown = shouldRenderFace(fluidState, blockState, Direction.DOWN, fluidStateDown)
			&& !isFaceOccludedByNeighbor(Direction.DOWN, 0.8888889F, blockStateDown);
		boolean renderNorth = shouldRenderFace(fluidState, blockState, Direction.NORTH, fluidStateNorth);
		boolean renderSouth = shouldRenderFace(fluidState, blockState, Direction.SOUTH, fluidStateSouth);
		boolean renderWest = shouldRenderFace(fluidState, blockState, Direction.WEST, fluidStateWest);
		boolean renderEast = shouldRenderFace(fluidState, blockState, Direction.EAST, fluidStateEast);

		if (!(renderUp || renderDown || renderEast || renderWest || renderNorth || renderSouth)) {
			info.cancel();
		}
	}
}

It appears that this issue stems from net/minecraft/world/level/block/grower/TreeGrower, which has the following code:

   private boolean hasFlowers(final LevelAccessor level, final BlockPos pos) {
      for (BlockPos p : MutableBlockPos.betweenClosed(pos.below().north(2).west(2), pos.above().south(2).east(2))) {
         if (level.getBlockState(p).is(BlockTags.FLOWERS)) {
            return true;
         }
      }

      return false;
   }

This scans a 5x5x2 area around the sapling and returns true if a #minecraft:flowers block is within that area. Potted flowers are separate blocks that are under #minecraft:flower_pots, so they never get checked.

Issue occurring in 26.1 Snapshot 6.

My only modification to video settings was setting my FOV to 90. Information about system specifications can be seen from within the debug screen in the video and what I've already provided in the environment field

Still in 1.21.11 according to MC-306132

You mentioned shaders and mods within your bug description. Please note that this tracker only accepts reports for unmodified versions of the game, so therefore this issue is invalid.

Can confirm:

[media: Replay 2026-02-02 18-17-33 - Trim.mp4]

Can confirm for 1.21.11 and 26.1 Snapshot 5

[media: 2026-02-02 17-54-35.mp4]
[media: 2026-02-02 17-55-49.mp4]

Can confirm, really odd

[media: 2026-02-02 17-43-21.mp4]

Bred trader llamas still use the TraderLlama despawn timer. TraderLlama sets int despawnDelay = 47999;. Breeding (makeNewLlama with BREEDING) doesn’t disable despawning. Every tick aiStep() calls this.maybeDespawn(), and because the baby is not tamed by default canDespawn() stays true and with the timer counting down eventuallydiscard() is called. The canDespawn() check returns false if the llama is tamed, leashed to something other than the wandering trader, or has a player passenger.

Occurs in 1.21.11 where the advance_time gamerule is set false first (no time pause):

[media: 2026-02-02 16-48-36.mp4]

Load more comments