KubeJS-Mods / KubeJS

https://kubejs.com
GNU Lesser General Public License v3.0
307 stars 90 forks source link

InputItem serializes to only the item, ignores count despite supporting count #845

Open JoelGanson opened 3 months ago

JoelGanson commented 3 months ago

Minecraft Version

1.20.1

KubeJS Version

2001.6.5-build.7

Rhino Version

2001.2.2-build.18

Architectury Version

9.2.14

Forge/Fabric Version

Forge 47.2.30

Describe your issue

I'm trying to set up recipeSchemaRegistry for a mod that supports stacked items in its machine's recipes. Particularly, Biomancy's Bio Forge.

According to what we know, the following KubeJS Startup code should work:

const $RecipeSchema = Java.loadClass(
  "dev.latvian.mods.kubejs.recipe.schema.RecipeSchema"
);
const $RecipeComponentBuilder = Java.loadClass(
  "dev.latvian.mods.kubejs.recipe.component.RecipeComponentBuilder"
);

StartupEvents.recipeSchemaRegistry((event) => {
  const Components = event.components;
  const result = Components.get("outputItem")().key("result");
  const input = Components.get("inputItemArray")()
    .key("ingredients");

  event.register(
    "biomancy:bio_forging",
    new $RecipeSchema(
      result,
      input,
      Components.get("intNumber")().key("nutrientsCost"),
      Components.get("anyString")().key("bio_forge_tab")
    )
  );
});

// This didn't work, because for some reason it ignores the item count now.

The following recipe in Server Events was used to test:

let r = event.recipes.biomancy
    .bio_forging(
      "bleed4me:steroidal_explosion",
      [
        Item.of("minecraft:potion", { Potion: "minecraft:regeneration" }),
        Ingredient.of("biomancy:exotic_dust", 6),
        InputItem.of("biomancy:flesh", 10),
        "10x biomancy:fibrous_flesh",
        { item: "minecraft:iron_block", count: 3 },
      ],
      10,
      "biomancy:misc"
    )
    .id("bleed4me:steroidal_explosion");
  r.serialize();
  console.log(r.json);

However, when InputItem is serialized, despite InputItem.of() accepting a count, it does not return the count, as evidenced by this part of KubeJS's code

Supporting Discord thread

Crash report/logs

No response

ChiefArug commented 3 months ago

This happens because the InputItem RecipeComponent delegates to RecipeJS#writeInputItem and RecipeJS#readInputItem: https://github.com/KubeJS-Mods/KubeJS/blob/fc38ad01dc7b98683bbdfc9aed1dbd727cf684b4/common/src/main/java/dev/latvian/mods/kubejs/recipe/component/ItemComponents.java#L38-L46

For writing, RecipeJS delegates to the Ingredient, which won't write the count because that is held in the InputItem. For reading it delegates to InputItem#of, which will actually read the count if it is there (I misread that in the Discord thread). https://github.com/KubeJS-Mods/KubeJS/blob/fc38ad01dc7b98683bbdfc9aed1dbd727cf684b4/common/src/main/java/dev/latvian/mods/kubejs/recipe/RecipeJS.java#L611-L618

MaxNeedsSnacks commented 3 months ago

This is intentional, as (up to 1.20.4), there is no unified standard for serialising ingredient stacks and some recipes actively broke if there was an invalid field present in the ingredient. You would need to override writeInputItem to respect the count (probably serialising it as "amount" or "count"?) in your schema using a custom recipe class

ChiefArug commented 3 months ago

Rip writing schemas from scripts.

JoelGanson commented 3 months ago

You would need to override writeInputItem to respect the count (probably serialising it as "amount" or "count"?) in your schema using a custom recipe class

Can confirm that the recipes I'm looking for use "count", so how would one go about doing this?