### Clone Fabric Example Mod Repository Source: https://docs.fabricmc.net/develop/getting-started/creating-a-project Use this Git command to clone the example mod repository for manual project creation. Ensure Git is installed beforehand. ```sh git clone https://github.com/FabricMC/fabric-example-mod.git example-mod ``` -------------------------------- ### Example Mod Initializer Source: https://docs.fabricmc.net/develop/getting-started/project-structure This is a main entrypoint for a Fabric mod. It implements ModInitializer and logs a message when the game starts. Use your mod id as the logger's name for clarity. ```java public class ExampleMod implements ModInitializer { // This logger is used to write text to the console and the log file. // It is considered best practice to use your mod id as the logger's name. // That way, it's clear which mod wrote info, warnings, and errors. public static final String MOD_ID = "example-mod"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); @Override public void onInitialize() { // This code runs as soon as Minecraft is in a mod-load-ready state. // However, some things (like resources) may still be uninitialized. // Proceed with mild caution. LOGGER.info("Hello Fabric world!"); } } ``` -------------------------------- ### Execute Sub-Command One Source: https://docs.fabricmc.net/develop/commands/basics The execution logic for the first sub-command example. ```java private static int executeSubCommandOne(CommandContext context) { context.getSource().sendSuccess(() -> Component.literal("Called /command sub_command_one."), false); return 1; } ``` -------------------------------- ### Run Gradle Client Task Source: https://docs.fabricmc.net/develop/getting-started/intellij-idea/launching-the-game Use this Gradle command to start the game in client mode from the command line. ```bash ./gradlew runClient ``` -------------------------------- ### Run Gradle Server Task Source: https://docs.fabricmc.net/develop/getting-started/intellij-idea/launching-the-game Use this Gradle command to start the game in server mode from the command line. ```bash ./gradlew runServer ``` -------------------------------- ### JSON Recipe Example Source: https://docs.fabricmc.net/develop/custom-recipe-types An example JSON file for an upgrading recipe. The 'type' field must match the registered recipe serializer ID, and other fields are defined by the recipe's codec. ```json { "type": "example-mod:upgrading", "baseItem": "minecraft:iron_pickaxe", "upgradeItem": "minecraft:diamond", "result": { "id": "minecraft:diamond_pickaxe" } } ``` -------------------------------- ### Example fabric.mod.json Source: https://docs.fabricmc.net/develop/loader/fabric-mod-json This is a comprehensive example of a fabric.mod.json file, showcasing all possible fields and their typical values. It includes entrypoints for main, client, and datagen, as well as mixins, dependencies, and access wideners. ```json { "schemaVersion": 1, "id": "example-mod", "version": "1.0.0", "name": "Example Mod", "icon": "assets/example-mod/icon.png", "environment": "*", "entrypoints": { "main": [ "com.example.docs.ExampleMod", "com.example.docs.event.ExampleModEvents", "com.example.docs.command.ExampleModCommands", "com.example.docs.effect.ExampleModEffects", "com.example.docs.potion.ExampleModPotions", "com.example.docs.sound.ExampleModSounds", "com.example.docs.damage.ExampleModDamageTypes", "com.example.docs.item.ExampleModItems", "com.example.docs.enchantment.ExampleModEnchantments", "com.example.docs.block.ExampleModBlocks", "com.example.docs.block.entity.ExampleModBlockEntities", "com.example.docs.menu.ExampleModMenuType", "com.example.docs.component.ExampleModComponents", "com.example.docs.advancement.ExampleModDatagenAdvancement", "com.example.docs.networking.ExampleModNetworking", "com.example.docs.networking.basic.ExampleModNetworkingBasic", "com.example.docs.debug.ExampleModDebug", "com.example.docs.saveddata.ExampleModSavedData", "com.example.docs.entity.attribute.ExampleModAttributes", "com.example.docs.recipe.ExampleModRecipes", "com.example.docs.entity.ExampleModEntity", "com.example.docs.gamerule.ExampleModGameRules", "com.example.docs.conditions.ExampleModResourceConditions" ], "client": [ "com.example.docs.client.command.ExampleModClientCommands", "com.example.docs.ExampleModBlockEntityRenderer", "com.example.docs.ExampleModDynamicSound", "com.example.docs.ExampleModClient", "com.example.docs.ExampleModScreens", "com.example.docs.rendering.CustomRenderPipeline", "com.example.docs.rendering.HudRenderingEntrypoint", "com.example.docs.rendering.RenderingConceptsEntrypoint", "com.example.docs.network.basic.ExampleModNetworkingBasicClient", "com.example.docs.appearance.ExampleModAppearanceClient", "com.example.docs.keymapping.ExampleModKeyMappingsClient", "com.example.docs.ExampleModRecipesClient", "com.example.docs.entity.ExampleModCustomEntityClient" ], "fabric-datagen": ["com.example.docs.datagen.ExampleModDataGenerator"] }, "mixins": [ "example-mod.mixins.json", { "config": "example-mod.client.mixins.json", "environment": "client" } ], "depends": { "fabricloader": ">=0.19.0", "minecraft": "~26.1", "java": ">=25", "fabric-api": "*" }, "accessWidener": "example-mod.classtweaker" } ``` -------------------------------- ### FabricRecipeProvider Setup Source: https://docs.fabricmc.net/develop/data-generation/recipes Extends FabricRecipeProvider and overrides buildRecipes to define custom recipes. Ensure prerequisites for datagen setup are met. ```java import java.util.List; import java.util.concurrent.CompletableFuture; import net.minecraft.core.HolderLookup; import net.minecraft.core.registries.Registries; import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.data.recipes.RecipeProvider; import net.minecraft.data.recipes.SimpleCookingRecipeBuilder; import net.minecraft.resources.Identifier; import net.minecraft.tags.ItemTags; import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.CookingBookCategory; import net.minecraft.world.item.crafting.Ingredient; import net.fabricmc.fabric.api.datagen.v1.FabricPackOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.fabricmc.fabric.api.resource.conditions.v1.ResourceConditions; import com.example.docs.ExampleMod; import com.example.docs.item.ModItems; public class ExampleModRecipeProvider extends FabricRecipeProvider { public ExampleModRecipeProvider(FabricPackOutput output, CompletableFuture registriesFuture) { super(output, registriesFuture); } @Override protected RecipeProvider createRecipeProvider(HolderLookup.Provider registryLookup, RecipeOutput exporter) { return new RecipeProvider(registryLookup, exporter) { @Override public void buildRecipes() { HolderLookup.RegistryLookup itemLookup = registries.lookupOrThrow(Registries.ITEM); } }; } @Override public String getName() { return "ExampleModRecipeProvider"; } } ``` -------------------------------- ### Chest Loot Table Provider Setup Source: https://docs.fabricmc.net/develop/data-generation/loot-tables Set up a class that extends SimpleFabricLootTableProvider for generating chest loot tables. ```java public class ExampleModChestLootTableProvider extends SimpleFabricLootTableSubProvider { public ExampleModChestLootTableProvider(FabricPackOutput output, CompletableFuture registryLookup) { super(output, registryLookup, LootContextParamSets.CHEST); } @Override public void generate(BiConsumer, LootTable.Builder> lootTableBiConsumer) { } } ``` -------------------------------- ### Example Instance of CoolBeansClass Source: https://docs.fabricmc.net/develop/codecs This code demonstrates how to create an instance of CoolBeansClass that can be serialized using the previously defined CODEC. ```java CoolBeansClass bean = new CoolBeansClass( 5, BuiltInRegistries.ITEM.wrapAsHolder(ModItems.LIGHTNING_TATER), List.of( new BlockPos(1, 2, 3), new BlockPos(4, 5, 6) ) ); ``` -------------------------------- ### Example List of BlockPos Data Source: https://docs.fabricmc.net/develop/codecs This shows an example of data that can be serialized or deserialized using the `Codec>`. ```java List data = List.of(new BlockPos(10, 5, 7)); ``` -------------------------------- ### All Mods Loaded Condition Source: https://docs.fabricmc.net/develop/resource-conditions This condition succeeds if all specified mods are loaded. The example requires 'example-mod' and 'another-mod' to be loaded. ```json { "fabric:load_conditions": [ { "condition": "fabric:all_mods_loaded", "values": [ "example-mod", "another-mod" ] } ] } ``` -------------------------------- ### Map Serialization Example Source: https://docs.fabricmc.net/develop/codecs Demonstrates how a map with Identifier keys serializes to a JSON object. ```java Map map = Map.of( Identifier.fromNamespaceAndPath("example", "number"), 23, Identifier.fromNamespaceAndPath("example", "the_cooler_number"), 42 ); ``` ```json { "example:number": 23, "example:the_cooler_number": 42 } ``` -------------------------------- ### Java Method Descriptor Example Source: https://docs.fabricmc.net/develop/mixins/bytecode Demonstrates how to construct a method descriptor in bytecode by concatenating parameter type descriptors and the return type descriptor. ```java void drawText(int x, int y, String text, int color) { // ... } ``` -------------------------------- ### Create FabricAdvancementProvider Source: https://docs.fabricmc.net/develop/data-generation/advancements Create a class that extends FabricAdvancementProvider and fill out the base methods. This is the starting point for defining custom advancements. ```java public class ExampleModAdvancementProvider extends FabricAdvancementProvider { protected ExampleModAdvancementProvider(FabricPackOutput output, CompletableFuture registryLookup) { super(output, registryLookup); } @Override public void generateAdvancement(HolderLookup.Provider wrapperLookup, Consumer consumer) { } } ``` -------------------------------- ### Block Loot Table Provider Setup Source: https://docs.fabricmc.net/develop/data-generation/loot-tables Set up a class that extends FabricBlockLootTableProvider to define block loot tables. ```java public class ExampleModBlockLootTableProvider extends FabricBlockLootSubProvider { protected ExampleModBlockLootTableProvider(FabricPackOutput dataOutput, CompletableFuture registryLookup) { super(dataOutput, registryLookup); } @Override public void generate() { } } ``` -------------------------------- ### Dependency Resolution Examples Source: https://docs.fabricmc.net/develop/loader/fabric-mod-json Configures mod dependencies, including required, recommended, suggested, broken, and conflicting mods, using semantic versioning. ```json "depends": { "example-mod": "*", "minecraft": [ "26.1", "26.1.1" ] } "suggests": { "another-mod": ">1.0.0" } ``` -------------------------------- ### Example Mod English Language Provider Source: https://docs.fabricmc.net/develop/data-generation/translations Extends FabricLanguageProvider to generate English translations. Requires a FabricPackOutput and a CompletableFuture. ```java public class ExampleModEnglishLangProvider extends FabricLanguageProvider { protected ExampleModEnglishLangProvider(FabricPackOutput dataOutput, CompletableFuture registryLookup) { // Specifying en_us is optional, as it's the default language code super(dataOutput, "en_us", registryLookup); } @Override public void generateTranslations(HolderLookup.Provider holderLookup, TranslationBuilder translationBuilder) { } } ``` -------------------------------- ### Creating a ListNode Instance Source: https://docs.fabricmc.net/develop/codecs An example of creating an instance of the `ListNode` record, representing a linked list with values 2, 3, and 5. ```java ListNode linkedList = new ListNode( 2, Optional.of( new ListNode( 3, Optional.of( new ListNode( 5, Optional.empty() ) ) ) ) ) ); ``` -------------------------------- ### Initialize Render State Source: https://docs.fabricmc.net/develop/blocks/block-entity-renderer Example of overriding the createRenderState method to initialize a new instance of the custom render state. ```java @Override public CounterBlockEntityRenderState createRenderState() { return new CounterBlockEntityRenderState(); } ``` -------------------------------- ### Configure Loom Options Source: https://docs.fabricmc.net/develop/loom/options Set the class tweaker file path, add log4j configs, and control archive remapping and variant setup. ```gradle loom { // Set the class tweaker file path, see https://docs.fabricmc.net/develop/class-tweakers/ accessWidenerPath = file("src/main/resources/example-mod.classtweaker") // Add additional log4j config files. log4jConfigs.from(file("log4j.xml")) // When enabled the output archives will be automatically remapped. remapArchives = true // When enabled the -dev jars in the *Elements configurations will be replaced by the remapped jars setupRemappedVariants = true // When enabled transitive access wideners will be applied from dependencies. enableTransitiveAccessWideners = true // When enabled log4j will only be on the runtime classpath, forcing the use of SLF4j. runtimeOnlyLog4j = false // When set only server related features and jars will be setup. serverOnlyMinecraftJar() // When set the minecraft jar will be split into common and clientonly. Highly experimental, fabric-loader does not support this option yet. splitMinecraftJar() // Used to configure existing or new run configurations runs { client { // Add a VM arg vmArgs "-Dexample=true" // Add a JVM property property("example", "true") // Add a program arg programArg "--example" // Add an environment variable environmentVariable("example", "true") // The environment (or side) to run, usually client or server. environment = "client" // The full name of the run configuration, i.e. 'Minecraft Client'. By default this is determined from the base name. configName = "Minecraft Client" // The default main class of the run configuration. This will be overridden if using a mod loader with a fabric_installer.json file. defaultMainClass = "" // The run directory for this configuration, relative to the root project directory. runDir = "run" // The source set to run, commonly set to sourceSets.test source = sourceSets.main // When true a run configuration file will be generated for IDE's. By default only set to true for the root project. ideConfigGenerated = true // Configure run config with the default client options. client() // Configure run config with the default server options. server() } // Example of creating a basic run config for tests testClient { // Copies settings from another run configuration. inherit client configName = "Test Minecraft Client" source = sourceSets.test } // Example of removing the built-in server configuration remove server } // Configure all run configs to generate ide run configurations. Useful for sub projects. runConfigs.configureEach { ideConfigGenerated = true } // Used to configure mixin options or apply to additional source sets. mixin { // When disabled tiny remapper will be used to remap Mixins instead of the AP. (Disabled by default in Loom 1.12+) useLegacyMixinAp = true // Set the default refmap name defaultRefmapName = "example.refmap.json" // See https://github.com/FabricMC/fabric-loom/blob/dev/0.11/src/main/java/net/fabricmc/loom/api/MixinExtensionAPI.java for options to add additional source sets } // Configure or add new decompilers decompilers { // Configure a default decompiler, either cfr, fernflower or vineflower cfr { // Pass additional options to the decompiler options += [ key: "value" ] // Set the amount of memory in megabytes used when forking the JVM memory = 4096 // Set the maximum number of threads that the decompiler can use. maxThreads = 8 } } interfaceInjection { // When enabled injected interfaces from dependencies will be applied. enableDependencyInterfaceInjection = true } // Splits the Minecraft jar and incoming dependencies across the main (common) and client only source sets. // This provides compile time safety for accessing client only code. splitEnvironmentSourceSets() // This mods block is used group mods that are made up of multiple classpath entries. mods { example-mod { // When using split sources you should add the main and client source set sourceSet sourceSets.main sourceSet sourceSets.client } } // Create modExampleImplementation and related configurations that remap mods. createRemapConfigurations(sourceSets.example) // Specifies the fabric.mod.json file location used in injected interface processing. // Defaults to src/main/resources/fabric.mod.json or src/client/resources/fabric.mod.json fabricModJsonPath = file("src/custom/resources/fabric.mod.json") } ``` -------------------------------- ### Initialize Mod to Register Resource Conditions Source: https://docs.fabricmc.net/develop/resource-conditions The ModInitializer for the example mod. It calls the registration method for custom resource conditions during initialization. ```java public class ExampleModResourceConditions implements ModInitializer { @Override public void onInitialize() { ModResourceConditions.register(); } } ``` -------------------------------- ### Static Method Bytecode Example with Doubles Source: https://docs.fabricmc.net/develop/mixins/bytecode Demonstrates the bytecode for a static method involving double-precision floating-point numbers, highlighting how they occupy two indexes in the LVT. ```java public static double add(double x, double y, double z) { return x + y + z; } ``` ```bytecode static add (DDD)D dload 0 // x dload 2 // y dadd dload 4 // z dadd dreturn ``` -------------------------------- ### Any Mods Loaded Condition Source: https://docs.fabricmc.net/develop/resource-conditions This condition succeeds if at least one of the specified mods is loaded. The example succeeds if 'example-mod' or 'another-mod' (or both) are loaded. ```json { "fabric:load_conditions": [ { "condition": "fabric:any_mods_loaded", "values": [ "example-mod", "another-mod" ] } ] } ``` -------------------------------- ### Non-static Method Bytecode Example Source: https://docs.fabricmc.net/develop/mixins/bytecode Illustrates the bytecode for a non-static method, showing how 'this', parameters, and local variables are indexed in the Local Variable Table (LVT). ```java public int getX(int offset) { int result = this.x + offset; return result; } ``` ```bytecode public getX (I)I aload 0 // this getfield x iload 1 // offset iadd istore 2 // result iload 2 // result ireturn ``` -------------------------------- ### Play UI Button Click Sound Source: https://docs.fabricmc.net/develop/sounds/dynamic-sounds Plays a simple UI button click sound on the client. This is a basic example using SimpleSoundInstance for immediate playback. ```java Minecraft client = Minecraft.getInstance(); client.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); ``` -------------------------------- ### Ore Configuration with Multiple Variants Source: https://docs.fabricmc.net/develop/data-generation/features Allows for different replacement targets based on the block type. This example sets diamond blocks for deepslate and iron blocks for stone. ```java List ironAndDiamondBlockOreConfig = List.of( OreConfiguration.target(deepslateReplaceableRule, Blocks.DIAMOND_BLOCK.defaultBlockState()), OreConfiguration.target(stoneReplaceableRule, Blocks.IRON_BLOCK.defaultBlockState()) ); ``` -------------------------------- ### Example Unit Test Class Source: https://docs.fabricmc.net/develop/automatic-testing An example of a JUnit test class for testing mod components. It includes setup for registries and assertions for bean codecs and item stacks. ```java public class BeanTypeTest { private static final Gson GSON = new GsonBuilder().create(); @BeforeAll static void beforeAll() { BeanTypes.register(); } @Test void testBeanCodec() { StringyBean expectedBean = new StringyBean("This bean is stringy!"); Bean actualBean = Bean.BEAN_CODEC.parse(JsonOps.INSTANCE, GSON.fromJson("{\"type\":\"example-mod:stringy_bean\",\"stringy_string\":\"This bean is stringy!\"}", JsonObject.class)).getOrThrow(); Assertions.assertInstanceOf(StringyBean.class, actualBean); Assertions.assertEquals(expectedBean.getType(), actualBean.getType()); Assertions.assertEquals(expectedBean.getStringyString(), ((StringyBean) actualBean).getStringyString()); } @Test void testDiamondItemStack() { // I know this isn't related to beans, but I need an example :) ItemStackTemplate diamondStack = new ItemStackTemplate(Items.DIAMOND, 65); Assertions.assertTrue(diamondStack.is(Items.DIAMOND)); Assertions.assertEquals(65, diamondStack.count()); } } ``` -------------------------------- ### Example Command to Remove a Component Source: https://docs.fabricmc.net/develop/items/custom-data-components Demonstrates a Minecraft command to give an item while explicitly excluding a specific custom component. Useful for testing scenarios where a component might be missing. ```mcfunction /give @p example-mod:counter[!example-mod:click_count] ``` -------------------------------- ### Configure Basic Tests Source: https://docs.fabricmc.net/develop/loom/fabric-api Sets up basic testing configurations, creating run configurations for both server and client-side game tests. ```gradle fabricApi { configureTests() } ``` -------------------------------- ### Configure Basic Data Generation Source: https://docs.fabricmc.net/develop/loom/fabric-api Sets up a basic data generation run configuration. This is the simplest way to enable data generation. ```gradle fabricApi { configureDataGeneration() } ``` -------------------------------- ### Play and Stop Custom Sound Instance Source: https://docs.fabricmc.net/develop/sounds/dynamic-sounds Demonstrates how to instantiate, play, and stop a custom sound instance on the client side. Ensure the custom instance is created and managed within a client-side context. ```java CustomSoundInstance instance = new CustomSoundInstance(client.player, CustomSounds.ENGINE_LOOP, SoundSource.NEUTRAL); // play the sound instance client.getSoundManager().play(instance); // stop the sound instance client.getSoundManager().stop(instance); ``` -------------------------------- ### Use Custom Date Matching Resource Condition Source: https://docs.fabricmc.net/develop/resource-conditions An example of using the custom 'date_matches' resource condition in a load condition. This specific example will only pass on April 1st. ```json { "fabric:load_conditions": [ { "condition": "example-mod:date_matches", "day": 1, "month": 4 } ] } ``` -------------------------------- ### Main Entrypoints Source: https://docs.fabricmc.net/develop/loader/fabric-mod-json Specifies the main classes for mod initialization, including client and server specific entrypoints. ```json "main": [ "net.fabricmc.example.ExampleMod", "net.fabricmc.example.ExampleMod::handle" ] ``` -------------------------------- ### Example Item Class for Debugging Source: https://docs.fabricmc.net/develop/debugging This Java code represents a custom item that attempts to change its name based on the block it's used on. It's used as an example to demonstrate debugging with breakpoints. ```java public class TestItem extends Item { public TestItem(Properties properties) { super(properties); } @Override public InteractionResult useOn(UseOnContext context) { Level level = context.getLevel(); Player user = context.getPlayer(); BlockPos targetPos = context.getBlockPos(); ItemStack itemStack = context.getItemInHand(); BlockState state = level.getBlockState(targetPos); if (state.is(ConventionalBlockTags.STONES)) { Component newName = Component.literal("[").append(state.getBlock().getName()).append(Component.literal("]")); itemStack.set(DataComponents.CUSTOM_NAME, newName); if (user != null) { user.displayClientMessage(Component.literal("Changed Item Name"), true); } } return InteractionResult.SUCCESS; } } ``` -------------------------------- ### Example Data Generator Entrypoint Class Source: https://docs.fabricmc.net/develop/data-generation/setup Create an entrypoint class for data generation. This class must implement the DataGeneratorEntrypoint interface and reside in the client package. The onInitializeDataGenerator method is where the data generation process is initiated. ```java public class ExampleModDataGenerator implements DataGeneratorEntrypoint { @Override public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { } } ``` -------------------------------- ### Configure Client Production Run Task with XVFB and Tracy Profiling Source: https://docs.fabricmc.net/develop/loom/production-run-tasks Configures the client production run task, enabling XVFB for headless environments and setting up Tracy profiling with custom executable paths and timeouts. ```gradle tasks.register("prodClient", net.fabricmc.loom.task.prod.ClientProductionRunTask) { // Whether to use XVFB to run the game, using a virtual framebuffer. This is useful for headless CI environments. // Defaults to true only on Linux and when the "CI" environment variable is set. // XVFB must be installed, on Debian-based systems you can install it with: `apt install xvfb` useXVFB = true // Optionally configure the tracy-capture executable. tracy { // The path to the tracy-capture executable. tracyCapture = file("tracy-capture") // The output path of the captured tracy profile. output = file("profile.tracy") // The maximum number of seconds to wait for tracy-capture to stop on its own before killing it. // Defaults to 10 seconds. maxShutdownWaitSeconds = 10 } } ``` -------------------------------- ### Initializing Custom Sounds in ModInitializer Source: https://docs.fabricmc.net/develop/sounds/custom This Java class demonstrates how to integrate the custom sound registration into the main Fabric mod initializer. It shows both a basic registration method and the preferred approach using the `CustomSounds.initialize()` helper method for a cleaner `ModInitializer`. ```java public class ExampleModSounds implements ModInitializer { @Override public void onInitialize() { // This is the basic registering. Use a new class for registering sounds // instead, to keep the ModInitializer implementing class clean! Registry.register(BuiltInRegistries.SOUND_EVENT, Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, "metal_whistle_simple"), SoundEvent.createVariableRangeEvent(Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, "metal_whistle_simple"))); // ... the cleaner approach. CustomSounds.initialize(); } public static Identifier identifierOf(String path) { return Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, path); } } ``` -------------------------------- ### Get Resource Condition Type Source: https://docs.fabricmc.net/develop/resource-conditions Returns the ResourceConditionType for the DateMatchesResourceCondition. This is used internally by the condition to identify its type. ```java @Override public ResourceConditionType getType() { return ModResourceConditions.DATE_MATCHES; } ``` -------------------------------- ### Accessing Command Source Source: https://docs.fabricmc.net/develop/commands/basics Demonstrates how to retrieve the command source from the CommandContext within a command's execution. ```java Command command = context -> { CommandSourceStack source = context.getSource(); return 0; }; ``` -------------------------------- ### Get Attribute Instance and Values Source: https://docs.fabricmc.net/develop/entities/attributes Retrieve an AttributeInstance, its current value, or its base value for a given attribute. ```java entity.getAttribute(ModAttributes.AGGRO_RANGE) // returns an `AttributeInstance` entity.getAttributeValue(ModAttributes.AGGRO_RANGE) // returns a double with the current value entity.getAttributeBaseValue(ModAttributes.AGGRO_RANGE) // returns a double with the base value ``` -------------------------------- ### Enable Debug Logging Configuration Source: https://docs.fabricmc.net/develop/debugging Create this XML file in your project's root directory to enable debug logs. Replace 'example-mod' with your mod's modid. ```xml ``` -------------------------------- ### And Condition Source: https://docs.fabricmc.net/develop/resource-conditions This condition succeeds only if all nested conditions are met. The example fails because the second nested condition negates 'true'. ```json { "fabric:load_conditions": [ { "condition": "fabric:and", "values": [ { "condition": "fabric:true" }, { "condition": "fabric:not", "value": { "condition": "fabric:true" } } ] } ] } ``` -------------------------------- ### Initialize Minecraft for Testing Source: https://docs.fabricmc.net/develop/automatic-testing Add this code to your `beforeAll` method to initialize Minecraft registries and classes required for testing. This prevents 'Not bootstrapped' errors. ```java SharedConstants.tryDetectVersion(); Bootstrap.bootStrap(); ``` -------------------------------- ### Not Condition Source: https://docs.fabricmc.net/develop/resource-conditions This condition inverts the result of another condition. The example shown will always fail because it negates the 'true' condition. ```json { "fabric:load_conditions": [ { "condition": "fabric:not", "value": { "condition": "fabric:true" } } ] } ``` -------------------------------- ### Create a Custom Screen with a Button and Label Source: https://docs.fabricmc.net/develop/rendering/gui/custom-screens Extend the `Screen` class and override `init` to add widgets like buttons. Use `extractRenderState` to draw custom text elements. Ensure `super` methods are called. ```java public class CustomScreen extends Screen { public CustomScreen(Component title) { super(title); } @Override protected void init() { Button buttonWidget = Button.builder(Component.literal("Hello World"), (btn) -> { // When the button is clicked, we can display a toast to the screen. this.minecraft.getToastManager().addToast( SystemToast.multiline(this.minecraft, SystemToast.SystemToastId.NARRATOR_TOGGLE, Component.nullToEmpty("Hello World!"), Component.nullToEmpty("This is a toast.")) ); }).bounds(40, 40, 120, 20).build(); // x, y, width, height // It's recommended to use the fixed height of 20 to prevent rendering issues with the button // textures. // Register the button widget. this.addRenderableWidget(buttonWidget); } @Override public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float delta) { super.extractRenderState(graphics, mouseX, mouseY, delta); // Minecraft doesn't have a "label" widget, so we'll have to draw our own text. // We'll subtract the font height from the Y position to make the text appear above the button. // Subtracting an extra 10 pixels will give the text some padding. // font, text, x, y, color, hasShadow graphics.text(this.font, "Special Button", 40, 40 - this.font.lineHeight - 10, 0xFFFFFFFF, true); } } ``` -------------------------------- ### AbstractDynamicSoundInstance Constructor Source: https://docs.fabricmc.net/develop/sounds/dynamic-sounds Initializes a new AbstractDynamicSoundInstance with default settings, including sound source, event, category, transition durations, volume/pitch limits, and a callback. ```java // ... // set up default settings of the SoundInstance in this constructor protected AbstractDynamicSoundInstance(DynamicSoundSource soundSource, SoundEvent soundEvent, SoundSource soundCategory, I've been working on a new dynamic sound system for FabricMC, and I'm looking for some documentation for the `AbstractDynamicSoundInstance` class. I need to understand its structure, how to initialize it, and how its `tick` method works. Can you provide documentation for this class, including code snippets? The source path is `sounds/dynamic-sounds.md`. ``` ```java public boolean canStartSilent() { // override to true, so that the SoundInstance can start // or add your own condition to the SoundInstance, if necessary return true; } ``` ```java @Override public void tick() { // handle states where sound might be actually stopped instantly if (this.soundSource == null) { this.callback.onFinished(this); } // basic tick behaviour this.currentTick++; this.setPositionToEntity(); // SoundInstance phase switching switch (this.transitionState) { case STARTING -> { this.transitionTick++; // go into next phase if starting phase finished its duration if (this.transitionTick > this.startTransitionTicks) { this.transitionTick = 0; // reset tick for future ending phase this.transitionState = TransitionState.RUNNING; } } case ENDING -> { this.transitionTick++; // set SoundInstance as finished if ending phase finished its duration if (this.transitionTick > this.endTransitionTicks) { this.callback.onFinished(this); } } } // apply volume and pitch modulation here, // if you use a normal SoundInstance class } ``` -------------------------------- ### Ore Replacement RuleTest Source: https://docs.fabricmc.net/develop/data-generation/features Defines which blocks can be replaced by a feature. This example uses a tag for deepslate ore replacements. ```java RuleTest deepslateReplaceableRule = new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES); ``` -------------------------------- ### Implement Recipe Methods Source: https://docs.fabricmc.net/develop/custom-recipe-types Implements the 'matches' and 'assemble' methods for the UpgradingRecipe. 'matches' checks if input items meet the recipe's ingredient requirements, and 'assemble' creates the resulting ItemStack. ```java @Override public boolean matches(UpgradingRecipeInput recipeInput, Level level) { return this.baseItem.test(recipeInput.baseItem()) && this.upgradeItem.test(recipeInput.upgradeItem()); } @Override public ItemStack assemble(UpgradingRecipeInput recipeInput) { return this.result.create().copy(); } ``` -------------------------------- ### Download File with Basic Configuration Source: https://docs.fabricmc.net/develop/loom/tasks A simple task to download files from a URL to a specified location. The output file is saved in the project directory. ```gradle tasks.register("download", net.fabricmc.loom.task.DownloadTask) { url = "https://example.com/file.txt" output = file("out.txt") } ``` -------------------------------- ### Or Condition Source: https://docs.fabricmc.net/develop/resource-conditions This condition succeeds if at least one of the nested conditions is met. The example succeeds because the first nested condition is 'true'. ```json { "fabric:load_conditions": [ { "condition": "fabric:or", "values": [ { "condition": "fabric:true" }, { "condition": "fabric:not", "value": { "condition": "fabric:true" } } ] } ] } ``` -------------------------------- ### Example NullPointerException in Crash Report Source: https://docs.fabricmc.net/develop/items/custom-data-components Illustrates a common NullPointerException that occurs when trying to access a custom component that is not present on an ItemStack. ```log java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "net.minecraft.world.item.ItemStack.get(net.minecraft.core.component.DataComponentType)" is null at com.example.docs.item.custom.CounterItem.appendHoverText(LightningStick.java:45) at net.minecraft.world.item.ItemStack.getTooltipLines(ItemStack.java:767) ``` -------------------------------- ### Register Parameterized Advancement Criterion Source: https://docs.fabricmc.net/develop/data-generation/advancements Registers a new parameterized advancement criterion with the game. This should be called during data generation setup. ```java public static final ParameterizedUseToolCriterion PARAMETERIZED_USE_TOOL = CriteriaTriggers.register(Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, "parameterized_use_tool").toString(), new ParameterizedUseToolCriterion()); ``` -------------------------------- ### Implement TooltipProvider for Custom Component Source: https://docs.fabricmc.net/develop/items/custom-data-components Recommended approach for adding tooltips by implementing the TooltipProvider interface within a custom component class. ```java public record ComponentWithTooltip(int clickCount) implements TooltipProvider { @Override public void addToTooltip(TooltipContext tooltip, Consumer textConsumer, TooltipFlag type, DataComponentGetter components) { textConsumer.accept(Component.translatable("item.example-mod.counter.info", this.clickCount).withStyle(ChatFormatting.GOLD)); } } ``` -------------------------------- ### Placed Features Class Setup Source: https://docs.fabricmc.net/develop/data-generation/features Initializes the class for defining placement features. This method is called during world generation configuration. ```java public class ExampleModWorldPlacedFeatures { public static void configure(BootstrapContext context) { } } ``` -------------------------------- ### JSON Output for Simple Advancement Source: https://docs.fabricmc.net/develop/data-generation/advancements The JSON representation of the 'get dirt' advancement, detailing its criteria, display properties, and requirements. ```json { "criteria": { "got_dirt": { "conditions": { "items": [ { "items": "minecraft:dirt" } ] }, "trigger": "minecraft:inventory_changed" } }, "display": { "background": "minecraft:gui/advancements/backgrounds/adventure", "description": "Now make a house from it", "icon": { "id": "minecraft:dirt" }, "title": "Your First Dirt Block" }, "requirements": [ [ "got_dirt" ] ], "sends_telemetry_event": true } ``` -------------------------------- ### Create DamageSource Instance (Java) Source: https://docs.fabricmc.net/develop/entities/damage-types Demonstrates how to create a DamageSource object using the custom damage type's ResourceKey. This is necessary before inflicting damage. ```java DamageSource damageSource = new DamageSource( level.registryAccess() .lookupOrThrow(Registries.DAMAGE_TYPE) .get(ExampleModDamageTypes.TATER_DAMAGE.identifier()).orElseThrow()); ``` -------------------------------- ### Update Render State with Entity Data Source: https://docs.fabricmc.net/develop/blocks/block-entity-renderer Example of overriding the extractRenderState method to update the render state with data from the block entity. ```java @Override public void extractRenderState(CounterBlockEntity blockEntity, CounterBlockEntityRenderState state, float tickProgress, Vec3 cameraPos, @Nullable ModelFeatureRenderer.CrumblingOverlay crumblingOverlay) { BlockEntityRenderer.super.extractRenderState(blockEntity, state, tickProgress, cameraPos, crumblingOverlay); state.setClicks(blockEntity.getClicks()); } ``` -------------------------------- ### Registering Fluid Instances Source: https://docs.fabricmc.net/develop/fluids/first-fluid Create a class to hold and register all your custom fluid instances. Ensure this class is loaded to trigger static initialization. ```java public class ModFluids { public static final FlowingFluid ACID_FLOWING = register("flowing_acid", new AcidFluid.Flowing()); public static final FlowingFluid ACID_STILL = register("acid", new AcidFluid.Source()); private static FlowingFluid register(String name, FlowingFluid fluid) { return Registry.register(BuiltInRegistries.FLUID, Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, name), fluid); } public static void initialize() { } } ``` -------------------------------- ### Drawing with RenderPipeline Source: https://docs.fabricmc.net/develop/rendering/world Executes the draw call for rendering geometry. Handles index buffer setup, uniform binding, and pipeline configuration. ```java private static void draw(Minecraft client, RenderPipeline pipeline, MeshData builtBuffer, MeshData.DrawState drawParameters, GpuBuffer vertices, VertexFormat format) { GpuBuffer indices; VertexFormat.IndexType indexType; if (pipeline.getVertexFormatMode() == VertexFormat.Mode.QUADS) { // Sort the quads if there is translucency builtBuffer.sortQuads(ALLOCATOR, RenderSystem.getProjectionType().vertexSorting()); // Upload the index buffer indices = pipeline.getVertexFormat().uploadImmediateIndexBuffer(builtBuffer.indexBuffer()); indexType = builtBuffer.drawState().indexType(); } else { // Use the general shape index buffer for non-quad draw modes RenderSystem.AutoStorageIndexBuffer shapeIndexBuffer = RenderSystem.getSequentialBuffer(pipeline.getVertexFormatMode()); indices = shapeIndexBuffer.getBuffer(drawParameters.indexCount()); indexType = shapeIndexBuffer.type(); } // Actually execute the draw GpuBufferSlice dynamicTransforms = RenderSystem.getDynamicUniforms() .writeTransform(RenderSystem.getModelViewMatrix(), COLOR_MODULATOR, MODEL_OFFSET, TEXTURE_MATRIX); try (RenderPass renderPass = RenderSystem.getDevice() .createCommandEncoder() .createRenderPass(() -> ExampleMod.MOD_ID + " example render pipeline rendering", client.getMainRenderTarget().getColorTextureView(), OptionalInt.empty(), client.getMainRenderTarget().getDepthTextureView(), OptionalDouble.empty())) { renderPass.setPipeline(pipeline); RenderSystem.bindDefaultUniforms(renderPass); renderPass.setUniform("DynamicTransforms", dynamicTransforms); // Bind texture if applicable: // Sampler0 is used for texture inputs in vertices // renderPass.bindTexture("Sampler0", textureSetup.texure0(), textureSetup.sampler0()); renderPass.setVertexBuffer(0, vertices); renderPass.setIndexBuffer(indices, indexType); // The base vertex is the starting index when we copied the data into the vertex buffer divided by vertex size //noinspection ConstantValue renderPass.drawIndexed(0 / format.getVertexSize(), 0, drawParameters.indexCount(), 1); } builtBuffer.close(); } ``` -------------------------------- ### Features Enabled Condition Source: https://docs.fabricmc.net/develop/resource-conditions This condition succeeds if all specified feature flags are enabled. The example checks if 'minecraft:vanilla' and 'minecraft:minecart_improvements' are enabled. ```json { "fabric:load_conditions": [ { "condition": "fabric:features_enabled", "features": [ "minecraft:vanilla", "minecraft:minecart_improvements" ] } ] } ``` -------------------------------- ### Create Recipe Input Class Source: https://docs.fabricmc.net/develop/custom-recipe-types Implements RecipeInput to hold base and upgrade items for an upgrading recipe. Defines how to access items by index and the total size of the input. ```java public record UpgradingRecipeInput(ItemStack baseItem, ItemStack upgradeItem) implements RecipeInput { @Override public ItemStack getItem(int index) { return switch (index) { case 0 -> this.baseItem; case 1 -> this.upgradeItem; default -> ItemStack.EMPTY; }; } @Override public int size() { return 2; } } ``` -------------------------------- ### Render Waypoint Geometry Source: https://docs.fabricmc.net/develop/rendering/world Sets up the rendering matrices and buffer for a waypoint. Initializes the BufferBuilder if it's null. ```java private void renderWaypoint(LevelRenderContext context) { PoseStack matrices = context.poseStack(); Vec3 camera = context.levelState().cameraRenderState.pos; matrices.pushPose(); matrices.translate(-camera.x, -camera.y, -camera.z); if (this.buffer == null) { this.buffer = new BufferBuilder(ALLOCATOR, FILLED_THROUGH_WALLS.getVertexFormatMode(), FILLED_THROUGH_WALLS.getVertexFormat()); } this.renderFilledBox(matrices.last().pose(), this.buffer, waypointState.x(), waypointState.y(), waypointState.z(), waypointState.x() + 1, waypointState.y() + 1, waypointState.z() + 1, waypointState.r(), waypointState.g(), waypointState.b(), waypointState.a()); matrices.popPose(); } ``` -------------------------------- ### Return to Previous Screen on Close Source: https://docs.fabricmc.net/develop/rendering/gui/custom-screens Implement `onClose` to set the screen to a stored parent screen, allowing navigation back. The parent screen must be passed to the constructor. ```java public Screen parent; public CustomScreen(Component title, Screen parent) { super(title); this.parent = parent; } @Override public void onClose() { this.minecraft.setScreen(this.parent); } ``` ```java Screen currentScreen = Minecraft.getInstance().currentScreen; Minecraft.getInstance().setScreen( new CustomScreen(Component.empty(), currentScreen) ); ``` -------------------------------- ### Registering Custom Sounds with a Helper Class Source: https://docs.fabricmc.net/develop/sounds/custom This Java class provides a structured way to register custom sound events. It includes methods to register individual sounds and to initialize the entire sound registration process. Use this to keep your main initializer clean. ```java public class CustomSounds { private CustomSounds() { // private empty constructor to avoid accidental instantiation } // ITEM_METAL_WHISTLE is the name of the custom sound event // and is called in the mod to use the custom sound public static final SoundEvent ITEM_METAL_WHISTLE = registerSound("metal_whistle"); public static final SoundEvent ENGINE_LOOP = registerSound("engine"); // actual registration of all the custom SoundEvents private static SoundEvent registerSound(String id) { Identifier identifier = Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, id); return Registry.register(BuiltInRegistries.SOUND_EVENT, identifier, SoundEvent.createVariableRangeEvent(identifier)); } // This static method starts class initialization, which then initializes // the static class variables (e.g. ITEM_METAL_WHISTLE). public static void initialize() { ExampleMod.LOGGER.info("Registering " + ExampleMod.MOD_ID + " Sounds"); // Technically this method can stay empty, but some developers like to notify // the console, that certain parts of the mod have been successfully initialized } } ``` -------------------------------- ### Send Debug Log Message Source: https://docs.fabricmc.net/develop/debugging Example of sending a debug log message in Java. This message will appear in the console if debug logging is enabled. ```java ExampleMod.LOGGER.debug("Debug logging is enabled"); ``` -------------------------------- ### Custom Tree Configuration Source: https://docs.fabricmc.net/develop/data-generation/features Defines the structure and block types for a custom tree. This example creates a tree with diamond trunks and gold leaves. ```java TreeConfiguration diamondTree = new TreeConfiguration.TreeConfigurationBuilder( // Trunk / Logs BlockStateProvider.simple(Blocks.DIAMOND_BLOCK), new StraightTrunkPlacer(4, 2, 0), // Leaves BlockStateProvider.simple(Blocks.GOLD_BLOCK), new BlobFoliagePlacer(ConstantInt.of(2), ConstantInt.of(0), 3), new TwoLayersFeatureSize(0, 0, 0) ).build(); ``` -------------------------------- ### Registering a Configured Ore Feature Source: https://docs.fabricmc.net/develop/data-generation/features Registers a configured ore feature with a specific vein size. This example registers a diamond block vein. ```java context.register( DIAMOND_BLOCK_VEIN_CONFIGURED_KEY, new ConfiguredFeature<>( Feature.ORE, new OreConfiguration(diamondBlockOreConfig, 10)) // 10 is the blocks per vein ); ``` -------------------------------- ### Make Inner Class Accessible Source: https://docs.fabricmc.net/develop/class-tweakers/access-widening This example shows how to make an inner class public using the 'accessible' directive in a class tweaker file. ```classtweaker accessible class net/minecraft/world/inventory/MenuType$MenuSupplier ```