### Configure Game Test Execution with Annotations Source: https://docs.neoforged.net/docs/1.20.4/misc/gametest Shows how to configure the execution of a Game Test using members of the `@GameTest` annotation. This example sets `setupTicks` to 20 for setup time and `required` to false, meaning test failure won't halt the batch. ```java // In some class @GameTest( setupTicks = 20L, // The test spends 20 ticks to set up for execution required = false // The failure is logged but does not affect the execution of the batch ) public static void exampleConfiguredTest(GameTestHelper helper) { // Do stuff } ``` -------------------------------- ### Querying Vanilla Registries (Java) Source: https://docs.neoforged.net/docs/1.20.4/concepts/registries Demonstrates how to retrieve registered objects by their ResourceLocation or get the ResourceLocation of a registered object using NeoForged's BuiltInRegistries. Also shows how to check for the existence of a registry key. ```java BuiltInRegistries.BLOCKS.get(new ResourceLocation("minecraft", "dirt")); // returns the dirt block BuiltInRegistries.BLOCKS.getKey(Blocks.DIRT); // returns the resource location "minecraft:dirt" // Assume that ExampleBlocksClass.EXAMPLE_BLOCK.get() is a Supplier with the id "yourmodid:example_block" BuiltInRegistries.BLOCKS.get(new ResourceLocation("yourmodid", "example_block")); // returns the example block BuiltInRegistries.BLOCKS.getKey(ExampleBlocksClass.EXAMPLE_BLOCK.get()); // returns the resource location "yourmodid:example_block" BuiltInRegistries.BLOCKS.containsKey(new ResourceLocation("minecraft", "dirt")); // true BuiltInRegistries.BLOCKS.containsKey(new ResourceLocation("create", "brass_ingot")); // true only if Create is installed ``` -------------------------------- ### Dispatch Codec Setup in Java Source: https://docs.neoforged.net/docs/1.20.4/datastorage/codecs Demonstrates setting up a dispatch codec using Codec#dispatch, which selects a subcodec based on a specified type. This is useful for registries like rule tests or block placers. ```java // Define our object abstract class ExampleObject { public abstract Codec type(); } // Create simple object which stores a string class StringObject extends ExampleObject { public StringObject(String s) { /* ... */ } public String s() { /* ... */ } public Codec type() { // A registered registry object // "string": // Codec.STRING.xmap(StringObject::new, StringObject::s) return STRING_OBJECT_CODEC.get(); } } // Create complex object which stores a string and integer class ComplexObject extends ExampleObject { public ComplexObject(String s, int i) { /* ... */ } public String s() { /* ... */ } public int i() { /* ... */ } public Codec type() { // A registered registry object // "complex": // RecordCodecBuilder.create(instance -> // instance.group( // Codec.STRING.fieldOf("s").forGetter(ComplexObject::s), // Codec.INT.fieldOf("i").forGetter(ComplexObject::i) // ).apply(instance, ComplexObject::new) // ) return COMPLEX_OBJECT_CODEC.get(); } } // Assume there is an IForgeRegistry> DISPATCH public static final Codec = DISPATCH.getCodec() // Gets Codec> .dispatch( ExampleObject::type, // Get the codec from the specific object Function.identity() // Get the codec from the registry ); ``` -------------------------------- ### Example: Query Block Item Handler Source: https://docs.neoforged.net/docs/1.20.4/datastorage/capabilities Demonstrates querying an IItemHandler capability for a block from the NORTH side, checking if the handler is available before use. ```java IItemHandler handler = level.getCapability(Capabilities.ItemHandler.BLOCK, pos, Direction.NORTH); if (handler != null) { // Use the handler for some item-related operation. } ``` -------------------------------- ### Java Package Structure Example Source: https://docs.neoforged.net/docs/1.20.4/gettingstarted/structuring Illustrates how distinct JAR files can contain classes with the same name in the same package, highlighting the importance of unique top-level packages to avoid conflicts and game crashes. This example shows that 'com.example.ExampleClass' in 'a.jar' would prevent the same class in 'b.jar' from being loaded. ```text a.jar - com.example.ExampleClass b.jar - com.example.ExampleClass // This class will not normally be loaded ``` -------------------------------- ### CompoundIngredient Example (JSON) Source: https://docs.neoforged.net/docs/1.20.4/resources/server/recipes/ingredients Demonstrates the structure of a CompoundIngredient, which acts as an OR condition for a list of ingredients. The input stack must match at least one of the provided ingredients. ```json // For some input [ // At least one of these ingredients must match to succeed { // Ingredient }, { // Custom ingredient "type": "examplemod:example_ingredient" } ] ``` -------------------------------- ### Java Class Naming Convention Examples Source: https://docs.neoforged.net/docs/1.20.4/gettingstarted/structuring Provides examples of common class naming conventions in Java development, particularly for Minecraft mods. It shows how to suffix class names with their type (e.g., Item, Block, Menu) for better clarity and easier identification of their purpose. ```java // An Item called PowerRing -> PowerRingItem public class PowerRingItem { ... } // A Block called NotDirt -> NotDirtBlock public class NotDirtBlock { ... } // A menu for an Oven -> OvenMenu public class OvenMenu { ... } ``` -------------------------------- ### EntityLootSubProvider Constructor Example (Java) Source: https://docs.neoforged.net/docs/1.20.4/datagen/loottables This example shows the constructor for an EntityLootSubProvider subclass. It initializes the superclass with all available feature flags, determining which entity types are enabled for loot table generation. ```java // In some EntityLootSubProvider subclass public MyEntityLootSubProvider() { super(FeatureFlags.REGISTRY.allFlags()); } ``` -------------------------------- ### DifferenceIngredient Example (JSON) Source: https://docs.neoforged.net/docs/1.20.4/resources/server/recipes/ingredients Shows the DifferenceIngredient, which performs set subtraction. The input stack must match the 'base' ingredient but not the 'subtracted' ingredient. ```json // For some input { "type": "forge:difference", "base": { // Ingredient the stack is in }, "subtracted": { // Ingredient the stack is NOT in } } ``` -------------------------------- ### Screen Rendering with Background and Widgets in Java Source: https://docs.neoforged.net/docs/1.20.4/gui/screens Provides an example of rendering a screen, including drawing the background and then the screen's widgets. The render method is responsible for drawing all visual elements of the screen each frame, and it's crucial to call super.render for widget rendering. ```java // In some Screen subclass // mouseX and mouseY indicate the scaled coordinates of where the cursor is in on the screen @Override public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) { // Background is typically rendered first this.renderBackground(graphics); // Render things here before widgets (background textures) // Then the widgets if this is a direct child of the Screen super.render(graphics, mouseX, mouseY, partialTick); // Render things after widgets (tooltips) } ``` -------------------------------- ### Generating Cooking Recipes with SimpleCookingRecipeBuilder (Java) Source: https://docs.neoforged.net/docs/1.20.4/datagen/recipes This example demonstrates how to generate various cooking recipes (smelting, blasting, etc.) using SimpleCookingRecipeBuilder. It shows how to set input, output, experience, cooking time, unlock criteria, and save the recipe. ```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 ``` -------------------------------- ### PartialNBTIngredient Example (JSON) Source: https://docs.neoforged.net/docs/1.20.4/resources/server/recipes/ingredients Shows how to use PartialNBTIngredient for a more flexible NBT comparison. It matches against specified keys in the NBT data, not the entire tag. Either 'item' or 'items' can be specified. ```json // For some input { "type": "forge:partial_nbt", // Either 'item' or 'items' must be specified // 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' // All other keys in the stack will not be checked "key1": "data1", "key2": { // Data 2 } } } ``` -------------------------------- ### Implementing a Custom LootTableSubProvider (Java) Source: https://docs.neoforged.net/docs/1.20.4/datagen/loottables This example demonstrates the basic structure of a custom LootTableSubProvider. It includes the necessary constructor and the generate method, where the logic for creating loot tables is implemented by calling the provided writer. ```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 } } ``` -------------------------------- ### Initialize RegistrySetBuilder for Datapack Registries Source: https://docs.neoforged.net/docs/1.20.4/concepts/registries Demonstrates the initial setup of a `RegistrySetBuilder` to hold entries for multiple datapack registries. This builder serves as a container for defining registry data. ```java new RegistrySetBuilder() .add(Registries.CONFIGURED_FEATURE, bootstrap -> { // Register configured features through the bootstrap context (see below) }) .add(Registries.PLACED_FEATURE, bootstrap -> { // Register placed features through the bootstrap context (see below) }); ``` -------------------------------- ### ContainerData Initialization and Usage in Menu Constructors (Java) Source: https://docs.neoforged.net/docs/1.20.4/gui/menus Demonstrates how to initialize and use ContainerData in both client and server-side menu constructors for synchronizing integers. It shows the creation of a SimpleContainerData instance and the use of addDataSlots. The example assumes a fixed ContainerData size for checking. ```java public class MyMenuAccess { // Client menu constructor public MyMenuAccess(int containerId, Inventory playerInventory) { this(containerId, playerInventory, new SimpleContainerData(3)); } // Server menu constructor 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); // ... } // Placeholder for checkContainerDataCount method private void checkContainerDataCount(ContainerData data, int expectedCount) { // Implementation would check data.getCount() == expectedCount } // Placeholder for addDataSlots method private void addDataSlots(ContainerData data) { // Implementation would add data slots based on ContainerData } // Placeholder for Inventory class static class Inventory {} // Placeholder for ContainerData interface interface ContainerData { int getCount(); } // Placeholder for SimpleContainerData class static class SimpleContainerData implements ContainerData { private final int size; public SimpleContainerData(int size) { this.size = size; } @Override public int getCount() { return size; } } } ``` -------------------------------- ### Implementing ICustomConfigurationTask Interface (Java) Source: https://docs.neoforged.net/docs/1.20.4/networking/configuration-tasks This example shows the implementation of the ICustomConfigurationTask interface, which is required for custom configuration tasks. It includes defining a unique task type and implementing the 'run' method to send custom data payloads. ```java public record MyConfigurationTask implements ICustomConfigurationTask { public static final ConfigurationTask.Type TYPE = new ConfigurationTask.Type(new ResourceLocation("mymod:my_task")); @Override public void run(final Consumer sender) { final MyData payload = new MyData(); sender.accept(payload); } @Override public ConfigurationTask.Type type() { return TYPE; } } ``` -------------------------------- ### Create a Basic KeyMapping in Java Source: https://docs.neoforged.net/docs/1.20.4/misc/keymappings Shows how to create a KeyMapping instance using its constructor. It takes a translation key for its name, a default input, and a category translation key. ```java import net.minecraft.client.KeyMapping; import net.minecraft.client.InputConstants; import org.lwjgl.glfw.GLFW; 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 ) ``` -------------------------------- ### Getting a Model Builder with ModelProvider (Java) Source: https://docs.neoforged.net/docs/1.20.4/resources/client/models/datagen Demonstrates the core functionality of ModelProvider: retrieving a BlockModelBuilder or ItemModelBuilder using the `getBuilder(String path)` method. This is the starting point for generating most models. ```java BlockModelBuilder blockModel = models.getBuilder("my_block"); ItemModelBuilder itemBuilder = itemModels.getBuilder("my_item"); ``` -------------------------------- ### Open Server Menu with SimpleMenuProvider (Java) Source: https://docs.neoforged.net/docs/1.20.4/gui/menus Demonstrates opening a server-side menu for a player using `NetworkHooks#openScreen` and `SimpleMenuProvider`. This method is used when a menu type is registered, the menu is finished, and a screen is attached. ```java NetworkHooks.openScreen(serverPlayer, new SimpleMenuProvider( (containerId, playerInventory, player) -> new MyMenu(containerId, playerInventory), Component.translatable("menu.title.examplemod.mymenu") )); ``` -------------------------------- ### Conditional Recipe Example (Mod Loaded) Source: https://docs.neoforged.net/docs/1.20.4/resources/server/conditional An example of a shaped crafting recipe that will only be loaded if the 'examplemod' is present in the current application. This utilizes the 'neoforge:mod_loaded' condition. ```json { "neoforge:conditions": [ { "type": "neoforge:mod_loaded", "modid": "examplemod" } ], "type": "minecraft:crafting_shaped", "category": "redstone", "key": { "#": { "item": "examplemod:example_planks" } }, "pattern": [ "##", "##", "##" ], "result": { "count": 3, "item": "mymod:compat_door" } } ``` -------------------------------- ### Create and Use BlockCapabilityCache (Java) Source: https://docs.neoforged.net/docs/1.20.4/datastorage/capabilities Demonstrates how to create a BlockCapabilityCache for a specific capability, level, position, and context. It also shows how to retrieve the cached capability and handle cases where it might be null. The cache is automatically managed by the garbage collector. ```Java private BlockCapabilityCache capCache; // Later, for example in `onLoad` for a block entity: this.capCache = BlockCapabilityCache.create( Capabilities.ItemHandler.BLOCK, // capability to cache level, // level pos, // target position Direction.NORTH // context ); IItemHandler handler = this.capCache.getCapability(); if (handler != null) { // Use the handler for some item-related operation. } ``` -------------------------------- ### Profiling Result Structure Example Source: https://docs.neoforged.net/docs/1.20.4/misc/debugprofiler An example of the hierarchical data structure found in the profiling.txt file, showing time spent in different game sections. This helps in identifying performance-intensive areas. ```text [00] levels - 96.70%/96.70% [01] | Level Name - 99.76%/96.47% [02] | | tick - 99.31%/95.81% [03] | | | entities - 47.72%/45.72% [04] | | | | regular - 98.32%/44.95% [04] | | | | blockEntities - 0.90%/0.41% [05] | | | | | unspecified - 64.26%/0.26% [05] | | | | | minecraft:furnace - 33.35%/0.14% [05] | | | | | minecraft:chest - 2.39%/0.01% ``` -------------------------------- ### Iterating Through Vanilla Registries (Java) Source: https://docs.neoforged.net/docs/1.20.4/concepts/registries Shows how to iterate over all keys (ResourceLocations) or entries (Map.Entry) within a vanilla registry in NeoForged. ```java for (ResourceLocation id : BuiltInRegistries.BLOCKS.keySet()) { // ... } for (Map.Entry entry : BuiltInRegistries.BLOCKS.entrySet()) { // ... } ``` -------------------------------- ### Screen Initialization and Widget Addition in Java Source: https://docs.neoforged.net/docs/1.20.4/gui/screens Illustrates the initialization process for a screen, including calling the superclass's init method and adding various types of widgets. The init method is called upon screen initialization and resizing, and is used for setting up widgets and precomputing coordinates. ```java // In some Screen subclass @Override protected void init() { super.init(); // Add widgets and precomputed values this.addRenderableWidget(new EditBox(/* ... */)); } ``` -------------------------------- ### Named Loot Pool Example (JSON) Source: https://docs.neoforged.net/docs/1.20.4/resources/server/loottables An example of how to define a named loot pool within a JSON loot table. The 'name' key assigns an identifier to the pool, which can be useful for referencing or debugging. Unnamed pools are automatically assigned a hash code prefixed with 'custom#'. ```json { "name": "example_pool", "rolls": { "min": 1, "max": 3 }, "entries": [ { "type": "minecraft:item", "name": "minecraft:diamond", "weight": 1 } ] } ``` -------------------------------- ### Registering a Custom Registry (Java) Source: https://docs.neoforged.net/docs/1.20.4/concepts/registries Demonstrates how to register a custom registry to the game's root registry using the NewRegistryEvent in NeoForged. ```java @SubscribeEvent // on the mod event bus public static void registerRegistries(NewRegistryEvent event) { event.register(SPELL_REGISTRY); } ``` -------------------------------- ### Get BlockState Property Value (Java) Source: https://docs.neoforged.net/docs/1.20.4/blocks/states Demonstrates how to retrieve the value of a specific property from a BlockState. This is useful for checking the current state of a block, such as its orientation or other properties. ```java Direction direction = endPortalFrameBlockState.getValue(EndPortalFrameBlock.FACING); ``` -------------------------------- ### Screen Initialization with Constructor in Java Source: https://docs.neoforged.net/docs/1.20.4/gui/screens Demonstrates the basic constructor for a screen subclass, accepting a Component for the screen's title. This component is primarily used for narration messages in the base screen. ```java // In some Screen subclass public MyScreen(Component title) { super(title); } ``` -------------------------------- ### Creating and Using ResourceLocations in Java Source: https://docs.neoforged.net/docs/1.20.4/misc/resourcelocation Demonstrates how to create new ResourceLocation objects in Java, either by providing namespace and path separately or as a combined string. It also shows how to retrieve the namespace, path, and combined string representation of a ResourceLocation. ```java import net.minecraft.resources.ResourceLocation; // Creating a new ResourceLocation ResourceLocation itemLocation = new ResourceLocation("examplemod", "example_item"); ResourceLocation anotherItemLocation = new ResourceLocation("examplemod:example_item"); ResourceLocation defaultNamespaceLocation = new ResourceLocation("example_item"); // Results in minecraft:example_item // Retrieving parts of a ResourceLocation String namespace = itemLocation.getNamespace(); // "examplemod" String path = itemLocation.getPath(); // "example_item" String combined = itemLocation.toString(); // "examplemod:example_item" // Utility methods return new ResourceLocations (immutable) ResourceLocation prefixedLocation = itemLocation.withPrefix("prefix_"); ResourceLocation suffixedLocation = itemLocation.withSuffix("_suffix"); ``` -------------------------------- ### StrictNBTIngredient Example (JSON) Source: https://docs.neoforged.net/docs/1.20.4/resources/server/recipes/ingredients Illustrates the use of StrictNBTIngredient for exact item, damage, and NBT tag matching. The 'type' must be set to 'forge:nbt'. ```json // For some input { "type": "forge:nbt", "item": "examplemod:example_item", "nbt": { // Add nbt data (must match exactly what is on the stack) } } ``` -------------------------------- ### IntersectionIngredient Example (JSON) Source: https://docs.neoforged.net/docs/1.20.4/resources/server/recipes/ingredients Demonstrates the IntersectionIngredient, which functions as an AND condition. The input stack must satisfy all provided child ingredients. Requires at least two children. ```json // For some input { "type": "forge:intersection", // All of these ingredients must return true to succeed "children": [ { // Ingredient 1 }, { // Ingredient 2 } // ... ] } ``` -------------------------------- ### Batching Game Tests with @BeforeBatch and @AfterBatch Source: https://docs.neoforged.net/docs/1.20.4/misc/gametest Explains how to group tests into batches using the 'batch' parameter in @GameTest. It also shows how to define setup (@BeforeBatch) and teardown (@AfterBatch) methods for these batches. Batch methods accept a ServerLevel parameter and return nothing. ```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 } } ``` -------------------------------- ### Create ModConfigSpec Builder and Configure ExampleConfig Source: https://docs.neoforged.net/docs/1.20.4/misc/config Demonstrates how to create a `ModConfigSpec` and a corresponding configuration class using `ModConfigSpec.Builder.configure`. This pattern is typically used with a static block to initialize configuration values. ```java class ExampleConfig { // Define values here in final fields ExampleConfig(ModConfigSpec.Builder builder) { // ... config value definitions ... } } static { Pair pair = new ModConfigSpec.Builder() .configure(ExampleConfig::new); // Store pair values in some constant field } ``` -------------------------------- ### BlockLootSubProvider Constructor Example (Java) Source: https://docs.neoforged.net/docs/1.20.4/datagen/loottables This snippet illustrates the constructor for a BlockLootSubProvider subclass. It initializes the superclass with an empty set for explosion-resistant items and all available feature flags. ```java // In some BlockLootSubProvider subclass public MyBlockLootSubProvider() { super(Collections.emptySet(), FeatureFlags.REGISTRY.allFlags()); } ``` -------------------------------- ### Nesting CompoundTags in Java Source: https://docs.neoforged.net/docs/1.20.4/datastorage/nbt Demonstrates how to embed one CompoundTag within another using the generic `get` and `put` methods. This allows for hierarchical data structures within NBT. ```java tag.put("Tag", new CompoundTag()); tag.get("Tag"); ``` -------------------------------- ### Create a KeyMapping for GUI Context in Java Source: https://docs.neoforged.net/docs/1.20.4/misc/keymappings Illustrates creating a KeyMapping that is restricted to GUI contexts. It uses a specific KeyConflictContext and a mouse input as the default. ```java import net.minecraft.client.KeyMapping; import net.minecraft.client.InputConstants; import net.neoforged.neoforge.client.settings.KeyConflictContext; import org.lwjgl.glfw.GLFW; 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 ) ``` -------------------------------- ### Generating Shaped Recipes with ShapedRecipeBuilder (Java) Source: https://docs.neoforged.net/docs/1.20.4/datagen/recipes This example shows how to use ShapedRecipeBuilder to create shaped recipes. It covers defining the recipe pattern, ingredients, unlock criteria, and saving the recipe. ```java // In RecipeProvider#buildRecipes(writer) ShapedRecipeBuilder builder = ShapedRecipeBuilder.shaped(RecipeCategory.MISC, result) .pattern("a a") // Create recipe pattern .define('a', item) // Define what the symbol represents .unlockedBy("criteria", criteria) // How the recipe is unlocked .save(writer); // Add data to builder ``` -------------------------------- ### Set BlockState in Level with Convenience Method (Java) Source: https://docs.neoforged.net/docs/1.20.4/blocks/states Provides an example of using the Level#setBlockAndUpdate convenience method, which internally calls Level#setBlock with the default UPDATE_ALL flag. This is a simpler way to update blocks when default behavior is desired. ```java level.setBlockAndUpdate(blockPos, blockState); ``` -------------------------------- ### Implement Menu Opening in a Block (Java) Source: https://docs.neoforged.net/docs/1.20.4/gui/menus Shows how to implement menu opening for a block by overriding `BlockBehaviour#use` and `BlockBehaviour#getMenuProvider`. The `use` method handles the interaction logic, opening the screen on the server side. ```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); } ``` -------------------------------- ### Encoded Pair Example Source: https://docs.neoforged.net/docs/1.20.4/datastorage/codecs Illustrates the JSON structure for an encoded Pair object. The 'fieldOf' method is used to look up keys for the left and right objects within the JSON. ```json { "left": 5, // fieldOf looks up 'left' key for left object "right": "value" // fieldOf looks up 'right' key for right object } ``` -------------------------------- ### Create an Advancement using Advancement.Builder Source: https://docs.neoforged.net/docs/1.20.4/datagen/advancements This example shows how to use the Advancement.Builder to construct a new advancement. It includes adding a criterion, specifying the writer, registry name, and existing file helper to save the advancement. ```java // In some ForgeAdvancementProvider$AdvancementGenerator#generate(registries, writer, existingFileHelper) Advancement example = Advancement.Builder.advancement() .addCriterion("example_criterion", triggerInstance) // How the advancement is unlocked .save(writer, name, existingFileHelper); // Add data to builder ``` -------------------------------- ### Composite Model JSON Example - NeoForged Source: https://docs.neoforged.net/docs/1.20.4/resources/client/models/modelloaders Defines a composite model structure in JSON for NeoForged, allowing for modular model parts. It specifies child models and their visibility, which can be overridden in parent models. ```json { "loader": "neoforge:composite", "children": { "part_1": { "parent": "examplemod:some_model_1" }, "part_2": { "parent": "examplemod:some_model_2" } }, "visibility": { "part_2": false } } ``` ```json { "parent": "examplemod:example_composite_model", "visibility": { "part_1": false, "part_2": true } } ```