### String to Integer Conversion Examples Source: https://docs.minecraftforge.net/en/1.20.1/datastorage/codecs Shows examples of string inputs to the `INT_CODEC`, illustrating successful conversion and error cases. ```json // Will return 5 "5" // Will error, not an integer "value" ``` -------------------------------- ### Batch Setup and Teardown Source: https://docs.minecraftforge.net/en/1.20.1/misc/gametest Annotate methods with @BeforeBatch for setup or @AfterBatch for teardown, matching the batch string of the game tests. Batch methods accept a ServerLevel parameter for level manipulation. ```java public class ExampleGameTests { @BeforeBatch(batch = "firstBatch") public static void beforeTest(ServerLevel level) { // Perform setup } @GameTest(batch = "firstBatch") public static void exampleTest2(GameTestHelper helper) { // Do stuff } } ``` -------------------------------- ### Package Naming Conflict Example (Modules) Source: https://docs.minecraftforge.net/en/1.20.1/gettingstarted/structuring Demonstrates how exporting the same package name from different modules can lead to mod loader crashes. ```text module A - package X - class I - class J module B - package X // This package will cause the mod loader to crash, as there already is a module with package X being exported - class R - class S - class T ``` -------------------------------- ### Implement AdvancementGenerator Source: https://docs.minecraftforge.net/en/1.20.1/datagen/server/advancements This is an example of how to implement the `ForgeAdvancementProvider$AdvancementGenerator` interface. The `generate` method is where you will define and build your advancements. ```java // In some subclass of ForgeAdvancementProvider$AdvancementGenerator or as a lambda reference @Override public void generate(HolderLookup.Provider registries, Consumer writer, ExistingFileHelper existingFileHelper) { // Build advancements here } ``` -------------------------------- ### Example Custom Recipe Implementation Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/recipes/custom Demonstrates a basic record implementation of the Recipe interface for custom recipe logic. Ensure that the 'assemble' method produces a unique ItemStack. ```java public record ExampleRecipe(Ingredient input, int data, ItemStack output) implements Recipe { // Implement methods here } ``` -------------------------------- ### PartialNBTIngredient Example Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/recipes/ingredients A looser NBT comparison, checking against items and only specified NBT keys. Can use 'item' or 'items'. ```json { "type": "forge:partial_nbt", "//": "Either 'item' or 'items' must be specified\n // If both are specified, only 'item' will be read", "item": "examplemod:example_item", "items": [ "examplemod:example_item", "examplemod:example_item2" "// ..." ], "nbt": { "//": "Checks only for equivalency on 'key1' and 'key2'\n // All other keys in the stack will not be checked", "key1": "data1", "key2": { "//": "Data 2" } } } ``` -------------------------------- ### Item Translation Key Example Source: https://docs.minecraftforge.net/en/1.20.1/concepts/internationalization Shows the required entry in a language file for an item with the registry name 'examplemod:example_item'. This ensures the item has a displayable name in the game. ```json { "item.examplemod.example_item": "Example Item Name" } ``` -------------------------------- ### Package Naming Conflict Example (JARs) Source: https://docs.minecraftforge.net/en/1.20.1/gettingstarted/structuring Illustrates how two JAR files with the same package name can cause conflicts and prevent one class from loading. ```text a.jar - com.example.ExampleClass b.jar - com.example.ExampleClass // This class will not normally be loaded ``` -------------------------------- ### Initialize RegistrySetBuilder and Add Registries Source: https://docs.minecraftforge.net/en/1.20.1/datagen/server/datapackregistries Demonstrates how to initialize a RegistrySetBuilder and add specific registries for registration. This includes examples for configured features and placed features, showing the structure for defining bootstrap consumers. ```java new RegistrySetBuilder() // Create configured features .add(Registries.CONFIGURED_FEATURE, bootstrap -> { // Register configured features here }) // Create placed features .add(Registries.PLACED_FEATURE, bootstrap -> { // Register placed features here }); ``` -------------------------------- ### Run Gradle Configurations Directly Source: https://docs.minecraftforge.net/en/1.20.1/gettingstarted These commands can be used to run various configurations directly from the terminal, including client, server, data, and game test server setups. They are also applicable within supported IDEs. ```bash gradlew runClient ``` ```bash gradlew runServer ``` ```bash gradlew runData ``` ```bash gradlew runGameTestServer ``` -------------------------------- ### Generate Visual Studio Code Run Configurations Source: https://docs.minecraftforge.net/en/1.20.1/gettingstarted Use this Gradle task to set up run configurations for Visual Studio Code. Ensure you have the 'Gradle for Java' plugin installed. ```bash gradlew getVSCodeRuns ``` -------------------------------- ### Encoded SomeObject JSON Examples Source: https://docs.minecraftforge.net/en/1.20.1/datastorage/codecs Illustrates the JSON representation of `SomeObject`, including cases where optional fields are omitted. ```json { "s": "value", "i": 5, "b": false } // Another encoded SomeObject { "s": "value2", // i is omitted, defaults to 0 "b": true } ``` -------------------------------- ### Integer Range Codec Examples Source: https://docs.minecraftforge.net/en/1.20.1/datastorage/codecs Illustrates inputs for the `RANGE_CODEC`, showing a valid value within the range and an invalid value outside the range. ```json // Will be valid, inside [0, 4] 4 // Will error, outside [0, 4] 5 ``` -------------------------------- ### Example mods.toml Configuration Source: https://docs.minecraftforge.net/en/1.20.1/gettingstarted/modfiles This TOML file defines the metadata for a mod, including its ID, version, display information, and dependencies on Forge and Minecraft. It is stored in src/main/resources/META-INF/mods.toml. ```toml modLoader="javafml" loaderVersion="[46,)" license="All Rights Reserved" issueTrackerURL="https://github.com/MinecraftForge/MinecraftForge/issues" showAsResourcePack=false [[mods]] modId="examplemod" version="1.0.0.0" displayName="Example Mod" updateJSONURL="https://files.minecraftforge.net/net/minecraftforge/forge/promotions_slim.json" displayURL="https://minecraftforge.net" logoFile="logo.png" credits="I'd like to thank my mother and father." authors="Author" description=''' Lets you craft dirt into diamonds. This is a traditional mod that has existed for eons. It is ancient. The holy Notch created it. Jeb rainbowfied it. Dinnerbone made it upside down. Etc. ''' displayTest="MATCH_VERSION" [[dependencies.examplemod]] modId="forge" mandatory=true versionRange="[46,)" ordering="NONE" side="BOTH" [[dependencies.examplemod]] modId="minecraft" mandatory=true versionRange="[1.20]" ordering="NONE" side="BOTH" ``` -------------------------------- ### Unit Codec Example Source: https://docs.minecraftforge.net/en/1.20.1/datastorage/codecs Creates a codec that supplies an in-code value and encodes to nothing. Useful for non-encodable entries within a data object. ```java public static final Codec> UNIT_CODEC = Codec.unit( () -> ForgeRegistries.BLOCKS // Can also be a raw value ); ``` -------------------------------- ### Implement quickMoveStack for Menu Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus This Java code implements the `#quickMoveStack` method for a custom menu. It handles shifting items between a data inventory and the player's inventory, including input slots, result slots, and the hotbar. Ensure the slot indexing and ranges match your specific inventory setup. ```java // Assume we have a data inventory of size 5 // The inventory has 4 inputs (index 1 - 4) which outputs to a result slot (index 0) // We also have the 27 player inventory slots and the 9 hotbar slots // As such, the actual slots are indexed like so: // - Data Inventory: Result (0), Inputs (1 - 4) // - Player Inventory (5 - 31) // - Player Hotbar (32 - 40) @Override public ItemStack quickMoveStack(Player player, int quickMovedSlotIndex) { // The quick moved slot stack ItemStack quickMovedStack = ItemStack.EMPTY; // The quick moved slot Slot quickMovedSlot = this.slots.get(quickMovedSlotIndex) // If the slot is in the valid range and the slot is not empty if (quickMovedSlot != null && quickMovedSlot.hasItem()) { // Get the raw stack to move ItemStack rawStack = quickMovedSlot.getItem(); // Set the slot stack to a copy of the raw stack quickMovedStack = rawStack.copy(); /* The following quick move logic can be simplified to if in data inventory, try to move to player inventory/hotbar and vice versa for containers that cannot transform data (e.g. chests). */ // If the quick move was performed on the data inventory result slot if (quickMovedSlotIndex == 0) { // Try to move the result slot into the player inventory/hotbar if (!this.moveItemStackTo(rawStack, 5, 41, true)) { // If cannot move, no longer quick move return ItemStack.EMPTY; } // Perform logic on result slot quick move slot.onQuickCraft(rawStack, quickMovedStack); } // Else if the quick move was performed on the player inventory or hotbar slot else if (quickMovedSlotIndex >= 5 && quickMovedSlotIndex < 41) { // Try to move the inventory/hotbar slot into the data inventory input slots if (!this.moveItemStackTo(rawStack, 1, 5, false)) { // If cannot move and in player inventory slot, try to move to hotbar if (quickMovedSlotIndex < 32) { if (!this.moveItemStackTo(rawStack, 32, 41, false)) { // If cannot move, no longer quick move return ItemStack.EMPTY; } } // Else try to move hotbar into player inventory slot else if (!this.moveItemStackTo(rawStack, 5, 32, false)) { // If cannot move, no longer quick move return ItemStack.EMPTY; } } } // Else if the quick move was performed on the data inventory input slots, try to move to player inventory/hotbar else if (!this.moveItemStackTo(rawStack, 5, 41, false)) { // If cannot move, no longer quick move return ItemStack.EMPTY; } if (rawStack.isEmpty()) { // If the raw stack has completely moved out of the slot, set the slot to the empty stack quickMovedSlot.set(ItemStack.EMPTY); } else { // Otherwise, notify the slot that that the stack count has changed quickMovedSlot.setChanged(); } /* The following if statement and Slot#onTake call can be removed if the menu does not represent a container that can transform stacks (e.g. chests). */ if (rawStack.getCount() == quickMovedStack.getCount()) { // If the raw stack was not able to be moved to another slot, no longer quick move return ItemStack.EMPTY; } // Execute logic on what to do post move with the remaining stack quickMovedSlot.onTake(player, rawStack); } return quickMovedStack; // Return the slot stack } ``` -------------------------------- ### Menu with ItemStack and Integer Synchronization Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus Example of a menu constructor handling both ItemStack synchronization via SlotItemHandler and integer synchronization via DataSlot. The client constructor should provide default instances. ```java public MyMenuAccess(int containerId, Inventory playerInventory) { this(containerId, playerInventory, new ItemStackHandler(5), DataSlot.standalone()); } ``` ```java public MyMenuAccess(int containerId, Inventory playerInventory, IItemHandler dataInventory, DataSlot dataSingle) { // Check if the data inventory size is some fixed value // Then, add slots for data inventory this.addSlot(new SlotItemHandler(dataInventory, /*...*/)); // Add slots for player inventory this.addSlot(new Slot(playerInventory, /*...*/)); // Add data slots for handled integers this.addDataSlot(dataSingle); // ... } ``` -------------------------------- ### Providing Known Blocks to BlockLootSubProvider Source: https://docs.minecraftforge.net/en/1.20.1/datagen/server/loottables Implement `getKnownBlocks` to supply all registered blocks to the `BlockLootSubProvider`. This example shows how to use `DeferredRegister` and `RegistryObject` to stream entries. ```java // In some BlockLootSubProvider subclass for some DeferredRegister BLOCK_REGISTRAR @Override protected Iterable getKnownBlocks() { return BLOCK_REGISTRAR.getEntries() // Get all registered entries .stream() // Stream the wrapped objects .flatMap(RegistryObject::stream) // Get the object if available ::iterator; // Create the iterable } ``` -------------------------------- ### KeyMapping with GUI Conflict Context Source: https://docs.minecraftforge.net/en/1.20.1/misc/keymappings Create a KeyMapping that is only active when a GUI screen is open. This example uses the mouse's left button as the default input. ```java new KeyMapping( "key.examplemod.example2", KeyConflictContext.GUI, // Mapping can only be used when a screen is open InputConstants.Type.MOUSE, // Default mapping is on the mouse GLFW.GLFW_MOUSE_BUTTON_LEFT, // Default mouse input is the left mouse button "key.categories.examplemod.examplecategory" // Mapping will be in the new example category ) ``` -------------------------------- ### Advancement Rewards Configuration Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/advancements Example JSON structure for defining rewards in an advancement. This includes experience, loot tables, recipes, and a function to be executed. ```json // In some advancement JSON "rewards": { "experience": 10, "loot": [ "minecraft:example_loot_table", "minecraft:example_loot_table2" // ... ], "recipes": [ "minecraft:example_recipe", "minecraft:example_recipe2" // ... ], "function": "minecraft:example_function" } ``` -------------------------------- ### Example Language File Structure Source: https://docs.minecraftforge.net/en/1.20.1/concepts/internationalization Defines translation keys and their corresponding displayable text for a specific locale. This JSON file should be placed in the assets/[namespace]/lang/[locale].json directory. ```json { "item.examplemod.example_item": "Example Item Name", "block.examplemod.example_block": "Example Block Name", "commands.examplemod.examplecommand.error": "Example Command Errored!" } ``` -------------------------------- ### RecipeTypeTagsProvider Implementation Source: https://docs.minecraftforge.net/en/1.20.1/datagen/server/tags Example of a custom TagsProvider for recipe types. This class extends the base TagsProvider and specifies the registry key for recipe types. ```java public RecipeTypeTagsProvider(PackOutput output, CompletableFuture registries, ExistingFileHelper fileHelper) { super(output, Registries.RECIPE_TYPE, registries, MOD_ID, fileHelper); } ``` -------------------------------- ### Menu with Multiple Integer Synchronization using ContainerData Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus Example of a menu constructor using ContainerData for synchronizing multiple integers. The client constructor provides a SimpleContainerData instance. ```java public MyMenuAccess(int containerId, Inventory playerInventory) { this(containerId, playerInventory, new SimpleContainerData(3)); } ``` ```java public MyMenuAccess(int containerId, Inventory playerInventory, ContainerData dataMultiple) { // Check if the ContainerData size is some fixed value checkContainerDataCount(dataMultiple, 3); // Add data slots for handled integers this.addDataSlots(dataMultiple); // ... } ``` -------------------------------- ### Dispatch Object Encoding Examples Source: https://docs.minecraftforge.net/en/1.20.1/datastorage/codecs Illustrates how simple and complex objects are encoded using dispatch codecs, showing differences in value placement based on codec augmentation. ```json // Simple object { "type": "string", // For StringObject "value": "value" // Codec type is not augmented from MapCodec, needs field } ``` ```json // Complex object { "type": "complex", // For ComplexObject // Codec type is augmented from MapCodec, can be inlined "s": "value", "i": 0 } ``` -------------------------------- ### Registering Blocks with RegisterEvent Source: https://docs.minecraftforge.net/en/1.20.1/concepts/registries The `RegisterEvent` allows for in-code registration of objects. This example shows how to register multiple blocks using a helper provided by the event. ```java @SubscribeEvent public void register(RegisterEvent event) { event.register(ForgeRegistries.Keys.BLOCKS, helper -> { helper.register(new ResourceLocation(MODID, "example_block_1"), new Block(...)); helper.register(new ResourceLocation(MODID, "example_block_2"), new Block(...)); helper.register(new ResourceLocation(MODID, "example_block_3"), new Block(...)); // ... } ); } ``` -------------------------------- ### GameTest Structure Template Naming Conventions Source: https://docs.minecraftforge.net/en/1.20.1/misc/gametest Demonstrates how to control the location of structure templates using annotations like @GameTestHolder, @GameTest, and @PrefixGameTestTemplate. These examples show different combinations of prepending the class name and specifying a custom template name. ```java // Modid for all structures will be MODID @GameTestHolder(MODID) public class ExampleGameTests { // Class name is prepended, template name is not specified // Template Location at 'modid:examplegametests.exampletest' @GameTest public static void exampleTest(GameTestHelper helper) { /*...*/ } // Class name is not prepended, template name is not specified // Template Location at 'modid:exampletest2' @PrefixGameTestTemplate(false) @GameTest public static void exampleTest2(GameTestHelper helper) { /*...*/ } // Class name is prepended, template name is specified // Template Location at 'modid:examplegametests.test_template' @GameTest(template = "test_template") public static void exampleTest3(GameTestHelper helper) { /*...*/ } // Class name is not prepended, template name is specified // Template Location at 'modid:test_template2' @PrefixGameTestTemplate(false) @GameTest(template = "test_template2") public static void exampleTest4(GameTestHelper helper) { /*...*/ } } ``` -------------------------------- ### Make class public Source: https://docs.minecraftforge.net/en/1.20.1/advanced/accesstransformers Example of making the ByteArrayToKeyFunction interface in Crypt public. Comments start with '#'. ```accesstransformer public net.minecraft.util.Crypt$ByteArrayToKeyFunction ``` -------------------------------- ### Create ExampleConfig Class and ForgeConfigSpec Source: https://docs.minecraftforge.net/en/1.20.1/misc/config Demonstrates how to create a configuration class and build a ForgeConfigSpec using a static block. This pattern is typically used to attach and hold config values. ```java static { Pair pair = new ForgeConfigSpec.Builder() .configure(ExampleConfig::new); // Store pair values in some constant field } ``` -------------------------------- ### IntersectionIngredient Example Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/recipes/ingredients Works as an AND condition where the stack must match all supplied ingredients. Requires at least two children. ```json { "type": "forge:intersection", "//": "All of these ingredients must return true to succeed", "children": [ { "//": "Ingredient 1" }, { "//": "Ingredient 2" } "// ..." ] } ``` -------------------------------- ### StrictNBTIngredient Example Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/recipes/ingredients Compares item, damage, and share tags for exact equivalency. Specify type as forge:nbt. ```json { "type": "forge:nbt", "item": "examplemod:example_item", "nbt": { "//": "Add nbt data (must match exactly what is on the stack)" } } ``` -------------------------------- ### Screen Initialization with Widgets Source: https://docs.minecraftforge.net/en/1.20.1/gui/screens The init method is used to set up screen elements like widgets and precompute coordinates. It is called on initialization and when the game window is resized. Use #addRenderableWidget for interactable, narrated, and rendered widgets. ```java @Override protected void init() { super.init(); // Add widgets and precomputed values this.addRenderableWidget(new EditBox(/* ... */)); } ``` -------------------------------- ### Registering LootTableProvider Source: https://docs.minecraftforge.net/en/1.20.1/datagen/server/loottables Add a LootTableProvider to the DataGenerator on the MOD event bus. This setup is typically done within the `gatherData` event. ```java // On the MOD event bus @SubscribeEvent public void gatherData(GatherDataEvent event) { event.getGenerator().addProvider( // Tell generator to run only when server data are generating event.includeServer(), output -> new MyLootTableProvider( output, // Specify registry names of tables that are required to generate, or can leave empty Collections.emptySet(), // Sub providers which generate the loot List.of(subProvider1, subProvider2, /*...*/) ) ); } ``` -------------------------------- ### DifferenceIngredient Example Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/recipes/ingredients Performs set subtraction (SUB), matching the base ingredient but not the subtracted one. Specify type as forge:difference. ```json { "type": "forge:difference", "base": { "//": "Ingredient the stack is in" }, "subtracted": { "//": "Ingredient the stack is NOT in" } } ``` -------------------------------- ### Defining Sounds with SoundDefinitionsProvider Source: https://docs.minecraftforge.net/en/1.20.1/datagen/client/sounds Demonstrates how to define sounds using `this.add()` within a `SoundDefinitionsProvider`. It shows how to specify subtitles, add multiple sounds with individual configurations like weight and volume, and stream sounds. ```java this.add(EXAMPLE_SOUND_EVENT, definition() .subtitle("sound.examplemod.example_sound") // Set translation key .with( sound(new ResourceLocation(MODID, "example_sound_1")) // Set first sound .weight(4) // Has a 4 / 5 = 80% chance of playing .volume(0.5), // Scales all volumes called on this sound by half sound(new ResourceLocation(MODID, "example_sound_2")) // Set second sound .stream() // Streams the sound ) ); this.add(EXAMPLE_SOUND_EVENT_2, definition() .subtitle("sound.examplemod.example_sound") // Set translation key .with( sound(EXAMPLE_SOUND_EVENT.getLocation(), SoundType.EVENT) // Adds sounds from 'EXAMPLE_SOUND_EVENT' .pitch(0.5) // Scales all pitches called on this sound by half ) ); ``` -------------------------------- ### Example GLM JSON Structure Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/glm This JSON defines a global loot modifier, specifying its type, conditions for activation, and custom properties. ```json { "type": "examplemod:example_loot_modifier", "conditions": [ // Normal loot table conditions // ... ], "prop1": "val1", "prop2": 10, "prop3": "minecraft:dirt" } ``` -------------------------------- ### CompoundIngredient Example Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/recipes/ingredients Used as an OR condition where at least one supplied ingredient must match. No type is specified as it's a compound ingredient. ```json [ { "//": "Ingredient" }, { "type": "examplemod:example_ingredient" } ] ``` -------------------------------- ### Creating a Basic KeyMapping Source: https://docs.minecraftforge.net/en/1.20.1/misc/keymappings Create a KeyMapping with a translation key, default input type, input code, and category. The default input is set to the 'P' key. ```java new KeyMapping( "key.examplemod.example1", // Will be localized using this translation key InputConstants.Type.KEYSYM, // Default mapping is on the keyboard GLFW.GLFW_KEY_P, // Default key is P "key.categories.misc" // Mapping will be in the misc category ) ``` -------------------------------- ### Registering a Basic MenuType Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus Demonstrates how to register a new `MenuType` using a `MenuSupplier` and a `FeatureFlagSet`. This is the standard way to create a new menu type for your mod. ```java public static final RegistryObject> MY_MENU = REGISTER.register("my_menu", () -> new MenuType(MyMenu::new, FeatureFlags.DEFAULT_FLAGS)); // In MyMenu, an AbstractContainerMenu subclass public MyMenu(int containerId, Inventory playerInv) { super(MY_MENU.get(), containerId); // ... } ``` -------------------------------- ### Registering a Language Provider Source: https://docs.minecraftforge.net/en/1.20.1/datagen/client/localization Add a LanguageProvider to the DataGenerator during the gatherData event. This example shows how to include client-side localizations for American English. ```java @SubscribeEvent public void gatherData(GatherDataEvent event) { event.getGenerator().addProvider( // Tell generator to run only when client assets are generating event.includeClient(), // Localizations for American English output -> new MyLanguageProvider(output, MOD_ID, "en_us") ); } ``` -------------------------------- ### Open Menu with SimpleMenuProvider Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus Opens a screen for a server player using `NetworkHooks#openScreen` and `SimpleMenuProvider`. This is typically called on the logical server. ```java NetworkHooks.openScreen(serverPlayer, new SimpleMenuProvider( (containerId, playerInventory, player) -> new MyMenu(containerId, playerInventory), Component.translatable("menu.title.examplemod.mymenu") )); ``` -------------------------------- ### MyMenuAccess Constructors and stillValid Method Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus Demonstrates the client and server constructors for a menu that uses ContainerLevelAccess, along with the implementation of the stillValid method to check player proximity to the associated block. ```java // Client menu constructor public MyMenuAccess(int containerId, Inventory playerInventory) { this(containerId, playerInventory, ContainerLevelAccess.NULL); } ``` ```java // Server menu constructor public MyMenuAccess(int containerId, Inventory playerInventory, ContainerLevelAccess access) { // ... } ``` ```java // Assume this menu is attached to RegistryObject MY_BLOCK @Override public boolean stillValid(Player player) { return AbstractContainerMenu.stillValid(this.access, player, MY_BLOCK.get()); } ``` -------------------------------- ### Registering Custom Ingredient Serializer Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/recipes/ingredients Example of how to declare a static serializer instance, register it during the `RegisterEvent`, and return it from the ingredient's `getSerializer` method. ```java // In some serializer class public static final ExampleIngredientSerializer INSTANCE = new ExampleIngredientSerializer(); // In some handler class public void registerSerializers(RegisterEvent event) { event.register(ForgeRegistries.Keys.RECIPE_SERIALIZERS, helper -> CraftingHelper.register(registryName, INSTANCE) ); } // In some ingredient subclass @Override public IIngredientSerializer getSerializer() { return INSTANCE; } ``` -------------------------------- ### MyMenu Constructors (Client and Server) Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus Provides the client and server constructors for a custom menu. The client constructor uses default values, while the server constructor initializes menu logic. ```java // Client menu constructor public MyMenu(int containerId, Inventory playerInventory) { this(containerId, playerInventory); } ``` ```java // Server menu constructor public MyMenu(int containerId, Inventory playerInventory) { // ... } ``` -------------------------------- ### Registering a LootTableSubProvider Entry Source: https://docs.minecraftforge.net/en/1.20.1/datagen/server/loottables Instantiate a `LootTableProvider.SubProviderEntry` to include your custom `LootTableSubProvider` in the `LootTableProvider`. ```java // In the list passed into the LootTableProvider constructor new LootTableProvider.SubProviderEntry( ExampleSubProvider::new, // Loot table generator for the 'empty' param set LootContextParamSets.EMPTY ) ``` -------------------------------- ### Get Item Handler Capability Instance Source: https://docs.minecraftforge.net/en/1.20.1/datastorage/capabilities Retrieves the unique instance for the IItemHandler capability. Use CapabilityManager.get with a CapabilityToken for generic type information. ```java public static final Capability ITEM_HANDLER = CapabilityManager.get(new CapabilityToken<>(){}); ``` -------------------------------- ### AbstractContainerScreen Constructor Source: https://docs.minecraftforge.net/en/1.20.1/gui/screens Example of initializing an AbstractContainerScreen subclass. Sets relative X coordinates for the title and inventory labels. Note that inventoryLabelY depends on imageHeight. ```java public MyContainerScreen(MyMenu menu, Inventory playerInventory, Component title) { super(menu, playerInventory, title); this.titleLabelX = 10; this.inventoryLabelX = 10; /* * If the 'imageHeight' is changed, 'inventoryLabelY' must also be * changed as the value depends on the 'imageHeight' value. */ } ``` -------------------------------- ### Define a Basic Config Value Source: https://docs.minecraftforge.net/en/1.20.1/misc/config Shows how to define a basic configuration value with a comment and a default value. The value is cached to prevent multiple file reads. ```java ConfigValue value = builder.comment("Comment") .define("config_value_name", defaultValue); ``` -------------------------------- ### Registering a Custom Condition Serializer Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/conditional Example of how to declare a static instance of a custom condition serializer and register it using CraftingHelper during the RegisterEvent for Recipe Serializers. ```java public static final ExampleConditionSerializer INSTANCE = new ExampleConditionSerializer(); public void registerSerializers(RegisterEvent event) { event.register(ForgeRegistries.Keys.RECIPE_SERIALIZERS, helper -> CraftingHelper.register(INSTANCE) ); } ``` -------------------------------- ### Ambient Occlusion Override Example Source: https://docs.minecraftforge.net/en/1.20.1/rendering/modelextensions/facedata Illustrates that specifying ambient_occlusion as true on an element or face has no effect if the top-level AO flag in the model is set to false. ```json { "ambientocclusion": false, "elements": [ { "forge_data": { "ambient_occlusion": true // Has no effect } } ] } ``` -------------------------------- ### Registering a MenuType with Extra Data Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus Shows how to register a `MenuType` using `IContainerFactory` to allow for additional data to be passed to the client via `FriendlyByteBuf`. This is useful when the client needs more information than just the container ID and player inventory. ```java // For some DeferredRegister> REGISTER public static final RegistryObject> MY_MENU_EXTRA = REGISTER.register("my_menu_extra", () -> IForgeMenuType.create(MyMenu::new)); // In MyMenuExtra, an AbstractContainerMenu subclass public MyMenuExtra(int containerId, Inventory playerInv, FriendlyByteBuf extraData) { super(MY_MENU_EXTRA.get(), containerId); // Store extra data from buffer // ... } ``` -------------------------------- ### Update JSON Format Example Source: https://docs.minecraftforge.net/en/1.20.1/misc/updatechecker This JSON structure defines the update information for a mod, including homepage, version-specific changelogs, and promotional version declarations. ```json { "homepage": "", "": { "": "", // List all versions of your mod for the given Minecraft version, along with their changelogs // ... }, "promos": { "-latest": "", // Declare the latest "bleeding-edge" version of your mod for the given Minecraft version "-recommended": "", // Declare the latest "stable" version of your mod for the given Minecraft version // ... } } ``` -------------------------------- ### Some object to create a codec for Source: https://docs.minecraftforge.net/en/1.20.1/datastorage/codecs Defines a simple Java class with a constructor and getter methods for its fields. ```java public class SomeObject { public SomeObject(String s, int i, boolean b) { /* ... */ } public String s() { /* ... */ } public int i() { /* ... */ } public boolean b() { /* ... */ } } ``` -------------------------------- ### Create a Custom ModelProvider Source: https://docs.minecraftforge.net/en/1.20.1/datagen/client/modelproviders Extend ModelProvider to generate models. Specify the subdirectory in the 'models' folder and the ModelBuilder to use. Models are generated to 'assets//models/example' by default. ```java public class ExampleModelProvider extends ModelProvider { public ExampleModelProvider(PackOutput output, String modid, ExistingFileHelper existingFileHelper) { // Models will be generated to 'assets//models/example' if no 'modid' is specified in '#getBuilder' super(output, modid, "example", ExampleModelBuilder::new, existingFileHelper); } } ``` -------------------------------- ### Implementing LootTableSubProvider Source: https://docs.minecraftforge.net/en/1.20.1/datagen/server/loottables Create a custom LootTableSubProvider to define how loot tables are generated. The `generate` method receives a writer to accept loot table definitions. ```java public class ExampleSubProvider implements LootTableSubProvider { // Used to create a factory method for the wrapping Supplier public ExampleSubProvider() {} // The method used to generate the loot tables @Override public void generate(BiConsumer writer) { // Generate loot tables here by calling writer#accept } } ``` -------------------------------- ### Forge Mod Loaded Condition Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/conditional Checks if a specific mod is present and loaded in the current game instance. Use this to enable content only when a particular mod is installed. ```json { "type": "forge:mod_loaded", "modid": "examplemod" } ``` -------------------------------- ### Initialize Client with Custom Renderer Source: https://docs.minecraftforge.net/en/1.20.1/items/bewlr Implement IClientItemExtensions to provide a custom BlockEntityWithoutLevelRenderer for an item. This is called during client initialization. ```java public void initializeClient(Consumer consumer) { consumer.accept(new IClientItemExtensions() { @Override public BlockEntityWithoutLevelRenderer getCustomRenderer() { return myBEWLRInstance; } }); } ``` -------------------------------- ### Registering a Loot Modifier Codec Source: https://docs.minecraftforge.net/en/1.20.1/resources/server/glm Register a custom IGlobalLootModifier codec using RecordCodecBuilder. This example shows how to include custom properties like prop1, prop2, and prop3. ```java // For some DeferredRegister> REGISTRAR public static final RegistryObject> = REGISTRAR.register("example_codec", () -> RecordCodecBuilder.create( inst -> LootModifier.codecStart(inst).and( inst.group( Codec.STRING.fieldOf("prop1").forGetter(m -> m.prop1), Codec.INT.fieldOf("prop2").forGetter(m -> m.prop2), ForgeRegistries.ITEMS.getCodec().fieldOf("prop3").forGetter(m -> m.prop3) ) ).apply(inst, ExampleModifier::new) ) ); ``` -------------------------------- ### Create SimpleChannel Instance Source: https://docs.minecraftforge.net/en/1.20.1/networking/simpleimpl Instantiate a SimpleChannel for custom packet handling. Ensure the protocol version matches between client and server for compatibility. ```java private static final String PROTOCOL_VERSION = "1"; public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel( new ResourceLocation("mymodid", "main"), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals ); ``` -------------------------------- ### Creating a Simple Cooking Recipe Source: https://docs.minecraftforge.net/en/1.20.1/datagen/server/recipes Use `SimpleCookingRecipeBuilder` for smelting, blasting, smoking, or campfire cooking recipes. Specify input, output, experience, and cooking time before saving. ```java // In RecipeProvider#buildRecipes(writer) SimpleCookingRecipeBuilder builder = SimpleCookingRecipeBuilder.smelting(input, RecipeCategory.MISC, result, experience, cookingTime) .unlockedBy("criteria", criteria) // How the recipe is unlocked .save(writer); // Add data to builder ``` -------------------------------- ### Element Face Data Example Source: https://docs.minecraftforge.net/en/1.20.1/rendering/modelextensions/facedata Demonstrates specifying forge_data at both the element and individual face levels in a vanilla elements model. Face-specific data overrides element-level data. ```json { "elements": [ { "forge_data": { "color": "0xFFFF0000", "block_light": 15, "sky_light": 15, "ambient_occlusion": false }, "faces": { "north": { "forge_data": { "color": "0xFFFF0000", "block_light": 15, "sky_light": 15, "ambient_occlusion": false }, // ... }, // ... }, // ... } ] } ``` -------------------------------- ### Block Implementation for Opening Menu Source: https://docs.minecraftforge.net/en/1.20.1/gui/menus Implements menu opening logic within a block's `use` method. The `MenuProvider` should be implemented via `getMenuProvider` for spectator mode support. ```java @Override public MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos) { return new SimpleMenuProvider(/* ... */); } @Override public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult result) { if (!level.isClientSide && player instanceof ServerPlayer serverPlayer) { NetworkHooks.openScreen(serverPlayer, state.getMenuProvider(level, pos)); } return InteractionResult.sidedSuccess(level.isClientSide); } ``` -------------------------------- ### Example Model for Cutout Block Source: https://docs.minecraftforge.net/en/1.20.1/rendering/modelextensions/rendertypes This JSON defines a model for a cutout block, specifying 'minecraft:cutout' as its render type and using the 'block/cube_all' parent with the 'block/glass' texture. ```json { "render_type": "minecraft:cutout", "parent": "block/cube_all", "textures": { "all": "block/glass" } } ```