mojira.dev
MC-269005

Player heads from previous versions cause game crash and/or are converted incorrectly

Incorrect Conversion

Player heads in previous versions could have a SkullOwner.Name set to an invalid username, such as a string with spaces, special characters, or more than 16 characters. This was commonly used to allow head names to persist when placed and broken again, due to MC-174496. When updating a world to the latest snapshot, all items with such data turn into plain player heads with no skin texture information, due to the entire minecraft:profile item component being invalidated.

Even if invalid usernames must be removed during conversion, the skin texture should at least remain. Currently it does not.

Game Crashes

Despite that, player heads placed down in block form remain the same: they are able to keep their texture and invalid player name. Therefore, when the player head block is broken, it drops a player head item with an invalid component:

[media]

Trying to use /data get entity @s SelectedItem while holding this invalid item results in the following error:

[media]

Furthermore, trying to save & quit the world results in a game crash:

[media]

Reproduction Steps

  1.  In a 1.20.4 creative world, use a command block to run the following command. This gives you the Elder Guardian head from the https://vanillatweaks.net/ "More Mob Heads" data pack (meaning many players will have this exact item in survival mode).

    give @p minecraft:player_head{SkullOwner:{Id:[I;1449915152,-149469738,-1161669070,1520260531],Name:"Elder Guardian",Properties:{textures:[{Value:"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNGEyZDY0ZjRhMDBlOWM4NWY2NzI2MmVkY2FjYjg0NTIzNTgxYWUwZjM3YmRhYjIyZGQ3MDQ1MjRmNjJlMTY5ZiJ9fX0="}]}},BlockEntityTag:{note_block_sound:"minecraft:entity.elder_guardian.ambient"}}
  1. Place the head down, but keep it in your inventory too.

  2. Upgrade the world to the latest snapshot.

  3. Observe that all the head in your inventory has become a plain player head with no profile component texture at all.

  4. Enter /gamemode survival.

  5. Break the head and pick it up.

  6. Log out of the world. The game crashes.

Possible Solutions

I believe the most backwards-compatible solution would be to once again allow invalid player names on player heads. (With the Vanilla Tweaks "More Mob Heads" pack, for example, this allows newly obtained mob heads to continue stacking with old heads, and perfectionist players who want the "real" head won't be dissatisfied with a mob head merely called "Player Head".)

But if for some reason that can't be done, then at worst, the conversion should only remove the player name part of the component, rather than deleting the entire head texture, because otherwise a lot of heads will just be lost. And at best, the old player name could somehow be converted into a display name on the item, provided there isn't already one set. (Using "More Mob Heads" as an example again, otherwise this would result in a lot of upset players losing difficult-to-obtain mob heads in their head collections. They will just turn into Steve.)

If necessary, the same conversion should be applied to player head block entity data as well, to prevent invalid item components from being generated when the block is broken.

Linked issues

Attachments

Comments 4

I'd also like to add some context to make you aware of how widely used the old behavior (SkullOwner.Name can contain any string) is and why it is so widely used; Vanilla Tweaks mentioned in the above issue is not the only use case, it is merly an example.

Another Example

Gamemode 4 also uses that behavior to repair its player heads when placed down (exact link to the mcfunction library responsible).

Why Is This Behavior So Useful to the mcfunction Community?

When a player head is placed down (before snapshot 24w09a) two properties from the player head item are conserved: SkullOwner.Name and SkullOwner.Properties.textures[0].
These are two very special tags to us, as player heads are often used as a form of custom item that has an in-built texture without needing a resource pack, and we don't want those to break when a player places them down, breaks them, and picks them back up!
Hence each player head used as such an item must use one of these two tags and insert a unique value so that once the placed down player head is broken and on ground in item form, commands can restore the rest of its NBT to the default state of that custom item (e.g. lore or just some other NBT data).

So why do we prefer matching a unique value in SkullOwner.Name instead of simply matching the texture? It's because the texture is not necessarily unique! There may be multiple of these custom player heads that share a texture, but are restored to different custom heads (e.g. different lores).
Apart from that, using SkullOwner.name also allows us to put a nice '[Drop to Fix]' in the name, so in case a player picks up the player head before the commands got around to fixing, the player is instructed to drop it again.

Over the years the community has settled on a de-facto standard where we store unique strings, usually even namespaced by our datapacks and with a '[Drop to Fix]' message in front, in the SkullOwner.Name to allow us to restore the skulls when they are placed and subsequently broken. Such a string may look like '[Drop to Fix] gm4_metallurgy:arborenda_shamir'.

As you can see, these strings may be very long (longer than 16 characters for sure!) and use non-ascii characters. As a result, these are definitely not real player names, and they're not meant to be! The fact that SkullOwner.Name can have invalid player names is something we really value a lot.

I hope this could add some much needed context.

@unknown It sounds like that use case could be addressed if Minecraft instead saved all item components in the tile entity, right? Similarly to MC-174496 but for more than just display name.

Grant Yes, if the game saved all the data from the player head item on the tile entity and properly restored the item to that data when the player head block is broken, we wouldn't need to do any of this.

In that case it would be fine if SkullOwner.Name can only contain real player names.

@Bloo only really if they were data fixed properly too

GrantGryczan

gegy

Confirmed

Platform

Very Important

Commands, Crash, Datafixer

24w09a

24w10a

Retrieved