Crafting and Smelting

From Minecraft Forge
Jump to: navigation, search


How-To Icon.png

This is a How-To guide or Tutorial detailing a practice or process for Minecraft Forge or related software.

Generic Mod

Havvy Generic Mod Banner Final.png

March 27, 2014 Updated Basic Items to 1.7.x --Jwosty

February 13, 2014 1.7 update happen and I fix up some of the stuff so far:

But it has one part not working yet

--Chibill

July 5, 2013

1.6.1 came out so I have fixed up some of the basic tutorials to go with it.

Ones that are updated include:

-- Mew

March 13, 2013

1.5 came out, so I fixed the methods to account for this (mostly the Icons/Textures tutorial).

--Squawkers13

December 13th, 2012

Alright, Forge made their installation process really simple and also made proper packages, removing the common/src distinction. I rewrote most of Basic Modding to account for this update. Overall though, this simplifies the explanations, but imports changed in all tutorials. Next up, I need to finish the world gen tutorial.

With the Basic Modding tutorial being mostly rewritten, if anything is confusing about it now, please tell me ASAP!

December 3rd, 2012

I finally finished the tutorial on Plants I started a month ago. I also fixed a minor compilation bug in Packet Handling. I reorganized the Generic Ore section by adding a Dropping Ore section. I'm starting to use a General Knowledge template where the background is grey. The knowledge in those boxes are general facts that are not specific to whatever thing we are implementing. I updated the Textures and Icons section to say that the image can be any scalar of 16x16 pixels where 256x256 will have each icon be 16x16 in size.



So, you've successful set up a base mod, and are ready to start modifying the game? Chances are, you'll have a recipe or two added to the game, and recipes are easy. There are three classes of recipes: Shaped, Shapeless, and Smelting recipes.

Contents

General Crafting Knowledge

Adding recipes usually happens in the @Init annotated method of the base mod. For the generic mod, this is the load method in tutorial.generic.Generic. At the end of the tutorial, the modified Generic class will be shown with all the shown crafting recipes.

The methods for crafting are static methods. They are all under GameRegistry, which just passes the data on to the CraftingManager. For that reason, in Eclipse, the method names will be italicized.

ItemStacks

Blocks and items in Minecraft don't have multiple instances per block/item type. Instead, these blocks and items are stored in inventory in ItemStacks. You can find all of the vanilla (unmodded) Minecraft blocks and items in net.minecraft.block.Block and net.minecraft.item.Item, usually at the top. As such, if you are playing with recipes, it might be a good idea to grab those lists.

An ItemStack has a couple of constructors, depending on the quantity and damage value of the item used.

Single, No Damage

Usually, an item you want to craft will be just one item with no damage value associated with it. Since this is the simple case, the constructor only takes a reference to the item itself.

1.6
ItemStack dirtStack = new ItemStack(Block.dirt);
1.7
ItemStack dirtStack = new ItemStack(Blocks.dirt); //Yes 1.7 moved Block.<blockname> to Blocks.<blockname>

This is a stack containing a single block of dirt.

Multiple, No Damage

While you can't request multiple items in the recipe itself, it can be the output of the recipe.

1.6
ItemStack diamondsStack = new ItemStack(Item.diamond, 64);
1.7
ItemStack diamondsStack = new ItemStack(Items.diamond, 64); // Same change to Item as Block

This is a full stack of diamonds.

With Damage

Unfortunately, if you want to include a damage or metadata value, you'll need to include the quantity.

1.6
ItemStack blackWoolStack = new ItemStack(Block.cloth, 42, 15);
1.7
ItemStack blackWoolStack = new ItemStack(Blocks.wool, 42, 15);

Wool is called cloth in the code. It's an old name. Anyways, this is a stack of 42 black wool, since black wool has a metadata value of 15. And apparently they updated it in 1.7 check out the Blocks class.

I know the item id!

If you don't have a reference to the item or block, but know the id of it, you can use the final constructor. I don't recommend it, and only include it here for completeness.

ItemStack unknownItemStack = new ItemStack(1, 3, 0);

This is a stack of 3 of the block with id 1. Possibly dirt? It's better to try getting a reference to the item or block first. Again, all vanilla items can be found in net.minecraft.init.Blocks and net.minecraft.init.Items.

Shapeless Crafting

Shapeless Crafting is crafting recipes where the order of items doesn't matter. Some common examples of this include Mushroom Soup and Books. The generic form of adding a shapeless recipe is:

GameRegistry.addShapelessRecipe(ItemStack result, Object... recipe)

Not sure what that "..." is doing in this method signature? It's an actual part of Java saying "and the rest of the parameters are Objects, which should be in an Object[] called recipe." It basically allows you to not have to type new Object[] { } in every recipe, though that is also possible.

The common vanilla recipe for explaining recipes is trading in nothing for something. In this case, we will trade in dirt for diamonds.

1.6

GameRegistry.addShapelessRecipe(new ItemStack(Item.diamond, 64), new ItemStack(Block.dirt));

1.7

GameRegistry.addShapelessRecipe(new ItemStack(Items.diamond, 64), new ItemStack(Blocks.dirt));

Mod 200 diamond from dirt.png

Microoptimization
A microoptimization is to create any ItemStack you use multiple times outside of the recipes and just use the reference to it.

If you want multiple items required, put in more ItemStacks. If you want more of the same item, just put the ItemStack in again. For an example, here's a slightly more expensive recipe that uses sand, gravel, cobblestone, and six dirt.

1.6

ItemStack dirtStack = new ItemStack(Block.dirt);
GameRegistry.addShapelessRecipe(new ItemStack(Item.diamond, 64),
                dirtStack, dirtStack, dirtStack,
                dirtStack, dirtStack, dirtStack,
                new ItemStack(Block.sand), gravelStack, cobbleStack);

1.7

ItemStack dirtStack = new ItemStack(Blocks.dirt);
GameRegistry.addShapelessRecipe(new ItemStack(Items.diamond, 64),
                dirtStack, dirtStack, dirtStack,
                dirtStack, dirtStack, dirtStack,
                new ItemStack(Blocks.sand), gravelStack, cobbleStack);

NOTE: If you need help with shapeless recipes, check out this video tutorial: http://www.youtube.com/watch?v=5-AuQtjYNEY

Shaped Crafting

Shaped recipes come in all sizes from 1x1 to 3x3. Strings are used for the recipe shape and values. The method signature is roughly as follows:

GameRegistry.addRecipe(String row1, [String row2[, String row3]]
        char itemType1, ItemStack itemStackType1[, ... char itemTypeN, ItemStack itemStackTypeN]);

That's probably confusing, so a couple of examples should clear this up. Let's say that we want a 2x2 recipe where two dirt and two gravel in the corners gives you one cobblestone. To do that, we use the following snippet:

1.6

ItemStack dirtStack = new ItemStack(Block.dirt);
ItemStack gravelStack = new ItemStack(Block.gravel);

GameRegistry.addRecipe(new ItemStack(Block.cobblestone), "xy", "yx",
        'x', dirtStack, 'y', gravelStack);

1.7

ItemStack dirtStack = new ItemStack(Blocks.dirt);
ItemStack gravelStack = new ItemStack(Blocks.gravel);

GameRegistry.addRecipe(new ItemStack(Blocks.cobblestone), "xy", "yx",
        'x', dirtStack, 'y', gravelStack);

Mod 200 cobblestone.png

Symmetric Recipes
If you have symmetric recipes like the two demonstrated in this section, it will help your players if you add the recipe with the recipe items switched. The simplest way to do that is to copy the recipe, and switch dirtStack and gravelStack around.

I find that the newline after the shape helps readability of the recipe.

So, what do you do when you want an empty space in your recipe? Well, the space character (" ") is already designated to do that. To demonstrate this, the following recipe takes alternating gravel and dirt in a circle to make stone.

GameRegistry.addRecipe(new ItemStack(Block.stone), "xyx", "y y", "xyx",
        'x', dirtStack, 'y', gravelStack);

Mod 200 stone.png

NOTE: If you need help with shaped recipes, check out this video tutorial: http://www.youtube.com/watch?v=Yt99TNIMuHs

Smelting

Smelting recipes are the easiest of the three. This is mainly because it is a one-for-one transfer of items and the only configurable value is the experience given. The method signature for smelting is as follows.

GameRegistry.addSmelting(int inputItemID, ItemStack result, float experience);

There are two values that need explaining here: itemID and experience.

The itemID is, as you might have guessed, the id of the item in the game. Blocks have a field blockID that gives this. Items have the field itemID.

For experience, the value given is the direct amount of experience given. In vanilla Minecraft, these values range between 0.1f and 1.0f and can be seen at the Minecraft Wiki's smelting article. You may use any positive value you want.

The example smelting recipe is smelting stone for stone bricks.

1.6

GameRegistry.addSmelting(Block.stone.blockID, new ItemStack(Block.stoneBrick), 0.1f);

1.7

// Note not only Block -> Blocks but stoneBrick -> stonebrick
GameRegistry.addSmelting(Blocks.stone, new ItemStack(Blocks.stonebrick), 0.1f);

With Metadata

1.6

You may have noticed that the input does not accept a metadata or damage value. This is quite silly, but the GameRegistry doesn't have an addSmelting variant that takes metadata. For that, we will need to input FurnaceRecipes, get its instance, and then use its addSmelting method.

The example here is burning black wool to get white wool.

FurnaceRecipes.smelting().addSmelting(Block.cloth.blockID, 15, new ItemStack(Block.cloth, 1, 0), 0.1f);

1.7

GameRegistry can handle ItemStacks now, which CAN have metadata/damage values

ItemStack woolStackBlack = new ItemStack(Blocks.wool);
ItemStack woolStackWhite = new ItemStack(Blocks.wool);
woolStackBlack.setItemDamage(15);
woolStackWhite.setItemDamage(1);
GameRegistry.addSmelting(woolStackBlack, woolStackWhite, 0.1f);

NOTE: If you need help with smelting recipes, check out this video tutorial: http://www.youtube.com/watch?v=nbqTc-xu82Q NOTE: This won't work on 1.7.2.

Finished Product

With all the recipes added, and avoiding the creation of any unnecessary Objects, here is what tutorial.generic.Generic looks like with all these recipes added. Take note that the following are added to the import list:

  • cpw.mods.fml.common.registry.GameRegistry
  • net.minecraft.block.Block
  • net.minecraft.item.Item
  • net.minecraft.item.ItemStack
  • net.minecraft.item.crafting.FurnaceRecipes
package tutorial.generic;

// This Import list will grow longer with each additional tutorial.
// It's not pruned between full class postings, unlike other tutorial code.
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraftforge.common.MinecraftForge;
import cpw.mods.fml.common.Mod;
//import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.Mod.Instance;  //1.6.X
//import cpw.mods.fml.common.Mod.PostInit;
//import cpw.mods.fml.common.Mod.PreInit;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;

@Mod(modid = "Generic", name = "Generic", version = "0.0.0")
@NetworkMod(clientSideRequired = true, serverSideRequired = false, channels = { "GenericRandom" })
public class Generic {

    @Instance("Generic")
    public static Generic instance;

    @SidedProxy(clientSide = "tutorial.generic.client.ClientProxy", serverSide = "tutorial.generic.CommonProxy")
    public static CommonProxy proxy;

    @EventHandler
    public void preInit (FMLPreInitializationEvent event) {
        // Stub Method
    }

    @EventHandler
    public void load (FMLInitializationEvent event) {
        proxy.registerRenderers();

        ItemStack dirtStack            = new ItemStack(Block.dirt);
        ItemStack diamondsStack  = new ItemStack(Item.diamond, 64);
        ItemStack blackWoolStack  = new ItemStack(Block.cloth, 42, 15);
        ItemStack gravelStack        = new ItemStack(Block.gravel);
        ItemStack cobbleStack       = new ItemStack(Block.cobblestone);

        GameRegistry.addShapelessRecipe(diamondsStack, dirtStack);

        GameRegistry.addShapelessRecipe(diamondsStack, dirtStack, dirtStack,
                dirtStack, dirtStack, dirtStack, dirtStack, new ItemStack(
                        Block.sand), gravelStack, cobbleStack);

        GameRegistry.addRecipe(new ItemStack(Block.cobblestone), "xy", "yx",
                'x', dirtStack, 'y', gravelStack);

        GameRegistry.addRecipe(new ItemStack(Block.stone), "xyx", "y y", "xyx",
                'x', dirtStack, 'y', gravelStack);

        GameRegistry.addSmelting(Block.stone.blockID, new ItemStack(
                Block.stoneBrick), 0.1f);

        FurnaceRecipes.smelting().addSmelting(Block.cloth.blockID, 15,
                new ItemStack(Block.cloth, 1, 0), 0.1f);
    }

    @EventHandler
    public void postInit (FMLPostInitializationEvent event) {
        // Stub Method
    }
}

In future tutorials, these recipes will not be shown. The imports will still be there, since it's a pain to clean out unused imports in the master source. Unless the code is required for another tutorial, you can expect each tutorial to start at a clean slate.

What's Next

Next up is creating blocks and items.

Personal tools
Namespaces
Variants
Actions
Navigation
tutorials
Toolbox