In order for your mod to be loaded, you must create a mod-loader specific entrypoint inside each corresponding mod-loader subproject, and register your mod with Balm inside.
To do that, you need to add calls to Balm.initializeMod() in each of your entrypoints - that is your ModInitializer on Fabric, and your @Mod class constructors in Neo/Forge.
Similarly, your ClientModInitializer and your client-side @Mod class (NeoForge only) should use BalmClient.initializeMod(). On Forge, wrap this call in a FMLEnvironment.dist.isClient() check. Examples for each mod loader are provided below.
Your mod must come with a neoforge.mods.toml file that defines the metadata, dependencies and mixin configurations to load.
Refer to the NeoForge documentation to learn more.
@Mod(Waystones.MOD_ID)
public class NeoForgeWaystones {
public NeoForgeWaystones(IEventBus modEventBus) {
final var loadContext = new NeoForgeLoadContext(modEventBus);
Balm.initializeMod(Waystones.MOD_ID, loadContext, Waystones::initialize);
}
}
@Mod(value = Waystones.MOD_ID, dist = Dist.CLIENT)
public class NeoForgeWaystonesClient {
public NeoForgeWaystonesClient(IEventBus modEventBus) {
final var loadContext = new NeoForgeLoadContext(modEventBus);
BalmClient.initializeMod(Waystones.MOD_ID, loadContext, WaystonesClient::initialize);
}
}
Your mod must come with a fabric.mod.json file that defines the main and client entrypoints to your entrypoint classes as well as all other metadata.
Refer to the Fabric documentation to learn more.
modmenu entrypoint if you want to provide your own configuration screen or make other changes.public class FabricWaystones implements ModInitializer {
@Override
public void onInitialize() {
Balm.initializeMod(Waystones.MOD_ID, FabricLoadContext.INSTANCE, Waystones::initialize);
}
}
public class FabricWaystonesClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
BalmClient.initializeMod(Waystones.MOD_ID, FabricLoadContext.INSTANCE, WaystonesClient::initialize);
}
}
Your mod must come with a mods.toml file that defines the metadata and dependencies to load.
Refer to the Forge documentation to learn more.
Also note that Forge uses the MixinConfigs manifest attribute to define mixin configurations.
On the template projects this is already taken care of, but otherwise you may have to adjust your gradle files to set the attribute accordingly.
@Mod(Waystones.MOD_ID)
public class ForgeWaystones {
final var loadContext = new ForgeLoadContext(context.getModEventBus());
Balm.initialize(Waystones.MOD_ID, loadContext, Waystones::initialize);
if (FMLEnvironment.dist.isClient()) {
BalmClient.initialize(Waystones.MOD_ID, loadContext, WaystonesClient::initialize);
}
}
The mod-loader specific entrypoints are also a good place to initialize addon compatibility classes that are only present in your mod-loader subprojects.
You can use Balm.initializeIfLoaded to only load the given class if the mod is present, avoiding a hard dependency on the third party mod.
Balm.initializeIfLoaded("exnihilosequentia", "net.blay09.mods.excompressum.compat.ExNihiloSequentiaIntegration");
YourIntegration.class.getName() as that will cause the class to be loaded even if the third party mod isn't present, which would lead to a crash if that class happens to access any classes from the third party mod.