Jump to content

Recommended Posts

Posted (edited)

I'm somewhat of a beginner at forge and I'm trying to add custom recipe types to my mod. I've been trying to adapt the solution from https://www.youtube.com/watch?v=IOFbegpYY0k and update it to 1.20.2 with the help of the forge docs without success.

Does anyone know anything about creating such behaviour? Any help would be appreciated.

My recipe is a simple recipe similar to the legacy smithing recipe, heres a JSON example (the "//" will be replaced with some items):

{
  "type": "magic_overhaul:rune_inscribing",
  "base": {
    "item": "//base item"
  },
  "template": {
    "item": "//template item"
  },
  "output": {
    "count": 1,
    "item": "//output item"
  }
}

What I'm interested most is how to implement the RecipeSerializer and RecipeType classes within my Recipe class.

Here's my current RecipeSerializer:

Spoiler
public static class Serializer implements RecipeSerializer<RuneInscribingRecipe> {
        private static final Codec<RuneInscribingRecipe> CODEC = RecordCodecBuilder.create(
                (builder) -> builder.group(
                        Ingredient.CODEC.fieldOf("template").forGetter(RuneInscribingRecipe::getTemplate),
                        Ingredient.CODEC.fieldOf("base").forGetter(RuneInscribingRecipe::getBase),
                        ItemStack.CODEC.fieldOf("output").forGetter((RuneInscribingRecipe recipe) -> recipe.output)
                ).apply(builder, RuneInscribingRecipe::new));


        public Serializer() {

        }

        @Override
        public Codec<RuneInscribingRecipe> codec() {
            return CODEC;
        }


        @Override
        public @Nullable RuneInscribingRecipe fromNetwork(FriendlyByteBuf friendlyByteBuf) {
            Ingredient base = Ingredient.fromNetwork(friendlyByteBuf);
            Ingredient template = Ingredient.fromNetwork(friendlyByteBuf);

            ItemStack output = friendlyByteBuf.readItem();

            return new RuneInscribingRecipe(base, template, output);
        }

        @Override
        public void toNetwork(FriendlyByteBuf friendlyByteBuf, RuneInscribingRecipe runeInscribingRecipe) {
            runeInscribingRecipe.base.toNetwork(friendlyByteBuf);
            runeInscribingRecipe.template.toNetwork(friendlyByteBuf);

            friendlyByteBuf.writeItemStack(runeInscribingRecipe.output, false);
        }
    }

 

Here's the RecipeType:

Spoiler
public static class Type implements RecipeType<RuneInscribingRecipe> {
        @Override
        public String toString() {
            return MagicOverhaul.MOD_ID + ":rune_inscribing";
        }
    }

 

 

Please comment if you need any more code fragments.

Edited by JacksStuff
Posted
1 hour ago, dee12452 said:

I don't spot anything obvious. Can you post the code where you register the serializer?

public class ModRecipes {
    public static final DeferredRegister<RecipeSerializer<?>> SERIALIZERS =
            DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, MagicOverhaul.MOD_ID);

    public static final RegistryObject<RecipeSerializer<RuneInscribingRecipe>> RUNE_INSCRIBING_SERIALIZER =
            SERIALIZERS.register("rune_inscribing", () -> new RuneInscribingRecipe.Serializer());


    public static void register(IEventBus eventBus){
        SERIALIZERS.register(eventBus);
    }
}

 

Posted
29 minutes ago, dee12452 said:

Yeah this looks good, alright post all of `RuneInscribingRecipe`

Spoiler
public class RuneInscribingRecipe implements Recipe<SimpleContainer> {
    private final Ingredient base;
    private final Ingredient template;
    private final ItemStack output;


    public RuneInscribingRecipe(Ingredient base, Ingredient template, ItemStack output) {
        this.base = base;
        this.template = template;
        this.output = output;
    }

    @Override
    public boolean matches(SimpleContainer simpleContainer, Level level) {
        if (level.isClientSide()) {
            return false;
        }

        return base.test(simpleContainer.getItem(RuneInscriberMenu.BASE_INPUT_SLOT)) && template.test(simpleContainer.getItem(RuneInscriberMenu.TEMPLATE_INPUT_SLOT));
    }

    @Override
    public ItemStack assemble(SimpleContainer simpleContainer, RegistryAccess registryAccess) {
        return output.copy();
    }

    @Override
    public boolean canCraftInDimensions(int i, int i1) {
        return true;
    }

    @Override
    public ItemStack getResultItem(RegistryAccess registryAccess) {
        return output.copy();
    }


    @Override
    public RecipeSerializer<?> getSerializer() {
        return ModRecipes.RUNE_INSCRIBING_SERIALIZER.get();
    }


    public Ingredient getTemplate() {
        return this.template;
    }

    public Ingredient getBase() {
        return this.base;
    }


    @Override
    public RecipeType<?> getType() {
        return new Type();
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }



    public static class Type implements RecipeType<RuneInscribingRecipe> {
        @Override
        public String toString() {
            return MagicOverhaul.MOD_ID + ":rune_inscribing";
        }
    }


    public static class Serializer implements RecipeSerializer<RuneInscribingRecipe> {
        private static final Codec<RuneInscribingRecipe> CODEC = RecordCodecBuilder.create(
                (builder) -> builder.group(
                        Ingredient.CODEC.fieldOf("template").forGetter(RuneInscribingRecipe::getTemplate),
                        Ingredient.CODEC.fieldOf("base").forGetter(RuneInscribingRecipe::getBase),
                        ItemStack.CODEC.fieldOf("output").forGetter((RuneInscribingRecipe recipe) -> recipe.output)
                ).apply(builder, RuneInscribingRecipe::new));


        public Serializer() {

        }

        @Override
        public Codec<RuneInscribingRecipe> codec() {
            return CODEC;
        }


        @Override
        public @Nullable RuneInscribingRecipe fromNetwork(FriendlyByteBuf friendlyByteBuf) {
            Ingredient base = Ingredient.fromNetwork(friendlyByteBuf);
            Ingredient template = Ingredient.fromNetwork(friendlyByteBuf);

            ItemStack output = friendlyByteBuf.readItem();

            return new RuneInscribingRecipe(base, template, output);
        }

        @Override
        public void toNetwork(FriendlyByteBuf friendlyByteBuf, RuneInscribingRecipe runeInscribingRecipe) {
            runeInscribingRecipe.base.toNetwork(friendlyByteBuf);
            runeInscribingRecipe.template.toNetwork(friendlyByteBuf);

            friendlyByteBuf.writeItemStack(runeInscribingRecipe.output, false);
        }
    }
}

 

 

Posted

There's a couple of discrepancies between my 1.20.2 implementation that's working and yours here but nothing I'd imagine is directly causing an issue. 

What's the exact problem that's happening? Is there a crash? Are you using a custom crafting menu you made from scratch (i.e. a new class that likely extends AbstractContainerMenu + a screen to go along with it)?  

Posted (edited)
6 hours ago, dee12452 said:

There's a couple of discrepancies between my 1.20.2 implementation that's working and yours here but nothing I'd imagine is directly causing an issue. 

What's the exact problem that's happening? Is there a crash? Are you using a custom crafting menu you made from scratch (i.e. a new class that likely extends AbstractContainerMenu + a screen to go along with it)?  

1.The game doesn't crash, everything seems normal, but when i insert the designated items into the block entity, the result item does not show up.

2.Yes, I'm using a custom menu, here's the source code:

Spoiler
public class RuneInscriberMenu extends AbstractContainerMenu {
    private final RuneInscriberBlockEntity blockEntity;
    private final ContainerLevelAccess levelAccess;
    private final ItemStackHandler inventory;

    public static final int BASE_INPUT_SLOT = 0;
    public static final int TEMPLATE_INPUT_SLOT = 1;
    public static final int OUTPUT_SLOT = 2;

    private ArrayList<ItemStack> stored = new ArrayList<>();



    //Client Constructor
    public RuneInscriberMenu(int pContainerId, Inventory inv, FriendlyByteBuf extraData) {
        this(pContainerId, inv, inv.player.level().getBlockEntity(extraData.readBlockPos()));
    }

    //Server Constructor
    public RuneInscriberMenu(int pContainerId, Inventory inv, BlockEntity entity) {
        super(ModMenuTypes.RUNE_INSCRIBER_MENU.get(), pContainerId);
        if (entity instanceof RuneInscriberBlockEntity be) {
            this.blockEntity = be;
        }
        else {
            throw new IllegalStateException("Incorrect block entity class (%s) passed into RuneInscriberMenu".formatted(entity.getClass().getCanonicalName()));
        }

        this.levelAccess = ContainerLevelAccess.create(blockEntity.getLevel(), blockEntity.getBlockPos());
        this.inventory = blockEntity.getInventory();
        createPlayerHotbar(inv);
        createPlayerInventory(inv);
        createBlockEntityInventory(blockEntity);
    }





    @Override
    public ItemStack quickMoveStack(Player playerIn, int pIndex) {
        Slot fromSlot = getSlot(pIndex);
        ItemStack fromStack = fromSlot.getItem();

        if(fromStack.getCount() <= 0)
            fromSlot.set(ItemStack.EMPTY);

        if(!fromSlot.hasItem())
            return ItemStack.EMPTY;

        ItemStack copyFromStack = fromStack.copy();

        if(pIndex < 36) {
            // We are inside of the player's playerInventory
            if(!moveItemStackTo(fromStack, 36, 37, false))
                return ItemStack.EMPTY;
        } else if (pIndex < 63) {
            // We are inside of the block entity playerInventory
            if(!moveItemStackTo(fromStack, 0, 36, false))
                return ItemStack.EMPTY;
        } else {
            System.err.println("Invalid slot index: " + pIndex);
            return ItemStack.EMPTY;
        }

        fromSlot.setChanged();
        fromSlot.onTake(playerIn, fromStack);

        return copyFromStack;
    }

    private boolean isEmpty() {
        return inventory.getStackInSlot(BASE_INPUT_SLOT).isEmpty() &&
                inventory.getStackInSlot(TEMPLATE_INPUT_SLOT).isEmpty() &&
                inventory.getStackInSlot(OUTPUT_SLOT).isEmpty();
    }

    private boolean isCrafted = false;

    @Override
    public boolean stillValid(Player player) {
        return stillValid(this.levelAccess, player, ModBlocks.RUNE_INSCRIBER.get());
    }


    public RuneInscriberBlockEntity getBlockEntity() {
        return blockEntity;
    }

    private boolean hasRecipe() {
        Optional<RecipeHolder<RuneInscribingRecipe>> recipe = getCurrentRecipe();

        if (recipe.isEmpty()) {
            return false;
        }

        return !isEmpty() &&
                recipe.get().value().getBase().test(inventory.getStackInSlot(RuneInscriberMenu.BASE_INPUT_SLOT)) &&
                recipe.get().value().getTemplate().test(inventory.getStackInSlot(RuneInscriberMenu.TEMPLATE_INPUT_SLOT));
    }

    private void suggestCraft()
    {

        if (!hasRecipe()) {
            clearOutput();
            return;
        }
        Optional<RecipeHolder<RuneInscribingRecipe>> recipe = getCurrentRecipe();
        ItemStack result = recipe.get().value().getResultItem(this.blockEntity.getLevel().registryAccess());


        blockEntity.getInventory().setStackInSlot(OUTPUT_SLOT, result);
    }

 
    private void craft() {
        Optional<RecipeHolder<RuneInscribingRecipe>> recipe = getCurrentRecipe();
        blockEntity.getInventory().setStackInSlot(BASE_INPUT_SLOT, new ItemStack(Items.AIR));
        isCrafted = true;
    }


	//Clears the output item from the block entity inventory
    private void clearOutput() {
        ItemStack stack = inventory.getStackInSlot(OUTPUT_SLOT);
        stack.shrink(1);
        inventory.setStackInSlot(OUTPUT_SLOT, stack);
    }

    @Override
    public void removed(Player pPlayer) {
        clear(pPlayer, blockEntity.getInventory().getStackInSlot(BASE_INPUT_SLOT));
        clear(pPlayer, blockEntity.getInventory().getStackInSlot(TEMPLATE_INPUT_SLOT));
        isEmpty();
        if (isCrafted) {
            clear(pPlayer, blockEntity.getInventory().getStackInSlot(OUTPUT_SLOT));
        }
        clearOutput();

        super.removed(pPlayer);
    }

	//Clears the item from the block entity inventory
    private void clear(Player pPlayer, ItemStack stack) {
        if (pPlayer instanceof ServerPlayer) {
            if (!stack.isEmpty()) {
                if (pPlayer.isAlive() && !((ServerPlayer) pPlayer).hasDisconnected()) {
                    pPlayer.getInventory().placeItemBackInInventory(stack);
                } else {
                    pPlayer.drop(stack, false);
                }
                stored.clear();
            }
        }
    }



    private Optional<RecipeHolder<RuneInscribingRecipe>> getCurrentRecipe() {
        SimpleContainer inventory = new SimpleContainer(2);
        inventory.setItem(BASE_INPUT_SLOT, this.inventory.getStackInSlot(BASE_INPUT_SLOT));
        inventory.setItem(TEMPLATE_INPUT_SLOT, this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT));
        List<RecipeHolder<RuneInscribingRecipe>> list = this.blockEntity.getLevel().getRecipeManager().getRecipesFor(new RuneInscribingRecipe.Type(), inventory, this.blockEntity.getLevel());
        if (list.isEmpty()) {
            return Optional.empty();
        }

        return Optional.of(list.get(0));
    }


    private void createBlockEntityInventory(RuneInscriberBlockEntity be) {
        be.getOptional().ifPresent(inventory -> {
            this.addSlot(new SlotItemHandler(inventory, BASE_INPUT_SLOT, 26, 35) {
                @Override
                public void setChanged() {
                    if (getItem().is(Tags.Items.STONE)) {
                        suggestCraft();
                    }
                    else {
                        clearOutput();
                    }
                    super.setChanged();
                }


                @Override
                public boolean mayPlace(@NotNull ItemStack stack) {
                    return stack.is(Tags.Items.STONE);
                }


                @Override
                public int getMaxStackSize() {
                    return 1;
                }

                @Override
                public int getMaxStackSize(@NotNull ItemStack stack) {
                    return 1;
                }
            });

            this.addSlot(new SlotItemHandler(inventory, TEMPLATE_INPUT_SLOT, 80, 35) {
                @Override
                public void setChanged() {
                    suggestCraft();
                    super.setChanged();
                }


                @Override
                public boolean mayPlace(@NotNull ItemStack stack) {
                    return stack.is(ModTags.Items.RUNE_TEMPLATES);
                }


                @Override
                public int getMaxStackSize() {
                    return 1;
                }

                @Override
                public int getMaxStackSize(@NotNull ItemStack stack) {
                    return 1;
                }
            });

            this.addSlot(new RuneOutputSlot(inventory, OUTPUT_SLOT, 133, 35));
        });
    }

    private void createPlayerInventory (Inventory playerInventory) {
        for (int row = 0; row < 3; row++) {
            for (int column = 0; column < 9; column++) {
                this.addSlot(new Slot(playerInventory, 9 + column + row * 9, 8 + column * 18, 84 + row * 18));
            }
        }
    }


    private void createPlayerHotbar (Inventory playerInventory) {
        for (int column = 0; column < 9; column++) {
            this.addSlot(new Slot(playerInventory, column, 8 + column * 18, 142));
        }
    }

    public class RuneOutputSlot extends SlotItemHandler {

        public RuneOutputSlot(IItemHandler itemHandler, int index, int xPosition, int yPosition) {
            super(itemHandler, index, xPosition, yPosition);
        }

        @Override
        public void setChanged() {
            if (this.hasItem())
                craft();
            super.setChanged();
        }

        @Override
        public void onTake(Player pPlayer, ItemStack pStack) {
            super.onTake(pPlayer, pStack);
        }


        @Override
        public boolean mayPlace(@NotNull ItemStack stack) {
            return false;
        }
    }

}

 

 

Edited by JacksStuff
Posted (edited)

Ok yeah I think this might be where the problem starts.

For starters, I think you can get rid of your RecipeType impl and make it a static constant instead. I'm not 100% sure this will fix it but it's posssible.

RuneInscribingRecipe

    public class RuneInscribingRecipe implements Recipe<SimpleContainer> {
        public static final RecipeType<RuneInscribingRecipe> RECIPE_TYPE = new RecipeType<>(){};
        
        // ....

        @Override
        public RecipeType<?> getType() {
            return RECIPE_TYPE;
        }
        
        // ....
    }

RuneInscriberMenu

    private Optional<RecipeHolder<RuneInscribingRecipe>> getCurrentRecipe() {
        SimpleContainer inventory = new SimpleContainer(2);
        inventory.setItem(BASE_INPUT_SLOT, this.inventory.getStackInSlot(BASE_INPUT_SLOT));
        inventory.setItem(TEMPLATE_INPUT_SLOT, this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT));
        List<RecipeHolder<RuneInscribingRecipe>> list = this.blockEntity.getLevel().getRecipeManager().getRecipesFor(RuneInscribingRecipe.RECIPE_TYPE, inventory, this.blockEntity.getLevel());
        if (list.isEmpty()) {
            return Optional.empty();
        }

        return Optional.of(list.get(0));
    }

 

Also, this here is a little suspicious where you're getting the `this.inventory.getStackInSlot` calls. I'd try and make sure those are what you expect they are with either a Debug line in IDE or print statement

SimpleContainer inventory = new SimpleContainer(2);
inventory.setItem(BASE_INPUT_SLOT, this.inventory.getStackInSlot(BASE_INPUT_SLOT));
System.out.printf("CHECKING BASE INPUT OF RECIPE: %s\n", this.inventory.getStackInSlot(BASE_INPUT_SLOT));
inventory.setItem(TEMPLATE_INPUT_SLOT, this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT));
System.out.printf("CHECKING TEMPLATE INPUT OF RECIPE: %s\n", this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT));

^ See what the result of those print statements are, make sure they're right

Edited by dee12452
Remove potential false info
Posted
2 hours ago, dee12452 said:

Ok yeah I think this might be where the problem starts.

For starters, I think you can get rid of your RecipeType impl and make it a static constant instead. I'm not 100% sure this will fix it but it's posssible.

RuneInscribingRecipe

    public class RuneInscribingRecipe implements Recipe<SimpleContainer> {
        public static final RecipeType<RuneInscribingRecipe> RECIPE_TYPE = new RecipeType<>(){};
        
        // ....

        @Override
        public RecipeType<?> getType() {
            return RECIPE_TYPE;
        }
        
        // ....
    }

RuneInscriberMenu

    private Optional<RecipeHolder<RuneInscribingRecipe>> getCurrentRecipe() {
        SimpleContainer inventory = new SimpleContainer(2);
        inventory.setItem(BASE_INPUT_SLOT, this.inventory.getStackInSlot(BASE_INPUT_SLOT));
        inventory.setItem(TEMPLATE_INPUT_SLOT, this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT));
        List<RecipeHolder<RuneInscribingRecipe>> list = this.blockEntity.getLevel().getRecipeManager().getRecipesFor(RuneInscribingRecipe.RECIPE_TYPE, inventory, this.blockEntity.getLevel());
        if (list.isEmpty()) {
            return Optional.empty();
        }

        return Optional.of(list.get(0));
    }

 

Also, this here is a little suspicious where you're getting the `this.inventory.getStackInSlot` calls. I'd try and make sure those are what you expect they are with either a Debug line in IDE or print statement

SimpleContainer inventory = new SimpleContainer(2);
inventory.setItem(BASE_INPUT_SLOT, this.inventory.getStackInSlot(BASE_INPUT_SLOT));
System.out.printf("CHECKING BASE INPUT OF RECIPE: %s\n", this.inventory.getStackInSlot(BASE_INPUT_SLOT));
inventory.setItem(TEMPLATE_INPUT_SLOT, this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT));
System.out.printf("CHECKING TEMPLATE INPUT OF RECIPE: %s\n", this.inventory.getStackInSlot(TEMPLATE_INPUT_SLOT));

^ See what the result of those print statements are, make sure they're right

Thanks for the suggestions, but nothing seemed to change after applying them. Also the "this.inventory.getStackInSlot" thing prints the correct items.

Posted

Hm yeah sorry, not seeing anything else that's sticking out, I'd need to debug myself probably. Do you have a github or bitbucket repo? I could poke around when I have time to see what the problem might be.

Posted

Sure, I'm sorry I couldn't be more helpful so far.

 

 Does this always return empty?

List<RecipeHolder<RuneInscribingRecipe>> list = this.blockEntity.getLevel().getRecipeManager().getRecipesFor(RuneInscribingRecipe.RECIPE_TYPE, inventory, this.blockEntity.getLevel());

 

Posted
10 minutes ago, dee12452 said:

Sure, I'm sorry I couldn't be more helpful so far.

 

 Does this always return empty?

List<RecipeHolder<RuneInscribingRecipe>> list = this.blockEntity.getLevel().getRecipeManager().getRecipesFor(RuneInscribingRecipe.RECIPE_TYPE, inventory, this.blockEntity.getLevel());

 

Yeah, always an empty list, I checked multiple times. 

Posted
{
  "type": "magic_overhaul:rune_inscribing",
  "base": {
    "item": "//base item"
  },
  "template": {
    "item": "//template item"
  },
  "output": {
    "count": 1,
    "item": "//output item"
  }
}

^ Ok, where is your recipe JSON placed in your file structure? What's it called? And paste the actual JSON you're testing with, because it needs to be valid.

Posted
14 hours ago, dee12452 said:
{
  "type": "magic_overhaul:rune_inscribing",
  "base": {
    "item": "//base item"
  },
  "template": {
    "item": "//template item"
  },
  "output": {
    "count": 1,
    "item": "//output item"
  }
}

^ Ok, where is your recipe JSON placed in your file structure? What's it called? And paste the actual JSON you're testing with, because it needs to be valid.

I accidentally forgot to push the recent changes, so all the stuff about the recipes is missing from github. Just fixed that. The JSON is located in the data/magic_overhaul/recipes folder and looks like this:

{
  "type": "magic_overhaul:rune_inscribing",
  "base": {
    "item": "minecraft:stone"
  },
  "template": {
    "item": "magic_overhaul:rune_template_acnar"
  },
  "output": {
    "count": 1,
    "item": "magic_overhaul:rune_acnar"
  }
}

 

Posted

@JacksStuff looks like at least one of your problems is your recipe JSON. ItemStack's CODEC isn't defined the way you're thinking it is. Try this instead

{
  "type": "magic_overhaul:rune_inscribing",
  "base": {
    "item": "minecraft:stone"
  },
  "template": {
    "item": "magic_overhaul:rune_template_acnar"
  },
  "output": {
    "Count": 1,
    "id": "magic_overhaul:rune_acnar"
  }
}

 

Posted
16 hours ago, chxr said:

Im running on a similar problem. Codecs are hurting my head more than they should

Yeah CODECs are super funky the first time you start working with them, I definitely had a few woes in the beginning when moving to 1.20.2. What's the JSON structure of your recipe? I'm sure either I or ChatGPT can whip you up a CODEC for it pretty quickly lol.

Posted
2 hours ago, dee12452 said:

Yeah CODECs are super funky the first time you start working with them, I definitely had a few woes in the beginning when moving to 1.20.2. What's the JSON structure of your recipe? I'm sure either I or ChatGPT can whip you up a CODEC for it pretty quickly lol.

Funny enough, Chatgpt is confusing me even more. My BE works like a furnace, you need 8 items and two fuel to make a third item. Here is an example recipe. In this case, 8 aberrant shards, each one in one slot, and two of aberrant fuel, each one on one slot for a total of 10 slots. Supposedly any block with the tag aberrant_fuel should be accepted but im not sure this is how the json should look:

 

{
  "type": "relativedimensions:particle_rebound",
  "inputItem": [
    {
      "item": "relativedimensions:aberrant_shard"
    }
  ],
  "fuelItem": [
    {
      "tag": "relativedimensions:block/aberrant_fuel"
    }
  ],
  "output": {
    "Count": 1,
    "id": "relativedimensions:aberrant_ingot"
  }
}

 

Posted

@chxr

Looks like you're making some sort of a crafting table / furnace hybrid? Are the inputs needing arranging like a shaped recipe, or is it shapeless?

I'll assume it's shapeless since that just adds a lot more complexity. In that case I'd probably do something like this

{
  "type": "relativedimensions:particle_rebound",
  "inputs": [
    {
      "ingredient": {
        "item": "relativedimensions:aberrant_shard"
      },
      "count": 8
    }
  ],
  "fuel": {
    "tag": "relativedimensions:block/aberrant_fuel"
  },
  "output": {
    "Count": 1,
    "id": "relativedimensions:aberrant_ingot"
  }
}

inputs: A list of ingredients and how many are needed. The count among each input adds up to 8. Since there's only 1 ingredient, the count is set to 8.

fuel: Same thing as before but remove the list and just make it an object with a tag.

output: Kept the same.

 

In this case the Codec I would make is

    public record ParticleReboundIngredient(Ingredient ingredient, int count) {
        public static final Codec<ParticleReboundIngredient> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(
                        Ingredient.CODEC.fieldOf("ingredient").forGetter((i) -> i.ingredient),
                        Codec.INT.fieldOf("count").forGetter(i -> i.count)
                ).apply(builder, ParticleReboundIngredient::new)
        );
    }
    
    public record ParticleReboundFuel(String tag) {
        public static final Codec<ParticleReboundFuel> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(Codec.STRING.fieldOf("tag").forGetter(f -> f.tag)).apply(builder, ParticleReboundFuel::new)
        );
        
        public boolean isFuel(ItemStack stack) {
            // TODO: Check if fuel item matches the tag
        }
    }

    public record ParticleReboundRecipe(List<ParticleReboundIngredient> inputs, ParticleReboundFuel fuel, ItemStack output) {
        public static final Codec<ParticleReboundRecipe> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(
                        ParticleReboundIngredient.CODEC.listOf().fieldOf("inputs").forGetter(r -> r.inputs),
                        ParticleReboundFuel.CODEC.fieldOf("fuel").forGetter(r -> r.fuel),
                        ItemStack.CODEC.fieldOf("output").forGetter(r -> r.output)
                ).apply(builder, ParticleReboundRecipe::new)
        );
    }

 

There might be a more proper Codec for the fuel and the tag that's built into minecraft / forge, but I didn't look

Posted (edited)

 

3 hours ago, dee12452 said:

@chxr

Looks like you're making some sort of a crafting table / furnace hybrid? Are the inputs needing arranging like a shaped recipe, or is it shapeless?

I'll assume it's shapeless since that just adds a lot more complexity. In that case I'd probably do something like this

{
  "type": "relativedimensions:particle_rebound",
  "inputs": [
    {
      "ingredient": {
        "item": "relativedimensions:aberrant_shard"
      },
      "count": 8
    }
  ],
  "fuel": {
    "tag": "relativedimensions:block/aberrant_fuel"
  },
  "output": {
    "Count": 1,
    "id": "relativedimensions:aberrant_ingot"
  }
}

inputs: A list of ingredients and how many are needed. The count among each input adds up to 8. Since there's only 1 ingredient, the count is set to 8.

fuel: Same thing as before but remove the list and just make it an object with a tag.

output: Kept the same.

 

In this case the Codec I would make is

    public record ParticleReboundIngredient(Ingredient ingredient, int count) {
        public static final Codec<ParticleReboundIngredient> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(
                        Ingredient.CODEC.fieldOf("ingredient").forGetter((i) -> i.ingredient),
                        Codec.INT.fieldOf("count").forGetter(i -> i.count)
                ).apply(builder, ParticleReboundIngredient::new)
        );
    }
    
    public record ParticleReboundFuel(String tag) {
        public static final Codec<ParticleReboundFuel> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(Codec.STRING.fieldOf("tag").forGetter(f -> f.tag)).apply(builder, ParticleReboundFuel::new)
        );
        
        public boolean isFuel(ItemStack stack) {
            // TODO: Check if fuel item matches the tag
        }
    }

    public record ParticleReboundRecipe(List<ParticleReboundIngredient> inputs, ParticleReboundFuel fuel, ItemStack output) {
        public static final Codec<ParticleReboundRecipe> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(
                        ParticleReboundIngredient.CODEC.listOf().fieldOf("inputs").forGetter(r -> r.inputs),
                        ParticleReboundFuel.CODEC.fieldOf("fuel").forGetter(r -> r.fuel),
                        ItemStack.CODEC.fieldOf("output").forGetter(r -> r.output)
                ).apply(builder, ParticleReboundRecipe::new)
        );
    }

 

There might be a more proper Codec for the fuel and the tag that's built into minecraft / forge, but I didn't look

Pretty much, although all the recipes im planning to make on it are shapeless. The idea is that the chamber uses energy to "fuse" the items in each of the center slots together, in this case an ingot. The two slots at the sides are fuel. (A special kind of wood in this case).

Here is an image of the interface just for reference (The center slot is the output)

spacer.png

 

As for the code- Can you elaborate a little bit on it? Seeing three different record classes has confused me a lot. (Elaborate as in why make them in three different records. I understand the code itself more or less)

Edited by chxr
Posted
35 minutes ago, chxr said:

 

Pretty much, although all the recipes im planning to make on it are shapeless. The idea is that the chamber uses energy to "fuse" the items in each of the center slots together, in this case an ingot. The two slots at the sides are fuel. (A special kind of wood in this case).

Here is an image of the interface just for reference (The center slot is the output)

spacer.png

 

As for the code- Can you elaborate a little bit on it? Seeing three different record classes has confused me a lot. (Elaborate as in why make them in three different records. I understand the code itself more or less)

That looks pretty cool, nice!

 

Sure, so looking at that JSON file I posted, I pretty much made a record class for each "custom" data type in that JSON. The Input is a good example of why

```

"inputs": [ { "ingredient": { "item": "relativedimensions:aberrant_shard" }, "count": 8 } ],

```

So here's the inputs, it's an array, which we can use the Codec builder's builder.listOf to define an array. Each Item is of some arbitrary object with keys "ingredient" (which we know is an Ingredient) and a "count" which is an int. You don't have to have an intermediate class to map this to necessarily but I found that it's just easier to see the data that way, hence the 'ParticleReboundIngredient' represents one of these inputs.

 

Let me know if that makes sense or not. 

Posted
33 minutes ago, dee12452 said:

That looks pretty cool, nice!

 

Sure, so looking at that JSON file I posted, I pretty much made a record class for each "custom" data type in that JSON. The Input is a good example of why

```

"inputs": [ { "ingredient": { "item": "relativedimensions:aberrant_shard" }, "count": 8 } ],

```

So here's the inputs, it's an array, which we can use the Codec builder's builder.listOf to define an array. Each Item is of some arbitrary object with keys "ingredient" (which we know is an Ingredient) and a "count" which is an int. You don't have to have an intermediate class to map this to necessarily but I found that it's just easier to see the data that way, hence the 'ParticleReboundIngredient' represents one of these inputs.

 

Let me know if that makes sense or not. 

It does but I'm struggling to see how to make it work in my recipe? (Its structure is the same as OP's, with a serializer subclass)

Posted
 public class ParticleReboundRecipe implements Recipe<CraftingContainer> {
   private List<ParticleReboundIngredient> inputs;
   private ParticleReboundFuel fuel; 
   private ItemStack output;
   
   public ParticleReboundRecipe(List<ParticleReboundIngredient> inputs, ParticleReboundFuel fuel, ItemStack output) {
     this.inputs = inputs;
     this.fuel = fuel;
     this.output = output;
   }
   
    // TODO: Implement interface ...
   
   // TODO: Move to separate file if desired
	public record ParticleReboundIngredient(Ingredient ingredient, int count) {
        public static final Codec<ParticleReboundIngredient> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(
                        Ingredient.CODEC.fieldOf("ingredient").forGetter((i) -> i.ingredient),
                        Codec.INT.fieldOf("count").forGetter(i -> i.count)
                ).apply(builder, ParticleReboundIngredient::new)
        );
    }
    
   // TODO: Move to separate file if desired
    public record ParticleReboundFuel(String tag) {
        public static final Codec<ParticleReboundFuel> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(Codec.STRING.fieldOf("tag").forGetter(f -> f.tag)).apply(builder, ParticleReboundFuel::new)
        );
        
        public boolean isFuel(ItemStack stack) {
            // TODO: Check if fuel item matches the tag
        }
    }
   
   public class Serializer implements RecipeSerializer<ParticleReboundRecipe> {
     public static final Codec<ParticleReboundRecipe> CODEC = RecordCodecBuilder.create(
       builder -> builder.group(
         ParticleReboundIngredient.CODEC.listOf().fieldOf("inputs").forGetter(r -> r.inputs),
         ParticleReboundFuel.CODEC.fieldOf("fuel").forGetter(r -> r.fuel),
         ItemStack.CODEC.fieldOf("output").forGetter(r -> r.output)
       ).apply(builder, ParticleReboundRecipe::new)
     );

     @Override
     public @NotNull Codec<ParticleReboundRecipe> codec() {
       return CODEC;
     }
     
     // TODO: The rest ...
   }
 }

 

?

Posted
14 hours ago, dee12452 said:
 public class ParticleReboundRecipe implements Recipe<CraftingContainer> {
   private List<ParticleReboundIngredient> inputs;
   private ParticleReboundFuel fuel; 
   private ItemStack output;
   
   public ParticleReboundRecipe(List<ParticleReboundIngredient> inputs, ParticleReboundFuel fuel, ItemStack output) {
     this.inputs = inputs;
     this.fuel = fuel;
     this.output = output;
   }
   
    // TODO: Implement interface ...
   
   // TODO: Move to separate file if desired
	public record ParticleReboundIngredient(Ingredient ingredient, int count) {
        public static final Codec<ParticleReboundIngredient> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(
                        Ingredient.CODEC.fieldOf("ingredient").forGetter((i) -> i.ingredient),
                        Codec.INT.fieldOf("count").forGetter(i -> i.count)
                ).apply(builder, ParticleReboundIngredient::new)
        );
    }
    
   // TODO: Move to separate file if desired
    public record ParticleReboundFuel(String tag) {
        public static final Codec<ParticleReboundFuel> CODEC = RecordCodecBuilder.create(
                builder -> builder.group(Codec.STRING.fieldOf("tag").forGetter(f -> f.tag)).apply(builder, ParticleReboundFuel::new)
        );
        
        public boolean isFuel(ItemStack stack) {
            // TODO: Check if fuel item matches the tag
        }
    }
   
   public class Serializer implements RecipeSerializer<ParticleReboundRecipe> {
     public static final Codec<ParticleReboundRecipe> CODEC = RecordCodecBuilder.create(
       builder -> builder.group(
         ParticleReboundIngredient.CODEC.listOf().fieldOf("inputs").forGetter(r -> r.inputs),
         ParticleReboundFuel.CODEC.fieldOf("fuel").forGetter(r -> r.fuel),
         ItemStack.CODEC.fieldOf("output").forGetter(r -> r.output)
       ).apply(builder, ParticleReboundRecipe::new)
     );

     @Override
     public @NotNull Codec<ParticleReboundRecipe> codec() {
       return CODEC;
     }
     
     // TODO: The rest ...
   }
 }

 

?

Yeah sorry i just managed to make it now, i shouldn't have tried to make it work in my head yesterday late at night. It correctly is recognizing the recipe. Im running on some other errors but they are now due to my recipe's inner workings and not the game not recognizing the recipe itself

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello support, I would like to tell you that I recently had troubles with getting into forge in Minecraft. I wanted to play with my friend a modpack in the game in version 1.20.1 when I downloaded it it crashed so we I started deleting some unnecessary mods to maybe lower the pressure if my PC is not good enough to run the modpack. But I went to delete every mod and installed a hole new version of forge with no mods installed or anything with it it still crashed. I found some help on the forms telling to download java 17 and install it on my windows so I did that and still couldn’t play because it crashes  The log files and everything I could find to help this problem is here : https://pastebin.com/9rWpANcW Hope your help arrives quickly
    • I'm testing a modpack for a server, and everything is fine, until I update the Aether mod from version "aether-1.20.1-1.4.2-neoforge" to version "aether-1.20.1-1.5.1-neoforge" now on the server it gives the error: Failed to load datapacks, can't proceed with server load. You can either fix your datapacks or reset to vanilla with --safeMode but in the game it says something different (scroll down) [21Nov2024 15:58:50.673] [main/WARN] [net.minecraft.server.Main/]: Failed to load datapacks, can't proceed with server load. You can either fix your datapacks or reset to vanilla with --safeMode 2002java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Failed to load registries due to above errors 2003at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396) ~[?:?] 2004at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2073) ~[?:?] 2005at net.minecraft.server.Main.main(Main.java:195) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2006at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] 2007at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?] 2008at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] 2009at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?] 2010at net.minecraftforge.fml.loading.targets.CommonLaunchHandler.runTarget(CommonLaunchHandler.java:111) ~[fmlloader-1.20.1-47.3.12.jar%2369!/:?] 2011at net.minecraftforge.fml.loading.targets.CommonLaunchHandler.serverService(CommonLaunchHandler.java:103) ~[fmlloader-1.20.1-47.3.12.jar%2369!/:?] 2012at net.minecraftforge.fml.loading.targets.CommonServerLaunchHandler.lambda$makeService$0(CommonServerLaunchHandler.java:27) ~[fmlloader-1.20.1-47.3.12.jar%2369!/:?] 2013at cpw.mods.modlauncher.LaunchServiceHandlerDecorator.launch(LaunchServiceHandlerDecorator.java:30) ~[modlauncher-10.0.9.jar%2355!/:?] 2014at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:53) ~[modlauncher-10.0.9.jar%2355!/:?] 2015at cpw.mods.modlauncher.LaunchServiceHandler.launch(LaunchServiceHandler.java:71) ~[modlauncher-10.0.9.jar%2355!/:?] 2016at cpw.mods.modlauncher.Launcher.run(Launcher.java:108) ~[modlauncher-10.0.9.jar%2355!/:?] 2017at cpw.mods.modlauncher.Launcher.main(Launcher.java:78) ~[modlauncher-10.0.9.jar%2355!/:?] 2018at cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:26) ~[modlauncher-10.0.9.jar%2355!/:?] 2019at cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:23) ~[modlauncher-10.0.9.jar%2355!/:?] 2020at cpw.mods.bootstraplauncher.BootstrapLauncher.main(BootstrapLauncher.java:141) ~[bootstraplauncher-1.1.2.jar:?] 2021Caused by: java.lang.IllegalStateException: Failed to load registries due to above errors 2022at net.minecraft.resources.RegistryDataLoader.m_247207_(RegistryDataLoader.java:77) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2023at net.minecraft.server.WorldLoader.m_246152_(WorldLoader.java:54) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2024at net.minecraft.server.WorldLoader.m_245736_(WorldLoader.java:58) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2025at net.minecraft.server.WorldLoader.m_214362_(WorldLoader.java:31) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2026at net.minecraft.server.Main.lambda$main$2(Main.java:167) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2027at net.minecraft.Util.m_214652_(Util.java:777) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2028at net.minecraft.Util.m_214679_(Util.java:772) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2029at net.minecraft.server.Main.main(Main.java:166) ~[server-1.20.1-20230612.114412-srg.jar%23535!/:?] 2030... 15 more   AND THE ERROR THAT THE GAME SAY WENT I WANT TO PLAY IN SOLO (local): Time: 2024-11-21 16:16:37 Description: mouseClicked event handler java.lang.IllegalStateException: Failed to load registries due to above errors     at net.minecraft.resources.RegistryDataLoader.m_247207_(RegistryDataLoader.java:77) ~[client-1.20.1-20230612.114412-srg.jar%23652!/:?] {re:mixin,pl:connector_pre_launch:A,re:classloading,pl:mixin:APP:bclib.mixins.common.json:RegistryDataLoaderMixin from mod bclib,pl:mixin:APP:lithostitched.mixins.json:common.RegistryDataLoaderMixin from mod lithostitched,pl:mixin:APP:zeta.mixins.json:RegistryDataLoaderMixin from mod zeta,pl:mixin:APP:fabric-registry-sync-v0.mixins.json:RegistryLoaderMixin from mod fabric_registry_sync_v0,pl:mixin:APP:together.mixins.common.json:RegistryDataLoaderMixin from mod bclib,pl:mixin:APP:connectormod.mixins.json:registries.RegistryDataLoaderMixin from mod connectormod,pl:mixin:A,pl:connector_pre_launch:A} at net.minecraft.server.WorldLoader.m_246152_(WorldLoader.java:54) ~[client-1.20.1-20230612.114412-srg.jar%23652!/:?] {re:mixin,pl:connector_pre_launch:A,re:classloading,pl:mixin:APP:together.mixins.common.json:WorldLoaderMixin from mod bclib,pl:mixin:A,pl:connector_pre_launch:A}     at net.minecraft.server.WorldLoader.m_245736_(WorldLoader.java:58) ~[client-1.20.1-20230612.114412-srg.jar%23652!/:?] {re:mixin,pl:connector_pre_launch:A,re:classloading,pl:mixin:APP:together.mixins.common.json:WorldLoaderMixin from mod bclib,pl:mixin:A,pl:connector_pre_launch:A}     at net.minecraft.server.WorldLoader.m_214362_(WorldLoader.java:31) ~[client-1.20.1-20230612.114412-srg.jar%23652!/:?] {re:mixin,pl:connector_pre_launch:A,re:classloading,pl:mixin:APP:together.mixins.common.json:WorldLoaderMixin from mod bclib,pl:mixin:A,pl:connector_pre_launch:A}     at net.minecraft.client.gui.screens.worldselection.CreateWorldScreen.m_232896_(CreateWorldScreen.java:125) ~[client-1.20.1-20230612.114412-srg.jar%23652!/:?] {re:mixin,pl:accesstransformer:B,pl:connector_pre_launch:A,pl:runtimedistcleaner:A,re:classloading,pl:accesstransformer:B,pl:mixin:APP:modernfix-common.mixins.json:perf.dedicated_reload_executor.CreateWorldScreenMixin from mod modernfix,pl:mixin:APP:modernfix-forge.mixins.json:bugfix.extra_experimental_screen.CreateWorldScreenMixin from mod modernfix,pl:mixin:APP:cumulus_menus.mixins.json:client.accessor.CreateWorldScreenAccessor from mod cumulus_menus,pl:mixin:APP:mediumcore.mixins.json:client.CreateWorldScreenMixin from mod mediumcore,pl:mixin:APP:aether.mixins.json:client.CreateWorldScreenMixin from mod aether,pl:mixin:APP:together.mixins.client.json:CreateWorldScreen_Mixin from mod bclib,pl:mixin:APP:fancymenu.mixins.json:client.MixinCreateWorldScreen from mod fancymenu,pl:mixin:A,pl:connector_pre_launch:A,pl:runtimedistcleaner:A}        
    • I just tried installing Forge version 1.21.3, and tried launching it with no mods installed. It loads, and immediately crashes while "loading bootstrap resourses." Does anyone know a fix for this? My Java is up to date, as well as my graphics drivers. Here's a snip right before it crashes: https://imgur.com/a/elLujPj
    • I know this is a forge only place, but just to be clear, my error is in Fabric I was actually super frustrated while trying to fix this, like this mod does work when I play it by launching it in minecraft, but when I was trying to install it onto the server it just kept crashing so I decided to delete every mod I've got but kept the bewitchment mod and the necessary mod it needs to function and I tried to run the server... But it somehow still crashed, and the thing is that I really do want the bewitchment mod to be in the SMP so it'll be SUPER helpful if anyone can figure out on how to fix this: It didn't give me any "crash-reports" so I'll be sending the logs and what the console said: Console: [18:51:46] [main/INFO]: SpongePowered MIXIN Subsystem Version=0.8.5 Source=file:/home/container/libraries/net/fabricmc/sponge-mixin/0.13.3+mixin.0.8.5/sponge-mixin-0.13.3+mixin.0.8.5.jar Service=Knot/Fabric Env=SERVER [18:51:46] [main/WARN]: Error loading class: io/github/apace100/origins/power/PreventItemUsePower (java.lang.ClassNotFoundException: io/github/apace100/origins/power/PreventItemUsePower) [18:51:46] [main/WARN]: @Mixin target io.github.apace100.origins.power.PreventItemUsePower was not found bewitchment.mixins.json:integration.origins.PreventItemUsePowerMixin from mod bewitchment [18:51:47] [main/INFO]: Initializing MixinExtras via com.llamalad7.mixinextras.service.MixinExtrasServiceImpl(version=0.3.5). [18:51:52] [main/FATAL]: Failed to start the minecraft server java.lang.RuntimeException: Could not execute entrypoint stage 'main' due to errors, provided by 'bewitchment'! at net.fabricmc.loader.impl.FabricLoaderImpl.lambda$invokeEntrypoints$2(FabricLoaderImpl.java:388) ~[fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.util.ExceptionUtil.gatherExceptions(ExceptionUtil.java:33) ~[fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.FabricLoaderImpl.invokeEntrypoints(FabricLoaderImpl.java:386) ~[fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.game.minecraft.Hooks.startServer(Hooks.java:63) ~[fabric-loader-0.15.11.jar:?] at net.minecraft.server.Main.main(Main.java:92) [server-intermediary.jar:?] at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470) [fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74) [fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.launch.knot.KnotServer.main(KnotServer.java:23) [fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.launch.server.FabricServerLauncher.main(FabricServerLauncher.java:69) [fabric-loader-0.15.11.jar:?] at net.fabricmc.installer.ServerLauncher.main(ServerLauncher.java:69) [server.jar:1.0.1] Caused by: java.lang.NoSuchFieldError: TEXTURE at moriyashiine.bewitchment.common.item.SpecterBangleItem.<clinit>(SpecterBangleItem.java:28) ~[bewitchment-1.16.5-18.jar:?] at moriyashiine.bewitchment.common.registry.BWObjects.<clinit>(BWObjects.java:272) ~[bewitchment-1.16.5-18.jar:?] at moriyashiine.bewitchment.common.Bewitchment.onInitialize(Bewitchment.java:221) ~[bewitchment-1.16.5-18.jar:?] at net.fabricmc.loader.impl.FabricLoaderImpl.invokeEntrypoints(FabricLoaderImpl.java:384) ~[fabric-loader-0.15.11.jar:?] ... 7 more Logs: https://mclo.gs/wSsqMfn
    • I know this is a forge only place, but just so you know my error is in Fabric I was actually super frustrated while trying to fix this, like this mod does work when I play it by launching it in minecraft, but when I was trying to install it onto the server it just kept crashing so I decided to delete every mod I've got but kept the bewitchment mod and the necessary mod it needs to function and I tried to run the server... But it somehow still crashed, and the thing is that I really do want the bewitchment mod to be in the SMP so it'll be SUPER helpful if anyone can figure out on how to fix this: It didn't give me any "crash-reports" so I'll be sending the logs and what the console said: Console: [18:51:46] [main/INFO]: SpongePowered MIXIN Subsystem Version=0.8.5 Source=file:/home/container/libraries/net/fabricmc/sponge-mixin/0.13.3+mixin.0.8.5/sponge-mixin-0.13.3+mixin.0.8.5.jar Service=Knot/Fabric Env=SERVER [18:51:46] [main/WARN]: Error loading class: io/github/apace100/origins/power/PreventItemUsePower (java.lang.ClassNotFoundException: io/github/apace100/origins/power/PreventItemUsePower) [18:51:46] [main/WARN]: @Mixin target io.github.apace100.origins.power.PreventItemUsePower was not found bewitchment.mixins.json:integration.origins.PreventItemUsePowerMixin from mod bewitchment [18:51:47] [main/INFO]: Initializing MixinExtras via com.llamalad7.mixinextras.service.MixinExtrasServiceImpl(version=0.3.5). [18:51:52] [main/FATAL]: Failed to start the minecraft server java.lang.RuntimeException: Could not execute entrypoint stage 'main' due to errors, provided by 'bewitchment'! at net.fabricmc.loader.impl.FabricLoaderImpl.lambda$invokeEntrypoints$2(FabricLoaderImpl.java:388) ~[fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.util.ExceptionUtil.gatherExceptions(ExceptionUtil.java:33) ~[fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.FabricLoaderImpl.invokeEntrypoints(FabricLoaderImpl.java:386) ~[fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.game.minecraft.Hooks.startServer(Hooks.java:63) ~[fabric-loader-0.15.11.jar:?] at net.minecraft.server.Main.main(Main.java:92) [server-intermediary.jar:?] at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470) [fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74) [fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.launch.knot.KnotServer.main(KnotServer.java:23) [fabric-loader-0.15.11.jar:?] at net.fabricmc.loader.impl.launch.server.FabricServerLauncher.main(FabricServerLauncher.java:69) [fabric-loader-0.15.11.jar:?] at net.fabricmc.installer.ServerLauncher.main(ServerLauncher.java:69) [server.jar:1.0.1] Caused by: java.lang.NoSuchFieldError: TEXTURE at moriyashiine.bewitchment.common.item.SpecterBangleItem.<clinit>(SpecterBangleItem.java:28) ~[bewitchment-1.16.5-18.jar:?] at moriyashiine.bewitchment.common.registry.BWObjects.<clinit>(BWObjects.java:272) ~[bewitchment-1.16.5-18.jar:?] at moriyashiine.bewitchment.common.Bewitchment.onInitialize(Bewitchment.java:221) ~[bewitchment-1.16.5-18.jar:?] at net.fabricmc.loader.impl.FabricLoaderImpl.invokeEntrypoints(FabricLoaderImpl.java:384) ~[fabric-loader-0.15.11.jar:?] ... 7 more Logs: https://mclo.gs/wSsqMfn
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.