Topic category: User side tutorials
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;
- GUI element and texture
- Block
- 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,
Now open the "build.gradle" file with notepad (or any other alternative),
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",
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
MIRROR LINKS FOR IMAGES;
Really nice! Can you make a Youtube Tutorial or can help me?
Does this method work on 1.12.2 ?
I'll check when I have access to my computer.
My workspace wont work. Here is my build.
buildscript {
repositories {
maven { url = 'https://files.minecraftforge.net/maven' }
jcenter()
mavenCentral()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
}
}
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'
}
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 from: 'mcreator.gradle'
Need to be in here;
To look something like;
nevermind this post. i figured it out.
You should make a video tutorial, but brilliant work either way. 👍👍🤑
I thought about it, but it's not my type of thing. So I tried to describe it as well as possible.
That being said, if anyone wants to make one I'm okay with that (link this page).
Hello @Tbroski, I would like to know if you could help me with my code, I don't know how to program very well, in fact I don't know how to program, but I'm making a mod with crafting tables, furnaces, compressors and I can't make any code! So could you help me?
Sorry for the bad English, I am from another country!
There is no need to code for this. I suggest you check our tutorials collection playlist on our YouTube channel which contains many examples and tutorials that can help you get started with MCreator: https://www.youtube.com/playlist?list=PLAeL-oIFIEngE6jRgFYeFMfuj8WQsO3Ei
Just wondering...
I find videos easier to follow so I was wonder wether somebody has made a video tutorial of this?
(I'm not asking somebody to make one as nice as that would be just if there is one out there.)
Thanks for the fantastic tutorial! With a bit of head-scratching and hours of painstakingly copying ingredients, I have over 60 recipes working perfectly with JEI!
Congrats! :D
Hello, you can add a ready-made sample code or a step-by-step sample to this guide (although I have some experience with Lua and C), but I still could not figure out this code, but thanks anyway)