Changes

529 bytes added ,  00:58, 30 July 2021
Update to 1.17
Line 5: Line 5:  
Most objects that are known within the game are handled by a <code>Registry</code>. Each registry uniquely defines each object through a "registry name" via a [[Using Resources#ResourceLocation|ResourceLocation]]. This "registry name" can be accessed with its respective getter and setter: <code>#getRegistryName</code> and <code>#setRegistryName</code>. You can only set the "registry name" of a given object once; otherwise, an exception will be thrown.
 
Most objects that are known within the game are handled by a <code>Registry</code>. Each registry uniquely defines each object through a "registry name" via a [[Using Resources#ResourceLocation|ResourceLocation]]. This "registry name" can be accessed with its respective getter and setter: <code>#getRegistryName</code> and <code>#setRegistryName</code>. You can only set the "registry name" of a given object once; otherwise, an exception will be thrown.
   −
{{Tip|In a global context, each object is universally unique through its <code>RegistryKey</code>: a concatenation of its registry's id and the object's registry name.}}
+
{{Tip|In a global context, each object is universally unique through its <code>ResourceKey</code>: a concatenation of its registry's id and the object's registry name.}}
    
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using <code>IForgeRegistry</code>. This guarantees that the loading order for these wrapped registries will be <code>Block</code>, <code>Item</code>, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the <code>ForgeRegistries</code> class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a <code>Block</code> and an <code>Item</code> each hold a registry object named <code>examplemod:object</code>.
 
Due to the inconsistent ordering and registration process vanilla uses, Forge wraps most vanilla registries using <code>IForgeRegistry</code>. This guarantees that the loading order for these wrapped registries will be <code>Block</code>, <code>Item</code>, and then the rest of the wrapped registries in alphabetical order. All registries supported by Forge can be found within the <code>ForgeRegistries</code> class. Since all registry names are unique to a specific registry, different registry objects within different registries can have the same name (e.g. a <code>Block</code> and an <code>Item</code> each hold a registry object named <code>examplemod:object</code>.
Line 26: Line 26:  
|java=private static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);
 
|java=private static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);
   −
public static final RegistryObject<Block> EXAMPLE_BLOCK = BLOCKS.register("example_block", () -> new Block(AbstractBlock.Properties.create(Material.ROCK)));
+
public static final RegistryObject<Block> EXAMPLE_BLOCK = BLOCKS.register("example_block", () -> new Block(BlockBehaviour.Properties.of(Material.STONE)));
    
public ExampleMod() {
 
public ExampleMod() {
Line 33: Line 33:  
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)
 
|kotlin=private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)
   −
val EXAMPLE_BLOCK: RegistryObject<Block> = BLOCKS.register("example_block") { Block(AbstractBlock.Properties.create(Material.ROCK)) }
+
val EXAMPLE_BLOCK: RegistryObject<Block> = BLOCKS.register("example_block") { Block(BlockBehaviour.Properties.of(Material.ROCK)) }
    
internal class ExampleMod {
 
internal class ExampleMod {
Line 43: Line 43:  
     private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)
 
     private final val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID)
   −
     final val EXAMPLE_BLOCK = registerBlock("example_block", () => new Block(AbstractBlock.Properties.create(Material.ROCK)))
+
     final val EXAMPLE_BLOCK = registerBlock("example_block", () => new Block(BlockBehaviour.Properties.of(Material.ROCK)))
 
}
 
}
 
class ExampleMod {
 
class ExampleMod {
Line 76: Line 76:  
|}}
 
|}}
   −
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, <code>*Type</code> classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Tile_Entities|<code>TileEntity</code>]] is wrapped via <code>TileEntityType</code>, and <code>Entity</code> is wrapped via <code>EntityType</code>. These <code>*Type</code> classes hold factories that simply create the containing type on demand.
+
{{Tip/Important|Since all objects registered must be singleton, some classes cannot by themselves be registered. Instead, <code>*Type</code> classes are registered and used in the formers' constructors to wrap the flyweight objects. For example, a [[Basics_of_Block_Entities|<code>BlockEntity</code>]] is wrapped via <code>BlockEntityType</code>, and <code>Entity</code> is wrapped via <code>EntityType</code>. These <code>*Type</code> classes hold factories that simply create the containing type on demand.
   −
These factory holders are created through the use of their <code>*Type$Builder</code> classes. An example: (<code>REGISTER</code> here refers to a <code>DeferredRegister<TileEntityType<?>></code>)
+
These factory holders are created through the use of their <code>*Type$Builder</code> classes. An example: (<code>REGISTER</code> here refers to a <code>DeferredRegister<BlockEntityType<?>></code>)
    
{{Template:Tabs/Code_Snippets
 
{{Template:Tabs/Code_Snippets
|java=public static final RegistryObject<TileEntityType<ExampleTile>> EXAMPLE_TILE = REGISTER.register(
+
|java=public static final RegistryObject<BlockEntityType<ExampleBlockEntity>> EXAMPLE_BLOCK_ENTITY = REGISTER.register(
     "example_tile", () -> TileEntityType.Builder.create(ExampleTile::new, EXAMPLE_BLOCK.get()).build(null)
+
     "example_block_entity", () -> BlockEntityType.Builder.of(ExampleBlockEntity::new, EXAMPLE_BLOCK.get()).build(null)
 
);
 
);
|kotlin=val EXAMPLE_TILE: RegistryObject<TileEntityType<ExampleTile>> = REGISTER.register("example_tile") { TileEntityType.Builder.create(::ExampleTile, EXAMPLE_BLOCK.get()).build(null)) }
+
|kotlin=val EXAMPLE_BLOCK_ENTITY: RegistryObject<BlockEntityType<ExampleBlockEntity>> = REGISTER.register("example_block_entity") { BlockEntityType.Builder.of(::ExampleBlockEntity, EXAMPLE_BLOCK.get()).build(null)) }
|scala=final val EXAMPLE_TILE = REGISTER.register("example_tile", () => TileEntityType.Builder.create(() => new ExampleTile(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))
+
|scala=final val EXAMPLE_BLOCK_ENTITY = REGISTER.register("example_block_entity", () => BlockEntityType.Builder.of(() => new ExampleBlockEntity(), GeneralRegistrar.EXAMPLE_BLOCK.get).build(null))
 
|}}
 
|}}
 
}}
 
}}
Line 95: Line 95:  
These registries include:
 
These registries include:
 
* Custom Stats (a <code>ResourceLocation</code> registry)
 
* Custom Stats (a <code>ResourceLocation</code> registry)
* <code>IRuleTestType</code>
+
* <code>RuleTestType</code>
* <code>IPosRuleTests</code>
+
* <code>PosRuleTestType</code>
* <code>IRecipeType</code>
+
* <code>RecipeType</code>
 +
* <code>GameEvent</code>
 +
* <code>PositionSourceType</code>
 
* <code>VillagerType</code>
 
* <code>VillagerType</code>
 
* <code>LootPoolEntryType</code>
 
* <code>LootPoolEntryType</code>
* <code>LootFunctionType</code>
+
* <code>LootItemFunctionType</code>
* <code>LootConditionType</code>
+
* <code>LootItemConditionType</code>
* <code>IStructurePieceType</code>
+
* <code>LootNumberProviderType</code>
 +
* <code>LootNbtProviderType</code>
 +
* <code>LootScoreProviderType</code>
 +
* <code>FloatProviderType</code>
 +
* <code>IntProviderType</code>
 +
* <code>HeightProviderType</code>
 +
* <code>StructurePieceType</code>
 
* <code>TrunkPlacerType</code>
 
* <code>TrunkPlacerType</code>
 
* <code>FeatureSizeType</code>
 
* <code>FeatureSizeType</code>
* <code>BiomeProvider</code> (A <code>Codec</code> registry)
+
* A <code>Codec</code> of <code>BiomeSource</code>
* <code>ChunkGenerator</code> (A <code>Codec</code> registry)
+
* A <code>Codec</code> of <code>ChunkGenerator</code>
* <code>IStructureProcessorType</code>
+
* <code>StructureProcessorType</code>
* <code>IJigsawDeserializer</code>
+
* <code>StructurePoolElementType</code>
* All registries within <code>WorldGenRegistries</code> excluding <code>Biome</code>
+
* All registries within <code>BuiltinRegistries</code> excluding <code>Biome</code>
    
To register objects to any one of these registries, you will need to call <code>Registry::register(Registry, ResourceLocation, T)</code> where the type parameter <code>T</code> is the object instance being registered. The method can then be called and registered during the highest priority of <code>FMLCommonSetupEvent</code>. We can also utilize a <code>Lazy</code> above to store the result on first access and use within our code.
 
To register objects to any one of these registries, you will need to call <code>Registry::register(Registry, ResourceLocation, T)</code> where the type parameter <code>T</code> is the object instance being registered. The method can then be called and registered during the highest priority of <code>FMLCommonSetupEvent</code>. We can also utilize a <code>Lazy</code> above to store the result on first access and use within our code.
Line 118: Line 126:  
|java=public static final Lazy<ConfiguredFeature<?, ?>> EXAMPLE_CONFIGURED_FEATURE = Lazy.of(() ->
 
|java=public static final Lazy<ConfiguredFeature<?, ?>> EXAMPLE_CONFIGURED_FEATURE = Lazy.of(() ->
 
     register("example_configured_feature",
 
     register("example_configured_feature",
         Feature.NO_OP.withConfiguration(NoFeatureConfig.field_236559_b_)
+
         Feature.NO_OP.configured(NoneFeatureConfiguration.INSTANCE)
             .withPlacement(Placement.NOPE.configure(NoPlacementConfig.INSTANCE))
+
             .decorated(FeatureDecorator.NOPE.configured(NoneDecoratorConfiguration.INSTANCE))
 
     )
 
     )
 
);
 
);
Line 129: Line 137:     
private static <T extends ConfiguredFeature<?, ?>> T register(String name, T value) {
 
private static <T extends ConfiguredFeature<?, ?>> T register(String name, T value) {
     return Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, new ResourceLocation(MODID, name), value);
+
     return Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new ResourceLocation(MODID, name), value);
 
}
 
}
 
|kotlin=val EXAMPLE_CONFIGURED_FEATURE: ConfiguredFeature<*, *> by lazy {
 
|kotlin=val EXAMPLE_CONFIGURED_FEATURE: ConfiguredFeature<*, *> by lazy {
 
     register("example_configured_feature",  
 
     register("example_configured_feature",  
         Feature.NO_OP.withConfiguration(NoFeatureConfig.field_236559_b_)
+
         Feature.NO_OP.configured(NoneFeatureConfiguration.INSTANCE)
             .withPlacement(Placement.NOPE.configure(NoPlacementConfig.INSTANCE)))
+
             .decorated(FeatureDecorator.NOPE.configured(NoneDecoratorConfiguration.INSTANCE)))
 
}
 
}
   Line 146: Line 154:     
private fun <T: ConfiguredFeature<*, *>> register(name: String, value: T): T =
 
private fun <T: ConfiguredFeature<*, *>> register(name: String, value: T): T =
     Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, ResourceLocation(MODID, name), value)
+
     Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, ResourceLocation(MODID, name), value)
 
|scala=class Events {
 
|scala=class Events {
 
     @SubscribeEvent(priority = EventPriority.HIGHEST)
 
     @SubscribeEvent(priority = EventPriority.HIGHEST)
Line 155: Line 163:  
object Events {
 
object Events {
 
     final lazy val EXAMPLE_CONFIGURED_FEATURE = register("example_configured_feature",
 
     final lazy val EXAMPLE_CONFIGURED_FEATURE = register("example_configured_feature",
         Feature.NO_OP.withConfiguration(NoFeatureConfig.field_236559_b_)
+
         Feature.NO_OP.configured(NoneFeatureConfiguration.INSTANCE)
             .withPlacement(Placement.NOPE.configure(NoPlacementConfig.INSTANCE)))
+
             .decorated(FeatureDecorator.NOPE.configured(NoneDecoratorConfiguration.INSTANCE)))
    
     private def register[T <: ConfiguredFeature[_, _]](name: String, value: T): T =
 
     private def register[T <: ConfiguredFeature[_, _]](name: String, value: T): T =
         Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, new ResourceLocation(MODID, name), value)
+
         Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new ResourceLocation(MODID, name), value)
 
}
 
}
 
|}}
 
|}}
Line 165: Line 173:  
{{Tip/Warning|Vanilla registry methods are not thread-safe, so they must be wrapped within the synchronous queue provided within the common setup event via <code>#enqueueWork</code>.}}
 
{{Tip/Warning|Vanilla registry methods are not thread-safe, so they must be wrapped within the synchronous queue provided within the common setup event via <code>#enqueueWork</code>.}}
   −
Besides the registries within <code>WorldGenRegistries</code>, all other '''non-forge''' wrapped registries can be statically initialized like so:
+
Besides the registries within <code>BuiltinRegistries</code>, all other '''non-forge''' wrapped registries can be statically initialized like so:
    
{{Template:Tabs/Code_Snippets
 
{{Template:Tabs/Code_Snippets
|java=public static final IRecipeType<ExampleRecipe> EXAMPLE_RECIPE = IRecipeType.register(MODID + ":example_recipe");
+
|java=public static final RecipeType<ExampleRecipe> EXAMPLE_RECIPE = RecipeType.register(MODID + ":example_recipe");
|kotlin=val EXAMPLE_RECIPE: IRecipeType<ExampleRecipe> = IRecipeType.register("${MODID}:example_recipe")
+
|kotlin=val EXAMPLE_RECIPE: RecipeType<ExampleRecipe> = RecipeType.register("${MODID}:example_recipe")
|scala=final val EXAMPLE_RECIPE = IRecipeType.register(s"${MODID}:example_recipe")
+
|scala=final val EXAMPLE_RECIPE = RecipeType.register(s"${MODID}:example_recipe")
 
|}}
 
|}}
   Line 177: Line 185:  
=== Data Driven Entries ===
 
=== Data Driven Entries ===
   −
Registries are considered to be data driven if they are located within <code>DynamicRegistries</code> with the exception of <code>Dimension</code>.
+
Registries are considered to be data driven if they are located within <code>RegistryAccess</code> with the exception of <code>LevelStem</code> and <code>Level</code>.
    
The following registries are data driven:
 
The following registries are data driven:
 
* <code>ConfiguredSurfaceBuilder</code>
 
* <code>ConfiguredSurfaceBuilder</code>
* <code>ConfiguredCarver</code>
+
* <code>ConfiguredWorldCarver</code>
 
* <code>ConfiguredFeature</code>
 
* <code>ConfiguredFeature</code>
* <code>StructureFeature</code>
+
* <code>ConfiguredStructureFeature</code>
 
* <code>StructureProcessorList</code>
 
* <code>StructureProcessorList</code>
* <code>JigsawPattern</code>
+
* <code>StructureTemplatePool</code>
 
* <code>Biome</code>
 
* <code>Biome</code>
* <code>DimensionSettings</code>
+
* <code>NoiseGeneratorSettings</code>
 
* <code>DimensionType</code>
 
* <code>DimensionType</code>
* <code>Dimension</code>
+
* <code>LevelStem</code>
 +
* <code>Level</code>
    
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a <code>ConfiguredFeature</code> for ore generation within an overworld <code>Biome</code>). Otherwise, their instance can be purely registered using a JSON file.
 
These registry objects only need to be registered within code if they are to be used within a pre-existing registry object (e.g. a <code>ConfiguredFeature</code> for ore generation within an overworld <code>Biome</code>). Otherwise, their instance can be purely registered using a JSON file.
Line 204: Line 213:  
<code>RegistryObject</code>s can be used to retrieve references to registered objects once they become available. Their references are updated along with all <code>@ObjectHolder</code> annotations after the associated <code>RegistryEvent$Register</code> has been dispatched and frozen.
 
<code>RegistryObject</code>s can be used to retrieve references to registered objects once they become available. Their references are updated along with all <code>@ObjectHolder</code> annotations after the associated <code>RegistryEvent$Register</code> has been dispatched and frozen.
   −
A <code>RegistryObject</code> can be retrieved as a result of using <code>DeferredRegister</code> or calling the static constructor <code>RegistryObject::of</code>. Each static constructor takes in the "registry name" of the object being referenced and either a <code>IForgeRegistry</code> or, if custom registries are used, a supplier of the object class implementing <code>IForgeRegistryEntry</code>. The <code>RegistryObject</code> can be stored within some field and retreive the registered object using <code>#get</code>.
+
A <code>RegistryObject</code> can be retrieved as a result of using <code>DeferredRegister</code> or calling the static constructor <code>RegistryObject::of</code>. Each static constructor takes in the "registry name" of the object being referenced and either a <code>IForgeRegistry</code> or, if custom registries are used, a supplier of the object class implementing <code>IForgeRegistryEntry</code>. The <code>RegistryObject</code> can be stored within some field and retrieve the registered object using <code>#get</code>.
    
An example using <code>RegistryObject</code>:
 
An example using <code>RegistryObject</code>:
Line 259: Line 268:  
@ObjectHolder("minecraft") // Inheritable resource namespace: "minecraft"
 
@ObjectHolder("minecraft") // Inheritable resource namespace: "minecraft"
 
class AnnotatedHolder {
 
class AnnotatedHolder {
     public static final Block diamond_block = null; // No annotation. [public static final] is required.
+
     public static final Block diamond_block = null;   // No annotation. [public static final] is required.
                                                    // Block has a corresponding registry: [Block]
+
                                                      // Block has a corresponding registry: [Block]
                                                    // Name path is the name of the field: "diamond_block"
+
                                                      // Name path is the name of the field: "diamond_block"
                                                    // Namespace is not explicitly defined.
+
                                                      // Namespace is not explicitly defined.
                                                    // So, namespace is inherited from class annotation: "minecraft"
+
                                                      // So, namespace is inherited from class annotation: "minecraft"
                                                    // To inject: "minecraft:diamond_block" from the [Block] registry
+
                                                      // To inject: "minecraft:diamond_block" from the [Block] registry
    
     @ObjectHolder("ambient.cave")
 
     @ObjectHolder("ambient.cave")
     public static SoundEvent ambient_sound = null; // Annotation present. [public static] is required.
+
     public static SoundEvent ambient_sound = null;   // Annotation present. [public static] is required.
                                                    // SoundEvent has a corresponding registry: [SoundEvent]
+
                                                      // SoundEvent has a corresponding registry: [SoundEvent]
                                                    // Name path is the value of the annotation: "ambient.cave"
+
                                                      // Name path is the value of the annotation: "ambient.cave"
                                                    // Namespace is not explicitly defined.
+
                                                      // Namespace is not explicitly defined.
                                                    // So, namespace is inherited from class annotation: "minecraft"
+
                                                      // So, namespace is inherited from class annotation: "minecraft"
                                                    // To inject: "minecraft:ambient.cave" from the [SoundEvent] registry
+
                                                      // To inject: "minecraft:ambient.cave" from the [SoundEvent] registry
    
     // Assume for the next entry that [ManaType] is a valid registry.           
 
     // Assume for the next entry that [ManaType] is a valid registry.           
 
     @ObjectHolder("neomagicae:coffeinum")
 
     @ObjectHolder("neomagicae:coffeinum")
     public static final ManaType coffeinum = null; // Annotation present. [public static] is required. [final] is optional.
+
     public static final ManaType coffeinum = null;   // Annotation present. [public static] is required. [final] is optional.
                                                    // ManaType has a corresponding registry: [ManaType] (custom registry)
+
                                                      // ManaType has a corresponding registry: [ManaType] (custom registry)
                                                    // Resource location is explicitly defined: "neomagicae:coffeinum"
+
                                                      // Resource location is explicitly defined: "neomagicae:coffeinum"
                                                    // To inject: "neomagicae:coffeinum" from the [ManaType] registry
+
                                                      // To inject: "neomagicae:coffeinum" from the [ManaType] registry
   −
     public static final Item ENDER_PEARL = null;   // No annotation. [public static final] is required.
+
     public static final Item ENDER_PEARL = null;     // No annotation. [public static final] is required.
                                                    // Item has a corresponding registry: [Item].
+
                                                      // Item has a corresponding registry: [Item].
                                                    // Name path is the name of the field: "ENDER_PEARL" -> "ender_pearl"
+
                                                      // Name path is the name of the field: "ENDER_PEARL" -> "ender_pearl"
                                                    // !! ^ Field name is valid, because they are
+
                                                      // !! ^ Field name is valid, because they are
                                                    //      converted to lowercase automatically.
+
                                                      //      converted to lowercase automatically.
                                                    // Namespace is not explicitly defined.
+
                                                      // Namespace is not explicitly defined.
                                                    // So, namespace is inherited from class annotation: "minecraft"
+
                                                      // So, namespace is inherited from class annotation: "minecraft"
                                                    // To inject: "minecraft:ender_pearl" from the [Item] registry
+
                                                      // To inject: "minecraft:ender_pearl" from the [Item] registry
    
     @ObjectHolder("minecraft:arrow")
 
     @ObjectHolder("minecraft:arrow")
     public static final ArrowItem arrow = null;     // Annotation present. [public static] is required. [final] is optional.
+
     public static final ArrowItem arrow = null;       // Annotation present. [public static] is required. [final] is optional.
                                                    // ArrowItem does not have a corresponding registry.
+
                                                      // ArrowItem does not have a corresponding registry.
                                                    // ArrowItem's supertype of Item has a corresponding registry: [Item]
+
                                                      // ArrowItem's supertype of Item has a corresponding registry: [Item]
                                                    // Resource location is explicitly defined: "minecraft:arrow"
+
                                                      // Resource location is explicitly defined: "minecraft:arrow"
                                                    // To inject: "minecraft:arrow" from the [Item] registry                                                     
+
                                                      // To inject: "minecraft:arrow" from the [Item] registry                                                     
   −
     public static Block bedrock = null;             // No annotation, so [public static final] is required.
+
     public static Block bedrock = null;               // No annotation, so [public static final] is required.
                                                    // Therefore, the field is ignored.
+
                                                      // Therefore, the field is ignored.
 
      
 
      
     public static final ItemGroup group = null;     // No annotation. [public static final] is required.
+
     public static final CreativeModeTab group = null; // No annotation. [public static final] is required.
                                                    // ItemGroup does not have a corresponding registry.
+
                                                      // CreativeModeTab does not have a corresponding registry.
                                                    // No supertypes of ItemGroup has a corresponding registry.
+
                                                      // No supertypes of CreativeModeTab has a corresponding registry.
                                                    // Therefore, THIS WILL PRODUCE AN EXCEPTION.
+
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.
 
}
 
}
    
class UnannotatedHolder { // Note the lack of an @ObjectHolder annotation on this class.
 
class UnannotatedHolder { // Note the lack of an @ObjectHolder annotation on this class.
 
     @ObjectHolder("minecraft:flame")
 
     @ObjectHolder("minecraft:flame")
     public static final Enchantment flame = null;   // Annotation present. [public static] is required. [final] is optional.
+
     public static final Enchantment flame = null;     // Annotation present. [public static] is required. [final] is optional.
                                                    // Enchantment has corresponding registry: [Enchantment].
+
                                                      // Enchantment has corresponding registry: [Enchantment].
                                                    // Resource location is explicitly defined: "minecraft:flame"
+
                                                      // Resource location is explicitly defined: "minecraft:flame"
                                                    // To inject: "minecraft:flame" from the [Enchantment] registry
+
                                                      // To inject: "minecraft:flame" from the [Enchantment] registry
   −
     public static final Biome ice_flat = null;     // No annotation on the enclosing class.
+
     public static final Biome ice_flat = null;       // No annotation on the enclosing class.
                                                    // Therefore, the field is ignored.
+
                                                      // Therefore, the field is ignored.
    
     @ObjectHolder("minecraft:creeper")
 
     @ObjectHolder("minecraft:creeper")
     public static Entity creeper = null;           // Annotation present. [public static] is required.
+
     public static Entity creeper = null;             // Annotation present. [public static] is required.
                                                    // Entity does not have a corresponding registry.
+
                                                      // Entity does not have a corresponding registry.
                                                    // No supertypes of Entity has a corresponding registry.
+
                                                      // No supertypes of Entity has a corresponding registry.
                                                    // Therefore, THIS WILL PRODUCE AN EXCEPTION.
+
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.
    
     @ObjectHolder("levitation")
 
     @ObjectHolder("levitation")
     public static final Potion levitation = null;   // Annotation present. [public static] is required. [final] is optional.
+
     public static final Potion levitation = null;     // Annotation present. [public static] is required. [final] is optional.
                                                    // Potion has a corresponding registry: [Potion].
+
                                                      // Potion has a corresponding registry: [Potion].
                                                    // Name path is the value of the annotation: "levitation"
+
                                                      // Name path is the value of the annotation: "levitation"
                                                    // Namespace is not explicitly defined.
+
                                                      // Namespace is not explicitly defined.
                                                    // No annotation in enclosing class.
+
                                                      // No annotation in enclosing class.
                                                    // Therefore, THIS WILL PRODUCE AN EXCEPTION.
+
                                                      // Therefore, THIS WILL PRODUCE AN EXCEPTION.
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>