fuzzybat23 Posted July 10, 2017 Share Posted July 10, 2017 I don't suppose anyone knows of any good tutorials on how to build a config gui in Forge? You know, when you go into the main menu, click on mods, scroll down to yours and click on Config button. One that's preferably in english? It'd be nice if Forge put out a template for those. 1 Quote Link to comment Share on other sites More sharing options...
That_Martin_Guy Posted July 10, 2017 Share Posted July 10, 2017 Which version? Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 10, 2017 Author Share Posted July 10, 2017 Oh, duh 1.12 Quote Link to comment Share on other sites More sharing options...
Choonster Posted July 11, 2017 Share Posted July 11, 2017 If you use the annotation-based config system, a config GUI will automatically be created for your mod. All you need to do is subscribe to ConfigChangedEvent.OnConfigChangedEvent, check if the event's mod ID is your mod ID and then call ConfigManager.sync to synchronise the changes made to the Configuration object (by the GUI) back to the fields of your @Config class. You can see an example of this here. 1 Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future. Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 I think I see, and I'm not even fully awake yet This is the best and simplest example I've seen yet. You don't know how to setup multiple pages in the Config screen, do you? Quote Link to comment Share on other sites More sharing options...
Choonster Posted July 11, 2017 Share Posted July 11, 2017 14 minutes ago, fuzzybat23 said: You don't know how to setup multiple pages in the Config screen, do you? Each category will be given its own page. Any field of the @Config class whose type is a class that directly extends Object will become a config category, with its fields becoming properties or categories following the same rules as the top-level class. Map fields are also mapped to categories with properties as key-value pairs. 1 Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future. Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 Let me see if my sleep addled brain got that right. Each time you declared a new public class in your example, that opened up a new category page? 1 Quote Link to comment Share on other sites More sharing options...
Choonster Posted July 11, 2017 Share Posted July 11, 2017 9 minutes ago, fuzzybat23 said: Let me see if my sleep addled brain got that right. Each time you declared a new public class in your example, that opened up a new category page? The classes could be declared anywhere, it's the fields that use those classes that are mapped to categories. 1 Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future. Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 I don't think I quite understand. I'm still learning this stuff, so I'm not up to snuff on all the terms What exactly do you mean by the fields the classes are mapped to? Quote Link to comment Share on other sites More sharing options...
Choonster Posted July 11, 2017 Share Posted July 11, 2017 (edited) 26 minutes ago, fuzzybat23 said: I don't think I quite understand. I'm still learning this stuff, so I'm not up to snuff on all the terms What exactly do you mean by the fields the classes are mapped to? Each field in the @Config class is mapped to either a configuration category or a configuration property depending on its type. If it's a type that implements Map, a category is created and a property is created in that category for each key-value pair in the Map. The Map must have String keys and primitive, primitive array, String or enum values. If it's a type that directly extends Object, a category is created and a sub-category or property is created in that category for each field of the class following the same rules as the @Config class. These classes can be declared anywhere, they don't have be nested in the @Config class. If it's a primitive, primitive array, enum or String, a property is created. If it's any other type, an error is thrown. Edited July 11, 2017 by Choonster 1 Quote Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future. Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 (edited) Which file in your Git did you initially create and populate the configuration file that your ModConfig.java syncs to? I'd like to compare it to mine. I think I'm slowly getting a grasp on the usage of @Config I'm also wondering how in your main class you initially access your ModConfig to open the Config screen. None of the examples I've seen so far were using @Config, so the structure is quite a bit different. Like.. This one for example, is some code I'm trying to convert to make use of @Config. Edited July 11, 2017 by fuzzybat23 Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 package com.mmyzd.llor; import java.io.File; import java.util.ArrayList; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Property; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class ConfigManager { public Configuration file; public Property useSkyLight; public Property displayMode; public Property chunkRadius; public Property pollingInterval; public ArrayList<String> displayModeName = new ArrayList<String>(); public ArrayList<String> displayModeDesc = new ArrayList<String>(); public ConfigManager(File configDir) { file = new Configuration(new File(configDir, "LLOverlayReloaded.cfg")); displayModeName.add("Standard"); displayModeName.add("Advanced"); displayModeName.add("Minimal"); displayModeDesc.add("Show green (safe) and red (spawnable) areas."); displayModeDesc.add("Show green (safe), red (always spawnable) and yellow (currently safe, but will be spawnable at night) areas."); displayModeDesc.add("Do not show green area. For other areas, use standard mode when not counting sky light, or advanced mode otherwise."); reload(); } @SubscribeEvent public void onConfigurationChanged(ConfigChangedEvent.OnConfigChangedEvent event) { if (event.getModID().equals(LightLevelOverlayReloaded.MODID)) update(); } void reload() { file.load(); String comment = "How to display numbers? (default: 0)"; for (int i = 0; i < displayModeName.size(); i++) { comment += "\n" + String.valueOf(i) + " - "; comment += displayModeName.get(i) + ": "; comment += displayModeDesc.get(i); } useSkyLight = file.get("general", "useSkyLight", false, "If set to true, the sunlight/moonlight will be counted in light level. (default: false)"); displayMode = file.get("general", "displayMode", 0, comment); chunkRadius = file.get("general", "chunkRadius", 3, "The distance (in chunks) of rendering radius. (default: 3)"); pollingInterval = file.get("general", "pollingInterval", 200, "The update interval (in milliseconds) of light level. Farther chunks update less frequently. (default: 200)"); update(); } public void update() { useSkyLight.set(useSkyLight.getBoolean(false)); displayMode.set(Math.min(Math.max(displayMode.getInt(0), 0), displayModeName.size() - 1)); chunkRadius.set(Math.min(Math.max(chunkRadius.getInt(3), 1), 9)); pollingInterval.set(Math.min(Math.max(pollingInterval.getInt(200), 10), 60000)); file.save(); } } Quote Link to comment Share on other sites More sharing options...
Jay Avery Posted July 11, 2017 Share Posted July 11, 2017 16 hours ago, Choonster said: If you use the annotation-based config system, a config GUI will automatically be created for your mod. Is this the case in 1.11, or is it only in 1.12+? Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 I'm working with 1.12. I guess 1.12 doesn't utilize GuiFActory at all anymore, just the @Config? Quote Link to comment Share on other sites More sharing options...
V0idWa1k3r Posted July 11, 2017 Share Posted July 11, 2017 9 minutes ago, Jay Avery said: Is this the case in 1.11, or is it only in 1.12+? It is true for 1.11 aswell. 4 minutes ago, fuzzybat23 said: I'm working with 1.12. I guess 1.12 doesn't utilize GuiFActory at all anymore, just the @Config? You can still use both. The annotation based config system is just less messy and easier to use in general. Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 Easy or not, I wish someone would make an actual tutorial for it on youtube. Quote Link to comment Share on other sites More sharing options...
Jay Avery Posted July 11, 2017 Share Posted July 11, 2017 14 minutes ago, V0idWa1k3r said: It is true for 1.11 aswell. Okay, in that case I'm confused. I've made a simple @Config class, it correctly reads the config file, but the "config" button in the mods list is still greyed out. Does the @Config class need to be registered or anything? Quote Link to comment Share on other sites More sharing options...
V0idWa1k3r Posted July 11, 2017 Share Posted July 11, 2017 1 minute ago, Jay Avery said: Does the @Config class need to be registered or anything? As far as I am aware, no. Forge just auto-detects classes annotated with Config. I had the annotation based config in 1.11.2 with the gui created for me just fine. Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 So this created the gui for you. How did you create your config file or did this automatically do that, too. And if so, where does it get the default values for the file? Quote Link to comment Share on other sites More sharing options...
V0idWa1k3r Posted July 11, 2017 Share Posted July 11, 2017 12 minutes ago, fuzzybat23 said: So this created the gui for you. How did you create your config file or did this automatically do that, too. Yes it did. I have no idea why it isn't working for Jay and I know that forge indeed automatically creates both the gui and the file for annotation based configs without you explicitly telling it to do so from multiple tests. 14 minutes ago, fuzzybat23 said: And if so, where does it get the default values for the file? It takes the values from the fields at the moment of file creation. Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 So when you did: @Config.Comment("Minimum Y coordinate for this ore") public int minHeight; It created an entry in the config file with minHeight but with no value set, where if you did: @Config.Comment("Minimum Y coordinate for this ore") public int minHeight = 20; then it would have created the config file with minHeight = 20? Quote Link to comment Share on other sites More sharing options...
V0idWa1k3r Posted July 11, 2017 Share Posted July 11, 2017 No, those fields are not static and they can't be assigned to a property as there is no object that hosts them. When I did this: public final GenSettings oreAether = new GenSettings(1, 80, 128, 4,-1, 1); It created a oreaether entry in the config file, and inside that entry it created multiple other entries with their values set according to the arguments i've passed. And this entry was created under a worldgen entry as this specified it: public static final Generation worldGen = new Generation(); So in the end for that code the config file looks like this: Spoiler # Configuration file general { worldgen { oreaether { # The list of dimension IDs this ore is NOT allowed to generate in I:blacklistDimensions < -1 1 > # Maximum Y coordinate for this ore I:maxHeight=128 # Minimum Y coordinate for this ore I:minHeight=80 # The amount of times the ore will try to generate in each chunk. Set to less than 1 to turn this into a chance to generate type of value D:triesPerChunk=1.0 # The maximum size of the vein I:veinSize=4 } } } Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 (edited) Ahhhh, I think I see. Int... blacklistDimensions ended up with -1, and 1 because they were the only two left and blacklistDimensions is an array, right? I wonder, though, why those values were placed in the order they were in your config file then I'd think that triesPerChunk would be at the top of the list, instead blacklistDimensions is. I'd say that it entered them in reverse order from how they're declared in your code, except that veinSize ends up being the last one entered into the config file. Edited July 11, 2017 by fuzzybat23 Quote Link to comment Share on other sites More sharing options...
V0idWa1k3r Posted July 11, 2017 Share Posted July 11, 2017 b -> ma -> mi -> t -> v. Looks like standard alphabetical sorting to me. Quote Link to comment Share on other sites More sharing options...
fuzzybat23 Posted July 11, 2017 Author Share Posted July 11, 2017 Oh crap, didn't notice that. My brain thinks in first in last out Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.