Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/02/23 in all areas

  1. Detection I was working on my first mod recently, and needed to detect another one (CC: Tweaked) for the purpose of loading optional integration with it. I only encountered threads on this forum which were very old and used an API which no longer exists in Forge to accomplish this. So, for posterity, the correct thing to use to detect another mod is: ModList.get().isLoaded("mod_id_goes_here") ModList is a class in the net.minecraftforge.fml package, and can be imported like: import net.minecraftforge.fml.ModList; Integration To actually integrate with another mod, it seems like you'll want to run some code which uses classes from the other mod. To do this without introducing a hard dependency on that mod (i.e., to retain the ability to run without it being there), you need to split the code which requires it out into its own class, and then load that class using Class.forName("YourClass") and avoid directly using that class. Instead, dynamically lookup the entry point method for your integration with something like your_class.getDeclaredMethod("yourEntryPoint") and invoke it with invoke. A complete loading side example might look something like: import net.minecraftforge.fml.ModList; import java.lang.reflect.InvocationTargetException; if (ModList.get().isLoaded("other_mod_id")) { try { var yourClass = Class.forName("YourIntegrationClass"); var yourMethod = yourClass.getDeclaredMethod("loadIntegration"); yourMethod.invoke(null, new Object[0]); } catch (ClassNotFoundException e) { // fail out in your preferred way, for the case where the integration class somehow isn't in your mod jar } catch (NoSuchMethodException e) { // fail out in your preferred way, for the case where the method named here doesn't exist. possibly a typo on your part. } catch (InvocationTargetException e) { // fail out in your preferred way, for the case where the method called throws its own exception } // okay, I didn't feel like listing all of the failure cases out like that. // there are additional exceptions to handle here. not all are mandatory, but here's the remaining as an unordered list: // - LinkageError // - ExceptionInInitializerError // - NullPointerException // - SecurityException // - IllegalAccessException // - IllegalArgumentException }
    1 point
  2. disclaimer: i do not know what you are asking. i'll guess and maybe this will cover your question: so you have two ores: ore1 and ore2. register blocks (smoothstone ore, deepslate ore, storage block) unconditionally. add them to tags. crafting and machine recipes should use tags only. register items (ingots, nuggets, dusts, raw ores...) unconditionally. assign tags to items. worldgen (ores in terrain) can and should be conditional - if i don't want your ore2 (maybe another mods add the same or i just don't want it) then let me not have it generated. do not worry about duplicates from other mods, just add tags and that's that.
    1 point
  3. If you have been a modder prior to 1.13, you would know about a thing called OreDictionary. OreDictionary was the forge way of creating inter-mod compatibility by allowing items to become interchangeable with other items registered under that name. This allowed recipes to use different types of the same item from different mods. This could include things like gems, ingot dust, or such things as gears or sticks. As of 1.13, Minecraft created their own system known as Tags. This version of inter-compatibility is more powerful than OreDictionary. Since Minecraft created the system, it allows users to have a greater interaction with the vanilla source. Tags can also hold an instance of another tag. In a modding standpoint, that also allows programmers to make their systems more dynamic such as having their machine take in a container of water rather than just a specific water bucket. It also removes the need from creating arbitrary reload listeners that could specify a list of items for greater compatibility. Recipes and advancements are the most common scenarios to use tags. Let's say I add in some planks called 'silverwood planks'. Well for starters, I could add the value to 'minecraft:planks' so that my planks can be used to create a crafting table, unlock the craft_planks advancement, or even repair shields. In a more system scenario, let's say I wanted to create a washing machine that would need a water bucket to run. Well instead of specifying a water bucket directly, I could create a tag such as 'forge:containers/water' to say that any container that holds water can be used to run this machine. Now, this does not mean you should go create a tag for every single block, item, or fluid. That would be extremely pointless and time wasting. I'm not going to create a tag called `domain:machines/washer` because I know it won't be used as an input for anything. However, if you are creating a system that you know will be commonly used or adapted in some fashion, you should make it possible to use tags to implement your specific recipe, advancement, system, etc. There are a few limitations to this system that I should review. First, commonalities between recipes. Let's say that my friend and I's mod both have emerald armor in our mod. If we both use 'forge:gems/emerald' to create our armor, then whatever recipe is registered first will be the one outputted (yes, I know I chose an example that would happen with standard emeralds too). This issue results from over-creation of unoriginal ideas. The best way of avoiding this is to be more creative in what you create, but that can be a struggle for almost any modder, including myself. To avoid this issue, if you create an item that you know will be present in many different mods, you should just use your specific item rather than tags. As far as I am aware, there is no way to pick a certain recipe output based on the inputs unless the recipe book contains some voodoo magic. Another limitation is that a tag can only take in a single instance of a specific object. This means no nbt data can be specified for any individual tag. This problem is very minor; however, due to laziness in porting or wanting to use a specific potion or arrow for example (for whatever reason), it seems to be an issue to talk about. To avoid this, don't use nbt data. If your mod still has items stored in nbt data, flatten it and create individual items. Now, of course, if you are trying to create a specific item that uses dynamic data (like a registry) this will probably not be possible. But, there shouldn't be any reason to have a single instance of a ItemStack within a tag. Just update to the current standards and try to avoid storing unnecessary information using nbt. The final limitation I will mention is in regards to naming conventions. There is no real standardized location to know how certain files are organized and whatnot. The default Minecraft and Forge ones are easy enough to implement, but what about something not within those realms? Let's go back to the water bucket example. Although I created it for 'forge:containers/water', what if somebody sees a water bucket and decides it to be 'forge:buckets/water'? Then that commonality between all mods becomes a bit more abstract to reference. The only way around this is to communicate with other creators and view their source. Take a look at how a mod stores a tag information and connect the information to what you want to specifically use. Now, this does not mean that you can't determine that an iron gear should be 'forge:gears/iron' or gold dust should be 'forge:dusts/gold'. Just realize that there are some gray areas when it comes to naming conventions and its better to be prepared than left in the dark. For my above example, I could have 'forge:buckets/water' be a subdirectory of 'forge:containers/water' and this would fix my issue. Since tags are stored in a list, you also don't need to worry about multiple people calling the same object into a specific tag. Tags are extremely important to implement and use within your mods for better compatibility with others and for a more dynamic and expandable response in your systems. If you have been avoiding using tags in your mod, especially if you are one of those people who make rubies or sapphires, go and reference them via 'forge:gems/ruby' and 'forge:gems/sapphire' instead of your specific item. So, make sure you realize the importance of using tags in your code and how to best balance what you have. If you want to learn more about tags and their uses/implementations, Forge does a good explanation of them within the docs. It should hold all the necessary links to get yourself familiarized with tags to implement them in your mod.
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.