Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-111339

Certain animated entities stutter inside of spawners

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • None
    • Minecraft 1.11, Minecraft 16w50a, Minecraft 1.11.1, Minecraft 1.11.2, Minecraft 17w06a, Minecraft 17w13b, Minecraft 17w14a, Minecraft 17w15a, Minecraft 17w16a, Minecraft 17w17b, Minecraft 17w18a, Minecraft 17w18b, Minecraft 1.12 Pre-Release 1, Minecraft 1.12 Pre-Release 2, Minecraft 1.12 Pre-Release 3, Minecraft 1.12 Pre-Release 4, Minecraft 1.12 Pre-Release 5, Minecraft 1.12 Pre-Release 6, Minecraft 1.12 Pre-Release 7, Minecraft 1.12, Minecraft 17w31a, Minecraft 1.12.1 Pre-Release 1, Minecraft 1.12.1, Minecraft 1.12.2 Pre-Release 1, Minecraft 1.12.2 Pre-Release 2, Minecraft 1.12.2, Minecraft 17w43a, Minecraft 17w43b, Minecraft 17w45a, Minecraft 17w46a, Minecraft 17w48a, Minecraft 18w01a, Minecraft 18w03b, Minecraft 18w06a, Minecraft 18w09a, Minecraft 18w10d, Minecraft 18w14b, Minecraft 1.13-pre1, Minecraft 1.13-pre3, Minecraft 1.13-pre6, Minecraft 1.13-pre10, Minecraft 1.13, Minecraft 18w30b, Minecraft 18w31a, Minecraft 18w33a, Minecraft 1.13.1, 1.14.4, 19w45b, 20w46a, 21w03a, 1.16.5, 21w05b, 21w06a
    • Confirmed
    • Block states, Rendering

      The bug

      Certain entities render weirdly in when inside spawners, stuttering backwards. This happens both while the spawner is active and while the spawner is not active, but is generally much easier to see when it's not active (since the stutter happens quite quickly).

      Affected entities

      Here's a table of the various situations where this can be found.

      The WF column indicates whether or not my suggested fix would solve the issue for this entity. If , then it's solved completely; in most cases when it's it's solved for when the spawner is not spinning and partialTicks is unused but not solved when partialTicks is used.

      The L column refers to the location where the offending code is. R means the renderer: a direct reference to partialTicks. M means the model: A reference to ageInTicks, which is generated via RenderLivingBase.handleRotationFloat.

      Entity WF L Depends on Spawner NBT Notes
      Charged creeper R ticksExisted
      {SpawnData:{id:"minecraft:creeper",powered:1}}
      Charge "armor" translates sideways as a function of time
      jeb_ sheep R ticksExisted
      {SpawnData:{id:"minecraft:sheep",CustomName:"jeb_"}}
      jeb_ sheep easter egg: wool cycles through all colors. Almost impossible to notice due to the partialTicks portion being very small, but detectable by comparing RGB values between screenshots.
      Wither aura R ticksExisted
      {SpawnData:{id:"minecraft:wither",Health:1}}
      Low health "armor" translates sideways as a function of time
      Arrow shaking R arrowShake
      {SpawnData:{id:"minecraft:arrow",shake:7}}
      While it does normally shake, the shake is supposed to be sinusoidal, not rapidly alternating like that.
      Dying entities R deathTime
      {SpawnData:{id:"minecraft:pig",Health:0,DeathTime:1}}
      Logic present both for regular entities and dragons specifically
      Shulker bullet R ticksExisted
      {SpawnData:{id:"minecraft:shulker_bullet"}}
      Spins around
      Lit TNT Minecart R fuseTicks
      {SpawnData:{id:"minecraft:tnt_minecart",TNTFuse:0}}
      Most notable with fuse of 1, but present for all values under 10. Fuse must be specified, though, or else it defaults to -1.
      Primed TNT R fuse
      {SpawnData:{id:"minecraft:tnt"}}
      TNT expands
      Ender crystal R innerRotation
      {SpawnData:{id:"minecraft:ender_crystal"}}
      Crystal rotation; stutter isn't significant
      Bat M ticksExisted
      {SpawnData:{id:"minecraft:bat"}}
      Bat flapping wings
      Blaze M ticksExisted
      {SpawnData:{id:"minecraft:blaze"}}
      Blaze rods
      Ender crystal (2) M ticksExisted
      {SpawnData:{id:"minecraft:ender_crystal"}}
      Crystal height; stutter is significant
      Endermite M ticksExisted
      {SpawnData:{id:"minecraft:endermite"}}
      Model swaggering
      Ghast tentacles M ticksExisted
      {SpawnData:{id:"minecraft:ghast"}}
      Ghast tentacles
      Guardian spikes M ticksExisted
      {SpawnData:{id:"minecraft:guardian"}}
      Only noticeable if inside the guardian model itself (spectator mode), though slightly visible from outside
      Silverfish M ticksExisted
      {SpawnData:{id:"minecraft:silverfish"}}
      Model swaggering
      Vex wings M ticksExisted
      {SpawnData:{id:"minecraft:vex"}}
       
      Phantom wings/tail M ticksExisted
      {SpawnData:{id:"minecraft:phantom"}}
       

      To reproduce

      You need to have over 20 frames per second to see this effect in-game. If your FPS is locked at or below 20 it will be more or less impossible to notice.

      The non-spinning-spawner variant of this issue is much easier to reproduce.

      1. Switch to spectator mode (/gamemode 3), so that the spawner doesn't spin even if you're close
      2. Use /setblock ~ ~ ~ minecraft:mob_spawner replace with the given data to create the appropriate spawner.
      3. Observe the spawner. In some cases, you'll need to fly really close (or even inside) the spawner to see the effect

      To reproduce with a spinning version, add Delay:10000 to the spawner NBT such that the spawner spins extremely slowly. (Previously, I recommended using cheat engine to slow the game, but dragonofthelakeabcd suggested this better way).

      1. Switch to creative mode (/gamemode 1).
      2. Use /setblock ~ ~ ~ minecraft:mob_spawner replace with the given data to create the appropriate spawner.
      3. Watch the spawner, trying to see the stutter while it's spinning.

      Cause

      These entities all have an animation that occurs as a function of both a variable on the entity (usually the time it has existed for) and the distance into the current tick (partialTicks). The reliance on partialTicks is what causes it to stutter, while the reliance on the time it has existed for is what causes it to not advance to the next part of the animation.

      Suggested fix

      There is no real good fix for this, but the best fix I can come up with is tweaking the way spawners render so that when the spawner is spinning, ticksExisted is updated, and when it is not spinning, partialTicks is always set to 0. That way, the animations play normally when the spawner is spinning, and when it isn't spinning, it doesn't attempt to animate a nonexistent animation.

      This could be done by adding this code into MobSpawnerBaseLogic.updateSpawner (ajg.c, line 62):

      if (cachedEntity != null) {
          // This null check may be unneeded.
          // Update the entity's existence ticks, for rendering purposes
          cachedEntity.ticksExisted++;
      }
      

      And then also adding this code into TileEntityMobSpawnerRenderer.renderMob (bsn.a, line 17):

      if (!mobSpawnerLogic.isActivated()) {
          // Don't interpolate the position if the spawner isn't rotating
          partialTicks = 0;
      }
      

      This doesn't help with all entities, but it does solve it for the common of them.

      An alternative fix would be to always use partialTicks set to 0, even if the spawner is spinning. This will prevent any kind of issue, but in my opinion is a slightly less interesting graphical effect.

            Unassigned Unassigned
            pokechu22 [Mod] Pokechu22
            Votes:
            14 Vote for this issue
            Watchers:
            10 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: