Jump to content

[1.10.2] Absolutely noobish Q.: How to properly register new Block?


Xanderr_K

Recommended Posts

Hi guys! Last few days I learning all stuff about Forge and trying to write my own example mod to test modding features.

 

I used some tutorials I found on the YouTube and other resources, but, TBH, I've not found proper and actual tutorial for 1.10 that show all steps in creating block. And the hardest thing I've impacted is my custom block isn't displaying texture (black/purple squares) and using placeholder instead BlockItem in inventory.

This is my working code:

 

BlockGreenOre class

 

package ru.testmod.block;

import java.util.Random;

import javax.annotation.Nullable;

import net.minecraft.block.Block;
import net.minecraft.block.BlockStone;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.MapColor;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.util.math.MathHelper;
import ru.testmod.init.TestBlocks;
import ru.testmod.init.TestItems;
import ru.testmod.main.Main;

public class BlockGreenOre extends Block 
{

public BlockGreenOre(Material materialIn) {
	super(materialIn);
	this.setUnlocalizedName("green_iron_ore");
	this.setRegistryName("green_iron_ore");
	this.setCreativeTab(Main.tabTest);
	this.setHardness(0.8f);
	this.setHarvestLevel("pickaxe", 1);
	this.setLightLevel(4.0f/16.0f);
	this.setLightOpacity(16);
	this.setResistance(5.0f);
	this.setSoundType(SoundType.STONE);

}


@Nullable
    public Item getItemDropped(IBlockState state, Random rand, int fortune)
    {
        return Item.getItemFromBlock(TestBlocks.green_iron_ore);
    }

public int quantityDropped (Random random)
{
	return 1;
}
}

 

TestBlock class that is called from Main

 

package ru.testmod.init;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraftforge.fml.common.registry.GameRegistry;
import ru.testmod.Reference;
import ru.testmod.block.BlockGreenOre;

public class TestBlocks 
{
public static Block green_iron_ore;

public static void init ()
{

}

public static void register ()
{
	GameRegistry.registerBlock(green_iron_ore = new BlockGreenOre(Material.ROCK));
}

public static void registerRenders ()
{
	registerRender(green_iron_ore);
}

public static void registerRender (Block block)
{
	Item item = Item.getItemFromBlock(block);
	Minecraft.getMinecraft().getRenderItem().getItemModelMesher().
	register(item, 0, new ModelResourceLocation(Reference.modID + ":" + item.getUnlocalizedName().substring(5), "inventory"));
}
}

 

and the Main class

 

package ru.testmod.main;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.EntityList;
import net.minecraft.item.ItemBlock;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy;
import ru.testmod.Reference;
import ru.testmod.init.TestBlocks;
import ru.testmod.init.TestItems;
import ru.testmod.init.TestTab;
import ru.testmod.proxy.CommonProxy;
import ru.testmod.recipes.TestRecipes;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.registry.EntityRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;

@Mod (modid = Reference.modID, name = Reference.name, version = Reference.version)

public class Main 
{
//instance
@Instance ("main")
public static Main instance;

//public static Block sbricks_carv_cracked;

//proxy
@SidedProxy (clientSide = Reference.client_proxy, serverSide = Reference.common_proxy)
public static CommonProxy proxy;

public static TestTab tabTest = new TestTab (12, "tabTest");

@EventHandler
public void preInit (FMLPreInitializationEvent event)
{
	TestItems.init();
	TestItems.register();
	TestBlocks.init();
	TestBlocks.register();
}

@EventHandler
public void init (FMLInitializationEvent event)
{
	proxy.registerRenders ();
	TestRecipes.AddRecipes ();
}

@EventHandler
public void postInit (FMLPostInitializationEvent event)
{

}

@EventHandler
public void serverLoad (FMLServerStartingEvent event)
{

}
}

 

 

And some shots:

 

b92e6fc782a3e47cbcbca0601057f77d.png

f86ffca308eb52481c52f4fd0dda78ff.png

 

 

So, when I trying to register new ItemBlock form green_ore (as told here), game crashes with error telling me about trying to register same name twice. If I changing the name (adding + " Block"), it gives me two blocks in a creative tab, both w/out textures and with same behaviour.

 

Also, when I trying to replace GameRegistry.registerBlock(block, block.getUnlocalizedName) with newest GameRegistry.register(block), it crashes (while creating an Item it is working).

Link to comment
Share on other sites

	public static void registerRender (Block block)
{
	Item item = Item.getItemFromBlock(block);
	Minecraft.getMinecraft().getRenderItem().getItemModelMesher().
	register(item, 0, new ModelResourceLocation(Reference.modID + ":" + item.getUnlocalizedName().substring(5), "inventory"));
}

 

This won't work.  You never create and register an ItemBlock for your block.

Also, don't use getUnlocalizedName for anything. Use getRegistryName.

Following that comment, do this:

setUnlocalizedName(getRegistryName())

 

Also, you have your rendering registration code inside common code, you can't do that.  It MUST exist in a proxy or you'll crash the dedicated server.

 

Here's how I do it:

https://github.com/Draco18s/ReasonableRealism/blob/master/src/main/java/com/draco18s/ores/client/ClientProxy.java

 

And if you check out my common proxy, you'll see how I register my items so that it translates cleanly from 1.7.10's style to 1.10's.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

After I kept seeing people make the same mistakes, I created this little GitHub project to help them.

Right now, it only handles Registering & Rendering of blocks, which seem to be exactly what you need :)

https://github.com/Matryoshika/Minecraft-Tests-Examples

 

It shows examples of simple, and looped registrations. As pointed out, the looped is the preferred there.

 

It also points you to use ModelLoader instead of getItemModelMesher(redundant) and why set & getRegistryName should be used instead of modid+substringing(completely horrid practice)

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

I created this little GitHub project ... Right now, it only handles Registering & Rendering of blocks

https://github.com/Matryoshika/Minecraft-Tests-Examples

I'm looking at the dynamic test block constructor. If it were ever called more than once, then multiple blocks would get the same name. Perhaps it could prepend some text derived from the input material.

 

I'm just starting my own upgrade from mc 1.8 to mc 1.10.2, so I'm looking at ways to handle changes like the explicit ItemBlock requirement and the shift to set/get RegistryName.

 

Is there really any gain from iterating a List of blocks? My gut says that building the List in the first place will be about as tedious as having each block call a shared setup method. Even so, I'll keep it in mind.

 

BTW, The OP doesn't mention having any blockstates file, so the mod probably needs to add one. If anyone knows where the new JSON rules for 1.10 are described in detail, please point. (I'm still digging out from under a pile of changed package names, so I haven't gotten there yet).

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

I'm just starting my own upgrade from mc 1.8 to mc 1.10.2, so I'm looking at ways to handle changes like the explicit ItemBlock requirement and the shift to set/get RegistryName.

 

Check out my Client/Common proxy files (linked above).

I boiled it down to a nice, clean "proxy.registerBlock," "proxy.registerBlockWithItem," etc. which does the game registry stuff and the rendering stuff all at once, and if it needs an item, then it gets an item registered automatically.  All that gets passed is the block (or item) and the registry name, so it looks very similar to 1.8 and prior.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

After I kept seeing people make the same mistakes, I created this little GitHub project to help them.

 

Thanks so much, I'm already re-writing my stuff, but not tested yet. BTW, another questions: is the loop method has sense for registering Items; and will this way of rendering Items work?:

ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory"));

 

 

ATM I just broke all my code trying to re-write it, so have no idea will it work or not

 

Link to comment
Share on other sites

Item and Blocks use the exact same way of registering, just need to convert the block to an item first(Item.getItemFromBlock(Block) == Item)

If you choose to use this way, then yes, it should work if you mirror the rendering.

Have a separate registering-list for items, and then call that item-list from your render-registry. Same setup as for the blocks.

 

Of course, this way only works for items without specific meta. That "0" inside

ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory"));

stands for the meta of the item that should be rendered.

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

Can you explain, please?

 

Blocks: Have a list that stores blocks

Items: Have list that stores items

 

Blocks in ModelLoader: Item.getItemFromBlock(block)

Items in ModelLoader: item

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

Can you explain, please?

 

Blocks: Have a list that stores blocks

Items: Have list that stores items

 

Blocks in ModelLoader: Item.getItemFromBlock(block)

Items in ModelLoader: item

 

Ah, of course, that's obvious. Just the word "mirror" confused me a bit  ;D

 

Thank you for your advices and patience, I got my new block and item registered and rendered correctly!

 

a528d383dfb8f5fd231b56d508b014a3.png

 

There is only one question remains: why my block not shading as like Coal Ore and other vanilla blocks does?

Link to comment
Share on other sites

Check out my Client/Common proxy files (linked above).

I boiled it down to a nice, clean "proxy.registerBlock," "proxy.registerBlockWithItem," etc. which does the game registry stuff and the rendering stuff all at once, and if it needs an item, then it gets an item registered automatically.  All that gets passed is the block (or item) and the registry name, so it looks very similar to 1.8 and prior.

Wow, several of those methods are very close to what I came up with. They neatly encapsulate several instructions that would otherwise be copy-pasted over and over somewhere else.

 

I also notice that most methods in those proxies are entirely generic (mod independent), meaning that it might be possible to promote them to higher-level classes outside any one mod. The common proxy would be usable by any mod as is, and any mod should be able to derive its client proxy by extending the generic client proxy. Of course, sharing code between mods has its downside...

 

Your example also answered (I think) another question I was pondering: Do we still need to set unlocalized names in 1.10 where we are using registry names. It seems that we do.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

Hey OP,

 

While I don't really have the answers you are looking for, I find MrCrayFish's tutorials are pretty accurate. They start with 1.9 and then transition to 1.10. I've been building a mod in 1.10 based on his tutorials and thus far things have been going pretty good. You can check out what I have so far based on his tutorial on github (https://github.com/CellverLimited/JADE)

 

Hope this can help you out a bit :)

Dustin / ReArmedHalo

Link to comment
Share on other sites

Your example also answered (I think) another question I was pondering: Do we still need to set unlocalized names in 1.10 where we are using registry names. It seems that we do.

 

Unlocalized names are purely for display, so yes, they still exist and don't point back to something else.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Hi again, guys :)

 

I have a new question. I digged around in MC and Forge code and manuals, but did not found any useful information about how to register render for custom blocks wit meta. I realized how to create, call and draw the blocks itself and I can get them via craft or tools (i.e. my item "moss pile" making chiseled mossy stone bricks from vanilla chiseled one), but my creative tab shows me three placeholders, each gives me the same block when placed (with meta=0). It assumes that standard way of registering render (where we casting Item.getItemFromBlock(block) ) is not correct in this way, so I calso can't register it via loop method described above. Should I manually call getItemFromBlock for each meta somehow?

Link to comment
Share on other sites

Well, if you cannot dynamically create your meta items through a simple for-loop, then you can always add them to a separate list. Let's call it itemMetaList.

Then you can iterate through that list, and get the meta value from them, though it will be in the order you added them to the list.

 

for(int meta = 0; meta < itemMetaList.size(); meta++){
   Item metaItem = itemMetaList.get(meta);
   //Code to register this metaItem using the variable "meta" for the meta parameter.
}

This method will also keep the easy set-and-forget method for rendering said items, as long as you remember to also initialize said stand-alone meta-renderer

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

Well, if you cannot dynamically create your meta items through a simple for-loop, then you can always add them to a separate list. Let's call it itemMetaList.

Then you can iterate through that list, and get the meta value from them, though it will be in the order you added them to the list.

 

Ok, I thought same way, but stuck when tried to loop through all metas -didn't found how to get every meta as int one by one if, say, we have no idea which block will be registered and how many metas it will have.

Link to comment
Share on other sites

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



×
×
  • Create New...

Important Information

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