Jump to content

[1.12.2] Soft Dependency on Capabilities


Cadiboo

Recommended Posts

Just now, NolValue said:

That wouldn't crash the code, hasCapability functions like a boolean from what I believe. 

You need to have a Capability<?> value in order to call hasCapability. The only way to get the Capability<?> instance is to access a class from the Mod itself, or as posted above the various other ways to get it.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

1 hour ago, Animefan8888 said:

The code will crash if the mod isn't loaded, seeing as how he would be getting the Capability from one of that mods classes, this post was so that he could find a way around that. And he has, but now he needs to know if an Event exists which as far as I know he will have to do something like Loader.isModLoaded and then only do his registration that way.

if(ModIsLoaded) {
  MinecraftForge.EVENT_BUS.register(new EventSubscriberThatDependsOnEvent());
} else {
  
}

?

However that goes back to this

On 10/6/2018 at 1:33 AM, jabelar said:

classes load when used. Which is supposed to be true, but technically "it depends"

 

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

23 minutes ago, Cadiboo said:

 However that goes back to this

I see two options

1. Expect it to be true

2. Make a separate mod for this specific interaction that is dependent on your mod and any other mods.

 

Or you can explain in more detail what you are trying to do with this.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Link to comment
Share on other sites

11 hours ago, Cadiboo said:

Yeah, to the EVENT_BUS

Can you explain more specifically what you're trying to do, like with an example?

 

For any code executing within an event handling method, the proxy approach (or similar approach also discussed in this thread) should work fine.

 

Then i also think it is possible to conditionally register event.

 

The key to all this is to instantiate classes with mod-dependent code dynamically. So I think you can do the same for the event handler class itself.

 

There is also the @Optional annotation system which can control class loading based on mod dependencies: 

If you use another mod's API and make calls to its methods in your code, your mod will fail to execute if the other mod isn't loaded. Although you can check if the mod is loaded with the mod loader class, that still cause failures if you've included code that calls the other mod.

It is therefore highly recommended, where possible, to use the @Optional annotation specifying the modid for the other mod. Any code marked with that annotation will only be considered for execution if a mod with that modid is loaded.

Furthermore, if the code is run once during mod loading you can organize the code by creating a secondary pre-init (or whichever FML phase you need) method in your main @Mod class and annotate it with @Optional specifying the modid of the mod you depend on. Then inside that method (and any classes that are only referenced by that method) you can freely interact with that mod and the method will only run if that mod is present.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Alright, i've skimmed this but the last part with recommending people use @Optional is just flat out wrong. It wouldn't 'not run' it would be stripped from the class. Thus any code calling it would error.

Using ASM hacks is DISCOURAGED. At the end of the day all you have to do to make your code have a soft dependency on anything else, is simply not load the code with the hard dep unless you know the dep is satisfied.

 

Have event handlers from other mods?

if (Loader.isModLoaded(modid)) BUS.register(new DepSpecificEventHandler());

Have caps that could not exist at runtime?

	@CapHolder
public static final CapabilityHolder<Foo> FOO_CAP;
	private Object myFoo = null;
	 
	TEInit(){
	  if (FOO_CAP != null) myFoo = new Foo();
	}

It really isn't that difficult. The JVM doesn't know a class exists unless the code referencing is invoked/resolved. If statements are usually enough to prevent this, if that doesn't work {something deeply resolves the code} then you can hide it even more with a Supplier

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Consider supporting the team on Patreon

Link to comment
Share on other sites

4 hours ago, LexManos said:

Alright, i've skimmed this but the last part with recommending people use @Optional is just flat out wrong. It wouldn't 'not run' it would be stripped from the class. Thus any code calling it would error.

Of course all code calling it also has to have @Optional annotation, I didn't say otherwise. The proposal is to make an @Optional-annotated method that is a pre-init handler, that in turn registers the event handling class (which is also @Optional-annotated since it will refer to custom events and probably other stuff dependent on the mod). Both the method that registers and the handling class itself would be stripped from the code if the mod isn't present. I think it would work, right?

 

Anyway, I only recommended it because he seemed to be giving up on our first (both me and VoidWalker) recommendation which was the same as yours: i.e. that conditional (based on isModLoaded() check) registration should work.

 

We have even already discussed that for the most part you can assume that the JVM and ClassLoader won't have trouble with code that references other unloaded mods unless you invoke something from the mod, and also discussed that if he's worried about trusting that he can do additional steps to protect from alternate JVM behavior.

 

So I think we've given him all the same advice -- checkIsModLoaded() and conditionally register the event handler. 

 

@Cadiboo Can you clarify what problem you're actually having with all this? I think the advice so far has been pretty clear.

Edited by jabelar

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

I'm just trying to support mods without depending on them. For example supporting machines from other mods that only have Tesla & RF Energy.

 

My question about the Event Subscriber is goes something like this

Mod (that may not exist) has a custom furnace that fires a getItemCookTime (not smelt time) event.

I want to return a non-standard cook time for one of my items.

However this is the only time that my mod and the other mod ever interact, so I don't want to make my mod dependant on it.

I'm going to be using this

if(Loader.isModLoaded(OTHER_MOD_ID)) {
  MinecraftForge.EVENT_BUS.register(()->new OtherModDependantEventSubscriber());
}

 

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

Hopefully, I'm going to try and put all this into code & see how it goes.

  • Like 1

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

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.