### Clone Fabric Example Mod Repository (Shell) Source: https://docs.fabricmc.net/1.21.10/develop/getting-started/creating-a-project This command clones the official Fabric example mod repository to your local machine. It's the first step in manually creating a new Fabric mod project. Ensure you have Git installed. ```shell git clone https://github.com/FabricMC/fabric-example-mod/ my-mod-project ``` -------------------------------- ### Run Minecraft Server with Gradle Source: https://docs.fabricmc.net/1.21.10/develop/getting-started/intellij-idea/launching-the-game Execute the Gradle task to start the Minecraft game in server mode. This command-line method is used for launching a dedicated server instance. ```bash ./gradlew runServer ``` -------------------------------- ### Run Minecraft Client with Gradle Source: https://docs.fabricmc.net/1.21.10/develop/getting-started/intellij-idea/launching-the-game Execute the Gradle task to start the Minecraft game in client mode. This is a command-line approach for launching the game without direct debugging capabilities. ```bash ./gradlew runClient ``` -------------------------------- ### Example Mod Datagen Advancement Implementation in Java Source: https://docs.fabricmc.net/1.21.10/develop/data-generation/advancements This Java code snippet provides an example of implementing `ModInitializer` to register event listeners for player block breaks. It includes a basic, non-persistent `HashMap` to track tool usage, demonstrating how to interact with game events and send messages to players. ```java public class ExampleModDatagenAdvancement implements ModInitializer { @Override public void onInitialize() { HashMap tools = new HashMap<>(); PlayerBlockBreakEvents.AFTER.register(((world, player, blockPos, blockState, blockEntity) -> { if (player instanceof ServerPlayer serverPlayer) { // Only triggers on the server side Item item = player.getMainHandItem().getItem(); Integer usedCount = tools.getOrDefault(item, 0); usedCount++; tools.put(item, usedCount); serverPlayer.sendSystemMessage(Component.nullToEmpty("You've used \"" + item + "\" as a tool " + usedCount + " times!")); } })); } } ``` -------------------------------- ### Setup Fabric Advancement Provider Source: https://docs.fabricmc.net/1.21.10/develop/data-generation/advancements Creates a class that extends FabricAdvancementProvider to handle advancement generation. It requires a FabricDataOutput and a CompletableFuture for registry lookups. ```java public class ExampleModAdvancementProvider extends FabricAdvancementProvider { protected ExampleModAdvancementProvider(FabricDataOutput output, CompletableFuture registryLookup) { super(output, registryLookup); } @Override public void generateAdvancement(HolderLookup.Provider wrapperLookup, Consumer consumer) { } } ``` -------------------------------- ### Create Data Pack in Entrypoint Source: https://docs.fabricmc.net/1.21.10/develop/data-generation/setup Initializes a new data pack within the `onInitializeDataGenerator` method of the datagen entrypoint class. This pack will later hold the generated data. ```java FabricDataGenerator.Pack pack = fabricDataGenerator.createPack(); ``` -------------------------------- ### AbstractDynamicSoundInstance canStartSilent Override Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Overrides the canStartSilent method to return true, allowing the SoundInstance to start playing immediately. This can be customized with specific conditions if needed. ```java @Override 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 Method Descriptor Example Source: https://docs.fabricmc.net/1.21.10/develop/mixins/bytecode Provides an example of a Java method signature and its corresponding bytecode descriptor. The descriptor concatenates the parameter type descriptors within parentheses, followed by the return type descriptor. ```java void drawText(int x, int y, String text, int color) { // ... } // Descriptor: (IILjava/lang/String;I)V ``` -------------------------------- ### Setup FabricRecipeProvider in Java Source: https://docs.fabricmc.net/1.21.10/develop/data-generation/recipes Extends FabricRecipeProvider to create a custom recipe provider for your mod. The buildRecipes method is where all recipe generation logic will reside. This setup is crucial for datagen. ```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.tags.ItemTags; import net.minecraft.world.item.Item; import net.minecraft.world.item.Items; import net.minecraft.world.item.crafting.Ingredient; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; public class ExampleModRecipeProvider extends FabricRecipeProvider { public ExampleModRecipeProvider(FabricDataOutput 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"; } } ``` -------------------------------- ### Data Generator Entrypoint Class Source: https://docs.fabricmc.net/1.21.10/develop/data-generation/setup Defines the main entrypoint class for Fabric's data generation. This class implements the DataGeneratorEntrypoint interface and is where the datagen process is initialized. ```java import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; public class ExampleModDataGenerator implements DataGeneratorEntrypoint { @Override public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { } } ``` -------------------------------- ### Enable Data Generation in build.gradle Source: https://docs.fabricmc.net/1.21.10/develop/data-generation/setup Configures the Fabric API in the build.gradle file to enable client-side data generation. This is a crucial step for setting up the datagen environment. ```gradle fabricApi { configureDataGeneration() { client = true } } ``` -------------------------------- ### Create Smelting Recipes in Java Source: https://docs.fabricmc.net/1.21.10/develop/data-generation/recipes Implements smelting recipes, which require additional parameters such as experience awarded, cooking time, and a group name. This example shows how to define inputs, output, and other properties for smelting. ```java oreSmelting( List.of(Items.BREAD, Items.COOKIE, Items.HAY_BLOCK), // Inputs RecipeCategory.FOOD, // Category Items.WHEAT, // Output 0.1f, // Experience 300, // Cooking time "food_to_wheat" // group ); ``` -------------------------------- ### Register Datagen Entrypoint in fabric.mod.json Source: https://docs.fabricmc.net/1.21.10/develop/data-generation/setup Registers the custom data generator entrypoint class within the fabric.mod.json file. This tells Fabric where to find the datagen initialization logic. ```json { // ... "entrypoints": { // ... "client": [ // ... ], "fabric-datagen": [ "com.example.docs.datagen.ExampleModDataGenerator" ] } } ``` -------------------------------- ### Add Item to Fuel Registry (Java) Source: https://docs.fabricmc.net/1.21.10/develop/items/first-item Uses Fabric API's FuelRegistryEvents.BUILD to register an item as fuel. This example sets the 'suspicious_substance' to have a burn time of 30 seconds (600 ticks). ```java // Add the suspicious substance to the registry of fuels, with a burn time of 30 seconds. // Remember, Minecraft deals with logical based-time using ticks. // 20 ticks = 1 second. FuelRegistryEvents.BUILD.register((builder, context) -> { builder.add(ModItems.SUSPICIOUS_SUBSTANCE, 30 * 20); }); ``` -------------------------------- ### Add Item to Composting Registry (Java) Source: https://docs.fabricmc.net/1.21.10/develop/items/first-item Uses Fabric API's CompostableItemRegistry to make an item compostable. This example adds a 'suspicious_substance' with a 30% chance of increasing the composter's level. ```java // Add the suspicious substance to the composting registry with a 30% chance of increasing the composter's level. CompostingChanceRegistry.INSTANCE.add(ModItems.SUSPICIOUS_SUBSTANCE, 0.3f); ``` -------------------------------- ### EngineSoundInstance Implementation Extending AbstractDynamicSoundInstance (Java) Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds An example implementation of a custom `SoundInstance` class, `EngineSoundInstance`, which extends `AbstractDynamicSoundInstance`. This class defines specific conditions for stopping the sound and applies custom sound modulation by calling the parent class's methods within its `tick` method. ```java public class EngineSoundInstance extends AbstractDynamicSoundInstance { // Here we just use the default constructor parameters. // If you want to specifically set values here already, // you can clean up the constructor parameters a bit public EngineSoundInstance(DynamicSoundSource soundSource, SoundEvent soundEvent, SoundSource soundCategory,

This is a Java code snippet that defines two methods within the `AbstractDynamicSoundInstance` class. The first method, `modulateSoundForTransition`, adjusts the volume of a sound instance based on its current transition state (STARTING or ENDING) and the progress of the transition. It uses a normalized tick value, calculated based on the transition state and its duration, to linearly interpolate the volume between 0.0 and the maximum volume. The second method, `modulateSoundForStress`, adjusts the pitch of the sound instance based on the normalized stress value of the sound source, interpolating between a minimum and maximum pitch. These methods are designed to be called within the `tick` method of a sound instance to dynamically alter its audio properties during playback. ``` ```java ``` ```java ``` -------------------------------- ### Create Custom Widget Class in Java Source: https://docs.fabricmc.net/1.21.10/develop/rendering/gui/custom-widgets Demonstrates how to create a custom widget by extending `AbstractWidget`. This example shows how to initialize the widget and override the `renderWidget` method to draw a gradient rectangle. It also includes a placeholder for `updateWidgetNarration`. ```java public class CustomWidget extends AbstractWidget { public CustomWidget(int x, int y, int width, int height) { super(x, y, width, height, Component.empty()); } @Override protected void renderWidget(GuiGraphics context, int mouseX, int mouseY, float delta) { // We'll just draw a simple rectangle for now. // x1, y1, x2, y2, startColor, endColor int startColor = 0xFF00FF00; // Green int endColor = 0xFF0000FF; // Blue context.fillGradient(getX(), getY(), getX() + this.width, getY() + this.height, startColor, endColor); } @Override protected void updateWidgetNarration(NarrationElementOutput builder) { // For brevity, we'll just skip this for now - if you want to add narration to your widget, you can do so here. return; } } ``` -------------------------------- ### Play and Stop Custom SoundInstance Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Demonstrates how to instantiate and control a custom `SoundInstance`. It shows playing a looping sound that follows the client's player and how to manually stop the sound instance when needed. This requires the `CustomSoundInstance` class to be defined elsewhere. ```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); ``` -------------------------------- ### Example JUnit Test Class for Fabric Mods Source: https://docs.fabricmc.net/1.21.10/develop/automatic-testing This Java code demonstrates a basic JUnit test class for a Fabric mod. It includes setup for registry access and example tests for codec parsing and ItemStack manipulation, utilizing Fabric Loader JUnit. ```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: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 :) ItemStack diamondStack = new ItemStack(Items.DIAMOND, 65); Assertions.assertTrue(diamondStack.is(Items.DIAMOND)); Assertions.assertEquals(65, diamondStack.getCount()); } } ``` -------------------------------- ### AbstractDynamicSoundInstance Constructor Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Initializes the AbstractDynamicSoundInstance with default settings. It takes parameters for the sound source, event, category, transition durations, volume/pitch limits, and a callback. It sets initial volume, pitch, looping state, transition state, and positions the sound to the entity. ```java // ... // set up default settings of the SoundInstance in this constructor protected AbstractDynamicSoundInstance(DynamicSoundSource soundSource, SoundEvent soundEvent, SoundSource soundCategory, int startTransitionTicks, int endTransitionTicks, float maxVolume, float minPitch, float maxPitch, SoundInstanceCallback callback) { super(soundEvent, soundCategory, SoundInstance.createUnseededRandom()); // store important references to other objects this.soundSource = soundSource; this.callback = callback; // store the limits for the SoundInstance this.maxVolume = maxVolume; this.minPitch = minPitch; this.maxPitch = maxPitch; this.startTransitionTicks = startTransitionTicks; // starting phase duration this.endTransitionTicks = endTransitionTicks; // ending phase duration // set start values this.volume = 0.0f; this.pitch = minPitch; this.looping = true; this.transitionState = TransitionState.STARTING; this.setPositionToEntity(); } // ... ``` -------------------------------- ### Serialized ListNode Example (JSON) Source: https://docs.fabricmc.net/1.21.10/develop/codecs An example of how a `ListNode` object would be serialized into JSON format, showcasing the recursive structure. ```json { "value": 2, "next": { "value": 3, "next": { "value": 5 } } } ``` -------------------------------- ### Main Entrypoint Initialization (Java) Source: https://docs.fabricmc.net/1.21.10/develop/getting-started/project-structure Demonstrates the basic structure of a Fabric mod's main entrypoint, implementing `ModInitializer` to execute code upon game startup. It includes logging initialization using a mod-specific logger. ```java import net.fabricmc.api.ModInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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!"); } } ``` -------------------------------- ### Serialized CountingBean JSON Example Source: https://docs.fabricmc.net/1.21.10/develop/codecs An example of the JSON output when serializing a 'CountingBean' object using the registry dispatch codec. It includes the 'type' field identifying the bean and the specific field 'counting_number'. ```json { "type": "example:counting_bean", "counting_number": 42 } ``` -------------------------------- ### Serialized StringyBean JSON Example Source: https://docs.fabricmc.net/1.21.10/develop/codecs An example of the JSON output when serializing a 'StringyBean' object using the registry dispatch codec. It includes the 'type' field identifying the bean and the specific field 'stringy_string'. ```json { "type": "example:stringy_bean", "stringy_string": "This bean is stringy!" } ``` -------------------------------- ### VS Code: Navigate Minecraft Classes Source: https://docs.fabricmc.net/1.21.10/develop/getting-started/vscode/tips-and-tricks This section explains how to use VS Code's features to navigate and understand Minecraft's source code. It covers 'Quick Open' for viewing class definitions and 'Go to Definition' for navigating to a class's origin. It also details how to find all references to a class. ```plaintext #Identifier Ctrl + clicking on its name ``` -------------------------------- ### Utility Methods in AbstractDynamicSoundInstance (Java) Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Provides utility methods for managing sound instances. The `setPositionToEntity` method synchronizes the sound instance's position with its associated sound source. The `end` method transitions the sound instance into its ending phase, useful for external control. ```java // moves the sound instance position to the sound source's position protected void setPositionToEntity() { this.x = soundSource.getPosition().x(); this.y = soundSource.getPosition().y(); this.z = soundSource.getPosition().z(); } // Sets the SoundInstance into its ending phase. // This is especially useful for external access to this SoundInstance public void end() { this.transitionState = TransitionState.ENDING; } ``` -------------------------------- ### Java Item Interaction Debug Example Source: https://docs.fabricmc.net/1.21.10/develop/debugging This Java code snippet demonstrates a problematic item interaction in FabricMC. It's intended to change an item's custom name based on the block it's used on, but it fails for cobblestone due to an incorrect block tag check. This example is useful for illustrating debugging scenarios. ```java public class TestItem extends Item { public TestItem(Properties properties) { super(properties); } @Override public InteractionResult useOn(UseOnContext context) { Level world = context.getLevel(); Player user = context.getPlayer(); BlockPos targetPos = context.getBlockPos(); ItemStack itemStack = context.getItemInHand(); BlockState state = world.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; } } ``` -------------------------------- ### Initializing ModBlocks Class in Java Source: https://docs.fabricmc.net/1.21.10/develop/blocks/first-block This Java code demonstrates how to ensure the `ModBlocks` class is loaded and its static fields are initialized. It includes a dummy `initialize` method within `ModBlocks` and a `ModInitializer` implementation in `ExampleModBlocks` to trigger this initialization during the mod's startup. ```java public class ModBlocks { // ... public static void initialize() {} } ``` ```java public class ExampleModBlocks implements ModInitializer { @Override public void onInitialize() { ModBlocks.initialize(); } } ``` -------------------------------- ### Instantiate and Register a Custom Item - Java Source: https://docs.fabricmc.net/1.21.10/develop/items/first-item Demonstrates how to use the `register` method to create and register a new item named 'suspicious_substance'. It utilizes `Item::new` as the factory and provides default `Item.Properties`. ```java public static final Item SUSPICIOUS_SUBSTANCE = register("suspicious_substance", Item::new, new Item.Properties()); ``` -------------------------------- ### Sound Modulation Methods in AbstractDynamicSoundInstance (Java) Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Implements methods to modulate sound volume and pitch based on the sound's transition state and the sound source's stress level. These methods utilize linear interpolation (lerp) with normalized values to shape audio parameters within preferred limits. It's important to manage interactions when multiple modulation methods affect the same value. ```java protected void modulateSoundForTransition() { float normalizedTick = switch (transitionState) { case STARTING -> (float) this.transitionTick / this.startTransitionTicks; case ENDING -> 1.0f - ((float) this.transitionTick / this.endTransitionTicks); default -> 1.0f; }; this.volume = Mth.lerp(normalizedTick, 0.0f, this.maxVolume); } // increase or decrease pitch based on the sound source's stress value protected void modulateSoundForStress() { this.pitch = Mth.lerp(this.soundSource.getNormalizedStress(), this.minPitch, this.maxPitch); } ``` -------------------------------- ### Initialize Custom Sounds in ModInitializer (Java) Source: https://docs.fabricmc.net/1.21.10/develop/sounds/custom This Java code demonstrates how to integrate the `CustomSounds` helper class into the `ModInitializer`. It shows both a basic direct registration and the preferred method of calling `CustomSounds.initialize()` to register all custom sound events cleanly. This keeps the `ModInitializer` focused on core initialization tasks. ```java public class ExampleModSounds implements ModInitializer { public static final String MOD_ID = ExampleMod.MOD_ID; public static final Logger LOGGER = ExampleMod.LOGGER; @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, ResourceLocation.fromNamespaceAndPath(MOD_ID, "metal_whistle_simple"), SoundEvent.createVariableRangeEvent(ResourceLocation.fromNamespaceAndPath(MOD_ID, "metal_whistle_simple"))); // ... the cleaner approach. CustomSounds.initialize(); } public static ResourceLocation identifierOf(String path) { return ResourceLocation.fromNamespaceAndPath(ExampleMod.MOD_ID, path); } } ``` -------------------------------- ### Register a Basic Command - Java Source: https://docs.fabricmc.net/1.21.10/develop/commands/basics Provides a Java code example for registering a simple command named 'test_command' using the Fabric API's `CommandRegistrationCallback`. It demonstrates how to use the `CommandDispatcher` to register a literal command and execute logic using `.executes()`. ```java CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { dispatcher.register(Commands.literal("test_command").executes(context -> { context.getSource().sendSuccess(() -> Component.literal("Called /test_command."), false); return 1; })); }); ``` -------------------------------- ### Scale Matrix with Matrix3x2fStack in Java Source: https://docs.fabricmc.net/1.21.10/develop/rendering/basic-concepts Demonstrates how to scale a matrix on the stack for HUD rendering using Matrix3x2fStack. It pushes a new matrix, applies scaling based on tick progress, and then pops the matrix. This is useful for animating UI elements. ```java Matrix3x2fStack matrices = drawContext.pose(); // Store the total tick delta in a field, so we can use it later. totalTickProgress += tickCounter.getGameTimeDeltaPartialTick(true); // Push a new matrix onto the stack. matrices.pushMatrix(); // Scale the matrix by 0.5 to make the triangle smaller and larger over time. float scaleAmount = Mth.sin(totalTickProgress / 10F) / 2F + 1.5F; // Apply the scaling amount to the matrix. // We don't need to scale the Z axis since it's on the HUD and 2D. matrices.scale(scaleAmount, scaleAmount); // We do not need to manually write to the buffer. DrawContext methods write to GUI buffer in `GuiRenderer` at the end of preparation. // Pop our matrix from the stack. matrices.popMatrix(); ``` -------------------------------- ### Create a Custom Screen with a Button and Label (Java) Source: https://docs.fabricmc.net/1.21.10/develop/rendering/gui/custom-screens Demonstrates how to extend the `Screen` class to create a custom GUI. It shows overriding `init` to add a button and `render` to draw a label. Widgets should be initialized in `init` as screen dimensions are available. ```java public class CustomScreen extends Screen { public CustomScreen(Component title) { super(title); } @Override protected void init() { Button buttonWidget = Button.builder(Component.nullToEmpty("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 render(GuiGraphics context, int mouseX, int mouseY, float delta) { super.render(context, 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. // textRenderer, text, x, y, color, hasShadow context.drawString(this.font, "Special Button", 40, 40 - this.font.lineHeight - 10, 0xFFFFFFFF, true); } } ``` -------------------------------- ### AbstractDynamicSoundInstance Tick Method Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Implements the tick method for AbstractDynamicSoundInstance. It handles sound source null checks, updates current ticks, sets the sound position, and manages state transitions between STARTING, RUNNING, and ENDING phases based on tick durations. It also includes a placeholder for volume and pitch modulation. ```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 } ``` -------------------------------- ### Mod Initializer for Attributes in Java Source: https://docs.fabricmc.net/1.21.10/develop/entities/attributes The main mod initializer class that calls the custom attributes' initialize method. This ensures that all custom attributes are registered when the mod starts. ```java public class ExampleModAttributes implements ModInitializer { @Override public void onInitialize() { ModAttributes.initialize(); } } ``` -------------------------------- ### Implement SoundInstanceCallback Interface in Java Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds A Java interface for creating callbacks to handle signals from SoundInstance objects. It includes an onFinished method to deliver the originating sound instance, allowing for custom signal handling logic. ```java public interface SoundInstanceCallback { // deliver the custom SoundInstance, from which this signal originates, // using the method parameters void onFinished(T soundInstance); } ``` -------------------------------- ### Get Attribute Instance and Values (Java) Source: https://docs.fabricmc.net/1.21.10/develop/entities/attributes Demonstrates how to retrieve an AttributeInstance, its current value, and its base value for a given attribute on an entity. This is useful for inspecting attribute states. ```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 ``` -------------------------------- ### Example JSON Structure for CoolBeansClass Source: https://docs.fabricmc.net/1.21.10/develop/codecs This JSON structure demonstrates how an instance of `CoolBeansClass` would be represented in a JSON file. It maps the class fields to JSON keys with appropriate data types. ```json { "beans_amount": 5, "bean_type": "beanmod:mythical_beans", "bean_positions": [ [1, 2, 3], [4, 5, 6] ] } ``` -------------------------------- ### Play UI Sound with SimpleSoundInstance Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Plays a simple UI sound effect, such as a button click, on the client side. This is useful for immediate feedback on user interactions. It utilizes the `Minecraft.getInstance()` to access the sound manager and `SimpleSoundInstance.forUI` to create the sound instance. ```java Minecraft client = Minecraft.getInstance(); client.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); ``` -------------------------------- ### DynamicSoundManager Singleton Implementation in Java Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds This Java code defines the DynamicSoundManager class, implementing the Singleton pattern to ensure a single instance. It manages a list of active sounds and provides a callback for when sounds finish. ```java public class DynamicSoundManager implements SoundInstanceCallback { // An instance of the client to use Minecraft's default SoundManager private static final Minecraft client = Minecraft.getInstance(); // static field to store the current instance for the Singleton Design Pattern private static DynamicSoundManager instance; // The list which keeps track of all currently playing dynamic SoundInstances private final List activeSounds = new ArrayList<>(); private DynamicSoundManager() { // private constructor to make sure that the normal // instantiation of that object is not used externally } // when accessing this class for the first time a new instance // is created and stored. If this is called again only the already // existing instance will be returned, instead of creating a new instance public static DynamicSoundManager getInstance() { if (instance == null) { instance = new DynamicSoundManager(); } return instance; } // This is where the callback signal of a finished custom SoundInstance will arrive. // For now, we can just stop and remove the sound from the list, but you can add // your own functionality too @Override public void onFinished(T soundInstance) { this.stop(soundInstance); } } ``` -------------------------------- ### Register Test Sheep Shear Listener (Java) Source: https://docs.fabricmc.net/1.21.10/develop/events Registers a custom listener to the `SheepShearCallback.EVENT`. This example modifies the shearing behavior to drop a diamond instead of wool and returns `InteractionResult.FAIL` to stop further processing. ```java SheepShearCallback.EVENT.register((player, sheep) -> { sheep.setSheared(true); // Create diamond item entity at sheep's position. ItemStack stack = new ItemStack(Items.DIAMOND); ItemEntity itemEntity = new ItemEntity(player.level(), sheep.getX(), sheep.getY(), sheep.getZ(), stack); player.level().addFreshEntity(itemEntity); return InteractionResult.FAIL; }); ``` -------------------------------- ### Define Simple TransitionState Enum in Java Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds A basic Java enum defining the three possible transition states for a sound instance: STARTING, RUNNING, and ENDING. This serves as a fundamental way to track the playback phase of a sound. ```java public enum TransitionState { STARTING, RUNNING, ENDING } ``` -------------------------------- ### Open Custom Screen Returning to Previous (Java) Source: https://docs.fabricmc.net/1.21.10/develop/rendering/gui/custom-screens Provides an example of how to instantiate a `CustomScreen` that will return to the previous screen upon closing. It retrieves the current screen and passes it as an argument to the `CustomScreen` constructor. ```java Screen currentScreen = Minecraft.getInstance().currentScreen; Minecraft.getInstance().setScreen( new CustomScreen(Component.empty(), currentScreen) ); ``` -------------------------------- ### Append Custom Tooltip (Java) Source: https://docs.fabricmc.net/1.21.10/develop/items/first-item Overrides the 'appendHoverText' method in an Item class to add custom text to an item's tooltip. This example adds a gold-colored, translatable string to the tooltip. ```java @Override public void appendHoverText(ItemStack stack, TooltipContext context, TooltipDisplay displayComponent, Consumer textConsumer, TooltipFlag type) { textConsumer.accept(Component.translatable("itemTooltip.example-mod.lightning_stick").withStyle(ChatFormatting.GOLD)); } ``` -------------------------------- ### Define Client Item JSON Source: https://docs.fabricmc.net/1.21.10/develop/items/first-item Registers the item's model with the client. This JSON file specifies the model type and the identifier for the item's model, and should be located in the 'assets/example-mod/items' folder. ```json { "model": { "type": "minecraft:model", "model": "example-mod:item/suspicious_substance" } } ``` -------------------------------- ### Java Object Type Descriptor Source: https://docs.fabricmc.net/1.21.10/develop/mixins/bytecode Shows the bytecode type descriptor format for Java objects. It starts with 'L', followed by the internal name of the class (slashes instead of dots), and ends with a semicolon ';'. ```java // String -> Ljava/lang/String; // java.util.List -> Ljava/util/List; ``` -------------------------------- ### Create Custom Tickable SoundInstance Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Defines a custom `SoundInstance` that can tick and follow a specific entity. This allows for sounds that persist and move with a game entity. The `tick()` method is overridden to update the sound's position and stop it if the entity is removed or dead. It extends `AbstractTickableSoundInstance`. ```java public class CustomSoundInstance extends AbstractTickableSoundInstance { private final LivingEntity entity; public CustomSoundInstance(LivingEntity entity, SoundEvent soundEvent, SoundSource soundCategory) { super(soundEvent, soundCategory, SoundInstance.createUnseededRandom()); // In this constructor we also add the sound source (LivingEntity) of // the SoundInstance and store it in the current object this.entity = entity; // set up default values when the sound is about to start this.volume = 1.0f; this.pitch = 1.0f; this.looping = true; this.setPositionToEntity(); } @Override public void tick() { // stop sound instantly if sound source does not exist anymore if (this.entity == null || this.entity.isRemoved() || this.entity.isDeadOrDying()) { this.stop(); return; } // move sound position over to the new position for every tick this.setPositionToEntity(); } @Override public boolean canStartSilent() { // override to true, so that the SoundInstance can start // or add your own condition to the SoundInstance, if necessary return true; } // small utility method to move the sound instance position // to the sound source's position private void setPositionToEntity() { this.x = this.entity.getX(); this.y = this.entity.getY(); this.z = this.entity.getZ(); } } ``` -------------------------------- ### Read Custom Component Value from ItemStack Source: https://docs.fabricmc.net/1.21.10/develop/items/custom-data-components Demonstrates how to retrieve the value of a custom component from an `ItemStack` using the `get()` method. This is crucial for accessing data associated with an item, such as a click count. ```java int clickCount = stack.get(ModComponents.CLICK_COUNT_COMPONENT); ``` -------------------------------- ### Conditional Jumps in Bytecode (Java) Source: https://docs.fabricmc.net/1.21.10/develop/mixins/bytecode Demonstrates how conditional logic in Java source code is translated into bytecode using jump instructions like 'ifeq' and 'goto'. This example shows a simple if-else statement compiled into bytecode, highlighting the use of labels for jump targets. ```java static String makeFoobar(boolean cond) { String result; if (cond) { result = "foo"; } else { result = "bar"; } return result; } ``` ```text static makeFoobar (Z)Ljava/lang/String; iload 0 # cond ifeq L1 ldc "foo" astore 1 # result goto L2 L1 ldc "bar" astore 1 # result L2 aload 1 # result areturn ``` -------------------------------- ### AbstractDynamicSoundInstance Class Definition Source: https://docs.fabricmc.net/1.21.10/develop/sounds/dynamic-sounds Defines the abstract class AbstractDynamicSoundInstance, inheriting from AbstractTickableSoundInstance. It includes properties for managing dynamic sound sources, transition states, tick durations, volume and pitch ranges, and a callback for finished sounds. ```java public abstract class AbstractDynamicSoundInstance extends AbstractTickableSoundInstance { protected final DynamicSoundSource soundSource; // Entities, BlockEntities, ... protected TransitionState transitionState; // current TransitionState of the SoundInstance protected final int startTransitionTicks, endTransitionTicks; // duration of starting and ending phases // possible volume range when adjusting sound values protected final float maxVolume; // only max value since the minimum is always 0 // possible pitch range when adjusting sound values protected final float minPitch, maxPitch; protected int currentTick = 0, transitionTick = 0; // current tick values for the instance protected final SoundInstanceCallback callback; // callback for soundInstance states // ... } ``` -------------------------------- ### Lambda Expression Compilation in Bytecode Source: https://docs.fabricmc.net/1.21.10/develop/mixins/bytecode Lambda expressions are compiled into separate methods and invoked using `invokedynamic`. This example demonstrates a simple lambda for printing 'Hello, World!', compiled into `lambda$hello$1`. ```bytecode invokedynamic run ()Ljava/lang/Runnable; java/lang/invoke/LambdaMetafactory.metafactory ()V lambda$hello$1 ()V astore 0 # r aload 0 # r invokeinterface run return static lambda$hello$1 ()V getstatic System.out ldc "Hello, World!" invokevirtual println return ``` -------------------------------- ### Object Creation in Bytecode Source: https://docs.fabricmc.net/1.21.10/develop/mixins/bytecode Bytecode separates object creation (`new`) from constructor invocation (`invokespecial`). This example shows creating a Creeper instance. The operand stack manages the object reference and constructor arguments. ```bytecode new net/minecraft/world/entity/monster/Creeper dup aload 0 # level invokespecial net/minecraft/world/entity/monster/Creeper. (Lnet/minecraft/world/level/Level;)V areturn ``` -------------------------------- ### Register Client-Side Particle Factory (Java) Source: https://docs.fabricmc.net/1.21.10/develop/rendering/particles/creating-particles Registers the particle's factory on the client-side, allowing it to be rendered. This example uses the `EndRodParticle.Provider` to mimic the end rod particle's behavior. ```java // For this example, we will use the end rod particle behaviour. ParticleFactoryRegistry.getInstance().register(ExampleMod.SPARKLE_PARTICLE, EndRodParticle.Provider::new); ``` -------------------------------- ### Update Gradle Dependencies for Mappings Source: https://docs.fabricmc.net/1.21.10/develop/migrating-mappings/ravel This snippet shows how to update the `dependencies` block in your `build.gradle` file to reflect the new mappings after using Ravel. It includes examples for both Yarn and Mojang mappings. ```groovy dependencies { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" mappings loom.officialMojangMappings() // Or the reverse if you're migrating from Mojang Mappings to Yarn } ```