If you're like me, you probably had a hard time updating to 1.7.2. So much was changed in 1.7.2, and updated tutorials are scarce at the moment. Well, dozens of tutorials and minecraftforge.net topics later, here's how to add a block and a item in Forge 1.7.2.
How to add a block:
You add blocks just like in 1.6.4, however, there's a new way of adding block names. Here's how to do it:
Simple starter mod class:
package tutorialmod.forge;
@Mod(modid=mod_Test.MODID,name="Test mod",version=mod_Test.VERSION)
public class mod_Test{
public static final String MODID = "tutorialmod";
public static final String VERSION = "v1.0";
public static Block testBlock;
@EventHandler
public void preInit(FMLPreInitializationEvent event){
}
}
NOTE: You may change any variable in the above starter class to your liking, but make sure that your modID is all lowercase. This is very important for making sure that block/item textures and names will work.
Next, we are going to add our block declaration into the preInit method:
this.testBlock = new BlockTestBlock(Material.rock).setHardness(3F).setResistance(5F).setBlockName("testBlock").setBlockTextureName("tutorialmod:testBlock");
Notice the "tutorialmod:" in the .setBlockTextureName() method. This is how Forge will find your custom texture for the block. More on this later.
Next, we need to register the block (this should always be done in your preInit method):
Now, we just need to add the localized block name, and the texture for it. LanguageRegistry.addName is no longer used. You now need to use .lang files.
Open up your root forge folder, and follow this path:
"*Root folder*/src/main/resources/assets/"
Create a folder with the same name as your modID, and when setting textures. This is how Forge finds your custom assets. Capitalization is very important, make sure it's exactly the same.
Go into that folder, and create two new folders called "lang" and "textures". First, let's set the block name.
Create a file called "en_US.lang" inside of the "lang" folder. Windows has a problem with doing this. If you create a new .txt file, and add the .lang suffix, you will get a file called "en_US.lang.txt", which will not work.
The easiest method to get a .lang file that i found was to go to this path:
"*Root folder*/eclipse/assets/lang"
Just grab any lang file in there, clear its contents by opening it and pressing ctrl + a then backspace, and renaming it "en_US".
Then set the block name by opening it and typing (without the quotes):
"tile.*your blocks unlocalized name, set in .setBlockName()*.name=Test Block"
Only set one name per line in the .lang file.
That's it for setting the name. Now it's time to add the texture:
Go into your "textures" folder that you created earlier. Make two new folders called "blocks" and "items". This is where you are going to put your textures. Place your block textures in the "blocks" folder, and your done!
How to add multiple textures to a block:
First, if you are going to use more then one texture, do not call the .setBlockTextureName() method when initializing the block. This causes issues, as Minecraft doesn't know whether to use the texture we are going to set in the method below, or the texture we set in the .setBlockTextureName() method.
Once you get rid of the .setBlockTextureName() method, add this to your block class:
//Add these new IIcon variables to the top of your class:
@SideOnly(Side.CLIENT)
private IIcon alternateTexture1;
//Continue for however much textures you wish to use.
//And add these new methods:
@SideOnly(Side.CLIENT)
public IIcon getIcon(int par1, int par2){
//par1 is which side of the block is currently being set. There are 6 sides on each block.
//This will render side 1 with the standard texture, and all other sides with the alternate texture.
if(par1 == 1){
return this.blockIcon;
}else{
return this.alternateTexture1;
}
}
@SideOnly(Side.CLIENT)
public void registerBlockIcons(IIconRegister par1IIconRegister){
this.blockIcon = par1IIconRegister.registerIcon("tutorialmod:standardTexture");
this.alternateTexture1 = par1IIconRegister.registerIcon("tutorialmod:alternateTexture");
//If you have more IIcon objects, continue registering them here.
}
How to add animated textures for a block:
Create a new file called "*your texture's name*.png.mcmeta". It might be easier to open up the "assets/minecraft/textures/blocks/" folder in a minecraft.jar file with a program like 7-zip, grab a .mcmeta file from there, and re-naming it, since Windows frequently has problems adding suffixes to files.
Paste this code into your new .mcmeta file:
{
"animation": {}
}
Once you've done that, create a new .png file in your favorite image editor, with the dimensions 16(width)x512(height). Fill up the entire column with standard 16x16 textures, with no spaces between them. Rename it to whatever you want it to be called, but make sure the name matches the name you have in the .mcmeta file. Once you have placed both these files in your "textures" folder, it should cycle through all the textures from the .png file, grabbing a 16x16 square at a time.
How to add a item:
Be sure to read the above section about adding blocks so you know what I'm talking about!
This is very similar to adding a block, but with 4 main differences:
-Change the "Block" in the "public static Block *objectName*; to "Item".
-The Item variant of ".setBlockName()" is ".setUnlocalizedName()", the ".setBlockTextureName()" for Items is ".setTextureName()", and the "GameRegistry.registerBlock()" for Items is "GameRegistry.registerItem()".
-Place the texture in the "items" folder that you created instead of the "blocks" folder.
-When adding the Item's name in your .lang file, type "item.*rest of line*" instead of "tile.*rest of line*".
Help! My custom textures and names aren't loading!
If you followed this tutorial, you probably aren't doing it wrong. This is a known bug with Forge 10.12.0.1024. How to get around this is to equip a resource pack in-game, then switch back to the default textures. This re-syncs Forge with Minecraft, and updates the names and textures.
Put custom resource packs here:
"*Root folder*/eclipse/resourcepacks/"
Anyway, i hope you learned something from this. Hope this helps!
If you have any problems, leave a reply and i'll try to help you out.
Great tutorial, but you may want to add that items and blocks should be registered in the pre-initialization phase of the mod's loading. I don't know if it was just a problem with my install of forge but if items and blocks were registered in the initialization of the mod occasionally they would just vanish at random.
Great tutorial, but you may want to add that items and blocks should be registered in the pre-initialization phase of the mod's loading. I don't know if it was just a problem with my install of forge but if items and blocks were registered in the initialization of the mod occasionally they would just vanish at random.
Thank you so much for this! I was stuck for ages wondering why my custom textures wouldn't load, and I scoured the web for an answer and all I needed to do was apply a resource pack and now they work! Thank you!
Thank you so much for this! I was stuck for ages wondering why my custom textures wouldn't load, and I scoured the web for an answer and all I needed to do was apply a resource pack and now they work! Thank you!
perhaps you could provide a list of the things I need to import because there is an annoying error in my code that just wont go away
If you're using Eclipse, it should let you import all the necessary classes just by hovering over the error and clicking the little ''import'' button that appears in the little drop-down box.
I don't understand the multiple textures tutorial. How do i make it specific to the block? because when ever i try to put it where my block code is it says that @SideOnly is not allowed for this location
Oh, I'm sorry! Could i see your code? Also, are you using @SideOnly(Side.CLIENT), not just @SideOnly (because that won't work).
Hey, you seem to have a lot of knowledge about this block stuff! Could you help me with something? I am making a mod with ores in the nether and I want the hardness and slipperness to be right!
For example the coal ore:
What is want is hardness of normal coal ore hardness + netherrack hardness - stone hardness.
I have tried and tried but it doesn't seem to work with getBlockhardness(World world, int x, int y, int z) or what it may be!
have you got any idea?
- Thanks
BSteurful
Coal ore hardness + netherrack hardness - stone hardness is 1.9F. You can set your ore's hardness by using setBlockHardness() in your block declaration, like this:
myTestBlock = new BlockMyBlock(yourMaterial).setBlockHardness(1.9F).setCreativeTab(yourTab).setUnlocalizedName("myBlock");
I need help with my Ore code I changed it to make it spawn more. I put the ore vain size from 2 - 6 and it spawns a lot of them at least 30+ and sometimes it generates 1 please help
public class MoreEverythingWorldGenerator implements IWorldGenerator
{
/**
* Method to get what world we are generating.
* For each case, we can have a different generator (0 = overworld, 1 = end, -1 = nether)
* We multiply chunkX by 16, to change the 'chunknumber' to an actual coordinate.
*/
@Override
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
{
switch(world.provider.dimensionId)
{
case 0: generateSurface(random, chunkX*16, chunkZ*16, world); break;
case 1: generateEnd(random, chunkX*16, chunkZ*16, world); break;
case -1: generateNether(random, chunkX*16, chunkZ*16, world); break;
default:
}
}
/**
* This is where you add your blocks to spawn for the overworld.
* call addOreSpawn, and give these parameters:
* Block: Block to generate
* World: world var (see params)
* Random: a random (see params)
* ChunkX: The x coordinate of a chunk (see params)
* ChunkZ: The z coordinate of a chunk (see params)
* minVainSize: Minimal vain size
* maxVainSize: The max vain size
* chanceToSpawn: The chance to spawn. Dont make this extreme like 1000, keep it around at most 50, or your world wont load.
* minY: Lowest point to spawn
* maxY: Highest point to spawn.
*
* Nether and End go the same way
*/
public void generateSurface(Random random, int chunkX, int chunkZ, World world)
{
addOreSpawn(RubyOre.RubyOre, world, random, chunkX, chunkZ, 4, 8, 10, 40, 120);
addOreSpawn(TinOre.TinOre, world, random, chunkX, chunkZ, 6, 10, 15, 40, 150);
}
public void generateEnd(Random random, int chunkX, int chunkZ, World world)
{
//Add End Generation
}
public void generateNether(Random random, int chunkX, int chunkZ, World world)
{
//Add Nether Generation
}
/**
*
* This method adds our block to the world.
* It randomizes the coordinates, and does that as many times, as defined in spawnChance.
* Then it gives all the params to WorldGenMinable, which handles the replacing of the ores for us.
*
*@param block The block you want to spawn
*@param world The world
*@param blockXPos the blockXpos of a chunk
*@param blockZPos the blockZpos of a chunk
*@param maxVainSize max vain
*@param chancesToSpawn the chance to spawn. Usually around 2
*@param minY lowest point to spawn
*@param maxY highest point to spawn
*/
public void addOreSpawn(Block block, World world, Random random, int blockXPos, int blockZPos, int minVainSize, int maxVainSize, int chancesToSpawn, int minY, int maxY )
{
for(int i = 0; i < chancesToSpawn; i++)
{
int posX = blockXPos + random.nextInt(16);
int posY = minY + random.nextInt(maxY - minY);
int posZ = blockZPos + random.nextInt(16);
new WorldGenMinable(block, (minVainSize + random.nextInt(maxVainSize - minVainSize)), Blocks.stone).generate(world, random, posX, posY, posZ);
}
}
public static void mainRegistry() {
// TODO Auto-generated method stub
public static void mainRegistry(){
initialiseBlock();
initialiseWorldGen();
registerBlock();
}
public static void initialiseWorldGen(){
registerWorldGen(new MoreEverythingWorldGenerator(), 1);
}
public static void registerWorldGen(IWorldGenerator worldGenClass, int weightedProberblity){
GameRegistry.registerWorldGenerator(worldGenClass, weightedProberblity);
}
public static Block RubyOre;
public static void initialiseBlock(){
RubyOre = new RubyOreBlock(Material.ground).setBlockName("RubyOre").setCreativeTab(CreativeTabs.tabBlock).setBlockTextureName(Strings.MODID + ":RubyOre");
}
public static void registerBlock(){
GameRegistry.registerBlock(RubyOre, RubyOre.getUnlocalizedName());
}
}
If you're using Eclipse, it should let you import all the necessary classes just by hovering over the error and clicking the little ''import'' button that appears in the little drop-down box.
it wont accept *new BlockTestBlock* it looks like it wants a class or something. can you please help me?
Did you create the class correctly (same spelling, extends Block)? If so, make sure to import it. In Eclipse, you should be able to just hover over the error, and hit "import BlockTestBlock" in the drop-down box that appears.
I imported the class and everything. it just says that it cant be resolved to a type and it gives me the option to set it to a snow block, a command block, or create a new class named BlockTestBlockand yes, I typed everything in correctly...
I imported the class and everything. it just says that it cant be resolved to a type and it gives me the option to set it to a snow block, a command block, or create a new class named BlockTestBlock
Could you post the line of code that's giving you the error?
If you're like me, you probably had a hard time updating to 1.7.2. So much was changed in 1.7.2, and updated tutorials are scarce at the moment. Well, dozens of tutorials and minecraftforge.net topics later, here's how to add a block and a item in Forge 1.7.2.
How to add a block:
You add blocks just like in 1.6.4, however, there's a new way of adding block names. Here's how to do it:
Simple starter mod class:
NOTE: You may change any variable in the above starter class to your liking, but make sure that your modID is all lowercase. This is very important for making sure that block/item textures and names will work.
Next, we are going to add our block declaration into the preInit method:
Notice the "tutorialmod:" in the .setBlockTextureName() method. This is how Forge will find your custom texture for the block. More on this later.
Next, we need to register the block (this should always be done in your preInit method):
Now, we just need to add the localized block name, and the texture for it. LanguageRegistry.addName is no longer used. You now need to use .lang files.
Open up your root forge folder, and follow this path:
"*Root folder*/src/main/resources/assets/"
Create a folder with the same name as your modID, and when setting textures. This is how Forge finds your custom assets. Capitalization is very important, make sure it's exactly the same.
Go into that folder, and create two new folders called "lang" and "textures". First, let's set the block name.
Create a file called "en_US.lang" inside of the "lang" folder. Windows has a problem with doing this. If you create a new .txt file, and add the .lang suffix, you will get a file called "en_US.lang.txt", which will not work.
The easiest method to get a .lang file that i found was to go to this path:
"*Root folder*/eclipse/assets/lang"
Just grab any lang file in there, clear its contents by opening it and pressing ctrl + a then backspace, and renaming it "en_US".
Then set the block name by opening it and typing (without the quotes):
"tile.*your blocks unlocalized name, set in .setBlockName()*.name=Test Block"
Only set one name per line in the .lang file.
That's it for setting the name. Now it's time to add the texture:
Go into your "textures" folder that you created earlier. Make two new folders called "blocks" and "items". This is where you are going to put your textures. Place your block textures in the "blocks" folder, and your done!
How to add multiple textures to a block:
First, if you are going to use more then one texture, do not call the .setBlockTextureName() method when initializing the block. This causes issues, as Minecraft doesn't know whether to use the texture we are going to set in the method below, or the texture we set in the .setBlockTextureName() method.
Once you get rid of the .setBlockTextureName() method, add this to your block class:
How to add animated textures for a block:
Create a new file called "*your texture's name*.png.mcmeta". It might be easier to open up the "assets/minecraft/textures/blocks/" folder in a minecraft.jar file with a program like 7-zip, grab a .mcmeta file from there, and re-naming it, since Windows frequently has problems adding suffixes to files.
Paste this code into your new .mcmeta file:
Once you've done that, create a new .png file in your favorite image editor, with the dimensions 16(width)x512(height). Fill up the entire column with standard 16x16 textures, with no spaces between them. Rename it to whatever you want it to be called, but make sure the name matches the name you have in the .mcmeta file. Once you have placed both these files in your "textures" folder, it should cycle through all the textures from the .png file, grabbing a 16x16 square at a time.
How to add a item:
Be sure to read the above section about adding blocks so you know what I'm talking about!
This is very similar to adding a block, but with 4 main differences:
-Change the "Block" in the "public static Block *objectName*; to "Item".
-The Item variant of ".setBlockName()" is ".setUnlocalizedName()", the ".setBlockTextureName()" for Items is ".setTextureName()", and the "GameRegistry.registerBlock()" for Items is "GameRegistry.registerItem()".
-Place the texture in the "items" folder that you created instead of the "blocks" folder.
-When adding the Item's name in your .lang file, type "item.*rest of line*" instead of "tile.*rest of line*".
Help! My custom textures and names aren't loading!
If you followed this tutorial, you probably aren't doing it wrong. This is a known bug with Forge 10.12.0.1024. How to get around this is to equip a resource pack in-game, then switch back to the default textures. This re-syncs Forge with Minecraft, and updates the names and textures.
Put custom resource packs here:
"*Root folder*/eclipse/resourcepacks/"
Anyway, i hope you learned something from this. Hope this helps!
If you have any problems, leave a reply and i'll try to help you out.
Thanks for reading!
~Geforce
Mapping and Modding rules | Global rules
Both added. Thanks for the positive feedback :)!
Mapping and Modding rules | Global rules
Sure, i'll add it in a few minutes.
EDIT: Added!
Mapping and Modding rules | Global rules
"new" and "BlockTestBlock" are spaced apart, like this: Hope this helps!
Mapping and Modding rules | Global rules
Could you post your code?
Mapping and Modding rules | Global rules
Your welcome! Thanks for the feedback.
Mapping and Modding rules | Global rules
If you're using Eclipse, it should let you import all the necessary classes just by hovering over the error and clicking the little ''import'' button that appears in the little drop-down box.
Mapping and Modding rules | Global rules
I have a probleme: I can't chang the framerate of my animated texture.
{
"animation": {3}
}
If a do that my texture doesn't show-up. But if a don't put a number, we see my texture.
Oh, I'm sorry! Could i see your code? Also, are you using @SideOnly(Side.CLIENT), not just @SideOnly (because that won't work).
Mapping and Modding rules | Global rules
Coal ore hardness + netherrack hardness - stone hardness is 1.9F. You can set your ore's hardness by using setBlockHardness() in your block declaration, like this:
Hope this helps!
Mapping and Modding rules | Global rules
That for loop in you addOreSpawn method isn't needed.
Thanks
Did you create the class correctly (same spelling, extends Block)? If so, make sure to import it. In Eclipse, you should be able to just hover over the error, and hit "import BlockTestBlock" in the drop-down box that appears.
Hope this helps!
Mapping and Modding rules | Global rules
Could you post the line of code that's giving you the error?
Mapping and Modding rules | Global rules