Farmer's Delight

Farmer's Delight

77M Downloads

Cooking Pot's interface does not check stack counts for ingredients

vectorwing opened this issue ยท 8 comments

commented

Description

As of now, the Cooking Pot only verifies each slot for the presence of a given ingredient, not its count. The six slots must match the given recipe by spreading ingredients across each other - that means that Beetroot Soup can only be made with one Beetroot in each slot, but not with 3 Beetroots stacked in a single slot.

This is both a design and automation problem, as nothing prevents datapack creators from allowing multiples of the same ingredient in a Cooking recipe. Say we want the pot to receive items from Hoppers - a hopper cannot round-robin the slots, and even if it could, it could end up clogging the inputs with six carrots before other types of ingredients, invalidating the recipe.

To do a deep check for ingredients, we run into a bigger logic puzzle that may result in ambiguity checks and performance issues. Simibubi raised some possibilities about the problem, though I'm unsure how practical the solution would be to implement.

Steps to reproduce

Attempt to prepare Beetroot Soup in the Cooking pot in the following ways:

  • Place 1 Beetroot in each slot - Success
  • Place 6 Beetroots in one slot - Failure
commented

Hello, I noticed the "help wanted" sign and thought I'd step in...

Matching stacks of input against ingredients seems to have a serious scaling problem, which you mentioned. Minecraft's RecipeMatcher class performs (up to) an exhaustive search of matches, but it assumes that the stack count matches the ingredient count, and that the number of ingredients doesn't exceed 9 items. Input stacks could be flattened and ingredients faked, but that would quickly exceed the 9-item limit. Maybe ingredients could be aggregated, but there's no way to ensure the input stacks are the right size to match. For example, an input of 2 beetroots + 1 beetroot doesn't match a recipe of 1 beetroot + 1 beetroot + 1 beetroot and it also doesn't match a test against 3 beetroots. Whichever way you slice it, RecipeMatcher probably won't help, and I can't imagine myself discovering a way to avoid the n! math of matching partial stacks of items.

With that in mind, could the problem itself be reconsidered?

This is both a design and automation problem, as nothing prevents datapack creators from allowing multiples of the same ingredient in a Cooking recipe. Say we want the pot to receive items from Hoppers - a hopper cannot round-robin the slots, and even if it could, it could end up clogging the inputs with six carrots before other types of ingredients, invalidating the recipe.

Could this be seen as a need for a new item rather than as a problem with the Cooking Pot? Maybe the Cooking Pot's limits are reasonable, and it's the job of a new block or item to simplify things. For example, the Item Router in the mod Modular Routers is able to handle round-robin moving of items. Would Farmer's Delight benefit from a new block that could do just that?

Or, what if Farmer's Delight has a Cookbook item that references one recipe: When a Cookbook is in the Cooking Pot's input, the Pot only accepts additional input that matches that recipe. When the output is produced, the Cookbook stays in the input, allowing the Pot to automate one recipe. This only avoids part of the scaling problem (ingredients still need to match the input), but maybe there is a similar, simpler solution out there.

Or, if the Pot is the problem, maybe the input slots could accept stacks only 1 item deep. The Smelter in Tinker's Construct uses this restriction to prevent dealing with (or even displaying) stacks. It would also fit the theme of the Pot: It can only hold so much at once, so you'd better spread the ingredients around. No need to unstack input, so there's no more concern about scaling. As before, this only addresses one angle, but...

Anyway, I think it's an interesting problem and I hope I wasn't out of line for commenting. ๐Ÿ‘‹

commented

Quick comment about changing the Cooking Pot's slot depth to 1 item: It does solve the automation problem. Here is a before-and-after, auto-cooking Beetroot Soup using Applied Energistics 2 blocks...

Automating the Cooking Pot with 64-deep slots (current functionality):

cookingpot-deep-slots.mp4

Automating the Cooking Pot with 1-deep slots:

cookingpot-shallow-slots.mp4
commented

Add "Lock Recipe" button. Just a small button with tooltip "Lock Recipe" or something like that.

If recipe is locked:

  • Cooking Pot only accepts this items
  • Empty slots don't accept items at all
  • If there is no items: item slots show transparent version of locked items.

Similar button has the Dissolution Chamber from Industrial Foregoing, but it only accepts one item at a time per slot.
I don't think this little button will confuse people. The tooltip shows what it's doing. It's intuitive.

image

It will really help if you just export items into the Cooking Pot. For example with vanila hopper of any other method.
Now you have to use Regulator Upgrade from Refined Storage, LaserIO, Item Transporter from Industrial Foregoing or any similar thing that allows you to limit amout of exported items.

It will also help to do autocrafts. If you request 2 stacks of some cooked food, with locked recipe Cooking Pot won't accept more than one stack of one ingridient.

However it doesn't solve the issue if some recipe has two identical ingredients, like Tomato Sauce.
But at least it will work if you just export tomatoes with hopper for example. Eventually all two stacks will be filled and crafting will begin.
I think Lock Recipe button is still better than nothing.

I can't believe that this issue is 2 years old and there is no good solution for this problem.

It's really panful to automate food production with this great mod right now.

commented

is there a reason why you don't just make a list of all the items inside of the cooking pot and match it with the json

like

for (Itemstack stack : stuff_in_cooking_pot) {
        ArrayList<ItemStack> stuff = new ArrayList<>();
         if (stuff.contains(stack)) {
                int i = stuff.indexOf(stack);
                stuff.set(i, new ItemStack(stack.getItem, stuff.get(i).getCount + stack.getCount));
        }
        else {
                stuff.add(stack);
        }
} 
commented

it's obviously not going to be that simple. but im just curious on why you can't do it like that

commented

Quick comment about changing the Cooking Pot's slot depth to 1 item: It does solve the automation problem. Here is a before-and-after, auto-cooking Beetroot Soup using Applied Energistics 2 blocks...

Automating the Cooking Pot with 64-deep slots (current functionality):

cookingpot-deep-slots.mp4
Automating the Cooking Pot with 1-deep slots:

cookingpot-shallow-slots.mp4

hi, can you please tell that how you managed to edit the stack of the pot? thanks

commented

Hmm, sure! It could even allow cooking recipes to be more expensive than six ingredients.
Although I am a little fearful that this change may make it less intuitive to experiment with ingredients. We'll have to test it a bunch.

commented

I might work on this but I'd need to change recipe format. Is that a possible option?
For example:

"ingredients": [
    {
      "item": "minecraft:beetroot"
    },
    {
      "item": "minecraft:beetroot"
    },
    {
      "item": "minecraft:beetroot"
    }
  ],

changed to:

"ingredients": [
    {
      "item": "minecraft:beetroot",
      "count": 3
    }
  ],