### Advanced Widget Creation (Java) Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt Provides a comprehensive example of creating a `ModularUI` with various advanced widgets. This includes `TabContainer`, `DraggableScrollableWidgetGroup`, `SwitchWidget`, `CycleButtonWidget`, `TextFieldWidget`, and `CodeEditorWidget`. It showcases how to set up their properties, textures, and callbacks for user interaction. ```java import com.lowdragmc.lowdraglib.gui.widget.*; import com.lowdragmc.lowdraglib.gui.texture.*; import com.lowdragmc.lowdraglib.gui.ModularUI; import com.lowdragmc.lowdraglib.gui.WidgetGroup; import com.lowdragmc.lowdraglib.gui.IUIHolder; import net.minecraft.world.entity.player.Player; import net.minecraft.resources.ResourceLocation; import java.util.Arrays; public class AdvancedWidgets { private boolean machineEnabled; private int currentMode; private String scriptCode; private String machineNameGetter() { return "defaultName"; } private void machineNameSetter(String name) {} private void toggleMachine(boolean pressed) {} private void onModeChange(int mode) {} public ModularUI createAdvancedUI(IUIHolder holder, Player player) { return new ModularUI(300, 200, holder, player) // Tab container .widget(new TabContainer(0, 0, 300, 200) .addTab(new TextTexture("Main"), createMainTab()) .addTab(new TextTexture("Config"), createConfigTab())) // Scrollable widget group .widget(new DraggableScrollableWidgetGroup(10, 10, 280, 180) .setYScrollBarWidth(4) .setYBarStyle(new ColorRectTexture(0x44FFFFFF), new ColorRectTexture(0x88FFFFFF))) // Switch widget (on/off toggle) .widget(new SwitchWidget(10, 50, 60, 20, (cd, pressed) -> { if (!holder.isRemote()) { toggleMachine(pressed); } }) .setPressed(machineEnabled) .setTexture(new ResourceTexture(new ResourceLocation("mymod:textures/gui/switch.png")), new ResourceTexture(new ResourceLocation("mymod:textures/gui/switch_pressed.png")))) // Cycle button (multiple states) .widget(new CycleButtonWidget(80, 50, 80, 20, Arrays.asList("Mode A", "Mode B", "Mode C"), currentMode, this::onModeChange) .setTextTexture(new TextTexture())) // Text field for user input .widget(new TextFieldWidget(10, 80, 150, 20, () -> machineNameGetter(), name -> machineNameSetter(name)) .setMaxStringLength(32) .setTextColor(0xFFFFFF)) // Code editor with syntax highlighting .widget(new CodeEditorWidget(10, 110, 280, 80, () -> scriptCode, code -> scriptCode = code) .setSyntaxHighlighter(CodeEditorWidget.LUA_HIGHLIGHTER)); } private WidgetGroup createMainTab() { return new WidgetGroup(0, 0, 300, 200) .addWidget(new ImageWidget(10, 10, 280, 180, new ResourceTexture(new ResourceLocation("mymod:textures/gui/main_tab.png")))); } private WidgetGroup createConfigTab() { return new WidgetGroup(0, 0, 300, 200) .addWidget(new LabelWidget(10, 10, "Configuration")); } } ``` -------------------------------- ### Initialize LDLib and Check Platform/Mod Compatibility (Java) Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt This snippet shows the main entry point for initializing the LDLib library within a Minecraft mod. It demonstrates how to access platform information (Forge/Fabric), check for the presence of other mods like JEI, REI, or KubeJS, and utilize utility methods for client-side or remote checks. It also shows how to access LDLib's configured Gson instance for JSON serialization. ```java package com.example.mymod; import com.lowdragmc.lowdraglib.LDLib; import com.lowdragmc.lowdraglib.Platform; public class MyMod { public static final String MOD_ID = "mymod"; public void init() { // LDLib automatically initializes on mod load LDLib.init(); // Check platform String platform = Platform.platformName(); // "Forge" or "Fabric" boolean isForge = Platform.isForge(); // Check mod compatibility boolean hasJEI = LDLib.isJeiLoaded(); boolean hasREI = LDLib.isReiLoaded(); boolean hasKubeJS = LDLib.isKubejsLoaded(); // Utility methods boolean isClientSide = LDLib.isClient(); boolean isRemote = LDLib.isRemote(); // Access LDLib's configured Gson instance String json = LDLib.GSON.toJson(myObject); } } ``` -------------------------------- ### Open BlockEntity UI with Factory (Java) Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt Demonstrates opening a BlockEntity's UI programmatically using `BlockEntityUIFactory.INSTANCE.openUI`. This is typically done on the server side when a player interacts with a block. It requires the `IUIHolder.BlockEntityUI` interface to be implemented by the BlockEntity. ```java import com.lowdragmc.lowdraglib.gui.factory.*; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionResult; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.entity.BlockEntity; // For BlockEntity UIs public class MachineBlock extends Block { @Override public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { if (!level.isClientSide && player instanceof ServerPlayer serverPlayer) { BlockEntity be = level.getBlockEntity(pos); if (be instanceof IUIHolder.BlockEntityUI uiHolder) { // Open UI using factory BlockEntityUIFactory.INSTANCE.openUI(uiHolder, serverPlayer); return InteractionResult.SUCCESS; } } return InteractionResult.CONSUME; } } ``` -------------------------------- ### Open Held Item UI with Factory (Java) Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt Illustrates how to open a UI associated with a held item using `HeldItemUIFactory.INSTANCE.openUI`. This method creates an `ItemUIHolder` from the `ItemStack` and `InteractionHand` and then opens the UI for the player on the server side. ```java import com.lowdragmc.lowdraglib.gui.factory.*; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.InteractionHand; import net.minecraft.world.level.Level; import net.minecraft.world.entity.player.Player; import com.lowdragmc.lowdraglib.gui.IUIHolder; import com.lowdragmc.lowdraglib.gui.ItemUIHolder; // For held item UIs public class ConfiguratorItem extends Item { @Override public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { if (!level.isClientSide && player instanceof ServerPlayer serverPlayer) { ItemStack stack = player.getItemInHand(hand); // Create UI holder for item IUIHolder holder = new ItemUIHolder(stack, hand); HeldItemUIFactory.INSTANCE.openUI(holder, serverPlayer); return InteractionResultHolder.success(stack); } return InteractionResultHolder.consume(player.getItemInHand(hand)); } } ``` -------------------------------- ### Fluid Storage and Transfer Implementation in Java Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt Demonstrates the implementation of a fluid storage and transfer system using `IFluidTransfer` interface. It covers creating fluid stacks with and without NBT data, modifying them, saving/loading, and handling fluid filling and draining operations within multiple tanks. This system is designed to be platform-agnostic. ```java import com.lowdragmc.lowdraglib.side.fluid.*; import net.minecraft.world.level.material.Fluids; import net.minecraft.nbt.CompoundTag; public class FluidProcessor implements IFluidTransfer { private FluidStack[] tanks = new FluidStack[3]; private long capacity = 16000; // millibuckets public FluidProcessor() { for (int i = 0; i < tanks.length; i++) { tanks[i] = FluidStack.empty(); } } // Create fluid stacks public void example() { // Create 1000mb of water FluidStack water = FluidStack.create(Fluids.WATER, 1000); // Create with NBT data CompoundTag nbt = new CompoundTag(); nbt.putInt("temperature", 300); FluidStack hotWater = FluidStack.create(Fluids.WATER, 1000, nbt); // Modify stack water.grow(500); // Add 500mb water.shrink(200); // Remove 200mb water.setAmount(1000); // Save/load CompoundTag tag = new CompoundTag(); water.saveToTag(tag); FluidStack loaded = FluidStack.loadFromTag(tag); // Copy FluidStack copy = water.copy(); } @Override public int getTanks() { return tanks.length; } @Override public FluidStack getFluidInTank(int tank) { return tank >= 0 && tank < tanks.length ? tanks[tank] : FluidStack.empty(); } @Override public long getTankCapacity(int tank) { return capacity; } @Override public boolean isFluidValid(int tank, FluidStack stack) { return true; // Accept any fluid } @Override public long fill(FluidStack resource, boolean simulate, boolean notifyChanges) { if (resource.isEmpty()) return 0; // Find tank with same fluid or empty tank for (int i = 0; i < tanks.length; i++) { if (tanks[i].isEmpty() || tanks[i].isFluidEqual(resource)) { long space = capacity - tanks[i].getAmount(); long toFill = Math.min(space, resource.getAmount()); if (!simulate && toFill > 0) { if (tanks[i].isEmpty()) { tanks[i] = FluidStack.create(resource.getFluid(), toFill); } else { tanks[i].grow(toFill); } if (notifyChanges) onContentsChanged(); } return toFill; } } return 0; } @Override public FluidStack drain(long maxDrain, boolean simulate, boolean notifyChanges) { for (int i = 0; i < tanks.length; i++) { if (!tanks[i].isEmpty()) { long toDrain = Math.min(maxDrain, tanks[i].getAmount()); FluidStack drained = FluidStack.create(tanks[i], toDrain); if (!simulate) { tanks[i].shrink(toDrain); if (notifyChanges) onContentsChanged(); } return drained; } } return FluidStack.empty(); } protected void onContentsChanged() { // Notify system of changes } } ``` -------------------------------- ### Create a Modular UI with Widgets (Java) Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt This Java snippet illustrates how to create a custom UI for a Minecraft mod using LDLib's modular UI system. It demonstrates adding various widgets such as item slots, fluid tank displays, progress bars, buttons, and image labels. The UI is defined within the `createUI` method, which returns a `ModularUI` object. Event handling for buttons is also shown, with a check to ensure actions are performed on the server side. ```java import com.lowdragmc.lowdraglib.gui.modular.ModularUI; import com.lowdragmc.lowdraglib.gui.modular.IUIHolder; import com.lowdragmc.lowdraglib.gui.widget.*; import com.lowdragmc.lowdraglib.gui.texture.*; import net.minecraft.world.entity.player.Player; public class MyMachine implements IUIHolder { private ItemStackTransfer inventory = new ItemStackTransfer(9); private FluidTank tank = new FluidTank(16000); @Override public ModularUI createUI(Player player) { return new ModularUI(176, 166, this, player) // Background texture .background(GuiTextures.BACKGROUND) // Add item slots (3x3 grid) .widget(new SlotWidget(inventory, 0, 10, 10, true, true) .setBackground(SlotWidget.ITEM_SLOT_TEXTURE)) .widget(new SlotWidget(inventory, 1, 28, 10, true, true) .setBackground(SlotWidget.ITEM_SLOT_TEXTURE)) // ... more slots // Fluid tank display .widget(new TankWidget(tank, 100, 10, 20, 60, true, true) .setShowAmount(true) .setBackground(new ColorRectTexture(0x88000000))) // Progress bar .widget(new ProgressWidget(() -> progress / (double) maxProgress, 50, 30, 20, 20) .setProgressTexture(GuiTextures.PROGRESS_BAR_ARROW) .setFillDirection(ProgressTexture.FillDirection.LEFT_TO_RIGHT)) // Button with callback .widget(new ButtonWidget(130, 10, 40, 20, new TextTexture("Start"), cd -> { if (!isRemote()) { startMachine(); } })) // Image label .widget(new ImageWidget(10, 80, 156, 10, new TextTexture("My Machine").setColor(0x404040))); } @Override public boolean isInvalid() { return false; } @Override public boolean isRemote() { return level.isClientSide; } @Override public void markAsDirty() { setChanged(); } } ``` -------------------------------- ### Define and Register Custom Network Packets in Java Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt This snippet demonstrates how to create a custom network packet class that implements the `IPacket` interface, handling encoding, decoding, and execution on both client and server sides. It also shows how to register these custom packets with the LDLib networking system and provides utility methods for sending packets to the server, specific players, or all players. ```java import com.lowdragmc.lowdraglib.networking.*; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.resources.ResourceLocation; import net.minecraft.client.Minecraft; import net.minecraft.server.level.ServerPlayer; // Define custom packet public class MyCustomPacket implements IPacket { private final int data; private final String message; public MyCustomPacket(int data, String message) { this.data = data; this.message = message; } public MyCustomPacket(FriendlyByteBuf buf) { this.data = buf.readInt(); this.message = buf.readUtf(); } @Override public void encode(FriendlyByteBuf buf) { buf.writeInt(data); buf.writeUtf(message); } @Override public void execute(IHandlerContext handler) { // Handle packet on receiving side if (handler.isClientSide()) { // Client-side handling Minecraft.getInstance().execute(() -> { // Use data on client System.out.println("Received: " + message); }); } else { // Server-side handling ServerPlayer player = (ServerPlayer) handler.getPlayer(); player.getServer().execute(() -> { // Use data on server processServerData(player, data, message); }); } } // Dummy method for server data processing to avoid compilation errors private void processServerData(ServerPlayer player, int data, String message) { System.out.println("Processing on server for player " + player.getName().getString() + ": " + message); } } // Register and use packets public class MyModNetworking { public static final INetworking NETWORK = INetworking.createNetworking( new ResourceLocation("mymod", "main"), "1.0.0"); public static void init() { // Register packets NETWORK.registerC2S(MyCustomPacket.class); // Client to server NETWORK.registerS2C(MyCustomPacket.class); // Server to client } public static void sendToServer(int data, String message) { NETWORK.sendToServer(new MyCustomPacket(data, message)); } public static void sendToPlayer(ServerPlayer player, int data, String message) { NETWORK.sendToPlayer(new MyCustomPacket(data, message), player); } public static void sendToAll(int data, String message) { NETWORK.sendToAll(new MyCustomPacket(data, message)); } } ``` -------------------------------- ### Java: Create 3D World Scene Widget in UI Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt This Java code demonstrates how to create an interactive 3D scene within a UI using the SceneWidget from LowDragLib. It defines which blocks to render, sets camera perspectives, enables interaction, and allows for custom block rendering hooks. This is useful for displaying complex structures or models within a GUI. ```java import com.lowdragmc.lowdraglib.gui.widget.SceneWidget; import net.minecraft.core.BlockPos; import java.util.*; public class BlueprintUI implements IUIHolder { @Override public ModularUI createUI(Player player) { // Create blocks to display in scene Set structureBlocks = new HashSet<>(); structureBlocks.add(new BlockPos(0, 0, 0)); structureBlocks.add(new BlockPos(1, 0, 0)); structureBlocks.add(new BlockPos(0, 1, 0)); structureBlocks.add(new BlockPos(1, 1, 0)); // Create 3D scene widget SceneWidget scene = new SceneWidget(10, 10, 200, 200, player.level(), true) // Set which blocks to render .setRenderedCore(structureBlocks) // Use orthographic projection (isometric view) .useOrtho(true) // Set camera distance and angle .setCameraDistance(10) .setCameraLookAt(new Vec3(0.5, 0.5, 0.5)) // Enable particle effects .setRenderParticles(true) // Enable user interaction (rotate/zoom) .setInteractive(true); // Add custom rendering hooks scene.addSceneBlockRenderHook(blockRenderer -> { // Custom per-block rendering modifications return true; }); return new ModularUI(220, 220, this, player) .background(GuiTextures.BACKGROUND) .widget(scene); } } ``` -------------------------------- ### Server-Client RPC Communication in Java Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt This Java code demonstrates how to implement Remote Procedure Calls (RPCs) for server-client communication within a Minecraft block entity. It uses LowDragLib's annotations to define methods callable from the other side of the network and RPCSender for initiating calls. Dependencies include LowDragLib's syncdata and rpc modules, and Minecraft's BlockEntity. ```java import com.lowdragmc.lowdraglib.syncdata.annotation.RPCMethod; import com.lowdragmc.lowdraglib.syncdata.rpc.RPCSender; public class RemoteControlMachine extends BlockEntity implements IManaged { @Persisted @DescSynced private boolean locked = false; // Client can call this method on server @RPCMethod public void unlockMachine(String password) { // This executes on server if (password.equals("secret123")) { locked = false; notifyClients(); } } // Server can call this on clients @RPCMethod public void playSound(String soundId, float volume) { // This executes on clients if (isRemote()) { level.playLocalSound(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), soundId, volume, 1.0f, false); } } // From client widget, call server method public void onClientButtonClick() { if (isRemote()) { // Call server method from client RPCSender.sendToServer(this, "unlockMachine", "secret123"); } } private void notifyClients() { if (!isRemote()) { // Call client method from server (broadcasts to all tracking clients) RPCSender.sendToTrackingChunk(this, "playSound", "minecraft:block.chest.open", 1.0f); } } } ``` -------------------------------- ### Java ProcessorMachine Block Entity with UI and Sync Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt This Java code defines a ProcessorMachine block entity that implements UI, synchronization, and rendering. It manages inventory, fluid tanks, processing progress, and energy. The machine's state is synchronized across the network, and its UI is defined using ldlib's modular UI system. ```java import com.lowdragmc.lowdraglib.gui.modular.*; import com.lowdragmc.lowdraglib.gui.widget.*; import com.lowdragmc.lowdraglib.gui.texture.*; import com.lowdragmc.lowdraglib.syncdata.*; import com.lowdragmc.lowdraglib.syncdata.annotation.*; import com.lowdragmc.lowdraglib.syncdata.field.*; import com.lowdragmc.lowdraglib.side.fluid.*; import com.lowdragmc.lowdraglib.side.item.*; public class ProcessorMachine extends BlockEntity implements IUIHolder.BlockEntityUI, IAsyncAutoSyncBlockEntity, IManaged { // Static field holder protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(ProcessorMachine.class); @Getter private final FieldManagedStorage syncStorage = new FieldManagedStorage(this); // Synced fields @Persisted @DescSynced private int progress = 0; @Persisted @DescSynced private int maxProgress = 200; @Persisted @DescSynced private int energy = 0; @Persisted @DescSynced @RequireRerender private boolean isActive = false; // Inventory (9 slots) @Persisted @DescSynced public final ItemStackTransfer inventory = new ItemStackTransfer(9); // Fluid tank (16000mb capacity) @Persisted @DescSynced public final FluidTank tank = new FluidTank(16000); public ProcessorMachine(BlockPos pos, BlockState state) { super(MyBlocks.PROCESSOR_BE.get(), pos, state); } public void tick() { if (!level.isClientSide) { if (energy >= 20 && canProcess()) { progress++; energy -= 20; setActive(true); if (progress >= maxProgress) { processRecipe(); progress = 0; } markDirty("progress"); } else { setActive(false); } } } private boolean canProcess() { return !inventory.getStackInSlot(0).isEmpty() && tank.getFluidAmount() >= 1000; } private void processRecipe() { inventory.extractItem(0, 1, false); tank.drain(1000, false, true); inventory.insertItem(1, new ItemStack(Items.DIAMOND), false); } public void setActive(boolean active) { if (this.isActive != active) { this.isActive = active; markDirty("isActive"); } } @Override public ModularUI createUI(Player player) { return new ModularUI(176, 166, this, player) .background(new ColorRectTexture(0xFF404040)) // Input slot .widget(new SlotWidget(inventory, 0, 30, 20, true, true) .setBackground(SlotWidget.ITEM_SLOT_TEXTURE)) // Output slot .widget(new SlotWidget(inventory, 1, 110, 20, false, true) .setBackground(SlotWidget.ITEM_SLOT_TEXTURE)) // Fluid tank .widget(new TankWidget(tank, 60, 10, 20, 50) .setShowAmount(true) .setBackground(new ColorRectTexture(0x88000000))) // Progress bar .widget(new ProgressWidget( () -> progress / (double) maxProgress, 85, 20, 20, 20) .setProgressTexture( new GuiTextureGroup( new ColorRectTexture(0xFF00AA00), new TextTexture("→"))) .setFillDirection(ProgressTexture.FillDirection.LEFT_TO_RIGHT)) // Energy display .widget(new ImageWidget(10, 50, 50, 10, new TextTexture(() -> "Energy: " + energy) .setColor(0xFFFFFF))) // Active indicator .widget(new ImageWidget(150, 10, 16, 16, () -> isActive ? new ColorRectTexture(0xFF00FF00) : new ColorRectTexture(0xFFFF0000))) // Player inventory .widget(new PlayerSlotWidget(player.getInventory(), 8, 84, 3, 9)); } @Override public ManagedFieldHolder getFieldHolder() { return MANAGED_FIELD_HOLDER; } @Override public IManagedStorage getRootStorage() { return getSyncStorage(); } @Override public void onChanged() { markAsDirty(); } } ``` -------------------------------- ### Java: Implement Custom Block Renderer with IRenderer Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt This Java code implements the IRenderer interface to provide custom rendering logic for blocks. It handles item rendering, model rendering, Tile Entity Special Renderer (TESR) checks, dynamic TESR rendering, and texture atlas preparation. Dependencies include various LowDragLib and Minecraft client rendering classes. ```java import com.lowdragmc.lowdraglib.client.renderer.*; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.world.item.ItemStack; import net.minecraft.core.Direction; public class CustomMachineRenderer implements IRenderer { private ResourceLocation modelLocation = new ResourceLocation("mymod", "block/machine_model"); @Override public void renderItem(ItemStack stack, ItemDisplayContext transformType, boolean leftHand, PoseStack poseStack, MultiBufferSource buffer, int combinedLight, int combinedOverlay, BakedModel model) { // Custom item rendering poseStack.pushPose(); poseStack.scale(1.5f, 1.5f, 1.5f); VertexConsumer consumer = buffer.getBuffer(RenderType.cutout()); // Render custom geometry poseStack.popPose(); } @Override public List renderModel(BlockAndTintGetter level, BlockPos pos, BlockState state, Direction side, RandomSource rand) { // Return static baked quads for block model List quads = new ArrayList<>(); // Get model and return quads BakedModel model = Minecraft.getInstance() .getModelManager().getModel(modelLocation); quads.addAll(model.getQuads(state, side, rand)); return quads; } @Override public boolean hasTESR(BlockEntity blockEntity) { // Return true if you need dynamic rendering return blockEntity instanceof CustomMachine custom && custom.isAnimating(); } @Override public void render(BlockEntity blockEntity, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int combinedLight, int combinedOverlay) { // Dynamic TESR rendering if (blockEntity instanceof CustomMachine machine) { poseStack.pushPose(); // Animate based on machine state float rotation = (machine.getTickCount() + partialTicks) * 2.0f; poseStack.translate(0.5, 0.5, 0.5); poseStack.mulPose(Axis.YP.rotationDegrees(rotation)); poseStack.translate(-0.5, -0.5, -0.5); // Render animated parts VertexConsumer consumer = buffer.getBuffer(RenderType.solid()); // ... render geometry poseStack.popPose(); } } @Override public void onPrepareTextureAtlas(ResourceLocation atlasName, Consumer register) { // Register additional textures for atlas stitching if (atlasName.equals(TextureAtlas.LOCATION_BLOCKS)) { register.accept(new ResourceLocation("mymod", "block/machine_overlay")); } } @Override public void onAdditionalModel(Consumer registry) { // Register additional models to be loaded registry.accept(modelLocation); } } ``` -------------------------------- ### Block Entity with Auto-Sync Fields in Java Source: https://context7.com/qihuang02/ldlib-multiloader/llms.txt This Java code defines a block entity with fields that automatically synchronize between the server and clients. It utilizes LowDragLib's annotations for managing persisted and synced data, including custom serialization for inventory items. Dependencies include LowDragLib's syncdata and gui modules, as well as Minecraft's BlockEntity. ```java import com.lowdragmc.lowdraglib.syncdata.*; import com.lowdragmc.lowdraglib.syncdata.annotation.*; import com.lowdragmc.lowdraglib.syncdata.blockentity.IAsyncAutoSyncBlockEntity; import com.lowdragmc.lowdraglib.syncdata.field.*; import com.lowdragmc.lowdraglib.gui.modular.IUIHolder; import net.minecraft.world.level.block.entity.BlockEntity; public class SyncedMachine extends BlockEntity implements IUIHolder.BlockEntityUI, IAsyncAutoSyncBlockEntity, IManaged { // Static field holder - required for managed fields protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(SyncedMachine.class); // Storage for synced data @Getter private final FieldManagedStorage syncStorage = new FieldManagedStorage(this); // Synced to clients in chunk range + saved to NBT @DescSynced @Persisted private int energy = 0; // Only saved to NBT (not synced) @Persisted private String ownerName = ""; // Synced but not saved @DescSynced private boolean isActive = false; // Triggers client re-render when changed @DescSynced @Persisted @RequireRerender private Direction facing = Direction.NORTH; // Custom managed object with serialization callbacks @DescSynced @Persisted @ReadOnlyManaged( onDirtyMethod = "onInventoryDirty", serializeMethod = "serializeInventory", deserializeMethod = "deserializeInventory" ) public ItemStackTransfer inventory = new ItemStackTransfer(9); // Update energy and sync to clients public void addEnergy(int amount) { this.energy += amount; markDirty("energy"); // Mark field as dirty for sync } // Add listener for field updates public void setupListeners() { addSyncUpdateListener("energy", (newValue, oldValue) -> { if (newValue > 1000) { // React to energy change setActive(true); } }); } // Required implementations @Override public ManagedFieldHolder getFieldHolder() { return MANAGED_FIELD_HOLDER; } @Override public IManagedStorage getRootStorage() { return getSyncStorage(); } @Override public void onChanged() { markAsDirty(); // Notify world of changes } // Custom serialization callbacks private boolean onInventoryDirty(ItemStackTransfer inv) { return inv.getSyncStorage().hasDirtySyncFields(); } private CompoundTag serializeInventory(ItemStackTransfer inv) { return inv.serializeNBT(); } private ItemStackTransfer deserializeInventory(CompoundTag tag) { ItemStackTransfer inv = new ItemStackTransfer(9); inv.deserializeNBT(tag); return inv; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.