Jump to content

IceMetalPunk

Members
  • Posts

    402
  • Joined

  • Last visited

Posts posted by IceMetalPunk

  1. I finally got the Forge MDK for 1.15.2 to install properly on my computer after months of frustration, so yay for that! But I haven't modded since 1.12, and man, things have changed. So I'm going to need some help from the community...

     

    I would like to create a furnace recipe that has no output. You put the item (probably will be redstone dust) in the input of a furnace with fuel, and it burns away, but leaves no output. (There will be tile entity things happening that will make this worthwhile.) Turns out, the vanilla recipe manager can't handle this: creating a recipe with the result being minecraft:air just doesn't work at all. So it seems like I'll have to create a custom recipe type... but wow, it's very different than 1.12! I can't seem to find any tutorials on it. It seems like the _factories.json is completely gone, and now there's some kind of three-part system, with recipes, serializers, and factories all being required for this? The Forge documentation seems out of date, still showing the _factories.json approach.

     

    I tried looking through some of the vanilla recipe serializers and using the blasting recipe class/serializer as a base for my own, but it's not working. I have this as my recipe class:

     

    package com.icemetalpunk.scarlet_alchemy.recipes;
    
    import com.icemetalpunk.scarlet_alchemy.ScarletAlchemy;
    
    import net.minecraft.item.ItemStack;
    import net.minecraft.item.Items;
    import net.minecraft.item.crafting.AbstractCookingRecipe;
    import net.minecraft.item.crafting.CookingRecipeSerializer;
    import net.minecraft.item.crafting.IRecipeSerializer;
    import net.minecraft.item.crafting.IRecipeType;
    import net.minecraft.item.crafting.Ingredient;
    import net.minecraft.util.ResourceLocation;
    
    public class VaporizingRecipe extends AbstractCookingRecipe {
    	static ResourceLocation RES_LOC = new ResourceLocation(ScarletAlchemy.MOD_ID, "vaporizing");
    	static IRecipeType<VaporizingRecipe> VAPORIZING_RECIPE_TYPE = IRecipeType.register("vaporizing");
    	static CookingRecipeSerializer<VaporizingRecipe> SERIALIZER = IRecipeSerializer.register("vaporizing",
    			new CookingRecipeSerializer<VaporizingRecipe>(VaporizingRecipe::new, 100));
    
    	public VaporizingRecipe(ResourceLocation idIn, String groupIn, Ingredient ingredientIn, ItemStack resultIn,
    			float experienceIn, int cookTimeIn) {
    		super(VAPORIZING_RECIPE_TYPE, RES_LOC, groupIn, ingredientIn, new ItemStack(Items.AIR, 0), experienceIn,
    				cookTimeIn);
    	}
    
    	@Override
    	public IRecipeSerializer<?> getSerializer() {
    		return SERIALIZER;
    	}
    }

     

    But Eclipse shows the error: "The type CookingRecipeSerializer<T>.IFactory<VaporizingRecipe> from the descriptor computed for the target context is not visible here."

     

    How exactly am I supposed to define a serializer based on the cooking recipe serializer? Do I actually need to create an entirely new class that copies all the code from CookingRecipeSerializer but which exposes its IFactory? The fields it uses are private, so I can't even extend it properly... There must be a cleaner way that I don't know about, right?

  2. On 1/26/2020 at 8:23 AM, GenElectrovise said:

    Hi what version of java are you using? I'm trying rn to set up a 1.15.2 workspace to also update from 1.12.2, and I fixed the error I was having (When importing the gradle project) by downgrading my java version to 8u241? I think ForgeGradle supports up to java 10?

    Looking through my old 1.12.2 workspace, I can't see an "eclipse" folder tho.

     

    Ps Just realised this thread is from December :/. Hope this helps someone a bit? Have you resolved this issue?

     

    I haven't found a solution. I'm using JDK/JRE 1.8.0u231, so that's definitely not the issue here :(

  3. It's been awhile since I've modded, and things have changed a bit since 1.12. I just downloaded the MDK for 1.15 (-29.0.4) and tried to set up a new project for Eclipse. I ran gradlew genEclipseRuns and then gradlew eclipse and it said everything built successfully. But then when I try to select my project as a workspace in Eclipse, the Package Explorer is just empty, with no files. I tried running gradlew clean and then the other two again, and nothing changed. I've tried pointing the workspace to the main project directory as well as the src directory, neither work. (I could swear in Forge for 1.12 there was an eclipse directory generated, but there's none here.) I tried importing it as a Gradle project from within Eclipse, and during the process some error pops up and then disappears too quickly for me to see (nothing shows in any logs); the Package Explorer remains empty. I haven't modified the build file or done anything to the default files except running the commands I mentioned in the order I mentioned them.

     

    Can anyone please help me get a new 1.15 project started with Eclipse? Thanks.

  4. 13 hours ago, drcrazy said:

    As for eclipse  - there is issue currently with eclipse not able to launch your mod using launch configuration. Use gradlew runClient instead.  In 1.12 eclipse is fine to both build and run. Hope same will be for 1.13.2

    That's unfortunate... as far as I can tell, Eclipse doesn't have a terminal, and trying to look through output in PowerShell is... ugh. Well, I'll try and sort through it all and see if the problem is solved in the latest (ish) revision. Thanks to both of you!

  5. 37 minutes ago, drcrazy said:

    You can change it via gradle.properties in project root. Just put

    
    org.gradle.java.home=<path>

    into it

    That worked, thanks! And now I'm going to have to ask what is likely a very stupid question... Until now, whenever I've worked with Forge (including the previous build for 1.13 from like a week or two ago), the Gradle build process has set up run configurations automatically. So I never really paid attention to the settings for the Client and Server run configs. This build didn't seem to do that; is there a quick rundown of what the various options need to be for each configuration? (That is, that main class for each, any required arguments, and any required environment variable setup.) I'm fine with the coding, but when it comes to IDE settings, I tend to feel a bit like a 5-year-old sometimes -_- But of course I can't test if I can't run, so... yeah.

  6. Hm... the latest version won't build at all. I've gotten everything setup for Eclipse, and the project imported into Eclipse, but there are no configurations. When I try to run the Gradle "build" task, it fails, because it's looking in my JRE folder instead of my JDK folder. My JAVA_HOME environment variables are set to point to the JDK directory... is there somewhere else I need to change a path definition?

  7. I just set up Forge for 1.13.2, and in an effort to ensure I set everything up correctly (since it's a bit different than older versions of Forge), I just ran the example mod under the Client configuration. It runs just fine... but I'm not seeing any of the example output. (I removed debug-level logging from the Java arguments, but as you can see, info-level logging shows up fine, just not the logs from the mod itself). I've attached the entire console logs from starting it, then quitting from the main menu without doing anything. In the main example mod code, there are logs like "HELLO FROM PREINIT" and such, but those didn't show up anywhere in the console.

    Is there an extra step that I need to do besides importing the Gradle project and running the "eclipse" task? (The fact that the project shows in my Package Explorer just fine and also runs just fine would suggest I set it up mostly correctly... I just don't know why I'm not getting any of the mod output.)

    forge_1.13_test.log

  8. 21 hours ago, Animefan8888 said:

    Is the apply method even being called?

    Yep. Not only is the compass pointing to the right direction, but any debug logging added to the apply method is output. It's just somehow applying to all copies of that item, even in different item stacks with different NBT data. (At least, they should have different NBT data. I'm about to start debugging now.)

     

    EDIT More debugging later... according to the apply() method, they *are* being called with different stacks, which *do* have different NBT data, as they should. But they're still rendering the same even though their overrides are being called with different data...

    EDIT 2 I've done some more investigation. I now know the stack trace (for lack of a better phrase) by which items are rendered into GUI slots.

    1. GuiContainer calls drawSlot(), which grabs the item stack from its given slot index.
    2. That calls RenderItem#renderItemAndEffectIntoGUI(), passing it the stack.
    3. That passes the item stack over to its getItemModelWithOverrides() method, and the result is passed to renderItemModelIntoGui(), which ultimately actually renders the item.
    4. getItemModelWithOverrides() passes the stack to ItemOverrideList#handleItemState().
    5. That passes the stack to its applyOverride() method. That passes the stack to ItemOverride#matchesItemStack(), for each ItemOverride in its list (which is populated with the overrides from the JSON model on construction).
    6. And finally, that passes the stack to the PropertyGetter's apply() method that we all know and love by now.

    Nowhere along that path is the stack altered, and debug output on the apply() method shows the two stacks I have contain different NBT tags being used in the getPosToAngle() method.

    Whew. That was a long path. And yet, at the end of it... each stack should be rendering separately! So why are they rendering identically? (Literally, I can change the NBT tags of one stack, and both models change simultaneously instead of just the one from the stack I changed.)

  9. 3 minutes ago, Daeruin said:

    I'm not sure I agree 100%. I've been hearing that Forge will take several months to be ready. If your Java knowledge is solid, you could get a lot done in that time and learn a lot of concepts that will remain the same. However, if your mod has anything to do with world gen, I would definitely wait. And if you don't know Java very well, I would recommend spending a few months getting your Java knowledge solid while you wait.

    I don't know about that. World gen changed, but so did block handling, item handling, command handling, and tons more. And from what I've seen on Twitter, Forge itself is getting a huge refactoring in response as well. So I'm not sure if the amount that remains unchanged will be all that significant... For people who already know how to work with Forge for 1.12.2, there's definitely enough time to make another mod. But for people who have never used it... I don't think there's enough time to learn Forge*and* make a complete mod before having to re-learn Forge for 1.13.

  10. Yep, everything's working now that I've switched over to the no-common-proxy style :) I still have an issue where *all* Ender Compasses point to the same location, even though the stack is being passed into the property override and the stacks should have different tags being read by the IPropertyGetter's methods. But that's a bug for a different day, as it's 1AM here now. (Unless someone wants to take a look at the ItemEnderCompass in the latest commit on the branch I linked to above... but if not, that's fine, I'll work on it tomorrow-ish.)

     

    Thanks!

  11. 5 minutes ago, Animefan8888 said:

    Ahh I see, my bad I've never seen someone have two ModelRegistryEvents and separated them between Blocks and Items. Speaking of which, don't, you only need one.

     

    Your problem is that since you are calling the super method in your client proxy the item is being added to the common proxies items and not the client proxies. Don't have two instances, only have one Registry Event per type.

    I admit I'm not as familiar with Java as I am with other languages, but... is that how inheritance works? If A extends B, and B calls a super method from A, doesn't that method still reference fields from B which override fields from A? (So in this case, since ClientProxy extends ServerProxy, and ClientProxy also overrides the blocks and items fields, shouldn't references to blocks and items point to the ones from ClientProxy?)

     

    *EDIT* Welp, my lack of Java knowledge has bitten me today, it seems. A quick Google (now that I know what to look for) tells me that fields in Java can be shadowed, but not truly overridden. Blech. Okay, time to merge in the refactor and move more stuff around... thanks.

  12. 14 minutes ago, Animefan8888 said:

    You need to have a ModelRegistryEvent to register your models. Also take a look at Code Styles #1 and #3.

    I do... if you look at the ItemRegistry and BlockRegistry (in the api package), they both listen for the ModelRegistryEvent and only fire the model registry methods on their items/blocks then.

    As for the coding styles, I guess that makes sense, and I can change it once I get things working here. (Correction: I have fixed it on the master branch, and am waiting to merge those changes into this Ender Compass feature branch until the item works, because I'd rather deal with all merge conflicts at once.)

  13. *EDIT* The original issue has been solved, but it's led to a related issue. Please check out that issue down below, in this reply. If you can help get this working 100% instead of just 75%, I'd appreciate it! :)

     

    The repo/branch for this issue is the same, still here: https://github.com/IceMetalPunk/Magical-Meta/tree/feature/ender-compass

    Original post kept for context and archival purposes:

    ==========================================================================================================

    I'm working on adding an item that's basically a compass, except it points to a player-set location instead of the spawn point. So I more or less copied over ItemCompass's property override for "angle", its model files, and its textures (and made the appropriate changes). And then when I load the game... it's the purple-and-black "not found" model and texture. I get no errors in the console. So I started throwing debug logging around, and it looks like my models are never being registered. Yet I can't figure out why.

    Here's the repo and branch where I'm working on this: https://github.com/IceMetalPunk/Magical-Meta/tree/feature/ender-compass

     

    Ultimately, I'd expect things to work like this: proxy instantiates ItemRegistry and adds an instance of ItemEnderCompass to it. ItemRegistry listens for events to register it, including the ModelRegistryEvent, during which (if it's on the client, i.e. instantiated by the ClientProxy) it'll call the item's registerModel() method. At that point, the model from the assets/magicalmeta/models folder will load, including the model overrides for the "angle" property, like a normal compass.

    But somehow, the debug logging I added to the BasicItem#registerModel method isn't showing up, which tells me the model isn't being registered at all.
    What am I missing here? It's been a little while since I've dealt with the foundations of Forge, so I know I'm rusty, but I just don't see the issue.

  14. 17 minutes ago, Animefan8888 said:

    Force them to use a Block or Ite instance then you can limit that by making methods that add them, but only take a Block or an Item.

     

    Hence why I said

    And make the constructor of the OreDictManager be protected so only classes extending it or in the same package can access instances of it. 

    ...I think I misread your original post >_< . I also have no idea why I didn't think of using a protected constructor with inheritance... that would probably be the best way to do this! Thank you! I'll be implementing it tomorrow-ish, as it's late here, and then I'll post with the results.

  15. 9 minutes ago, Animefan8888 said:

    I dont see why this is a problem actually, are you the only one using this code? If so then you should know that the only two types it can accept are Blocks and Items.

    Ultimately you could make two classes that extend your OreDictManager that explicitly uses Item and Block respectively and possibly make your OreDictManager abstract unless there won't be a difference between the two functionally.

    For now, yes, but I may allow IMC-based registration for other mods in the future. And the two have identical functionality, but because they (a) need to return the bound object from some methods and (b) call ore dictionary methods which exist only for Items and Blocks... well, you see the problem.

    I suppose I could just make two different classes that are identical except for the data types that those particular methods return/use... that seems like a ton of repetition, though, and I was always taught that the DRY approach is the best, for various reasons.

     

    *EDIT* A little more background about what this OreDictManager does: I'm using it so that blocks and items can supply ore prefixes and suffixes, and every combination will be registered automatically for them. So for instance, if I wanted an item to be registered as nuggetIron, nuggetFerrous, coinIron, coinFerrous, shardIron, and shardFerrous; rather than registering all those manually, I could just register the prefixes "nugget", "coin", and "shard" with the item's OreDictManager, and the suffixes "Iron" and "Ferrous", and all combinations will be registered automatically when appropriate. So I could use something like this:
     

    this.oreDictManager.registerSuffixes("Iron", "Ferrous");
    this.oreDictManager.registerPrefixes("nugget", "coin", "shard");

    Wouldn't even have to make any calls to the OreDictionary itself, as the manager handles that.

  16. 11 minutes ago, Draco18s said:

    Only do items and handle blocks if they are ItemBlock?

    Hm... Looking back at my code, I may be able to make it work with just ItemStacks instead... and only Items and Blocks can be passed to an ItemStack's constructor, right? So that'll at least move the burden of exception handling onto the code instantiating the OreDictManager rather than anywhere else... I'll try that and see if it looks cleaner...

    *EDIT* Wait, no, shoot. One reason I went with templating was so that the OreDictManager's methods could return the original object, for method chaining. I can't do that if it's not actually templated...

  17. I have a class that extends Block. It also has composed in it a different, generic, class: OreDictManager. So in other words, the structure is basically this:
     

    public class BasicBlock extends Block {
        private final OreDictManager<Block> oreDictManager;
    }

    I'm actually instantiating the new OreDictManager<Block> in the BasicBlock's constructor; the OreDictManager's constructor takes "this" as a parameter to bind the two together.

    But here's the problem I'm having: the OreDictManager can manage either Block or Item classes. I don't want it to be able to be called with any other type. I couldn't find a way to have a Java generic that could take only two different classes which don't share a common ancestor, so instead I'm explicitly checking if the passed in argument's class is assignable from Block or Item, and throwing an exception in the OreDictManager's constructor if not.

    My mod will be adding several BasicBlock instances to a list, but if any of them throw an exception upon instantiation, they shouldn't be added to the list. So what I figured was I'd just allow the exception thrown in OreDictManager's constructor to bubble up through BasicBlock's constructor, and in the registry code that adds the blocks to a list, just put a try/catch around the instantiation and list-adding.

    But that's the problem: I don't know if this is the right approach. If I do this, there would be no code in the catch block, as I simply want the BasicBlock that failed instantiation to just not be added to the list. On the other hand, a try without a catch feels a bit like a bad habit.

    What's the best way to handle this?

  18. So you don't want something that's similar, you want someone to update the actual mod? Unfortunately, that's illegal, unless you get the original author's permission (that is, permission from mister_person). By default, the code is his and only he has the rights to it, unless he gives permission for others to modify or distribute it. But even more, he explicitly put a copyright notice on his post about the mod, saying that any derivative mod can only be distributed with his explicit permission.

    So without his permission, it's just illegal for anyone to update it for you. (He did, however, give permission for people to modify it for their own personal use. When "private use" becomes "public" is not a legal line I'm sure of, but having someone distribute it to you is a gray area I don't think it's worth the risk to take.)

  19. There are so many possible causes that without more information, it's impossible to say how to fix your issue. There are general-purpose "optimization" mods, like BetterFPS and Optifine that you could try which might help. (Note, though: you are not legally allowed to distribute a modpack with Optifine in it, so only use Optifine if you're just making the pack for yourself. BetterFPS should be fine to distribute.)

  20. How hard something is depends on your experience and your skills. But if you have no experience with modding at all, custom map displays may not be a good place to start. They depend on the interaction between many classes to display properly (ItemMap, MapData, ItemRenderer, and MapItemRenderer), so it's not as simple as just rendering some text.

    If you look at this topic you''ll see Major Squirrel tried doing something similar, and was only able to make it work with lots of copypasta and spaghetti code. So without modding experience, I would suggest you save this project for later and start with something smaller. (I know it may seem small in theory, but maps are unique in how they render, so it's not really as simple as it sounds.)

  21. Just now, KatherineFtw said:

    All things considered, 1.14 was rumored to be almost a total overhaul. Expect worse for that than this. The biggest problem will be worldgen/resoucegen prob for 1.12 >1.13.

    Did you hear that before or after 1.13 became the Aquatic Update (i.e. merged with what was planned for 1.14)? Because from what I heard, the devs are trying not to do any major code refactoring for a little while after 1.13.

    • Like 1
  22. I know what you mean in terms of a "starter mod"; I've gotten into the habit of using one common base for my mods and just starting each new project with that base. In my latest project (which I've lost... but that's another story), I ended up just making the starter into a library anyway. As a kind of "core library" that the other mods can rely on, with block/item bases and registrations set up how I like them.

    But I agree with the other comments here: don't use version control to split up projects. It's meant for revisions, reversions, and a commit history, which doesn't make much sense for inter-project work (for instance, you should never want to revert a new project back to  a commit before the base). That also means you don't need all the projects' histories in your tree, either. So I'd say just keep it at one repo per project, branching for various features and fixes, and then (if you don't want to make the starter into a library) copying the starter files manually for new projects and initializing them as a new repo.

×
×
  • Create New...

Important Information

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