Cayde Dixon bio photo

Cayde Dixon

Independant minecraft modder, developer and gamer. Email Twitter Google+ Github

Forge Mod Loader has an interesting addition that can be used in the placement of fields in relation to the instances of the Minecraft Items, including the modded items within it’s own system.

This system is used within Minecraft when FML is added to manage both the net.minecraft.init.Blocks and the net.minecraft.init.Items registries but, we can also use the @ObjectHolder(value) to our advantage to automatically provide both our own items, and potentially even modded items if they exist without the need for their APIs just to grab blocks and item instances though we may not be able to interact directly with them, it can be useful. And we do not even need to register, it is done automatically!

Why Use This?

When exploring this feature in FML it came to me of the power that could be used to just pull any object out of the registries and then use that in our systems1.

How Do We Use This?

Currently ObjectHolder is a very easy class to use, so there is not too much to document about other than when using @cpw.mods.fml.common.registry.GameRegistry.ObjectHolder is just to document on what the value() is all about.

Currently, there are only 3 different usages for the annotation but, for every field, they HAVE to be public static final.

Class Level

When we assign a value to the class level annotation it becomes the owner modid for the class, and each field is the block or item name that is being looked for.

Field level

Like when we apply this annotation to the class level, we have to specify a value, for this, it needs to be a fully qualified2 reference to the block.

For example, the value if we want to get the Jukebox block from my mod Jukebox-Reloaded we would have a value() for the annotation to be, jukeboxreloaded:jukebox

For example, the annotation could be

@GameRegistry.ObjectHolder("jukeboxreloaded:jukebox")
public static final Block jukebox = null;

Pro-tip: The initialization of the field is done so the java compiler does not complain, but it is set by FML in the run-time.

Class and Field level

FML is smart to the point, maybe the user does not want to code the names of the blocks or items, to be the same names?

Well in this case, we can have the class level annotation defining the modid as previously discussed, but also having the field level annotation, show the identifier for the block.

import cpw.mods.fml.common.registry.GameRegistry;

@GameRegistry.ObjectHolder("jukeboxreloaded")
public class JukeboxReloadedBlocks {
	@GameRegistry.ObjectHolder("jukebox")
	public static final Block someOtherName = null;
}

As you can see here, it can be hugely dynamic, and it even keeps up to date for any aliases3 that are placed on any blocks or items in the GameRegistry for Minecraft

How Can This be Useful?

Most mod APIs supply a method of linking to their Blocks and items, but it is commonly said, in the JVM, reflection is relatively slow, and many proprietary mods, provide a reflection based API. But here, we can drop those APIs if we are using just the blocks.

  1. Though, it is possible using the FML system, it is not recommended that you use the @OjbectHolder annotation to look up vanilla blocks or items, since they are easily accessible from the respective classes in net.minecraft.init

  2. in the format of modid:name

  3. To be covered in a later date (once I work this out).