mojira.dev
MC-91727

loot table "spreading large stacks" will overwrite existing items

The bug

Item stacks with a count > 1 generated by loot tables are spread into multiple smaller item stacks even if there is not enough place in the container resulting in a loss of items and the following warning message:

[Server thread/WARN]: Tried to over-fill a container

How to reproduce

  1. Create a loot table which generates 27 item stacks, with some of them having a count > 1

    {
        "pools": [
            {
                "rolls": 24,
                "entries": [
                    {
                        "type": "item",
                        "name": "minecraft:iron_sword",
                        "weight": 1
                    }
    	    ]
    	},
            {
                "rolls": 3,
                "entries": [
                    {
                        "type": "item",
                        "name": "minecraft:torch",
                        "functions": [
                            {
                                "function": "set_count",
                                "count": 16
                            }
                        ],
                        "weight": 1
                    }
                ]
            }
        ]
    }
  2. Save it for example in a data pack under \data\loot_tables\custom\test_loot_table.json

  3. Load the world and place a chest with the loot table

    /setblock ~ ~ ~ chest{LootTable:"custom:test_loot_table"}
  4. Open the chest
    → You will notice that it contains less than 24 swords, but the torch item stacks are split into more than 3. Additionally a warning should appear in the log: "[Server thread/WARN]: Tried to over-fill a container"

Code analysis and suggested fix

Based on 1.11.2 decompiled using MCP 9.35 rc1

The problem is that the method net.minecraft.world.storage.loot.LootTable.shuffleItems(List<ItemStack>, int, Random) only calculates the amount of free slots once and not in every iteration and additionally the amount of stacks which should be split is not subtracted.

Suggested fix

/**
 * shuffles items by changing their order and splitting stacks
 *
 * @param p_186463_2_ Free slots in container
 */
private void shuffleItems(List<ItemStack> stacks, int p_186463_2_, Random rand)
{
    // Comment: "list" contains the item stacks to split
    List<ItemStack> list = Lists.<ItemStack>newArrayList();
    Iterator<ItemStack> iterator = stacks.iterator();

    while (iterator.hasNext())
    {
        ItemStack itemstack = (ItemStack)iterator.next();

        if (itemstack.isEmpty())
        {
            iterator.remove();
        }
        else if (itemstack.getCount() > 1)
        {
            list.add(itemstack);
            iterator.remove();
        }
    }

    // Comment: Removed this and moved it in the loop condition
    // p_186463_2_ = p_186463_2_ - stacks.size();

    // while (p_186463_2_ > 0 && ((List)list).size() > 0)
    while ((p_186463_2_ - stacks.size() - list.size()) > 0 && ((List)list).size() > 0)
    {
        ItemStack itemstack2 = (ItemStack)list.remove(MathHelper.getInt(rand, 0, list.size() - 1));
        int i = MathHelper.getInt(rand, 1, itemstack2.getCount() / 2);
        ItemStack itemstack1 = itemstack2.splitStack(i);

        if (itemstack2.getCount() > 1 && rand.nextBoolean())
        {
            list.add(itemstack2);
        }
        else
        {
            stacks.add(itemstack2);
        }

        if (itemstack1.getCount() > 1 && rand.nextBoolean())
        {
            list.add(itemstack1);
        }
        else
        {
            stacks.add(itemstack1);
        }
    }

    stacks.addAll(list);
    Collections.shuffle(stacks, rand);
}

Attachments

Comments 23

Note that this is similar to MC-91310 which they just fixed, which is another instance of 'DeathLootTable's being exact, whereas chest 'LootTable's were "lossy". So I expect this bug is an unintended thing they will fix, since they fixed the other similar issue.

Still present in 15w45a

This is your ticket, please update the affected versions yourself instead of leaving a comment.

Confirmed for 15w50a

I've seen this happen with vanilla loot tables. Like when I go to a nether fortress, often, I find gold ingots, all in stacks of one, spread throughout the chest.

13 more comments

You do realize this was fixed all the wayback in 1.13, right?

Im working on a datapack and I guess the issue is becuase the items are being spread, other items are failing to be added if there's no room left. Basically, this bug but backwards. If you have the torches placed first, they spread so there's not enough room for everything else/.

Should I post a new bug report?

Aceplante, unfortunately I can't reproduce your bug. Spreading is done after all rolls have been made. Please verify your datapack and if you still find the bug present in latest stable or snapshot version, feel free to create a new bug report with steps to reproduce. Thank you.

@@unknown, to me it sounds like you are requesting the behavior which was originally considered a bug here. It appears there can either be the current behavior of omitting items if there is no free space, or overwriting existing ones, but not both.
You can create a new bug report (please refer to this one then), but most likely the Mojang developers will close it as "Works as Intended" or similar.

Brian McNamara

Nathan Adams

Confirmed

container, count, item, item-stack, loot-table, split

Minecraft 15w44b, Minecraft 15w45a, Minecraft 15w46a, Minecraft 15w47c, Minecraft 15w50a, ..., Minecraft 1.11.2, Minecraft 17w06a, Minecraft 1.12.2, Minecraft 18w03b, Minecraft 1.13-pre5

Minecraft 1.13-pre6

Retrieved