Posted September 3, 20169 yr 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: 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).
September 3, 20169 yr 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.
September 3, 20169 yr 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.
September 3, 20169 yr 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.
September 3, 20169 yr 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.
September 3, 20169 yr Author 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
September 3, 20169 yr 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.
September 3, 20169 yr 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.
September 4, 20169 yr Author 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 Thank you for your advices and patience, I got my new block and item registered and rendered correctly! There is only one question remains: why my block not shading as like Coal Ore and other vanilla blocks does?
September 4, 20169 yr Check those lines in the constructor of your block: this.setLightLevel(4.0f/16.0f); this.setLightOpacity(16); Developer of Primeval Forest.
September 4, 20169 yr Author Check those lines in the constructor of your block: this.setLightLevel(4.0f/16.0f); this.setLightOpacity(16); Yea, I found I experimented with this parameter and forgot to zero it Just came here to edit post, but you replied. Thanks!
September 4, 20169 yr 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.
September 4, 20169 yr 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
September 4, 20169 yr 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.
September 5, 20169 yr Author 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?
September 5, 20169 yr 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.
September 5, 20169 yr Author 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.
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.