[1.15.2-1.14.4] JEI API integration for Custom Crafting!

Started by tbroski on

Topic category: User side tutorials

Last seen on 04:35, 17. Jan 2021
Joined Sep 2019
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
[1.15.2-1.14.4] JEI API integration for Custom Crafting!
Fri, 08/21/2020 - 21:12 (edited)

JEI API integration for Custom Crafting

You will need java knowledge for this tutorial.

In the tutorial, I will assume you know how to create a variable and know basic java syntax. However, I am open to helping everybody, so if you need extra guidance. Add my discord (in profile).

 

Before we get started, you will need these elements and textures;

  1. GUI element and texture
  2. Block
  3. Working procedure recipes in-game

 

Now lets get started 😋,

First, we have to install the JEI API in our MCreator workspace.

To do this go to,

Open workspace folder

 

Now open the "build.gradle" file with notepad (or any other alternative),

build.gradle

Now add the following,

repositories {
  maven {
    // location of the maven that hosts JEI files
    name = "Progwml6 maven"
    url = "https://dvs1.progwml6.com/files/maven/"
  }
  maven {
    // location of a maven mirror for JEI files, as a fallback
    name = "ModMaven"
    url = "https://modmaven.k-4u.nl"
  }
}
 compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.4:api")
  // at runtime, use the full JEI jar
  runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.4")

Keep in mind, you can change, "6.0.0.4" to any compatible JEI version.

Now add the above snippets so your build.gradle file looks similar to this,

buildscript {
    repositories {
        maven { url = 'https://files.minecraftforge.net/maven' }
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
    }
}
repositories {
  maven {
    name = "Progwml6 maven"
    url = "https://dvs1.progwml6.com/files/maven/"
  }
  maven {
    name = "ModMaven"
    url = "https://modmaven.k-4u.nl"
  }
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'

version = '1.0'
group = 'com.yourname.modid'
archivesBaseName = 'modid'
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
minecraft {
    mappings channel: 'snapshot', version: '20200514-1.15.1'

    runs {
        client {
            workingDirectory project.file('run')
            property 'forge.logging.markers', 'REGISTRIES'
            property 'forge.logging.console.level', 'debug'
            mods {
                examplemod {
                    source sourceSets.main
                }
            }
        }

        server {
            workingDirectory project.file('run')
            property 'forge.logging.markers', 'REGISTRIES'
            property 'forge.logging.console.level', 'debug'
            mods {
                examplemod {
                    source sourceSets.main
                }
            }
        }
    }
}

dependencies {
    minecraft 'net.minecraftforge:forge:1.15.2-31.2.0'
  compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.4:api")
  runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.4")

}
apply from: 'mcreator.gradle'

 

Now you should be done with the build.gradle file!🤪🤪 All you have to do now is save and close the file and open the MCreator workspace again. Finally, build the workspace by clicking the hammer in the top right corner!😎😎

If you get an error, 😡🤬, post your build.gradle file in the comments. And I will try to respond quick!

 

Now we have to create our plugin, recipe/s, and category 😀. So let's create a custom element and name it "JeiPlugin",

Custom Element

JeiPlugin code

Now optimize the code to look similar to this, and remove the constructor😱😱😱. Also add, "@mezz.jei.api.JeiPlugin" to the top;

package net.mcreator.jeitest;


@mezz.jei.api.JeiPlugin
public class JeiPlugin {

}

Now that we have a clean slate to work with, we can follow (not copy) the template at the end of the post.

 

An explanation for each method follows;

Blue Text = Important

Green Text = Self explanatory or a simple method

 

JeiPlugin Class Methods,

getPluginUid - Well, you provide a ResourceLocation for your plugin...

 

registerCategories - This method register's category of your crafting. For example in vanilla minecraft, the crafting table category, furnace table category, and a blast furnace.*This does not provide JEI with an extra tab (see registerRecipeCatalysts for that)*.

 

registerRecipes - This method registers the recipe. For example, when you click on a torch in JEI you can see the stick + coal recipe. In the template we register a list of all of our recipes. To add a recipe, add another;

	private List<[YOURBLOCK]JeiCategory.[YOURBLOCK]RecipeWrapper> generate[YOURBLOCK]Recipes() {
		List<[YOURBLOCK]JeiCategory.[YOURBLOCK]RecipeWrapper> recipes = new ArrayList<>();
		ArrayList<ItemStack> inputs = new ArrayList<>();
        ArrayList<ItemStack> outputs = new ArrayList<>();
        inputs.add(new ItemStack([ANYINPUTITEM));
        outputs.add(new ItemStack([ANYOUTPUTITEM]));
		recipes.add(new [YOURBLOCK]JeiCategory.[YOURBLOCK]RecipeWrapper(inputs, outputs));
		return recipes;
	}

However, to add more inputs/outputs, add another;

        inputs.add(new ItemStack([ANYINPUTITEM]));

or

        outputs.add(new ItemStack([ANYOUTPUTITEM]));

To the correlated list

 

registerRecipeCatalysts - This provides JEI with the tab for the recipes. I.e. the Crafting Table tab. This parameter;

new ItemStack([YOURBLOCK].block)

is the block/icon the tab shows. Similar but different to the Creative tabs.

 

JeiCategory sub-class methods,

getUid - Well, returns the Uid variable...

getRecipeClass - returns our "recipe wrapper"

getTitle = returns the title of our GUI

getBackground- returns the background texture of the GUI

getIcon = returns null if you want to have your block as the icon. If you want a custom icon, return the icon ResourceLocation (I won't be covering that, if you need help add my discord).

setIngredients - This may be the most important method, it allows you to set the inputs and outputs of your gui. To add more inputs, see the "registerRecipes" method. 

setRecipes - This also tops the most important method, it provides JEI the layout of your gui. To add more slots add additional init and set corresponding to the slot coordinates in the GUI texture. I.e this;

            IGuiItemStackGroup stacks = iRecipeLayout.getItemStacks();

            stacks.init(input1, true, [IN1SLOTX], [IN1SLOTY]);
            stacks.init(output1, false, [OUT1SLOTX], [OUT1SLOTY]);
            //...

            stacks.set(input1, iIngredients.getInputs(VanillaTypes.ITEM).get(0));
            stacks.set(output1, iIngredients.getOutputs(VanillaTypes.ITEM).get(0));
            //...

to this;

            IGuiItemStackGroup stacks = iRecipeLayout.getItemStacks();

            stacks.init(input1, true, [IN1SLOTX], [IN1SLOTY]);
            stacks.init(input2, true, [IN2SLOTX], [IN2SLOTY]);
            stacks.init(output1, false, [OUT1SLOTX], [OUT1SLOTY]);
            //...

            stacks.set(input1, iIngredients.getInputs(VanillaTypes.ITEM).get(0));
            stacks.set(input2, iIngredients.getInputs(VanillaTypes.Item).get(1)); //+1 from previous variable.
            stacks.set(output1, iIngredients.getOutputs(VanillaTypes.ITEM).get(0));
            //...

You need to create another variable, "input2", that corresponds to that slotID. If you need help add my discord (in profile).

That should cover a lot, a may be missing something so if anything jumps out comment below. If you have any questions/additions comment below or add my discord. Thanks!

 

 

TEMPLATE BELOW

Key;

Basics,

[MODID] = Your modid i.e. mobench

[YOURBLOCK] = Your block name, i.e. InfuseBlock

[YOURBLOCKLOWERCASE]  = Your block name no capitals, i.e. infuseblock

[YOURBLOCKNAMEINGAME] = The title of your block, i.e. Crafting Bench and Infuse Bench

[GUIFILELOCATION] = Where the GUI texture is stored, i.e. "textures/infuse_bench_gui.png"

[GUIWIDTH] = The width of the GUI, i.e 176

[GUIHEIGHT] = The height of the GUI, i.e. 166

//... = You can add on to these elements

 

You should have, {Number of items in recipe = Number of slots in gui}

You can have more than provided two items in the template. If you need help with how to do this, ask below or add my discord (in profile).

@mezz.jei.api.JeiPlugin
public class JeiPlugin implements IModPlugin {
	public static IJeiHelpers jeiHelper;
	@Override
	public ResourceLocation getPluginUid() {
		return new ResourceLocation("[MODID]", "default");
	}

	@Override
	public void registerCategories(IRecipeCategoryRegistration registration) {
		jeiHelper = registration.getJeiHelpers();
		registration.addRecipeCategories(new [YOURBLOCK]JeiCategory(jeiHelper.getGuiHelper()));
	}

	@Override
	public void registerRecipes(IRecipeRegistration registration) {
		registration.addRecipes(generate[YOURBLOCK]Recipes(), [YOURBLOCK]JeiCategory.Uid);
		// ...
	}

	private List<[YOURBLOCK]JeiCategory.[YOURBLOCK]RecipeWrapper> generate[YOURBLOCK]Recipes() {
		List<[YOURBLOCK]JeiCategory.[YOURBLOCK]RecipeWrapper> recipes = new ArrayList<>();
		ArrayList<ItemStack> inputs = new ArrayList<>();
        ArrayList<ItemStack> outputs = new ArrayList<>();
        inputs.add(new ItemStack([ANYINPUTITEM]));
        outputs.add(new ItemStack([ANYOUTPUTITEM]));
        // ...
		recipes.add(new [YourBlock]JeiCategory.[YourBlock]RecipeWrapper(inputs, outputs));
		return recipes;
	}

	@Override
	public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
		registration.addRecipeCatalyst(new ItemStack([YOURBLOCK].block), [YOURBLOCK]JeiCategory.Uid);
	}
	public static class [YOURBLOCK]JeiCategory implements IRecipeCategory<[YOURBLOCK]JeiCategory.[YOURBLOCK]RecipeWrapper> {
		private static ResourceLocation Uid = new ResourceLocation("[MODID]", "[YOURBLOCKLOWERCASE]category");
		private static final int input1 = 0; // THE NUMBER = SLOTID
		private static final int output1 = 1; // THE NUMBER = SLOTID
		// ...
		private final String title;
		private final IDrawable background;
		public [YOURBLOCK]JeiCategory(IGuiHelper guiHelper) {
			this.title = "[YOURBLOCKNAMEINGAME]";
			this.background = guiHelper.createDrawable(new ResourceLocation("[MODID]", "[GUIFILELOCATION].png"), 0, 0, [GUIWIDTH], [GUIHEIGHT]);
		}

		@Override
		public ResourceLocation getUid() {
			return Uid;
		}

		@Override
		public Class<? extends [YOURBLOCK]RecipeWrapper> getRecipeClass() {
			return [YOURBLOCK]JeiCategory.[YOURBLOCK]RecipeWrapper.class;
		}

		@Override
		public String getTitle() {
			return title;
		}

		@Override
		public IDrawable getBackground() {
			return background;
		}

		@Override
		public IDrawable getIcon() {
			return null;
		}

		@Override
		public void setIngredients([YOURBLOCK]RecipeWrapper recipeWrapper, IIngredients iIngredients) {
            iIngredients.setInputs(VanillaTypes.ITEM, recipeWrapper.getInput());
            iIngredients.setOutputs(VanillaTypes.ITEM, recipeWrapper.getOutput());
		}

		@Override
		public void setRecipe(IRecipeLayout iRecipeLayout, [YOURBLOCK]RecipeWrapper recipeWrapper, IIngredients iIngredients) {
			IGuiItemStackGroup stacks = iRecipeLayout.getItemStacks();
			stacks.init(input1, true, [IN1SLOTX], [IN1SLOTY]);
			stacks.init(output1, false, [OUT1SLOTX], [OUT1SLOTY]);
            // ...

            stacks.set(input1, iIngredients.getInputs(VanillaTypes.ITEM).get(0));
			stacks.set(output1, iIngredients.getOutputs(VanillaTypes.ITEM).get(0));
			// ...
		}
		public static class [YOURBLOCK]RecipeWrapper {
            private List<ItemStack> input;
            private List<ItemStack> output;

            public [YourBlock]RecipeWrapper(List<ItemStack> input, List<ItemStack> output) {
                this.input = input;
                this.output = output;
            }


            public List<ItemStack> getInput() {
                return input;
            }

            public List<ItemStack> getOutput() {
                return output;
            }
        }
	}
}

MAKE SURE TO ADD THESE BARE MINIMUM IMPORTS😁😁😁!

import mezz.jei.api.IModPlugin;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.helpers.IJeiHelpers;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.registration.IRecipeCatalystRegistration;
import mezz.jei.api.registration.IRecipeCategoryRegistration;
import mezz.jei.api.registration.IRecipeRegistration;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.ResourceLocation;

import java.util.ArrayList;
import java.util.List;

PROOF OF WORKING

[NEW TEMPLATE] CODE PROOF

[OLD] CODE PROOF

InGame GUI

JEI recipe

 

MIRROR LINKS FOR IMAGES;

Open Workspace Folder

Build.Gradle File

Custom Element

Custom Element Code

Edited by tbroski on Fri, 08/21/2020 - 21:12
Last seen on 02:16, 22. Aug 2023
Joined Mar 2018
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Before I potentially waste…
Sat, 02/13/2021 - 03:51

Before I potentially waste hours, has anyone tried this with the 1.12.2 generator plugin?  also its really cool that made the tutorial thing my guy!

Last seen on 19:10, 12. Oct 2023
Joined Mar 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
I really like your hard work…
Mon, 03/08/2021 - 11:46

I really like your hard work but rather then including paste bins why not just add comments to the code in a workspace and share that, this way users a little slower to learn can still use it but ones whom hate the way this website as formatted the whole tutorial there for I can't follow it as it hurts my eyes.

Also you could give your hand at creating plugins rather then just tutorials :)

All the same good work.

Last seen on 22:47, 4. Nov 2022
Joined Jan 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
What is the [ANYINPUTITEM]…
Fri, 04/02/2021 - 23:51

What is the [ANYINPUTITEM] and [ANYOUTPUTITEM] in the inputs/outputs part?

Last seen on 07:51, 15. Jul 2021
Joined May 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Hi! I keep getting an error…
Wed, 05/12/2021 - 17:31

Hi!

I keep getting an error message when I re-build Gradle. This is what the console says:

Executing Gradle task: build 
Build info: MCreator 2020.2.14217, 1.12.2, 64-bit, 15804 MB, Windows 10, JVM 1.8.0_232, JAVA_HOME: C:\Program Files\Pylo\MCreator\jdk 
FAILURE: Build failed with an exception. 
* Where: 
Build file 'C:\Users\user\MCreatorWorkspaces\multimachines\build.gradle' line: 23 
* What went wrong: 
A problem occurred evaluating root project 'multimachines'. 
> Could not get unknown property 'fg' for root project 'multimachines' of type org.gradle.api.Project. 
* Try: 
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. 
* Get more help at https://help.gradle.org 
BUILD FAILED in 0s 
BUILD FAILED 
Task completed in 251 milliseconds

And this is my build.gradle code:

buildscript {
    repositories {
        jcenter()
        maven { url = "http://files.minecraftforge.net/maven" }
    }
    dependencies {
        classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
    }
}

repositories {
  maven {
    // location of the maven that hosts JEI files
    name = "Progwml6 maven"
    url = "https://dvs1.progwml6.com/files/maven/"
  }
  maven {
    // location of a maven mirror for JEI files, as a fallback
    name = "ModMaven"
    url = "https://modmaven.k-4u.nl"
  }
}
 compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.4:api")
  // at runtime, use the full JEI jar
  runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.4")

apply plugin: 'net.minecraftforge.gradle.forge'

version = "1.0"
group = "com.yourname.modid"
archivesBaseName = "modid"

sourceCompatibility = targetCompatibility = '1.8'
compileJava {
    sourceCompatibility = targetCompatibility = '1.8'
}

minecraft {
    version = '1.12.2-14.23.5.2768'
    runDir = 'run'
    mappings = 'snapshot_20171003'
}

processResources {
    inputs.property "version", project.version
    inputs.property "mcversion", project.minecraft.version
    from(sourceSets.main.resources.srcDirs) {
        include 'mcmod.info'
        expand 'version': project.version, 'mcversion': project.minecraft.version
    }
    from(sourceSets.main.resources.srcDirs) {
        exclude 'mcmod.info'
    }
}

runClient.outputs.upToDateWhen { false }
runServer.outputs.upToDateWhen { false }

apply from: 'mcreator.gradle'

Thanks! :)

Last seen on 16:16, 16. May 2021
Joined May 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
I have everything working…
Fri, 05/14/2021 - 23:39

I have everything working properly except the background image. For some reason it wants to blow the image up 3x. (the source gui image is 126 x 21)

I can't make the image any smaller without losing details and I can't leave it like this because the image is now blocking a lot of the screen (outside the bounds of the gui)

 

Does anyone have any ideas?

Last seen on 16:16, 16. May 2021
Joined May 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Edit: Figured it out. the…
Sat, 05/15/2021 - 02:43

Edit: Figured it out. the texture MUST be a 256x256 to maintain aspect ratio

Last seen on 20:18, 9. May 2023
Joined Mar 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Works in 1.16.5! Nice
Tue, 05/25/2021 - 18:41

Works in 1.16.5! Nice

Last seen on 15:11, 2. Oct 2021
Joined Mar 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
May be overwhelming at first…
Fri, 06/18/2021 - 14:54

May be overwhelming at first, but the amazing explanation made it very easy . Amazing job!

Last seen on 02:30, 2. Jul 2021
Joined Jun 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
THANK YOU FOR THIS NICE…
Wed, 06/30/2021 - 22:24

THANK YOU FOR THIS NICE GUISEDE FOR JAVA 1.6 Jey tutorial!

Last seen on 06:03, 27. Feb 2024
Joined Feb 2015
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
I see this as very useful
Wed, 06/30/2021 - 22:57

I see this as very useful

Last seen on 18:56, 28. Mar 2024
Joined Dec 2015
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
hi, how we can to put a mod…
Sun, 11/07/2021 - 20:44

hi, how we can to put a mod item in input of recipe ??

my background gui ois too large how i can reduce it ??

Last seen on 17:34, 28. Dec 2023
Joined Aug 2018
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
When I try to build, it When…
Tue, 03/22/2022 - 00:44

When I try to build, it When I try to build, it says that "Gradle was not able to access the internet connection!". And when I look in the Console, there are a bunch of "Internal Server Error" messages.

This is my build.gradle file:

buildscript {
    repositories {
        maven { url = 'https://maven.minecraftforge.net' }
        mavenCentral()
    }
    dependencies {
        classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
    }
}

repositories {
  maven {
    // location of the maven that hosts JEI files
    name = "Progwml6 maven"
    url = "https://dvs1.progwml6.com/files/maven/"
  }
  maven {
    // location of a maven mirror for JEI files, as a fallback
    name = "ModMaven"
    url = "https://modmaven.k-4u.nl"
  }
}
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse'

version = '1.0'
group = 'com.yourname.modid'
archivesBaseName = 'modid'

java.toolchain.languageVersion = JavaLanguageVersion.of(8)

minecraft {
    mappings channel: 'snapshot', version: '20201028-1.16.3'

    runs {
        client {
            workingDirectory project.file('run')

            property 'forge.logging.markers', 'REGISTRIES'
            property 'forge.logging.console.level', 'debug'

            jvmArgs = [
                    "--add-exports=java.base/sun.security.util=ALL-UNNAMED",
                    "--add-opens=java.base/java.util.jar=ALL-UNNAMED"
            ]

            mods {
                examplemod {
                    source sourceSets.main
                }
            }
        }

        server {
            workingDirectory project.file('run')

            property 'forge.logging.markers', 'REGISTRIES'
            property 'forge.logging.console.level', 'debug'

            jvmArgs = [
                    "--add-exports=java.base/sun.security.util=ALL-UNNAMED",
                    "--add-opens=java.base/java.util.jar=ALL-UNNAMED"
            ]

            mods {
                examplemod {
                    source sourceSets.main
                }
            }
        }
    }
}

dependencies {
    minecraft 'net.minecraftforge:forge:1.16.5-36.2.20'
     compileOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.4:api")
  // at runtime, use the full JEI jar
  runtimeOnly fg.deobf("mezz.jei:jei-1.15.2:6.0.0.4")
}

apply from: 'mcreator.gradle'

 

Last seen on 19:10, 12. Oct 2023
Joined Mar 2021
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
You can use ShadowsAPIs and…
Tue, 03/22/2022 - 22:42

You can use ShadowsAPIs and enable JEI so you can skip the Gradle part, as you have put the wrong version in there