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

Entities from old (<= 1.5.2) worlds are killed when loaded in current versions due to a typo in the health data fixer

    Details

    • Type: Bug
    • Status: Resolved
    • Resolution: Fixed
    • Affects Version/s: Minecraft 1.9.1, Minecraft 1.9.2, Minecraft 1.9.4, Minecraft 1.10
    • Fix Version/s: Minecraft 1.10.1
    • Labels:
      None
    • Confirmation Status:
      Confirmed

      Description

      Entities in old worlds (created in versions older than 1.6, IE anything before or including 1.5.2) spontaneously die when loaded in Minecraft 1.10 or 1.9.4. This shouldn't happen, and they do not die if they were created (or more specifically saved) in a newer version before being loaded in 1.9.4.

      This is caused by a typo in the health data fixer, which attempts to use a nonexistent tag named Heath (sic) if it cannot find a HealF tag.

      Reproduction

      1. Create a world in Minecraft 1.5.2 (or an earlier version). (Alternatively, download the attached one: World from 1_5_2.zip from MC-103753).
      2. Spawn/find some animals or monsters and make sure that you are in front of them.
      3. Save and quit.
      4. Load the world in Minecraft 1.10.
      5. Observe the animals die right before your very eyes! (The death animation plays, but it is quick, so you might miss it).
      6. Attempt to reproduce in 1.6 instead of 1.5 (possibly using World from 1_6_4.zip from MC-103753); it will not happen there.

      Cause

      This is caused by a typo in the data fixer used to replace the HealF tag with the Health tag. It looks like its logic is to first check if there is a HealF tag, and then if so, use that value for the float Health tag. If there is no HealF tag, it first looks for a Health tag, and if that doesn't exist, it cancels the operation (there is no data for it to fix). But if there is a Health tag (which would be a short rather than a float as it is now), it tries to get the value of a tag named Heath (sic). Since that tag does not exist, it always gets a value of 0. It then uses that value and assigns it to a float tag named Health, which means that it gives the entity 0 health, killing it (this process does work with HealF though).

      The HealF tag was introduced in 1.6, and prior to that a Health tag using a short was used; in 1.9 (specifically, 15w33a) the Health tag was changed to a float and HealF was deprecated.

      Code

      Here's an annotated version of the relevant code snippet with MCP 1.9.4 names. In 1.10, this method is obfuscated as pi.a(dr).

      net.minecraft.util.datafix.fixes.EntityHealth
      public NBTTagCompound fixTagCompound(NBTTagCompound compound) {
          // ENTITY_LIST contains basically everything that extends EntityLivingBase (animals, monsters, and armorstands)
          if (ENTITY_LIST.contains(compound.getString("id"))) {
              float f;
      
              if (compound.hasKey("HealF", 99)) {
                  // Use the value of the HealF tag (99 in hasKey means "of any type")
                  f = compound.getFloat("HealF");
                  compound.removeTag("HealF");
              } else {
                  if (!compound.hasKey("Health", 99)) {
                      // If there is neither a Health nor a HealF tag, there isn't any data that can be recovered; abort
                      return compound;
                  }
                  // In older versions, there was a Health tag that used a short, which was replaced by the HealF tag that used a float
      
                  // TYPO here - it checks for the Health tag but uses a nonexistent Heath tag
                  // getFloat returns 0 if the tag does not exist
                  f = compound.getFloat("Heath");
              }
      
              // Use the previously acquired value
              compound.setFloat("Health", f);
          }
      
          return compound;
      }
      

      Fix

      Simply correct the Heath typo in the health data fixer. There is no way to recover entities that were killed when fixed by this fixer, however. (But if they were never loaded, then they will be fine).

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                grum [Mojang] Grum (Erik Broes)
                Reporter:
                Kademlia Kademlia
              • Votes:
                2 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  CHK: