You can use @Optional to dynamically strip classes and methods that are not present, preventing your mod from crashing. This is useful when implementing an interface that you otherwise couldn't isolate, such as on one of your Items. See here.
Also, you can get your mod to run by only accessing other mod classes when those mods are present, as long as you have them available when you compile your source.
An example:
if (Loader.isModLoaded("battlegear2")) {
MinecraftForge.EVENT_BUS.register(new BattlegearEvents());
}
Then in BattlegearEvents, you have Forge event handlers that interact with Battlegear2 classes and such. If BG2 is not installed, then that code is never accessed and you can play on.
Dynamic class/method operations can be further made outside Forge-specific methods by using Java's reflection. You can use stuff like getClass and null checks and operate on them; though you'd usually still want an API to make it easier (a skeleton or "stub" package/classes is a possible way of making an API i.e. to get it to compile without the Java compiler complaining, where these references would be replaced by the real mods' packages/classes if present). Note however that this is not only more prone to bugs since your IDE can't error check the string literals, but you have to work-around any possible obfuscation - Forge has some helper classes for this type of thing.
The Meaning of Life, the Universe, and Everything.
Join Date:
10/20/2012
Posts:
50
Member Details
Just to compliment CosmicDan post, if you want anything close to a conditional import (out of forge), like you pointed out, you will need to look not only at reflection but at a custom classloader.
Soft dependencies can be handled in the @MOD annotation by using the "after:<mod>" or "before:<mod>" instructions.
If your mod requires another mod to be loaded then you specify "required-after:<mod>".
If you mod supports another mod if present, but doesn't require it, you can specify "after:<mod>" to ensure that your mod will run after it...if it is present. Then you have to use the "Loader.isModLoaded()" call around anything that would use the mod to prevent your mod from crashing.
What's the best way to organize the mod code to handle this?
You would also want to add a soft dependency for the mods in your @Mod annotation to ensure your mod is loading after them.
AFAIK there is no conditional import in Java.
If the class is never loaded, it should be okay. Else, simply use full class names. (it might work anyways, I have never tried.)
Also, you can get your mod to run by only accessing other mod classes when those mods are present, as long as you have them available when you compile your source.
An example:
Then in BattlegearEvents, you have Forge event handlers that interact with Battlegear2 classes and such. If BG2 is not installed, then that code is never accessed and you can play on.
I was thinking about dividing the mod into submods with different dependencies, all hooked to the base mod's API if necessary.
Soft dependencies can be handled in the @MOD annotation by using the "after:<mod>" or "before:<mod>" instructions.
If your mod requires another mod to be loaded then you specify "required-after:<mod>".
If you mod supports another mod if present, but doesn't require it, you can specify "after:<mod>" to ensure that your mod will run after it...if it is present. Then you have to use the "Loader.isModLoaded()" call around anything that would use the mod to prevent your mod from crashing.
sboy205, don't bump year old posts that have already been answered.
Matter Overdrive co-developer. Maker of a number of other mods. Temporal Reality lead developer. Open source connoisseur.