4
\$\begingroup\$

After looking at a few tutorials on making minecraft mods i got as far as making my own blocks and the ModBlocks class to me looks awful and unruly especially when more blocks are added:

public class ModBlocks {

public static BlockPlatinum blockPlatinum;
public static BlockNickel blockNickel;

public static void init() {
    registerPlatinum();

    registerNickel();

}

@SideOnly(Side.CLIENT)
public static void initClient(ItemModelMesher mesher) {
    registerClientPlatinum(mesher);
    registerClientNickel(mesher);
}

private static void registerClientNickel(ItemModelMesher mesher) {
    Item item = Item.getItemFromBlock(blockNickel);
    ModelResourceLocation model = new ModelResourceLocation(ModMetaData.RESOURCE_PREFIX + References.NICKEL_BLOCK,
            "inventory");
    ModelLoader.registerItemVariants(item, model);
    mesher.register(item, 0, model);
}

private static void registerClientPlatinum(ItemModelMesher mesher) {
    Item item = Item.getItemFromBlock(blockPlatinum);
    ModelResourceLocation model = new ModelResourceLocation(ModMetaData.RESOURCE_PREFIX + References.PLATINUM_BLOCK,
            "inventory");
    ModelLoader.registerItemVariants(item, model);
    mesher.register(item, 0, model);
}

private static void registerNickel() {
    ResourceLocation location = new ResourceLocation(ModMetaData.MODID, References.NICKEL_BLOCK);
    blockNickel = new BlockNickel();
    blockNickel.setRegistryName(location);
    GameRegistry.register(blockNickel);
    GameRegistry.register(new ItemBlock(blockNickel), location);
}

private static void registerPlatinum() {
    ResourceLocation location = new ResourceLocation(ModMetaData.MODID, References.PLATINUM_BLOCK);
    blockPlatinum = new BlockPlatinum();
    blockPlatinum.setRegistryName(location);
    GameRegistry.register(blockPlatinum);
    GameRegistry.register(new ItemBlock(blockPlatinum), location);
}

}

I have already tried extracting the Block* classes and putting them into a static list and then refactoring the init and client init methods to iterate over the list but that produces invisible blocks.

I am sure this is a problem long since solved by Minecraft mod devs, so if anyone has any guidance that would be awesome.

\$\endgroup\$
1
\$\begingroup\$

Your updated version is pretty darn good. As in, "You're basically done, no need to make any further changes." (See note at the bottom).

The only thing I did differently (aside from creating non-normal registration methods as well that do all sorts of things) was to take two classes I already had and give them the register function: ClientProxy and CommonProxy.

My setup is such that ClientProxy.register calls super (which calls GameRegistry.register for the block as well as creating and registering the itemblock) and then calls ModelLoader.setCustomModelResourceLocation for the item (or registerItemVariants for block-variant items, or other methods for other pathways).

I later moved this code over into a library package I already had (centralizing the gains and avoiding duplication), added some static methods (in the Common) as helper redirects and ended up with this class which can be boiled down to these two methods for the basic no-nonsense blocks:

public void _registerBlockWithItem(Block block, String registryname) {
    super._registerBlockWithItem(block, registryname);
    _registerBlockResources(block);
}

private void _registerBlockResources(Block block) {
    Item item = Item.getItemFromBlock(block);
    ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(block.getRegistryName(),"normal"));
}

The first method being equivalent to your register method which self-calls your registerClient only on the client side, which then allows us to merge init and initClient.

This made my ModBlocks (well, main mod class in my case) very slim when it comes to registering blocks and items. Looks almost 1.7ish!

There are still some minor improvements which could be made, but at two-three lines per block it's a vast improvement over your original thirteen lines per block.

Note: you should also mark registerClient as @SideOnly(Side.CLIENT) as well: that method is still refers to a class that doesn't exist on the server (ModelLoader) and may crash the dedicated server when the JVM tries to load your ModBlocks class.

\$\endgroup\$
0
\$\begingroup\$

Do BlockPlatinum, BlockTin,... extend the Block class? If yes, you can create Map<Reference, Block> and iterate over it.

Map<String, Block> blocksWithReferences = new HashMap<>();

...

for(Map.Entry<String, Block> blockEntry:blocks.entrySet()){
        blockEntry.getKey();//Reference in String
        blockEntry.getValue();//Block object
}

For adding new block you just need to add it:

block.put(reference, Block);

Do you need blocks to be public? It is better to change them to private and create getters/setters methods when you need them only in this class.

\$\endgroup\$
  • \$\begingroup\$ The downside to this method is if you ever want to do anything non-normal, say a block with a custom ItemBlock class. That's going to need to be registered differently. Or a block with a custom IStateMapper (but default item)? Custom IStateMapper and custom item..? A block with no item..? The hashmap idea only works if every block you have is registered the exact same way. It's one of the reasons that 1.11's RegistryEvent<T> makes me grind my teeth (and all the examples of using said events). I can't do all the "with custom..." things in the same place as I create the block itself. \$\endgroup\$ – Draco18s Apr 27 '17 at 18:11
  • \$\begingroup\$ Theoretically you can make wrapper on it or even put just Object into HashMap. In second approach you need to remember somehow what class this object was. Maybe if else with instanceof? \$\endgroup\$ – Michał Piątkowski Apr 27 '17 at 20:18
  • \$\begingroup\$ Oh there are ways to handle it, it just feels messy and disconnected to me. I'll probably come up with a new system that handles it eventually, but I haven't needed to yet (GameRegistry.register still works) and it'll probably end up being a bunch of interfaces I apply to my classes. \$\endgroup\$ – Draco18s Apr 27 '17 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.