mojira.dev
MC-179998

Items With Same Lore Won't Stack

So, my friends and I have Schlatt Coins that we use as currency. Each Schlatt Coin is a Gold Nugget, named "Schlatt Coin", which the Lore "The Server's Currency", to ensure that the item is a legitimate Schlatt Coin. We have been having this issue for a while in 1.15.2. Originally, we had a custom villager that can trade Schlatt Coins to and from diamonds. We noticed that the villager often would not work when translating Schlatt Coins back into diamonds. We then started to notice that Schlatt Coins created on different visits to the custom villager would not stack correctly. We then decided that it was not worth it to try and handle the buggy villager, so we got rid of the villager's ability to give items back, as people were losing Schlatt Coins and not getting items back. I then tried to create an item sorting machine at the market which would take items, verify that they were Schlatt Coins, and activate a command block that would give the player diamonds when they dropped Schlatt Coins in the hopper. That didn't work either. It would take Schlatt Coins that were in the original stack that the Schlatt Coins inside the item sorter was from, but none from any other stack.

I will attempt to describe how to replicate the issue, but I will warn you that this is the strangest bug I have ever come across in my 5 years of playing Minecraft. So it may not work as expected originally. Here are the steps you may use to reproduce the issue:

  1. Summon a custom villager with the following command: /summon villager ~ ~ ~ {VillagerData:{profession:cleric,level:99,type:plains},Invulnerable:1,PersistenceRequired:1,Silent:1,NoAI:1,CustomName:"\"Jebidiah Schlatt\"",Offers:{Recipes:[{buy:{id:diamond,Count:20},sell:{id:gold_nugget,Count:1,tag:{display:{Name:"\"Schlatt Coin\"",Lore:["\"The Server's Currency\""]}}},maxUses:9999999},{buy:{id:gold_nugget,Count:1,tag:{display:{Name:"\"Schlatt Coin\"",Lore:["\"The Server's Currency\""]}}},sell:{id:diamond,Count:20}

  2. Trade 20 diamonds for a Schlatt Coin from the villager

  3. Now, use the following command to give yourself a Schlatt Coin: /give @s gold_nugget{display:{Name:"[{\"text\":\"Schlatt Coin\"}]",Lore:["[{\"text\":\"The Server's Currency\"}]}} 1

  4. Attempt to stack the two coins together. It may appear to work, but it may separate when you leave the inventory GUI. It may also work because this bug is incredibly unpredictable.

  5. Use the same command in step 3 to generate a third Schlatt Coin, now attempt to trade the Schlatt Coin with the villager. It shouldn't work. You may have to do a little bit of mangling with this one. If it works at first, try and stack two of the Schlatt Coins together, and trade with the villager.

PS. I will note here that we use a Paper server. When experimenting with this issue, I took all of the plugins and datapacks away from the server. I then switched to a vanilla 1.15.2 server. I then verified again with the villager. I also made sure that there were no custom NBT tags from any of the plugins or datapacks which may have interfered with the Schlatt Coins. The only NBT tags we are using are the renaming and the lore.

Linked issues

Attachments

Comments 9

See MC-124186. You can fix this by ensuring that all forms of the item contain the full canonically structured and ordered text component

I verified this issue and made sure that the structure and order of the text components were correct. No dice. It still causes the same issue. Will somebody please reopen this report!

I can confirm that on Spigot 1.14.4.

I use codegen to create an item and a villager which accepts the item for buy in, and sells the same item as another recipe. The trade breaks in a weird way, I can't take the item from the right slot, and the moment I click it, all of the "buy" items dissapear from inventory until the trade is closed. The only stable behavior I can reproduce is that if an item is bought from the villager itself, it works fine during that trade session. If I take the same item I've just bought and throw it on the ground, then pick up, or relog to the server with the same item in inventory right after purchase, - it's not accepted by the same trader anymore. I've compared both item's NBT (acquired from vendor immediately and in the next session) with `data entity get @s SelectedItem` and it's identical to the point of symbols I can see in console, so it seems there is some hidden data which breaks the comparison. Previously there was an issue with 'Damage' tag, might it reappear? It also doesn't reproduce for every item, but can't see the pattern. It's (I think) less likely to break the trade on items that do not stack originally, which is not directly related to the issue. I can confirm that it has to do with `display` tag, as any common item works perfectly even with custom (hidden) NBT, like {currency:"Coin"} and matches correctly, but custom named items definetely have some comparison issues, and it seems that it has to do with villager trade particularly, as `clear` command and other command-based interactions work perfectly.  Also spawning the villager from scratch during the same session seems to fix the first trade, but not the following ones. I haven't found any way to debug this further, but there are like 10 different threads on reddit regarding that issue, and anecdotal evidence suggests that certain scenarios like that we working until 1.14 but collapsed afterwards. I believe that helps and the issue should be reopened 

P.S. And yes, we shouldn't be comparing items by names, but how else we let the player know which item the villager wants? 

Okay, here's the (almost) minimum reproducible case on 1.14.4:

Edit: I've reassembled all the JSON Text components in accordance to what my particular server implementation returns in `data entity get @s SelectedItem`, creating identical and uniform order of attributes, as suggested above, which fixed most of issues, but some state condition still remains and is desribed here

I have a fancy golden ingot (or any stackable item, basically)

give @p minecraft:gold_ingot{display:{Lore:['{"italic":false,"color":"gold","text":"My Coin"}'],Name:'{"bold":true,"italic":false,"color":"yellow","text":"My Coin"}'},Enchantments:[{id:"minecraft:vanishing_curse",lvl:1}],"custom":"1"} 1

 

 

and a vendor which offers an enchanted elytra in exchange for a basic one + my fancy golden ingot (formatted for convinience)

summon villager ~ {Rotation:[180f,0f],CustomName:'[{"text":"My Vendor","color":"red","bold":true}]',CustomNameVisible:1,
VillagerData:{profession:"minecraft:fletcher",level:6,type:"minecraft:swamp"},CanPickUpLoot:0,PersistenceRequired:1,NoAI:1,Silent:1,Invulnerable:1,Attributes:[{Name:"generic.maxHealth",Base:99999}],Offers:{Recipes:[
{

buy:{id:"minecraft:gold_ingot",Count:1,tag:{display:{Lore:['{"italic":false,"color":"gold","text":"My Coin"}'],Name:'{"bold":true,"italic":false,"color":"yellow","text":"My Coin"}'},Enchantments:[{id:"minecraft:vanishing_curse",lvl:1}],"custom":"1"}},

buyB:{id:"elytra",Count:1},

maxUses:999999,

sell:{id:"elytra",Count:1,tag:{display:{Name:'[{"text":"Fancy Item","italic":false,"color":"gold","bold":true}]',Lore:['[{"text":"With a description","italic":false,"color":"yellow"}]']},Enchantments:[{id:"binding_curse",lvl:1}]}},

xp:0,
rewardExp:0b,
specialPrice:0,
priceMultiplier:0,
demand:0
}]}}

I have an elytra, then I run the first function, then attempt the trade. The recipe fills in as if it is vaild and works. Then I run the function again few more times, so I have an excess of ingots. And then I do `time add 1000s` several times to skip a night, and boom - the trade stops working with those "old" ingots, but works fine if I create new ones with the function, or even get them from another trade. I'm being the only person on server during that experiment. I didn't manage to measure the exact time, it's probably connected to some runtime procedures. I can verify that hard restarting the server while having the item in my inventory breaks the trade next time i log in (3 out of 3 attempts), while it was working right before. Yet again, the item created once more from scratch - works, while the one created on previous session doesn't.

Gonna do some more tests with `Age` tags, just in case, but that's most definitely a hidden state issue which affects only villager trades. Now we need to find out if it's a particular implementation issue, I suppose, so please try reproducing. @Frank Hawk

@ALEKSANDER USKOV On my server we've pretty much given up on the whole Schlatt Coin idea by now, but I am willing to peer review this idea myself. I figure it is probably in the benefit of the general public that this issue gets fixed, so I am going to head onto my Redstone world right now and see if I can reproduce the issue with the code you have sent me. Hopefully, we can get the attention of Mojang so they can fix this issue and the mods will unresolve it.

Spigot does make this problem more prominent:
https://hub.spigotmc.org/jira/browse/SPIGOT-5063 (more specifically https://hub.spigotmc.org/jira/browse/SPIGOT-5656)

Please comment if you encounter items with exactly equal data that aren't stacking in a vanilla environment

@ALEKSANDER USKOV I am running 1.16.1 on my Singleplayer Redstone world. Your implementation seems to work fine. I will also attempt to run it on a Vanilla Minecraft server. I'm not going to try and run it on Bukkit/Spigot/Paper because those are modded servers and not officially supported by Mojang.

@ALEKSANDER USKOV Just after I posted that last message, the page reloaded and I noticed that a Moderator had given a bug report for that problem occurring on Spigot. It was something that I was worried about. I loaded up the previous world on a Vanilla environment, but obviously the data must not have been canonicalized by Spigot, and the issue transferred over to vanilla. I guess the problem is a Spigot issue after all.

@ALEKSANDER USKOV Like I said, we have gotten rid of the Schlatt Coins on my server, mainly because it was practically impossible to chase down the issue. That and we don't really have enough time to handle something minor like that so we just replaced it with Netherite Scraps when 1.16 rolled out. We're still a small server, but we are big enough that we have to deal with bigger problems like people and bigger issues with plugins and stuff. If you find the answer to the problem, send it my way. We probably won't be implementing the Schlatt Coins back anytime soon, but I would like to know what was going on in case I ever have to do something similar in the future. You can add me on Discord:

Poopoo head#6025

Frank Hawk

(Unassigned)

Unconfirmed

(Unassigned)

1.15.2

Retrieved