BaseMod
Most Foundation-based mods will extend BaseMod
, which provides a lot of boilerplate code,
however most of the functionality it provides (e.g. Registration
Managers) can be used even if you don’t extend BaseMod
.
A minimal mod class would look like this. Note that for Kotlin mods being loaded through Kottle,
you have to pass true
to the kottleContext
constructor parameter.
~import com.teamwizardry.librarianlib.foundation.BaseMod;
~import net.minecraftforge.fml.common.Mod;
~
@Mod(ExampleMod.MODID)
public class ExampleMod extends BaseMod {
public static final String MODID = "examplemod";
public static ExampleMod INSTANCE;
public ExampleMod() {
INSTANCE = this;
setLoggerBaseName("Example Mod");
}
}
BaseMod
features
Override points
Trying to remember what events to do what during can be confusing and annoying, so Foundation provides pre-built methods designed to be overridden by subclasses.
commonSetup
- Called on theFMLCommonSetupEvent
clientSetup
- Called on theFMLClientSetupEvent
dedicatedServerSetup
- Called on theFMLDedicatedServerSetupEvent
interModCommsEnqueue
- Send IMC messages hereinterModCommsProcess
- Receive IMC messages heremodLoadingContextEventBus
- If you’re using a custom mod language provider, override thiscreateRegistries
- Create any custom registries hereregisterBlocks
†registerItems
†registerTileEntities
†registerEntities
†registerFluids
‡registerContainers
†registerSounds
‡
† If you can, prefer using the Registration Manager instead
of registering manually.
‡ Support for these in the Registration Manager has not been implemented yet.
Loggers
The default logger configuration for forge means that creating a logger for a specific class results
in a useless mess of a logger name. For example, creating a logger for the MessageScanner
class in
Facade would result in a logger named co.te.li.fa.co.me.MessageScanner
. That name is ugly and does
little to help identify the actual mod or class. Luckily, Foundation provides a system for making
useful loggers.
At the beginning of your mod constructor, you should call setLoggerBaseName
and give it a
human-readable mod name (e.g. "Example Mod"
). After you do that, you can get the root logger from
the mod using mod.getLogger()
or create custom loggers using mod.makeLogger("Subsystem name")
or
mod.makeLogger(SomeClass.class)
. These two methods will produce loggers named "Example Mod: Subsystem name"
and "Example Mod: SomeClass"
respectively.
This logger functionality is also available independent of BaseMod
in the ModLogManager
class.
Recommended mod structure
I won’t prescribe much organization, but I would recommend you have a set of classes (e.g.
ModBlocks
, ModItems
, ModTiles
) that handle registering and holding references to their
specific types of object. The mod class would then call methods on these classes and pass them the
mod’s Registration Manager.
~import com.teamwizardry.librarianlib.foundation.registration.BlockSpec;
~import com.teamwizardry.librarianlib.foundation.registration.LazyBlock;
~import com.teamwizardry.librarianlib.foundation.registration.RegistrationManager;
~
public class ModBlocks {
public static final LazyBlock awesomeBricks = new LazyBlock();
public static void register(RegistrationManager registrationManager) {
awesomeBricks.from(registrationManager.add(
new BlockSpec("awesome_bricks")
// ...spec configuration
));
}
}
You should also add everything to the Registration Manager during your mod’s constructor. This is to ensure everything is set up before any of important events that the Registration Manager uses.