### Use OneConfig UI Manager and File Dialogs (Java) Source: https://context7.com/polyfrost/oneconfig/llms.txt Demonstrates how to interact with the OneConfig UIManager to get the PolyUI renderer, open a mod's configuration menu, control background blur, and use native file dialogs for opening and saving files. Requires the OneConfig and PolyUI libraries. ```java package com.example.mymod; import org.polyfrost.oneconfig.api.ui.v1.UIManager; import org.polyfrost.polyui.renderer.Renderer; public class UIFeatures { public void useUIManager() { UIManager ui = UIManager.INSTANCE; // Get PolyUI renderer Renderer renderer = ui.getRenderer(); // Open config menu for specific mod ui.openConfigMenu("my_mod"); // Control background blur ui.blur(true); // Enable blur ui.blur(false); // Disable blur // File dialogs (native) String selectedFile = ui.getTinyFd().openFileDialog( "Select a file", ".", new String[]{"*.json", "*.txt"}, "JSON and Text files", false // allowMultiple ); String saveLocation = ui.getTinyFd().saveFileDialog( "Save configuration", "config.json", new String[]{"*.json"}, "JSON files" ); } // ... notification methods ... } ``` -------------------------------- ### Show OneConfig Notifications (Java) Source: https://context7.com/polyfrost/oneconfig/llms.txt Illustrates how to display different types of toast notifications (info, warning, error) and timed notifications using OneConfig's notification system. This example assumes the existence of helper methods for displaying notifications. ```java package com.example.mymod; // ... other imports ... public class UIFeatures { // ... UIManager methods ... public void showNotifications() { // Info notification (blue) showInfoNotification("Configuration loaded successfully"); // Warning notification (yellow) showWarningNotification("Some settings could not be applied"); // Error notification (red) showErrorNotification("Failed to connect to server"); // Notification with custom duration showTimedNotification("This will disappear in 5 seconds", 5000); } private void showInfoNotification(String message) { // Notifications API usage (implementation detail) System.out.println("[INFO] " + message); } private void showWarningNotification(String message) { System.out.println("[WARNING] " + message); } private void showErrorNotification(String message) { System.out.println("[ERROR] " + message); } private void showTimedNotification(String message, int durationMs) { System.out.println("[TIMED:" + durationMs + "ms] " + message); } } ``` -------------------------------- ### Java: Use Platform Abstractions for Minecraft Cross-Version Compatibility Source: https://context7.com/polyfrost/oneconfig/llms.txt This Java code demonstrates how to utilize Polyfrost OneConfig's Platform Abstractions API. It shows how to access loader and mod information, perform internationalization, get screen dimensions, and check Minecraft version compatibility. No external dependencies beyond the OneConfig API are required. ```java package com.example.mymod; import org.polyfrost.oneconfig.api.platform.v1.Platform; import org.polyfrost.oneconfig.api.platform.v1.LoaderPlatform; import org.polyfrost.oneconfig.api.platform.v1.I18nPlatform; public class PlatformExample { public void usePlatformAbstractions() { // Loader information LoaderPlatform loader = Platform.loader(); System.out.println("Mod loader: " + loader.getModLoader()); System.out.println("Minecraft version: " + loader.getMinecraftVersion()); System.out.println("Is development: " + loader.isDevelopment()); // Get mod information loader.getMods().forEach(mod -> { System.out.println("Mod: " + mod.getName() + " v" + mod.getVersion()); System.out.println(" ID: " + mod.getId()); System.out.println(" Authors: " + mod.getAuthors()); }); // Check if mod is loaded if (loader.isModLoaded("optifine")) { System.out.println("OptiFine detected!"); } // OpenGL utilities Platform.gl().glVersion(); // Get OpenGL version Platform.gl().maxTextureSize(); // Get max texture size // Internationalization I18nPlatform i18n = Platform.i18n(); String translated = i18n.get("mymod.config.title"); System.out.println("Translated: " + translated); // Screen utilities Platform.screen().getWidth(); // Get screen width Platform.screen().getHeight(); // Get screen height Platform.screen().getScaleFactor(); // Get GUI scale // Version compatibility checks Platform.compatibility().isLegacy(); // Before 1.13 Platform.compatibility().isModern(); // 1.13+ } } ``` -------------------------------- ### Annotation-Based Command Registration in Java Source: https://context7.com/polyfrost/oneconfig/llms.txt Demonstrates how to register commands using annotations in Java. This method simplifies command creation by automatically parsing arguments and handling subcommands. It requires the OneConfig API and OmniCore for chat messages. ```java package com.example.mymod; import org.polyfrost.oneconfig.api.commands.v1.CommandManager; import org.polyfrost.oneconfig.api.commands.v1.factories.annotated.Command; import org.polyfrost.oneconfig.api.commands.v1.factories.annotated.Handler; import com.mojang.authlib.GameProfile; import dev.deftu.omnicore.api.client.chat.OmniClientChat; // Annotation-based command (easiest method) @Command(value = {"mymod", "mm"}) // Command name and aliases public class MyModCommand { @Handler // Default handler - executes when no arguments provided private static void main() { OmniClientChat.displayChatMessage("§aMyMod v1.0.0"); OmniClientChat.displayChatMessage("§7Usage: /mymod "); } // Handler with typed arguments - automatically parsed @Handler private void teleport(int x, int y, int z) { // Usage: /mymod teleport OmniClientChat.displayChatMessage( String.format("§7Teleporting to: %d, %d, %d", x, y, z) ); // Teleport logic here } // Handler with player argument @Handler private void info(GameProfile player) { // Usage: /mymod info String name = player.getName(); String uuid = player.getId().toString(); OmniClientChat.displayChatMessage("§7Player: §f" + name); OmniClientChat.displayChatMessage("§7UUID: §f" + uuid); } // Handler with varargs @Handler private void say(String... words) { // Usage: /mymod say String message = String.join(" ", words); OmniClientChat.displayChatMessage("§e" + message); } // Nested subcommand @Command(value = {"config", "cfg"}) private static class ConfigSubCommand { @Handler private static void main() { // Usage: /mymod config OmniClientChat.displayChatMessage("§aOpening config GUI..."); // Open config screen } @Handler(value = {"reload"}) private void reload() { // Usage: /mymod config reload OmniClientChat.displayChatMessage("§aReloading config..."); // Reload logic } @Handler private void set(String key, String value) { // Usage: /mymod config set OmniClientChat.displayChatMessage( String.format("§7Set §f%s §7to §f%s", key, value) ); } // Deeply nested subcommand @Command(value = {"export"}) private static class ExportSubCommand { @Handler private void json(String filename) { // Usage: /mymod config export json OmniClientChat.displayChatMessage("§7Exporting to JSON: " + filename); } @Handler private void yaml(String filename) { // Usage: /mymod config export yaml OmniClientChat.displayChatMessage("§7Exporting to YAML: " + filename); } } } // Register the command public static void register() { CommandManager.register(new MyModCommand()); } } ``` -------------------------------- ### Builder-Based Command Registration in Java Source: https://context7.com/polyfrost/oneconfig/llms.txt Illustrates advanced command creation using a builder pattern in Java. This method provides more control over command structure and argument parsing, utilizing `CommandManager.literal` and `CommandManager.argument`. Requires OneConfig API and OmniCore. ```java // Builder-based command (advanced method) public class AdvancedCommand { public static void registerBuilderCommand() { CommandManager.register( CommandManager.literal("advanced") .then(CommandManager.argument("count", IntegerArgumentType.integer(1, 100)) .executes(context -> { int count = IntegerArgumentType.getInteger(context, "count"); OmniClientChat.displayChatMessage("Count: " + count); return 1; // Success })) .then(CommandManager.literal("help") .executes(context -> { OmniClientChat.displayChatMessage("Help text here"); return 1; })) .build() ); } } ``` -------------------------------- ### Subscribe to Minecraft Events using OneConfig Java API Source: https://context7.com/polyfrost/oneconfig/llms.txt Demonstrates registering event listeners for various Minecraft events such as render, world change, and screen open. Supports both lambda-based and annotation-based registration. Ensure OneConfig API is available as a dependency. ```java package com.example.mymod; import org.polyfrost.oneconfig.api.event.v1.EventManager; import org.polyfrost.oneconfig.api.event.v1.Subscribe; import org.polyfrost.oneconfig.api.event.v1.events.*; // Method 1: Lambda-based registration public class MyModInitializer { public void initialize() { // Register render event with lambda EventManager.register(RenderEvent.class, event -> { // Called every render tick renderCustomOverlay(); }); // Register world change event EventManager.register(WorldEvent.class, event -> { if (event.world != null) { System.out.println("Joined world: " + event.world); } }); // Register screen open event EventManager.register(ScreenOpenEvent.class, event -> { if (event.screen != null) { System.out.println("Opening screen: " + event.screen.getClass()); } }); } private void renderCustomOverlay() { // Custom rendering logic } } // Method 2: Annotation-based registration public class MyEventListener { @Subscribe public void onRender(RenderEvent event) { // Called every render tick updateAnimations(); } @Subscribe public void onHudRender(HudRenderEvent event) { // Called during HUD rendering drawCustomHud(event.context); } @Subscribe public void onWorldChange(WorldEvent event) { if (event.world == null) { System.out.println("Left world"); cleanup(); } } @Subscribe public void onResize(ResizeEvent event) { System.out.println("Window resized to: " + event.width + "x" + event.height); rescaleUI(event.width, event.height); } private void updateAnimations() { /* ... */ } private void drawCustomHud(Object context) { /* ... */ } private void cleanup() { /* ... */ } private void rescaleUI(int w, int h) { /* ... */ } // Register this listener public void register() { EventManager.register(this); } // Unregister this listener (requires removable=true) public void unregister() { EventManager.unregister(this); } } // Method 3: Self-removing event handler public class OneTimeSetup { public void registerInitEvent() { EventManager.register( EventHandler.ofRemoving(InitializationEvent.class, event -> { System.out.println("OneConfig initialized!"); performSetup(); return true; // Return true to unregister after first call }) ); } private void performSetup() { // One-time initialization logic } } ``` -------------------------------- ### Create Simple Text HUD (Kotlin) Source: https://context7.com/polyfrost/oneconfig/llms.txt Implements a basic text HUD to display the FPS counter. It supports showing an average FPS and customizing the text color. The update frequency is set to once per second. This HUD relies on a placeholder function for fetching current FPS. ```kotlin package com.example.mymod import org.polyfrost.oneconfig.api.hud.v1.Hud import org.polyfrost.oneconfig.api.hud.v1.HudManager import org.polyfrost.oneconfig.api.hud.v1.TextHud import org.polyfrost.oneconfig.api.config.v1.annotations.* import org.polyfrost.polyui.component.impl.Block import org.polyfrost.polyui.component.impl.Text import org.polyfrost.polyui.unit.* import org.polyfrost.polyui.color.PolyColor // Simple text HUD class FpsCounterHud : TextHud( "fps_counter", "FPS Counter", Category.INFO, "FPS: 60" // Initial text ) { @Switch(title = "Show Average") var showAverage = false @Color(title = "Text Color") var textColor = PolyColor.WHITE private var frameCount = 0 private var totalFps = 0.0 override fun update(): Boolean { val currentFps = getCurrentFps() frameCount++ totalFps += currentFps text = if (showAverage) { "FPS: $currentFps (Avg: ${(totalFps / frameCount).toInt()})" } else { "FPS: $currentFps" } // Update text color this.hud.color = textColor return true // Size changed, trigger recalculate } override fun updateFrequency(): Long = 1_000_000_000L // 1 second in nanoseconds private fun getCurrentFps(): Int { // Get FPS from Minecraft return 60 // Placeholder } } ``` -------------------------------- ### Create Java Config Tree Programmatically with OneConfig API Source: https://context7.com/polyfrost/oneconfig/llms.txt Demonstrates the creation of a configuration tree using the OneConfig API in Java. This involves defining various property types, including simple, callback-based, nested, field-backed, and functional properties. It also covers registering the tree and accessing/modifying its properties. ```java package com.example.mymod; import org.polyfrost.oneconfig.api.config.v1.*; import java.util.Map; public class ProgrammaticConfig { public static Tree createConfigTree() { // Create root tree Tree root = Tree.tree("my_mod_config"); root.setTitle("My Mod Configuration"); // Add simple properties root.put( Properties.simple("enabled", "Enable Feature", "Main feature toggle", true, Boolean.class), Properties.simple("scale", "Scale", "UI scale factor", 100.0f, Float.class), Properties.simple("text", "Message", "Custom message", "Hello World", String.class) ); // Add property with callback Property debugProp = Properties.simple("debug", "Debug Mode", null, false, Boolean.class); debugProp.addCallback(enabled -> { System.out.println("Debug mode: " + enabled); return false; // Don't cancel change }); root.put(debugProp); // Add nested subtree Tree advancedTree = Tree.tree("advanced"); advancedTree.setTitle("Advanced Settings"); advancedTree.put( Properties.simple("timeout", "Timeout", "Request timeout in ms", 5000, Integer.class), Properties.simple("retries", "Max Retries", "Maximum retry attempts", 3, Integer.class) ); root.put(advancedTree); // Field-backed property MySettings settings = new MySettings(); try { root.put(Properties.field( "API Key", "Your API key", MySettings.class.getDeclaredField("apiKey"), settings )); } catch (NoSuchFieldException e) { e.printStackTrace(); } // Functional property (getter/setter) root.put(Properties.functional( () -> getCurrentValue(), (value) -> setCurrentValue(value), "dynamic", "Dynamic Value", "This value is computed dynamically", Integer.class )); // Register tree with ConfigManager ConfigManager.active().register(root); return root; } private static int currentValue = 0; private static int getCurrentValue() { return currentValue; } private static void setCurrentValue(int value) { currentValue = value; } // Access and modify properties public static void useConfigTree(Tree tree) { // Get property value Property enabledProp = tree.getProp("enabled"); boolean enabled = enabledProp.get(); // Set property value enabledProp.set(!enabled); // Access nested property Property timeoutProp = tree.getProp("advanced", "timeout"); System.out.println("Timeout: " + timeoutProp.get()); // Iterate over all properties tree.onAllProps((id, prop) -> { System.out.println(id + " = " + prop.get()); }); // Convert tree to map Map values = tree.unpack(); System.out.println("Config values: " + values); // Save tree ConfigManager.active().save(tree); } static class MySettings { public String apiKey = "default-key"; } } ``` -------------------------------- ### Create Mod Configs with OneConfig Annotations (Java) Source: https://context7.com/polyfrost/oneconfig/llms.txt This Java code demonstrates how to define a mod configuration class using OneConfig's annotations. It showcases various configuration options including boolean toggles, sliders, text inputs, number inputs with units, color pickers, dropdowns, radio buttons, keybinds, and collapsible sections. It also illustrates how to set up conditional visibility, option dependencies, and callbacks for value changes. ```java package com.example.mymod; import org.polyfrost.oneconfig.api.config.v1.Config; import org.polyfrost.oneconfig.api.config.v1.annotations.*; import org.polyfrost.polyui.input.PolyBind; import org.polyfrost.polyui.input.KeyModifiers; import dev.deftu.omnicore.api.client.input.OmniKeys; import org.polyfrost.oneconfig.api.ui.v1.keybind.OCKeybindHelper; public class MyModConfig extends Config { // Boolean toggle switch @Switch(title = "Enable Feature", description = "Enables the main feature") public static boolean enabled = true; // Numeric slider @Slider(title = "Scale", min = 0f, max = 200f, step = 1f) public static float scale = 100f; // Text input @Text(title = "Server IP", placeholder = "Enter server IP") public static String serverIp = "mc.hypixel.net"; // Number input with unit @Number(title = "Distance", min = 0, max = 500, unit = "blocks") public static int distance = 100; // Color picker @Color(title = "Highlight Color") public PolyColor highlightColor = PolyColor.WHITE; // Dropdown selector @Dropdown(title = "Mode", options = {"Fast", "Normal", "Slow"}) public static int modeIndex = 1; // Radio button group (for enums) @RadioButton(title = "Alignment") public static Align.Content alignment = Align.Content.Center; // Keybinding @Keybind(title = "Toggle Key", description = "Press to toggle feature") public PolyBind toggleKey = OCKeybindHelper.builder() .keys(OmniKeys.KEY_G) .mods(KeyModifiers.PRIMARY) // CTRL/CMD .does((pressed) -> { if (pressed) { enabled = !enabled; System.out.println("Feature toggled: " + enabled); } }) .register(); // Collapsible accordion section @Accordion(title = "Advanced Settings") public static class AdvancedSection { @Include // Adds enable/disable toggle for this section public static boolean enabled = false; @Slider(title = "Precision", min = 0.1f, max = 10f) public static float precision = 1.0f; @Switch(title = "Debug Mode") @DependsOn("enabled") // Only shown when section is enabled public static boolean debug = false; } // Button action @Button(title = "Reset Settings") private void resetButton() { restoreDefaults(); System.out.println("Settings reset to defaults"); } public MyModConfig() { super("my_mod", "My Mod Title", Category.QOL); // Add conditional visibility hideIf("distance", "enabled"); // Hide distance when enabled is false // Add option dependencies addDependency("scale", "enabled"); // Gray out scale when enabled is false // Add callbacks for value changes addCallback("enabled", (Boolean newValue) -> { System.out.println("Enabled changed to: " + newValue); return false; // Return true to cancel the change }); } } ``` -------------------------------- ### Create Custom Component HUD (Kotlin) Source: https://context7.com/polyfrost/oneconfig/llms.txt Implements a HUD that displays player statistics using custom UI components. It includes options to show health and position, and to customize the background color. The HUD updates every 100ms and has a default position at the top-left corner. ```kotlin // Custom component HUD class PlayerStatsHud : Hud( "player_stats", "Player Stats", Category.PLAYER ) { @Switch(title = "Show Health") var showHealth = true @Switch(title = "Show Position") var showPosition = true @Color(title = "Background Color") var bgColor = PolyColor.BLACK.withAlpha(0.5f) private lateinit var healthText: Text private lateinit var positionText: Text override fun create(): Block { // Create container with vertical layout return Block( sizes = Sizing.scaled(200f, 60f), radii = Radii.all(4f), color = bgColor ).apply { padding = Padding.all(8f) alignment = Align.Content.TopLeft // Add health text healthText = Text("Health: 20/20").apply { fontSize = 12f color = PolyColor.RED } children.add(healthText) // Add position text positionText = Text("Pos: 0, 64, 0").apply { fontSize = 12f color = PolyColor.GREEN } children.add(positionText) } } override fun update(): Boolean { var changed = false if (showHealth) { val health = getPlayerHealth() val maxHealth = getPlayerMaxHealth() healthText.text = "Health: $health/$maxHealth" healthText.renders = true changed = true } else { healthText.renders = false } if (showPosition) { val pos = getPlayerPosition() positionText.text = "Pos: ${pos.x}, ${pos.y}, ${pos.z}" positionText.renders = true changed = true } else { positionText.renders = false } // Update background color hud.color = bgColor return changed } override fun updateFrequency(): Long = 100_000_000L // 100ms override fun defaultPosition(): Vec2 = Vec2(10f, 10f) // Top-left corner override fun backgroundColor(): PolyColor = bgColor override fun minimumSize(): Vec2 = Vec2(150f, 40f) private fun getPlayerHealth(): Float = 20f private fun getPlayerMaxHealth(): Float = 20f private fun getPlayerPosition(): Vec3 = Vec3(0f, 64f, 0f) data class Vec3(val x: Float, val y: Float, val z: Float) } ``` -------------------------------- ### Register HUDs (Kotlin) Source: https://context7.com/polyfrost/oneconfig/llms.txt Provides a method to register instances of custom HUDs with the HudManager. This is essential for the HUDs to be recognized and displayed by the OneConfig system. It demonstrates registering both the FPS counter and player stats HUDs. ```kotlin // Register HUDs class HudRegistration { fun register() { HudManager.register(FpsCounterHud()) HudManager.register(PlayerStatsHud()) } } ``` -------------------------------- ### Property Migration with PreviousNames Annotation - Java Source: https://context7.com/polyfrost/oneconfig/llms.txt Demonstrates how to use the @PreviousNames annotation in Java for migrating configuration properties across different versions. It allows specifying old names for properties, ensuring compatibility when upgrading configurations. ```java package com.example.mymod; import org.polyfrost.oneconfig.api.config.v1.*; import org.polyfrost.oneconfig.api.config.v1.serialize.ObjectSerializer; import org.polyfrost.oneconfig.api.config.v1.annotations.PreviousNames; import com.google.gson.*; public class AdvancedConfigFeatures { // Config with property migration public static class MigratingConfig extends Config { @PreviousNames({"oldEnabled", "wasEnabled"}) @Switch(title = "Enabled") public boolean enabled = true; @PreviousNames({"oldScale"}) @Slider(title = "Scale", min = 0f, max = 2f) public float scale = 1.0f; public MigratingConfig() { super("migrating_config", "Migrating Config", Category.OTHER); // Add migration entries for nested properties addMigrationEntry("settings.oldValue", "settings.newValue"); addMigrationEntry("advanced.timeout_ms", "advanced.timeout"); } } // Custom type adapter for serialization public static class CustomType { public int x, y, z; public CustomType(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } } public static void registerCustomTypeAdapter() { ObjectSerializer.registerTypeAdapter(CustomType.class, new JsonSerializer() { @Override public JsonElement serialize(CustomType src, java.lang.reflect.Type typeOfSrc, JsonSerializationContext context) { JsonObject obj = new JsonObject(); obj.addProperty("x", src.x); obj.addProperty("y", src.y); obj.addProperty("z", src.z); return obj; } }); ObjectSerializer.registerTypeAdapter(CustomType.class, new JsonDeserializer() { @Override public CustomType deserialize(JsonElement json, java.lang.reflect.Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject obj = json.getAsJsonObject(); return new CustomType( obj.get("x").getAsInt(), obj.get("y").getAsInt(), obj.get("z").getAsInt() ); } }); } // Config using custom type public static class ConfigWithCustomType extends Config { public CustomType position = new CustomType(0, 64, 0); @Switch(title = "Use Custom Position") public boolean useCustomPos = false; public ConfigWithCustomType() { super("custom_type_config", "Custom Type Config", Category.OTHER); } } // Manual config loading and saving public static void manualConfigOperations() { // Load config from specific path ConfigWithCustomType config = new ConfigWithCustomType(); config.loadFrom("old_config_name"); // Save config config.save(); // Restore defaults config.restoreDefaults(); // Restore specific property config.restoreProperty("useCustomPos"); // Access tree directly Tree tree = config.getTree(); Property prop = tree.getProp("useCustomPos"); System.out.println("Value: " + prop.get()); } } ``` -------------------------------- ### Custom Type Serialization with Gson - Java Source: https://context7.com/polyfrost/oneconfig/llms.txt Illustrates how to register custom type adapters for Gson serialization and deserialization in Java. This allows handling complex custom objects like `CustomType` by defining how they are converted to and from JSON. ```java package com.example.mymod; import org.polyfrost.oneconfig.api.config.v1.*; import org.polyfrost.oneconfig.api.config.v1.serialize.ObjectSerializer; import org.polyfrost.oneconfig.api.config.v1.annotations.PreviousNames; import com.google.gson.*; public class AdvancedConfigFeatures { // Config with property migration public static class MigratingConfig extends Config { @PreviousNames({"oldEnabled", "wasEnabled"}) @Switch(title = "Enabled") public boolean enabled = true; @PreviousNames({"oldScale"}) @Slider(title = "Scale", min = 0f, max = 2f) public float scale = 1.0f; public MigratingConfig() { super("migrating_config", "Migrating Config", Category.OTHER); // Add migration entries for nested properties addMigrationEntry("settings.oldValue", "settings.newValue"); addMigrationEntry("advanced.timeout_ms", "advanced.timeout"); } } // Custom type adapter for serialization public static class CustomType { public int x, y, z; public CustomType(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } } public static void registerCustomTypeAdapter() { ObjectSerializer.registerTypeAdapter(CustomType.class, new JsonSerializer() { @Override public JsonElement serialize(CustomType src, java.lang.reflect.Type typeOfSrc, JsonSerializationContext context) { JsonObject obj = new JsonObject(); obj.addProperty("x", src.x); obj.addProperty("y", src.y); obj.addProperty("z", src.z); return obj; } }); ObjectSerializer.registerTypeAdapter(CustomType.class, new JsonDeserializer() { @Override public CustomType deserialize(JsonElement json, java.lang.reflect.Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject obj = json.getAsJsonObject(); return new CustomType( obj.get("x").getAsInt(), obj.get("y").getAsInt(), obj.get("z").getAsInt() ); } }); } // Config using custom type public static class ConfigWithCustomType extends Config { public CustomType position = new CustomType(0, 64, 0); @Switch(title = "Use Custom Position") public boolean useCustomPos = false; public ConfigWithCustomType() { super("custom_type_config", "Custom Type Config", Category.OTHER); } } // Manual config loading and saving public static void manualConfigOperations() { // Load config from specific path ConfigWithCustomType config = new ConfigWithCustomType(); config.loadFrom("old_config_name"); // Save config config.save(); // Restore defaults config.restoreDefaults(); // Restore specific property config.restoreProperty("useCustomPos"); // Access tree directly Tree tree = config.getTree(); Property prop = tree.getProp("useCustomPos"); System.out.println("Value: " + prop.get()); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.