Jump to content

Calling ModLoader to add jarfile to loading queue


Chaos_02

Recommended Posts

Hi and first of all thanks in advance!
I am currently trying to write a mod for Forge 1.18.1 (and upwards, maybe even backport) that needs to load a mod jarfile from a subfolder and I found the net.minecraftforge.fml.ModLoader package/class which I imported in hopes of being able to just queue the jarfile with this

I have found this text when hovering over the ModLoader class:

Quote

Loads mods. Dispatch cycle is seen in #loadMods() and #finishMods() Overall sequence for loadMods is:

CONSTRUCT

Constructs the mod instance. Mods can typically setup basic environment such as Event listeners and Configuration specifications here.

Automated dispatches

Dispatches automated elements : net.minecraftforge.fml.common.Mod.EventBusSubscriber,net.minecraftforge.event.RegistryEvent, net.minecraftforge.common.capabilities.CapabilityInject and others

CONFIG_LOAD

Dispatches ConfigLoadEvent to mods

COMMON_SETUP

Dispatches net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent to mods

SIDED_SETUP

Dispatches net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent ornet.minecraftforge.fml.event.lifecycle.FMLDedicatedServerSetupEvent to mods

Overall sequence for finishMods is:

ENQUEUE_IMC

Dispatches net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent to mods, for enqueuing InterModComms messages for other mods to receive subsequently

PROCESS_IMC

Dispatches net.minecraftforge.fml.event.lifecycle.InterModProcessEvent to mods, for processing InterModComms messages received from other mods prior to this event

COMPLETE

Dispatches net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent to mods, and completes the mod loading sequence.

but I can't find any information online on what the # in #loadMods could stand for and or how I would use the class.
I am pretty new to java and using eclipse tho I think I found my way around things by now! I have previously programmed in several C derivatives but Java is my first object oriented language.

If you could help me find the right ressources and / or tell me how to use ModLoader to load a .jar file (I have the surrounding structure for finding the folder etc. already written) I would really appreciate that!
Again, thanks in advance - looking forward to getting help :)
~Chaos_02

Link to comment
Share on other sites

13 minutes ago, diesieben07 said:

Why?

Simply enough - I want to have a structure in my modfolders and since forge itself commited to not load subfolders anymore and will keep it that way according to previous questions about it I will try to do it myself!
 

EDIT: I already implemented an algorithm that filters out folders containing configurable strings but the config file itself is also not yet documented in forge docs (I found a tutorial here tho: https://forge.gemwire.uk/wiki/Configs)

Edited by Chaos_02
Link to comment
Share on other sites

3 hours ago, diesieben07 said:

This is a terrible idea... And inferior to the actual solution (separate game directories) in every way. There is a good reason why Forge does not do this anymore.

If you really want to, you can provide your own IModLocator implementation, which allows you to plug into FMLs mod loading process and provide additional mods to load. It is discovered via the standard Java service loader, see the ModDiscoverer class.

The config system is irrelevant here, as this happens before mods are even loaded.

thank you about the concern with multiple directories but I am talking about modpacks and that I can at least sort out library mods or coremods into their own folder (which I happily did in the minecraft verion folder)
Thank you for providing me with the details I need anyway though! :)
I'll consider this thread closed tho I still may have questions so will keep it open!

Link to comment
Share on other sites

54 minutes ago, diesieben07 said:

Why...?

well because it makes it easier for modpack creators to find mods that achieve a specific thing or two
or to just be able to see which mod adds content and which one does not
and by that definition filter out mods to reduce system load or size
You'll probably see the demand for such thing once I upload it to curseforge ¯\_(ツ)_/¯

Link to comment
Share on other sites

To add my modfinding (or override FML) would I need to override the net.minecraftforge.fml.loading.moddiscovery.MinecraftLocator.scanMods method?
And if yes, how do I because when I extend my main class with MinecraftLocator and @Override scanMods with an exact copy of it it gives these errors:

  1. ModJarMetadata.buildFile(...):
    The method buildFile(Function<SecureJar,IModFile>, Predicate<SecureJar>, BiPredicate<String,String>, Path...) from the type ModJarMetadata is not visible
  2. this::buildMinecraftTOML:
    The type StructuredModLoader does not define buildMinecraftTOML(IModFile) that is applicable here

I just want to add to this method, not entirely rewrite it.

Link to comment
Share on other sites

8 hours ago, diesieben07 said:

You need to implement IModLocator and provide it via ServiceLoader. Look at the ModDiscoverer constructor how it will then fetch it and use it to discover mods.

if I implement IModLocator I need to implement all methods of it - even implementing the scanMods() method is hard enough because I keep having to recursively add code from other classes, which then doesnt work outside of said class.
easiest example is the ModJarMetadata.buildFile method which is deprecated.
Eclipse shows that buildFile is invisible.
When I then copy the code of buildFile it needs the class object of ModJarMetadata which I cannot provide.

Then there's also NightConfigWrapper.setFile()
0uovZTR.png

How do I get around this???

EDIT: I think I have it figured out now. because I just want to add to the artifacts object I can override the scanMods() method while calling itself:
 

Quote

public class StructuredModLoader extends net.minecraftforge.fml.loading.moddiscovery.MinecraftLocator {

@Override
    public List<IModFile> scanMods() {
        List<IModFile> artifacts = super.scanMods();
        artifacts.addAll(ownOtherMods);
        return artifacts;
    }

}

 

Edited by Chaos_02
possible solution
Link to comment
Share on other sites

4 hours ago, diesieben07 said:

There are various classes available that you can extend. The most meaningful one probably being AbstractJarFileLocator.

Another question has come up:
How can I cast from a regular java File type to the IModFile type?
I can't find any examples in the source code where it is done except the private method createMod.

 

Link to comment
Share on other sites

@diesieben07
Hey, so with some extensieve help from literally a random guy on Discord I got the project finished!
I have noticed a "bug"? in FML tho:

Although my mod works now, I cannot add the event listeners and stuff (literally taken from the docs) in the constructor, then the Mod crashes and fails to override the scanCandidates() method of AbstractJarFileLocator. Full Stacktrace (afterwards it just loaded default mods folder), should I create an issue on gitHub?

Sadly, because of this, I was unable to use the forge config system and implemented my own with the nightconfig library. Also the Mod is currently not displayed in Minecraft in the Mods tab (looking forward!!)

My most up-to-date code is on GitHub, where you can btw also find a link to its curseforge page!
(for future reference: GitHub name will at some point be changed to StructuredModLoader instead of SubFolderLoader!!)

 

Link to comment
Share on other sites

14 hours ago, diesieben07 said:

This is not something that is to be done with a mod I think.

do you mean this?
 

@Mod("examplemod")
public class ExampleMod
{
    // Directly reference a log4j logger.
    private static final Logger LOGGER = LogManager.getLogger();

    public ExampleMod() {
        // Register the setup method for modloading
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
        // Register the enqueueIMC method for modloading
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
        // Register the processIMC method for modloading
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);

        // Register ourselves for server and other game events we are interested in
        MinecraftForge.EVENT_BUS.register(this);
    }

    private void setup(final FMLCommonSetupEvent event)
    {
        // some preinit code
        LOGGER.info("HELLO FROM PREINIT");
        LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName());
    }

from literally mdk.zip/src/main/java/com/example/examplemod/examplemod.java ?
Because, as you can see I literally copied it and then needed to comment it out because it crashes when the mod is constructed at that time

Link to comment
Share on other sites

43 minutes ago, diesieben07 said:

Yes, I don't think you want this as a mod jar. I am not 100% on the details, but ModLauncher implements a multi-module-layer system and you need to load into a specific layer.

okay thank you for clarifying!
I'll try to implement the setup method and event listeners as an extra class, maybe this works!

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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